Merge remote-tracking branch 'origin/master' into debug-next
diff --git a/CREDITS b/CREDITS index 8bdfde1..08d7529 100644 --- a/CREDITS +++ b/CREDITS
@@ -3113,6 +3113,11 @@ D: AMD Microcode loader driver S: Germany +N: Pierre Ossman +D: MMC maintainer 2006-2009 +D: First SDIO implementation +S: Sweden + N: Jens Osterkamp E: jens@de.ibm.com D: Maintainer of Spidernet network driver for Cell @@ -4414,6 +4419,18 @@ D: Linux/PARISC hacker. Filesystem hacker. Random other hacking. Custom D: PPC port hacking. +N: Dan J Williams +D: Technical Advisory Board member +D: Asynchronous Transfers/Transforms (IOAT) API, Compute Express Link (CXL), +D: Device Direct Access (DAX), Filesystem Direct Access (DAX), +D: Intel I/OAT DMA driver, libnvdimm BTT: block translation table, +D: libnvdimm PMEM: persistent memory driver, +D: libnvdimm: non-volatile memory device subsystem, +D: Trusted Execution Environment Security Manager (TSM) +D: Intel C600 SAS driver (ISCI) +D: Intel XScale IOP SOC +D: MDRAID IMSM external metadata format + N: G\"unter Windau E: gunter@mbfys.kun.nl D: Some bug fixes in the polling printer driver (lp.c)
diff --git a/Documentation/ABI/testing/ppc-memtrace b/Documentation/ABI/testing/ppc-memtrace index 9606aed..2de9fd18 100644 --- a/Documentation/ABI/testing/ppc-memtrace +++ b/Documentation/ABI/testing/ppc-memtrace
@@ -3,7 +3,7 @@ KernelVersion: 4.14 Contact: linuxppc-dev@lists.ozlabs.org Description: This folder contains the relevant debugfs files for the - hardware trace macro to use. CONFIG_PPC64_HARDWARE_TRACING + hardware trace macro to use. CONFIG_PPC_MEMTRACE must be set. What: /sys/kernel/debug/powerpc/memtrace/enable
diff --git a/Documentation/ABI/testing/sysfs-auxdisplay-linedisp b/Documentation/ABI/testing/sysfs-auxdisplay-linedisp index 55f1b55..ac9e964 100644 --- a/Documentation/ABI/testing/sysfs-auxdisplay-linedisp +++ b/Documentation/ABI/testing/sysfs-auxdisplay-linedisp
@@ -11,7 +11,8 @@ Writing an empty string clears the display. - Example: + Example:: + echo "Hello World" > message cat message # Returns "Hello World\n" @@ -23,7 +24,8 @@ Read-only attribute showing the character width capacity of the line display device. Messages longer than this will scroll. - Example: + Example:: + cat num_chars # Returns "16\n" for 16-char display What: /sys/.../scroll_step_ms @@ -35,7 +37,8 @@ Setting to 0 disables scrolling. Default is 500ms. - Example: + Example:: + echo "250" > scroll_step_ms # 4Hz scrolling cat scroll_step_ms # Returns "250\n"
diff --git a/Documentation/ABI/testing/sysfs-class-spi-master b/Documentation/ABI/testing/sysfs-class-spi-master index 0a524fc..4e1e8a7 100644 --- a/Documentation/ABI/testing/sysfs-class-spi-master +++ b/Documentation/ABI/testing/sysfs-class-spi-master
@@ -17,7 +17,8 @@ with delete_device; platform and DT devices are not affected. - Example: + Example:: + # echo spidev 0 > /sys/class/spi_master/spi0/new_device # echo spidev 0 10000000 > /sys/class/spi_master/spi0/new_device # echo spidev 0 10000000 3 > /sys/class/spi_master/spi0/new_device @@ -30,5 +31,6 @@ new_device. Takes a single parameter: the chip select number of the device to remove. - Example: + Example:: + # echo 0 > /sys/class/spi_master/spi0/delete_device
diff --git a/Documentation/ABI/testing/sysfs-driver-amd-sfh b/Documentation/ABI/testing/sysfs-driver-amd-sfh index c053126..15abd99 100644 --- a/Documentation/ABI/testing/sysfs-driver-amd-sfh +++ b/Documentation/ABI/testing/sysfs-driver-amd-sfh
@@ -11,3 +11,63 @@ Access: Read/Write Valid values: enabled/disabled + +What: /sys/bus/pci/drivers/pcie_mp2_amd/*/in_bag_state +Date: August 2026 +Contact: Basavaraj.Natikar@amd.com +Description: + Operating-mode telemetry reported by the SRA sensor that + indicates whether the device is detected inside a bag. + + Access: Read only + Valid values: unsigned integer + +What: /sys/bus/pci/drivers/pcie_mp2_amd/*/out_bag_state +Date: August 2026 +Contact: Basavaraj.Natikar@amd.com +Description: + Operating-mode telemetry reported by the SRA sensor that + indicates whether the device is detected outside a bag. + + Access: Read only + Valid values: unsigned integer + +What: /sys/bus/pci/drivers/pcie_mp2_amd/*/on_table_state +Date: August 2026 +Contact: Basavaraj.Natikar@amd.com +Description: + Operating-mode telemetry reported by the SRA sensor that + indicates whether the device is placed on a table or on a lap. + + Access: Read only + Valid values: unsigned integer + +What: /sys/bus/pci/drivers/pcie_mp2_amd/*/hinge_angle +Date: August 2026 +Contact: Basavaraj.Natikar@amd.com +Description: + Operating-mode telemetry reported by the SRA sensor that + reports the hinge angle of the device in degrees. + + Access: Read only + Valid values: unsigned integer (degrees) + +What: /sys/bus/pci/drivers/pcie_mp2_amd/*/lid_status +Date: August 2026 +Contact: Basavaraj.Natikar@amd.com +Description: + Operating-mode telemetry reported by the SRA sensor that + indicates whether the device lid is open or closed. + + Access: Read only + Valid values: unsigned integer + +What: /sys/bus/pci/drivers/pcie_mp2_amd/*/device_mode +Date: August 2026 +Contact: Basavaraj.Natikar@amd.com +Description: + Operating-mode telemetry reported by the SRA sensor that + reports the platform/device mode. + + Access: Read only + Valid values: unsigned integer
diff --git a/Documentation/ABI/testing/sysfs-driver-qat_kpt b/Documentation/ABI/testing/sysfs-driver-qat_kpt index c6480ea..80831ce 100644 --- a/Documentation/ABI/testing/sysfs-driver-qat_kpt +++ b/Documentation/ABI/testing/sysfs-driver-qat_kpt
@@ -14,7 +14,8 @@ Description: (RW) Enables or disables Key Protection Technology (KPT). - Write 1 to enable KPT, or 0 to disable it. + Write 1 to enable KPT, or 0 to disable it. The device must be + in the down state before changing the KPT state. Example usage::
diff --git a/Documentation/admin-guide/LSM/ipe.rst b/Documentation/admin-guide/LSM/ipe.rst index a756d81..9e82a20 100644 --- a/Documentation/admin-guide/LSM/ipe.rst +++ b/Documentation/admin-guide/LSM/ipe.rst
@@ -502,11 +502,11 @@ Event Examples:: type=1404 audit(1653425689.008:55): enforcing=0 old_enforcing=1 auid=4294967295 ses=4294967295 enabled=1 old-enabled=1 lsm=ipe res=1 - type=1300 audit(1653425689.008:55): arch=c000003e syscall=1 success=yes exit=2 a0=1 a1=55c1065e5c60 a2=2 a3=0 items=0 ppid=405 pid=441 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=) + type=1300 audit(1653425689.008:55): arch=c000003e syscall=1 success=yes exit=2 a0=1 a1=55c1065e5c60 a2=2 a3=0 items=0 ppid=405 pid=441 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 type=1327 audit(1653425689.008:55): proctitle="-bash" type=1404 audit(1653425689.008:55): enforcing=1 old_enforcing=0 auid=4294967295 ses=4294967295 enabled=1 old-enabled=1 lsm=ipe res=1 - type=1300 audit(1653425689.008:55): arch=c000003e syscall=1 success=yes exit=2 a0=1 a1=55c1065e5c60 a2=2 a3=0 items=0 ppid=405 pid=441 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=) + type=1300 audit(1653425689.008:55): arch=c000003e syscall=1 success=yes exit=2 a0=1 a1=55c1065e5c60 a2=2 a3=0 items=0 ppid=405 pid=441 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 type=1327 audit(1653425689.008:55): proctitle="-bash" This record will always be emitted in conjunction with a ``AUDITSYSCALL`` record for the ``write`` syscall. @@ -791,7 +791,7 @@ Additional Information ---------------------- -- `Github Repository <https://github.com/microsoft/ipe>`_ +- `IPE website <https://ipe-lsm.org/>`_ - :doc:`Developer and design docs for IPE </security/ipe>` FAQ
diff --git a/Documentation/admin-guide/LSM/landlock.rst b/Documentation/admin-guide/LSM/landlock.rst index 2998552..718e0d2 100644 --- a/Documentation/admin-guide/LSM/landlock.rst +++ b/Documentation/admin-guide/LSM/landlock.rst
@@ -7,7 +7,7 @@ ================================ :Author: Mickaël Salaün -:Date: August 2026 +:Date: October 2026 Landlock can leverage the audit framework to log events. @@ -20,10 +20,12 @@ Denied access requests are logged by default for a sandboxed program if `audit` is enabled. This default behavior can be changed with the sys_landlock_restrict_self() flags (cf. -Documentation/userspace-api/landlock.rst), or suppressed on a per-object -basis by using ``LANDLOCK_ADD_RULE_QUIET`` (ABI 10+). Landlock logs can -also be masked thanks to audit rules. Landlock can generate 2 audit -record types. +Documentation/userspace-api/landlock.rst), suppressed on a per-object +basis by using ``LANDLOCK_ADD_RULE_QUIET`` (ABI 10+), or suppressed for +specific capability or namespace members with the corresponding permission +rule's ``quiet_*`` field (ABI 12+). Quiet rules only suppress audit submission; +they do not suppress denial trace events. Landlock logs can also be masked +thanks to audit rules. Landlock can generate two audit record types. Record types ------------ @@ -65,14 +67,28 @@ - scope.abstract_unix_socket - Abstract UNIX socket connection denied - scope.signal - Signal sending denied + **namespace.*** - Namespace restrictions (ABI 12+): + - namespace.use - Namespace use was denied (creation via + :manpage:`unshare(2)`, :manpage:`clone(2)`, :manpage:`clone3(2)`, + :manpage:`open_tree(2)`, or :manpage:`fsmount(2)`, or joining via + :manpage:`setns(2)`); + ``namespace_type`` indicates the type (hex ``CLONE_NEW*`` bitmask), + and ``namespace_id`` identifies the target namespace for + :manpage:`setns(2)` operations (zero for creation) + + **capability.*** - Capability restrictions (ABI 12+): + - capability.use - Capability use was denied; + ``capability`` indicates the capability number + Multiple blockers can appear in a single event (comma-separated) when multiple access rights are missing. For example, creating a regular file in a directory that lacks both ``make_reg`` and ``refer`` rights would show ``blockers=fs.make_reg,fs.refer``. - The object identification fields (path, dev, ino for filesystem; opid, - ocomm for signals) depend on the type of access being blocked and provide - context about what resource was involved in the denial. + The object identification fields depend on the type of access being blocked: + ``path``, ``dev``, ``ino`` for filesystem; ``opid``, ``ocomm`` for signals; + ``namespace_type`` and ``namespace_id`` for namespace operations; + ``capability`` for capability use. AUDIT_LANDLOCK_DOMAIN @@ -178,8 +194,9 @@ attack attempt or a bug in the security policy. We can put in place some filters to limit noise with two complementary ways: -- with sys_landlock_restrict_self()'s flags, or - ``LANDLOCK_ADD_RULE_QUIET`` (ABI 10+) if we can fix the sandboxed +- with sys_landlock_restrict_self()'s flags, + ``LANDLOCK_ADD_RULE_QUIET`` (ABI 10+), or the permission rules' + per-member ``quiet_*`` fields (ABI 12+) if we can fix the sandboxed programs, - or with audit rules (see :manpage:`auditctl(8)`). @@ -243,8 +260,10 @@ - **NOAUDIT hooks**: Some LSM hooks suppress logging for speculative permission probes (e.g., reading ``/proc/<pid>/status`` uses - ``PTRACE_MODE_NOAUDIT``). When NOAUDIT is set, neither audit records - nor trace events are emitted, and the denial is not counted in + ``PTRACE_MODE_NOAUDIT``, and :manpage:`listxattr(2)` probes + ``CAP_SYS_ADMIN`` with ``CAP_OPT_NOAUDIT`` to decide whether to list + ``trusted.*`` extended attributes). When NOAUDIT is set, neither audit + records nor trace events are emitted, and the denial is not counted in ``denials``. The denial is still enforced. This avoids performance overhead and noise from speculative probes that test permissions without performing an actual access. @@ -269,7 +288,8 @@ Both audit records and trace events expose information about all Landlock-sandboxed processes on the system, including filesystem paths -being accessed, network ports, and process identities. System +being accessed, network ports, capability numbers, namespace types and IDs, +and process identities. System administrators must ensure that access to audit logs (controlled by the audit subsystem configuration) and to trace events (requiring ``CAP_SYS_ADMIN`` or ``CAP_BPF`` + ``CAP_PERFMON``) is restricted to
diff --git a/Documentation/admin-guide/cgroup-v2.rst b/Documentation/admin-guide/cgroup-v2.rst index 86a2a009..bd8c80f 100644 --- a/Documentation/admin-guide/cgroup-v2.rst +++ b/Documentation/admin-guide/cgroup-v2.rst
@@ -2536,16 +2536,55 @@ A read-only multiple values file which exists on all cpuset-enabled cgroups. - It lists the onlined CPUs that are actually granted to this - cgroup by its parent. These CPUs are allowed to be used by - tasks within the current cgroup. + It lists the active CPUs available to tasks in this cgroup. - If "cpuset.cpus" is empty, the "cpuset.cpus.effective" file shows - all the CPUs from the parent cgroup that can be available to - be used by this cgroup. Otherwise, it should be a subset of - "cpuset.cpus" unless none of the CPUs listed in "cpuset.cpus" - can be granted. In this case, it will be treated just like an - empty "cpuset.cpus". + For a cgroup that is not a valid partition root, an empty + "cpuset.cpus" makes "cpuset.cpus.effective" show all CPUs + available from the parent cgroup. Otherwise, it is a subset + of "cpuset.cpus" unless none of the requested CPUs can be + granted. In that case, it is treated like an empty + "cpuset.cpus". + + For example:: + + P (cpuset.cpus.effective=0-3) + | + +-- C0 (member): cpuset.cpus=1-2 + | cpuset.cpus.effective=1-2 + +-- C1 (invalid root): cpuset.cpus=4-5 + | cpuset.cpus.effective=0-3 + \-- C2 (member): cpuset.cpus=<empty> + cpuset.cpus.effective=0-3 + + C0 gets CPUs 1-2 because they are available from P. + None of C1's requested CPUs 4-5 are available from P, so C1 uses P's + effective CPUs 0-3 instead. + C2 has an empty "cpuset.cpus" and therefore also uses P's effective + CPUs 0-3. + + For a valid non-root partition root, "cpuset.cpus.effective" contains + the active CPUs from "cpuset.cpus.exclusive.effective" except + those granted to valid child partition roots. If + "cpuset.cpus.exclusive" is set to a value different from + "cpuset.cpus", the effective CPUs need not be a subset of + "cpuset.cpus". + + For example, if CPUs 2-5 are allocated to P for exclusive use, + CPUs 2-4 are active, CPU 5 is offline, and none of CPUs 2-5 are + assigned to a valid child partition root:: + + top (root) + | + \-- P (valid partition root) + cpuset.cpus=0-3 + cpuset.cpus.exclusive=2-5 + cpuset.cpus.exclusive.effective=2-5 + cpuset.cpus.effective=2-4 + + P has 2-5 in "cpuset.cpus.exclusive.effective", including the + offline CPU 5. CPU 5 is excluded from "cpuset.cpus.effective", + leaving 2-4. The result also shows that "cpuset.cpus.effective" + need not be a subset of "cpuset.cpus", which is 0-3. Its value will be affected by CPU hotplug events. @@ -2657,8 +2696,9 @@ A read-only and root cgroup only multiple values file. This file shows the set of all isolated CPUs used in existing - isolated partitions. It will be empty if no isolated partition - is created. + isolated partitions or isolated at boot time via the "domain" + flag of "isolcpus". The latter remain listed even after any + partition using them is released. cpuset.cpus.partition A read-write single value file which exists on non-root
diff --git a/Documentation/arch/powerpc/papr_hcalls.rst b/Documentation/arch/powerpc/papr_hcalls.rst index 14e39f0..44c9c8b 100644 --- a/Documentation/arch/powerpc/papr_hcalls.rst +++ b/Documentation/arch/powerpc/papr_hcalls.rst
@@ -305,8 +305,8 @@ | Input: authorization, objectlabel, objectlabellen, policy, out, outlen | Out: *Hypervisor Generated Key, or None when the wrapping key policy is set* | Return Value: *H_SUCCESS, H_Function, H_State, H_R_State, H_Parameter, H_P2, - H_P3, H_P4, H_P5, H_P6, H_Authority, H_Nomem, H_Busy, H_Resource, - H_Aborted* + H_P3, H_P4, H_P5, H_P6, H_Authority, H_Nomem, H_Busy, + H_Resource, H_Aborted* H_PKS_GEN_KEY is used to have the hypervisor generate a new random key. This key is stored as an object in the Power LPAR Platform KeyStore with @@ -321,8 +321,8 @@ | inlen, out, outlen, continue-token | Out: *continue-token, byte size of wrapped object, wrapped object* | Return Value: *H_SUCCESS, H_Function, H_State, H_R_State, H_Parameter, H_P2, - H_P3, H_P4, H_P5, H_P6, H_P7, H_P8, H_P9, H_Authority, H_Invalid_Key, - H_NOT_FOUND, H_Busy, H_LongBusy, H_Aborted* + H_P3, H_P4, H_P5, H_P6, H_P7, H_P8, H_P9, H_Authority, + H_Invalid_Key, H_NOT_FOUND, H_Busy, H_LongBusy, H_Aborted* H_PKS_WRAP_OBJECT is used to wrap an object using a wrapping key stored in the Power LPAR Platform KeyStore and return the wrapped object to the caller. The @@ -331,16 +331,16 @@ is then encrypted with the wrapping key and additional metadata and the result is returned to the caller. - **H_PKS_UNWRAP_OBJECT** | Input: authorization, objectwrapflags, in, inlen, out, outlen, continue-token | Out: *continue-token, byte size of unwrapped object, unwrapped object* | Return Value: *H_SUCCESS, H_Function, H_State, H_R_State, H_Parameter, H_P2, - H_P3, H_P4, H_P5, H_P6, H_P7, H_Authority, H_Unsupported, H_Bad_Data, - H_NOT_FOUND, H_Invalid_Key, H_Busy, H_LongBusy, H_Aborted* + H_P3, H_P4, H_P5, H_P6, H_P7, H_Authority, H_Unsupported, + H_Bad_Data, H_NOT_FOUND, H_Invalid_Key, H_Busy, H_LongBusy, + H_Aborted* -H_PKS_UNWRAP_OBJECT is used to unwrap an object that was previously warapped with +H_PKS_UNWRAP_OBJECT is used to unwrap an object that was previously wrapped with H_PKS_WRAP_OBJECT. References
diff --git a/Documentation/dev-tools/kselftest.rst b/Documentation/dev-tools/kselftest.rst index 64c0ec7..26a536e 100644 --- a/Documentation/dev-tools/kselftest.rst +++ b/Documentation/dev-tools/kselftest.rst
@@ -133,6 +133,44 @@ This applies to both the ``all`` and ``install`` targets and is useful in CI environments where a silent partial build would be misleading. +Recording suite build results +============================= + +Since the build succeeds as long as one target builds, the exit status of +make does not show which targets failed. Set ``KSFT_BUILD_REPORT`` to the +absolute path of a file to have the ``all`` and ``install`` targets append +a tab-separated record for each target they process:: + + $ : > /tmp/ksft-build.tsv + $ make -C tools/testing/selftests O=/tmp/kernel-build \ + KSFT_BUILD_REPORT=/tmp/ksft-build.tsv install + +Each record holds the phase (``all`` or ``install``), a name and the exit +status of that step. Recording does not change which targets are built or +installed, or the exit status of make, also with ``FORCE_TARGETS=1``. The +caller creates or truncates the report before a build; the rules only +append to it. Nothing is recorded by ``make -n``, ``-t`` or ``-q``. + +The same name can appear several times: ``install`` builds the targets +again, and generating ``kselftest-list.txt`` is recorded as part of the +``install`` phase. Targets that are added automatically as installation +dependencies of other targets, such as ``net/lib``, are recorded too. +Suites that are built from several subdirectories may also record each +subdirectory under its path, for example ``arm64/tags``; a failure there +means that the suite was built or installed only partially. A record +belongs to the target with the longest name that is equal to the record +name or followed by ``/`` in it. + +A target was built and installed successfully only if all of its records +have a zero status. Missing records do not show that a target was built. +A successful target that installs no tests has no entries in +``kselftest-list.txt``. Install the kernel headers with ``make headers`` +before building: a suite that fails because the headers are missing is +recorded as failed even if a later step installs them. + +``KSFT_BUILD_REPORT_VERSION`` in tools/testing/selftests/Makefile gives the +version of this format, currently ``1``. + Running the full range hotplug selftests ========================================
diff --git a/Documentation/devicetree/bindings/arm/apple.yaml b/Documentation/devicetree/bindings/arm/apple.yaml index fb277c9..7c3e713 100644 --- a/Documentation/devicetree/bindings/arm/apple.yaml +++ b/Documentation/devicetree/bindings/arm/apple.yaml
@@ -82,6 +82,10 @@ - iPhone 8 Plus - iPhone X + Devices based on the "A18 Pro" SoC: + + - MacBook Neo (A18 Pro, 2026) + Devices based on the "M1" SoC: - Mac mini (M1, 2020) @@ -103,6 +107,15 @@ - MacBook Pro (14-inch, M3, 2023) - iMac (24-inch, M3, 2023) + Devices based on the "M4" SoC: + + - MacBook Pro (14-inch, M4, 2024) + - iMac (24-inch, 2x USB-C, M4, 2024) + - iMac (24-inch, 4x USB-C, M4, 2024) + - MacBook Air (13-inch, M4, 2025) + - MacBook Air (15-inch, M4, 2025) + - Mac mini (M4, 2024) + Devices based on the "M1 Pro", "M1 Max" and "M1 Ultra" SoCs: - MacBook Pro (14-inch, M1 Pro, 2021) @@ -291,6 +304,13 @@ - const: apple,t8015 - const: apple,arm-platform + - description: Apple A18 Pro SoC based platforms + items: + - enum: + - apple,j700 # MacBook Neo (A18 Pro, 2026) + - const: apple,t8140 + - const: apple,arm-platform + - description: Apple M1 SoC based platforms items: - enum: @@ -323,6 +343,18 @@ - const: apple,t8122 - const: apple,arm-platform + - description: Apple M4 SoC based platforms + items: + - enum: + - apple,j604 # MacBook Pro (14-inch, M4, 2024) + - apple,j623 # iMac (24-inch, 2x USB-C, M4, 2024) + - apple,j624 # iMac (24-inch, 4x USB-C, M4, 2024) + - apple,j713 # MacBook Air (13-inch, M4, 2025) + - apple,j715 # MacBook Air (15-inch, M4, 2025) + - apple,j773g # Mac mini (M4, 2024) + - const: apple,t8132 + - const: apple,arm-platform + - description: Apple M1 Pro SoC based platforms items: - enum:
diff --git a/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml b/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml index 1d20018..bf21a5b 100644 --- a/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml +++ b/Documentation/devicetree/bindings/arm/apple/apple,pmgr.yaml
@@ -41,6 +41,8 @@ - apple,t6030-pmgr - apple,t6031-pmgr - apple,t8122-pmgr + - apple,t8132-pmgr + - apple,t8140-pmgr - const: apple,t8103-pmgr - const: syscon - const: simple-mfd
diff --git a/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml b/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml index 2729a54..7ad6583 100644 --- a/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml +++ b/Documentation/devicetree/bindings/arm/bcm/bcm2835.yaml
@@ -29,6 +29,12 @@ - raspberrypi,5-model-b - const: brcm,bcm2712 + - description: BCM2712-d0 stepping based Boards + items: + - enum: + - raspberrypi,5-model-b-d0 + - const: brcm,bcm2712-d0 + - description: BCM2835 based Boards items: - enum:
diff --git a/Documentation/devicetree/bindings/arm/cpus.yaml b/Documentation/devicetree/bindings/arm/cpus.yaml index 5be89c5..96136b7 100644 --- a/Documentation/devicetree/bindings/arm/cpus.yaml +++ b/Documentation/devicetree/bindings/arm/cpus.yaml
@@ -86,6 +86,8 @@ - apple,avalanche - apple,blizzard - apple,cyclone + - apple,donan-e + - apple,donan-p - apple,everest - apple,firestorm - apple,hurricane-zephyr @@ -93,6 +95,8 @@ - apple,mistral - apple,monsoon - apple,sawtooth + - apple,tahiti-e + - apple,tahiti-p - apple,twister - apple,typhoon - arm,arm710t @@ -212,6 +216,7 @@ - qcom,kryo465 - qcom,kryo468 - qcom,kryo470 + - qcom,kryo475 - qcom,kryo485 - qcom,kryo560 - qcom,kryo570 @@ -227,6 +232,9 @@ - qcom,oryon-2-1 - qcom,oryon-2-2 - qcom,oryon-2-3 + - qcom,oryon-3-0 + - qcom,oryon-3-1 + - qcom,oryon-3-2 - qcom,scorpion - samsung,mongoose-m2 - samsung,mongoose-m3
diff --git a/Documentation/devicetree/bindings/arm/fsl.yaml b/Documentation/devicetree/bindings/arm/fsl.yaml index 656f259..c8290a8 100644 --- a/Documentation/devicetree/bindings/arm/fsl.yaml +++ b/Documentation/devicetree/bindings/arm/fsl.yaml
@@ -186,6 +186,7 @@ - description: i.MX50 based Boards items: - enum: + - amazon,yoshi - fsl,imx50-evk - kobo,aura - const: fsl,imx50 @@ -950,6 +951,23 @@ - const: toradex,colibri-imx7d-emmc - const: fsl,imx7d + - description: i.MX7D Variscite Boards based on VAR-SOM-MX7 Module + oneOf: + - items: + - enum: + - variscite,var-som-imx7d-emmc-mx7customboard + - variscite,var-som-imx7d-emmc-wm8731-mx7customboard + - variscite,var-som-imx7d-nand-mx7customboard + - variscite,var-som-imx7d-nand-wm8731-mx7customboard + - const: variscite,var-som-imx7d + - const: fsl,imx7d + - items: + - enum: + - variscite,var-som-imx7d-v2-emmc-mx7customboard + - variscite,var-som-imx7d-v2-nand-mx7customboard + - const: variscite,var-som-imx7d-v2 + - const: fsl,imx7d + - description: i.MX7ULP based Boards items: - enum: @@ -1511,6 +1529,21 @@ - fsl,imx91-11x11-frdm-s # FRDM i.MX91S Development Board - const: fsl,imx91 + - description: i.MX91 boards with Toradex Lino Modules and Verdin Adapter + items: + - enum: + - toradex,lino-imx91-verdin-dahlia # Lino iMX91 Module on Verdin Dahlia Board + - toradex,lino-imx91-verdin-dev # Lino iMX91 Module on Verdin Dev Board + - const: toradex,lino-imx91-verdin # Lino iMX91 Module on Verdin Adapter + - const: toradex,lino-imx91 + - const: fsl,imx91 + + - description: i.MX91 boards with Toradex OSM Modules + items: + - const: toradex,osm-imx91-dev # OSM iMX91 Module on OSM Dev Board + - const: toradex,osm-imx91 + - const: fsl,imx91 + - description: i.MX93 based Boards items: - enum: @@ -1519,6 +1552,22 @@ - fsl,imx93-11x11-frdm # i.MX93 11x11 FRDM Board - fsl,imx93-14x14-evk # i.MX93 14x14 EVK Board - fsl,imx93-wireless-evk # i.MX93 and IW610G WLCSP (Wi-Fi + BLE + 802.15.4) SiP EVK Board + - fsl,imx93-wireless-frdm # i.MX93 and IW610G WLCSP (Wi-Fi + BLE + 802.15.4) SiP FRDM Board + - const: fsl,imx93 + + - description: i.MX93 boards with Toradex Lino Modules and Verdin Adapter + items: + - enum: + - toradex,lino-imx93-verdin-dahlia # Lino iMX93 Module on Verdin Dahlia Board + - toradex,lino-imx93-verdin-dev # Lino iMX93 Module on Verdin Dev Board + - const: toradex,lino-imx93-verdin # Lino iMX93 Module on Verdin Adapter + - const: toradex,lino-imx93 + - const: fsl,imx93 + + - description: i.MX93 boards with Toradex OSM Modules + items: + - const: toradex,osm-imx93-dev # OSM iMX93 Module on OSM Dev Board + - const: toradex,osm-imx93 - const: fsl,imx93 - description: i.MX94 based Boards @@ -1535,6 +1584,7 @@ - fsl,imx95-15x15-frdm # i.MX95 15x15 FRDM Board - fsl,imx95-19x19-evk # i.MX95 19x19 EVK Board - fsl,imx95-19x19-frdm-pro # i.MX95 19x19 FRDM PRO Board + - fsl,imx95-navq # MR-NAVQ95 board - toradex,verdin-imx95-19x19-evk # i.MX95 Verdin Evaluation Kit (EVK) - const: fsl,imx95 @@ -1542,6 +1592,7 @@ items: - enum: - fsl,imx952-evk # i.MX952 EVK Board + - fsl,imx952-frdm # i.MX952 FRDM Board - const: fsl,imx952 - description: PHYTEC i.MX 95 FPSC based Boards @@ -1559,6 +1610,12 @@ - const: toradex,aquila-imx95 # Aquila iMX95 Module - const: fsl,imx95 + - description: Toradex Boards with OSM iMX95 Modules + items: + - const: toradex,osm-imx95-dev # Toradex OSM iMX95 Module on Toradex OSM Development Board + - const: toradex,osm-imx95 # Toradex OSM iMX95 Module + - const: fsl,imx95 + - description: Toradex Boards with SMARC iMX95 Modules items: - const: toradex,smarc-imx95-dev # Toradex SMARC iMX95 on Toradex SMARC Development Board @@ -1737,9 +1794,11 @@ - fsl,vf610 - fsl,vf610m4 - - description: Toradex Colibri VF50 Module on Colibri Evaluation Board + - description: Toradex Colibri VF50 Module on a carrier board items: - - const: toradex,vf500-colibri_vf50-on-eval + - enum: + - toradex,vf500-colibri_vf50-on-eval + - toradex,vf500-colibri-vf50-on-iris - const: toradex,vf500-colibri_vf50 - const: fsl,vf500 @@ -1751,9 +1810,11 @@ - phytec,vf610-cosmic # PHYTEC Cosmic/Cosmic+ Board - const: fsl,vf610 - - description: Toradex Colibri VF61 Module on Colibri Evaluation Board + - description: Toradex Colibri VF61 Module on a carrier board items: - - const: toradex,vf610-colibri_vf61-on-eval + - enum: + - toradex,vf610-colibri_vf61-on-eval + - toradex,vf610-colibri-vf61-on-iris - const: toradex,vf610-colibri_vf61 - const: fsl,vf610 @@ -1930,6 +1991,7 @@ - description: LX2160A based Boards items: - enum: + - freemobile,nbxv3 - fsl,lx2160a-bluebox3 - fsl,lx2160a-bluebox3-rev-a - fsl,lx2160a-qds
diff --git a/Documentation/devicetree/bindings/arm/google.yaml b/Documentation/devicetree/bindings/arm/google.yaml index 99961e5..b5977e2 100644 --- a/Documentation/devicetree/bindings/arm/google.yaml +++ b/Documentation/devicetree/bindings/arm/google.yaml
@@ -13,27 +13,16 @@ ARM platforms using SoCs designed by Google branded "Tensor" used in Pixel devices. - Currently upstream this is devices using "gs101" SoC which is found in Pixel - 6, Pixel 6 Pro and Pixel 6a. - - Google have a few different names for the SoC: - - Marketing name ("Tensor") - - Codename ("Whitechapel") - - SoC ID ("gs101") - - Die ID ("S5P9845") - - Likewise there are a couple of names for the actual device - - Marketing name ("Pixel 6") - - Codename ("Oriole") - - Devicetrees should use the lowercased SoC ID and lowercased board codename, - e.g. gs101 and gs101-oriole. + Currently upstream this is devices using gs101 SoC which is found in Pixel + 6, Pixel 6 Pro and Pixel 6a and Laguna SoC canonically referred to as lga + found in Pixel 10, Pixel 10 Pro and Pixel 10 Pro XL. properties: $nodename: const: '/' compatible: oneOf: + # Google Tensor G1 AKA gs101 AKA whitechapel AKA Die ID S5P9845 boards - description: Google Pixel 6 or 6 Pro (Oriole or Raven) items: - enum: @@ -41,14 +30,35 @@ - google,gs101-raven - const: google,gs101 - # Bootloader requires empty ect node to be present + # Google Tensor G5 AKA lga (laguna) SoC and boards + - description: + Google Pixel 10, 10 Pro, 10 Pro XL (Frankel, Blazer, + Mustang). + items: + - enum: + - google,lga-blazer + - google,lga-frankel + - google,lga-mustang + - const: google,lga + ect: type: object additionalProperties: false -required: - - ect - additionalProperties: true +allOf: + # Bootloader requires empty ect node to be present + - if: + properties: + compatible: + contains: + const: google,gs101 + then: + required: + - ect + else: + properties: + ect: false + ...
diff --git a/Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.yaml b/Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.yaml index 7e77310..130128c 100644 --- a/Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.yaml +++ b/Documentation/devicetree/bindings/arm/marvell/armada-7k-8k.yaml
@@ -119,6 +119,13 @@ - const: marvell,armada-ap807 - description: + Sophos XGS 87/107 network processing unit (Armada CN9130 SoC + with an 88E6193X switch) + items: + - const: sophos,xgs107w-npu + - const: marvell,cn9130 + + - description: SolidRun CN9130 SoM based single-board computers items: - enum:
diff --git a/Documentation/devicetree/bindings/arm/mediatek.yaml b/Documentation/devicetree/bindings/arm/mediatek.yaml index cd4040a..180e6e4 100644 --- a/Documentation/devicetree/bindings/arm/mediatek.yaml +++ b/Documentation/devicetree/bindings/arm/mediatek.yaml
@@ -122,6 +122,7 @@ - const: mediatek,mt7988a - items: - enum: + - amazon,ford - mediatek,mt8127-moose - const: mediatek,mt8127 - items:
diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml index f3f3fea..335a8e1 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml
@@ -32,6 +32,7 @@ - qcom,glymur-ctcu - qcom,kaanapali-ctcu - qcom,qcs8300-ctcu + - qcom,shikra-ctcu - qcom,sm8750-ctcu - qcom,x1e80100-ctcu - const: qcom,sa8775p-ctcu
diff --git a/Documentation/devicetree/bindings/arm/qcom-soc.yaml b/Documentation/devicetree/bindings/arm/qcom-soc.yaml index e7160b6..179aadc 100644 --- a/Documentation/devicetree/bindings/arm/qcom-soc.yaml +++ b/Documentation/devicetree/bindings/arm/qcom-soc.yaml
@@ -30,7 +30,7 @@ contains: oneOf: - pattern: "^qcom,.*(apq|ipq|mdm|msm|qcm|qcs|q[dr]u|sa|sar|sc|sd[amx]|sm|x1[ep])[0-9]+.*$" - - pattern: "^qcom,.*(eliza|kaanapali|glymur|hawi|mahua|maili|milos|nord|shikra).*$" + - pattern: "^qcom,.*(eliza|kaanapali|kuno|glymur|hawi|mahua|maili|milos|nord|shikra).*$" required: - compatible @@ -42,7 +42,7 @@ - pattern: "^qcom,(apq|ipq|mdm|msm|qcm|qcs|q[dr]u|sa|sc|sd[amx]|sm|x1[ep])[0-9]+(pro)?-.*$" - pattern: "^qcom,sar[0-9]+[a-z]?-.*$" - pattern: "^qcom,(sa|sc)8[0-9]+[a-z][a-z]?-.*$" - - pattern: "^qcom,(eliza|kaanapali|glymur|hawi|mahua|maili|milos|nord|shikra)-.+$" + - pattern: "^qcom,(eliza|kaanapali|kuno|glymur|hawi|mahua|maili|milos|nord|shikra)-.+$" # Legacy namings - variations of existing patterns/compatibles are OK, # but do not add completely new entries to these:
diff --git a/Documentation/devicetree/bindings/arm/qcom.yaml b/Documentation/devicetree/bindings/arm/qcom.yaml index ff8a35d..121ca55 100644 --- a/Documentation/devicetree/bindings/arm/qcom.yaml +++ b/Documentation/devicetree/bindings/arm/qcom.yaml
@@ -86,8 +86,12 @@ - items: - enum: + - asus,zenbook-a14-ux3407na - asus,zenbook-a16-ux3607oa + - hp,elitebook-x-g2q + - lenovo,yoga-slim7x-gen11 - qcom,glymur-crd + - qcom,glymur-qcb - const: qcom,glymur - items: @@ -177,9 +181,26 @@ - items: - enum: + - qcom,kalambo-crd + - const: qcom,kalambo + + - items: + - enum: + - qcom,kuno-idp + - const: qcom,kuno + + - items: + - enum: - qcom,mahua-crd - const: qcom,mahua + - items: + - enum: + - lenovo,thinkpad-t14s-gen7-lcd + - lenovo,thinkpad-t14s-gen7-oled + - const: lenovo,thinkpad-t14s-gen7 + - const: qcom,mahua + - description: Sierra Wireless MangOH Green with WP8548 Module items: - const: swir,mangoh-green-wp8548 @@ -291,7 +312,13 @@ - items: - enum: + - generalmobile,shamrock + - const: qcom,msm8952 + + - items: + - enum: - flipkart,rimob + - motorola,deen - motorola,potter - xiaomi,daisy - xiaomi,mido @@ -347,6 +374,7 @@ - items: - enum: + - leeco,s2 - longcheer,l9360 - const: qcom,msm8976 @@ -402,6 +430,12 @@ - xiaomi,sagit - const: qcom,msm8998 + - items: + - enum: + - qcom,iq10-rrd + - qcom,sa8797p-ride + - const: qcom,nord + - description: Qualcomm Technologies, Inc. Robotics RB1 items: - enum: @@ -433,6 +467,7 @@ - items: - enum: - arduino,monza + - qcom,monaco-ac-evk - qcom,monaco-evk - qcom,qcs8300-ride - const: qcom,qcs8300 @@ -1033,6 +1068,7 @@ - items: - enum: - fxtec,pro1x + - xiaomi,lemon - const: qcom,sm6115 - items: @@ -1068,6 +1104,8 @@ - items: - enum: + - samsung,a52q + - samsung,a72q - xiaomi,curtana - xiaomi,joyeuse - const: qcom,sm7125 @@ -1086,6 +1124,7 @@ - enum: - motorola,dubai - nothing,spacewar + - xiaomi,lisa - xiaomi,taoyao - const: qcom,sm7325 @@ -1154,6 +1193,18 @@ - items: - enum: + - ayntec,odin2 + - ayntec,odin2mini + - ayntec,odin2portal + - ayntec,thor + - retroidpocket,nova + - retroidpocket,rp6 + - const: qcom,qcs8550 + - const: qcom,sm8550 + + - items: + - enum: + - ayaneo,pocket-ds - qcom,qcs8550-rb5gen2 - const: qcom,qcs8550 - const: qcom,sm8550 @@ -1164,6 +1215,7 @@ - qcom,sm8650-hdk - qcom,sm8650-mtp - qcom,sm8650-qrd + - valve,deckard - const: qcom,sm8650 - items: @@ -1224,6 +1276,13 @@ - const: qcom,x1e80100 - items: + - enum: + - advantech,som-db5830 + - const: advantech,som-6820 + - const: qcom,iq-x7181-evk-som + - const: qcom,x1e80100 + + - items: - const: microsoft,denali-oled - const: microsoft,denali - const: qcom,x1e80100 @@ -1333,6 +1392,7 @@ - qcom,msm8917 - qcom,msm8937 - qcom,msm8939 + - qcom,msm8952 - qcom,msm8953 - qcom,msm8956 - qcom,msm8992
diff --git a/Documentation/devicetree/bindings/arm/rockchip.yaml b/Documentation/devicetree/bindings/arm/rockchip.yaml index a799bb8..a24949b 100644 --- a/Documentation/devicetree/bindings/arm/rockchip.yaml +++ b/Documentation/devicetree/bindings/arm/rockchip.yaml
@@ -175,6 +175,11 @@ - const: coolpi,pi-4b - const: rockchip,rk3588s + - description: DFRobot UNIHIKER M10 V1.2 + items: + - const: dfrobot,unihiker-m10-v1.2 + - const: rockchip,rk3308 + - description: Alientek CLRV1126F SoM based boards items: - enum: @@ -216,6 +221,13 @@ - const: embedfire,lubancat-4 - const: rockchip,rk3588s + - description: EmbedFire LubanCat 5IO + items: + - enum: + - embedfire,lubancat-5io + - const: embedfire,lubancat-5-btb + - const: rockchip,rk3588 + - description: Engicam PX30.Core C.TOUCH 2.0 items: - const: engicam,px30-core-ctouch2 @@ -340,6 +352,13 @@ - friendlyarm,nanopi-r2s-plus - const: rockchip,rk3328 + - description: FriendlyElec NanoPi RK3528 series boards + items: + - enum: + - friendlyarm,nanopi-r28s + - friendlyarm,nanopi-zero2 + - const: rockchip,rk3528 + - description: FriendlyElec NanoPi R3S items: - const: friendlyarm,nanopi-r3s @@ -369,9 +388,10 @@ - friendlyarm,nanopi-r5s - const: rockchip,rk3568 - - description: FriendlyElec NanoPi R6 series boards + - description: FriendlyElec NanoPi6 series boards items: - enum: + - friendlyarm,nanopi-m6 - friendlyarm,nanopi-r6c - friendlyarm,nanopi-r6s - const: rockchip,rk3588s @@ -381,11 +401,6 @@ - const: friendlyarm,nanopi-r76s - const: rockchip,rk3576 - - description: FriendlyElec NanoPi Zero2 - items: - - const: friendlyarm,nanopi-zero2 - - const: rockchip,rk3528 - - description: FriendlyElec NanoPC T6 series boards items: - enum: @@ -844,6 +859,11 @@ - lunzn,fastrhino-r68s - const: rockchip,rk3568 + - description: MangoPi M28K + items: + - const: widora,mangopi-m28k + - const: rockchip,rk3528 + - description: mqmaker MiQi items: - const: mqmaker,miqi @@ -1005,9 +1025,11 @@ - const: radxa,e20c - const: rockchip,rk3528 - - description: Radxa E52C + - description: Radxa E52C/E54C items: - - const: radxa,e52c + - enum: + - radxa,e52c + - radxa,e54c - const: rockchip,rk3582 - const: rockchip,rk3588s @@ -1336,9 +1358,11 @@ - const: tsd,rk3588-jaguar - const: rockchip,rk3588 - - description: Theobroma Systems RK3588-Q7 with Haikou baseboard + - description: Theobroma Systems RK3588-Q7 with baseboards items: - - const: tsd,rk3588-tiger-haikou + - enum: + - tsd,rk3588-tiger-displayport-carrier + - tsd,rk3588-tiger-haikou - const: tsd,rk3588-tiger - const: rockchip,rk3588
diff --git a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml index 2734644..db19a68 100644 --- a/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml +++ b/Documentation/devicetree/bindings/arm/samsung/samsung-boards.yaml
@@ -232,6 +232,7 @@ - description: Exynos850 based boards items: - enum: + - samsung,a217f # Samsung Galaxy A21s (SM-A217F) - winlink,e850-96 # WinLink E850-96 - const: samsung,exynos850
diff --git a/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml b/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml index 95d2319..a559f8b 100644 --- a/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml +++ b/Documentation/devicetree/bindings/arm/stm32/st,stm32-syscon.yaml
@@ -39,6 +39,17 @@ "#clock-cells": const: 0 + "#address-cells": + const: 1 + + "#size-cells": + const: 1 + +patternProperties: + "^phy@2[48]00$": + type: object + $ref: /schemas/phy/st,stm32-usb2phy.yaml + required: - compatible - reg @@ -54,13 +65,30 @@ then: required: - clocks + else: + properties: + clocks: false - if: properties: compatible: - const: st,stm32mp25-syscfg + contains: + enum: + - st,stm32mp23-syscfg + - st,stm32mp25-syscfg then: required: + - "#address-cells" - "#clock-cells" + - "#size-cells" + - phy@2400 + - phy@2800 + else: + properties: + '#address-cells': false + '#clock-cells': false + '#size-cells': false + phy@2400: false + phy@2800: false additionalProperties: false
diff --git a/Documentation/devicetree/bindings/arm/stm32/stm32.yaml b/Documentation/devicetree/bindings/arm/stm32/stm32.yaml index c6af3a4..3ee6d7f 100644 --- a/Documentation/devicetree/bindings/arm/stm32/stm32.yaml +++ b/Documentation/devicetree/bindings/arm/stm32/stm32.yaml
@@ -196,12 +196,17 @@ - const: ultratronik,stm32mp157c-ultra-fly-sbc - const: st,stm32mp157 - - description: ST STM32MP257 based Boards + - description: ST STM32MP215 based Boards items: - enum: - - st,stm32mp257f-dk - - st,stm32mp257f-ev1 - - const: st,stm32mp257 + - st,stm32mp215f-dk + - const: st,stm32mp215 + + - description: DH STM32MP231 DHCOS SoM based Boards + items: + - const: dh,stm32mp231a-dhcos-bb + - const: dh,stm32mp231a-dhcos-som + - const: st,stm32mp231 - description: ST STM32MP235 based Boards items: @@ -209,11 +214,31 @@ - st,stm32mp235f-dk - const: st,stm32mp235 - - description: ST STM32MP215 based Boards + - description: DH STM32MP251 DHCOS SoM based Boards + items: + - const: dh,stm32mp251a-dhcos-bb + - const: dh,stm32mp251a-dhcos-som + - const: st,stm32mp251 + + - description: DH STM32MP255 DHCOS SoM based Boards + items: + - const: dh,stm32mp255c-dhcos-dhsbc + - const: dh,stm32mp255c-dhcos-som + - const: st,stm32mp255 + + - description: Engicam MicroGEA STM32MP257 SoM based Boards items: - enum: - - st,stm32mp215f-dk - - const: st,stm32mp215 + - engicam,microgea-stm32mp257d-rmm + - const: engicam,microgea-stm32mp257 + - const: st,stm32mp257 + + - description: ST STM32MP257 based Boards + items: + - enum: + - st,stm32mp257f-dk + - st,stm32mp257f-ev1 + - const: st,stm32mp257 additionalProperties: true
diff --git a/Documentation/devicetree/bindings/arm/sunxi.yaml b/Documentation/devicetree/bindings/arm/sunxi.yaml index f04db28..28437c4 100644 --- a/Documentation/devicetree/bindings/arm/sunxi.yaml +++ b/Documentation/devicetree/bindings/arm/sunxi.yaml
@@ -933,6 +933,16 @@ - const: tbs-biometrics,a711 - const: allwinner,sun8i-a83t + - description: Teclast P80 Tablet + items: + - const: teclast,p80 + - const: allwinner,sun50i-a133 + + - description: Teclast P85T Tablet + items: + - const: teclast,p85t + - const: allwinner,sun55i-a523 + - description: Topwise A721 Tablet items: - const: topwise,a721
diff --git a/Documentation/devicetree/bindings/arm/tegra.yaml b/Documentation/devicetree/bindings/arm/tegra.yaml index a54d002..e7545c8 100644 --- a/Documentation/devicetree/bindings/arm/tegra.yaml +++ b/Documentation/devicetree/bindings/arm/tegra.yaml
@@ -46,6 +46,12 @@ - items: - const: acer,picasso - const: nvidia,tegra20 + - description: Motorola Mot based Device family + items: + - enum: + - motorola,daytona + - motorola,olympus + - const: nvidia,tegra20 - items: - enum: - nvidia,beaver
diff --git a/Documentation/devicetree/bindings/arm/ti/k3.yaml b/Documentation/devicetree/bindings/arm/ti/k3.yaml index eebb352..9a0d622 100644 --- a/Documentation/devicetree/bindings/arm/ti/k3.yaml +++ b/Documentation/devicetree/bindings/arm/ti/k3.yaml
@@ -229,6 +229,13 @@ - ti,j722s-evm - const: ti,j722s + - description: K3 AM67 SoC PHYTEC phyBOARD-Rigel + items: + - enum: + - phytec,am6754-phyboard-rigel + - const: phytec,am67-phycore-som + - const: ti,j722s + - description: K3 J742S2 SoC items: - enum:
diff --git a/Documentation/devicetree/bindings/arm/ux500/power_domain.txt b/Documentation/devicetree/bindings/arm/ux500/power_domain.txt deleted file mode 100644 index 5679d174..0000000 --- a/Documentation/devicetree/bindings/arm/ux500/power_domain.txt +++ /dev/null
@@ -1,35 +0,0 @@ -* ST-Ericsson UX500 PM Domains - -UX500 supports multiple PM domains which are used to gate power to one or -more peripherals on the SOC. - -The implementation of PM domains for UX500 are based upon the generic PM domain -and use the corresponding DT bindings. - -==PM domain providers== - -Required properties: - - compatible: Must be "stericsson,ux500-pm-domains". - - #power-domain-cells : Number of cells in a power domain specifier, must be 1. - -Example: - pm_domains: pm_domains0 { - compatible = "stericsson,ux500-pm-domains"; - #power-domain-cells = <1>; - }; - -==PM domain consumers== - -Required properties: - - power-domains: A phandle and PM domain specifier. Below are the list of - valid specifiers: - - Index Specifier - ----- --------- - 0 DOMAIN_VAPE - -Example: - sdi0_per1@80126000 { - compatible = "arm,pl18x", "arm,primecell"; - power-domains = <&pm_domains DOMAIN_VAPE> - };
diff --git a/Documentation/devicetree/bindings/cache/qcom,llcc.yaml b/Documentation/devicetree/bindings/cache/qcom,llcc.yaml index a134022..2141e5d 100644 --- a/Documentation/devicetree/bindings/cache/qcom,llcc.yaml +++ b/Documentation/devicetree/bindings/cache/qcom,llcc.yaml
@@ -26,6 +26,7 @@ - qcom,hawi-llcc - qcom,ipq5424-llcc - qcom,kaanapali-llcc + - qcom,nord-llcc - qcom,qcs615-llcc - qcom,qcs8300-llcc - qcom,qdu1000-llcc @@ -56,11 +57,11 @@ reg: minItems: 1 - maxItems: 14 + maxItems: 18 reg-names: minItems: 1 - maxItems: 14 + maxItems: 18 interrupts: maxItems: 1 @@ -355,6 +356,56 @@ - const: llcc3_base - const: llcc_broadcast_base - const: llcc_broadcast_and_base + + - if: + properties: + compatible: + contains: + enum: + - qcom,nord-llcc + then: + properties: + reg: + items: + - description: LLCC0 base register region + - description: LLCC1 base register region + - description: LLCC2 base register region + - description: LLCC3 base register region + - description: LLCC4 base register region + - description: LLCC5 base register region + - description: LLCC6 base register region + - description: LLCC7 base register region + - description: LLCC8 base register region + - description: LLCC9 base register region + - description: LLCC10 base register region + - description: LLCC11 base register region + - description: LLCC12 base register region + - description: LLCC13 base register region + - description: LLCC14 base register region + - description: LLCC15 base register region + - description: LLCC broadcast OR register region + - description: LLCC broadcast AND register region + reg-names: + items: + - const: llcc0_base + - const: llcc1_base + - const: llcc2_base + - const: llcc3_base + - const: llcc4_base + - const: llcc5_base + - const: llcc6_base + - const: llcc7_base + - const: llcc8_base + - const: llcc9_base + - const: llcc10_base + - const: llcc11_base + - const: llcc12_base + - const: llcc13_base + - const: llcc14_base + - const: llcc15_base + - const: llcc_broadcast_base + - const: llcc_broadcast_and_base + - if: properties: compatible:
diff --git a/Documentation/devicetree/bindings/clock/qcom,hawi-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,hawi-gpucc.yaml new file mode 100644 index 0000000..b7179d5 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/qcom,hawi-gpucc.yaml
@@ -0,0 +1,80 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/qcom,hawi-gpucc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Graphics Clock & Reset Controller on Hawi + +maintainers: + - Dongfang Zhao <dongfang.zhao@oss.qualcomm.com> + +description: | + Qualcomm graphics clock control module provides the clocks, resets and power + domains on Qualcomm SoCs. + + See also: include/dt-bindings/clock/qcom,hawi-gpucc.h + +properties: + compatible: + enum: + - qcom,hawi-gpucc + - qcom,maili-gpucc + + clocks: + items: + - description: Board XO source + - description: GPLL0 main branch source + - description: GPLL0 div branch source + + power-domains: + items: + - description: A phandle to the MX power-domain + - description: A phandle to the CX power-domain + - description: A phandle to the GMXC power-domain + + required-opps: + items: + - description: MX performance points + - description: CX performance points + - description: GMXC performance points + +required: + - compatible + - clocks + - power-domains + - required-opps + - '#power-domain-cells' + +allOf: + - $ref: qcom,gcc.yaml# + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/clock/qcom,hawi-gcc.h> + #include <dt-bindings/power/qcom,rpmhpd.h> + + soc { + #address-cells = <2>; + #size-cells = <2>; + + clock-controller@3d90000 { + compatible = "qcom,hawi-gpucc"; + reg = <0x0 0x03d90000 0x0 0x9800>; + clocks = <&bi_tcxo_div2>, + <&gcc GCC_GPU_GPLL0_CLK_SRC>, + <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>; + power-domains = <&rpmhpd RPMHPD_MX>, + <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_GMXC>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs_d3>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + }; +...
diff --git a/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml b/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml index e868963..94f84d5 100644 --- a/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,kaanapali-gxclkctl.yaml
@@ -4,25 +4,32 @@ $id: http://devicetree.org/schemas/clock/qcom,kaanapali-gxclkctl.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Qualcomm Graphics power domain Controller on Kaanapali +title: Qualcomm Graphics GX Power Domain Controller maintainers: - Taniya Das <taniya.das@oss.qualcomm.com> description: | - Qualcomm GX(graphics) is a clock controller which has PLLs, clocks and - Power domains (GDSC). This module provides the power domains control - of gxclkctl on Qualcomm SoCs which helps the recovery of Graphics subsystem. + The Qualcomm graphics GX clock controller (GXCLKCTL) contains PLLs, clocks + and power domains (GDSC). This module provides the power domain control of + GXCLKCTL on Qualcomm SoCs, which helps the recovery of the graphics + subsystem. See also: include/dt-bindings/clock/qcom,kaanapali-gxclkctl.h properties: compatible: - enum: - - qcom,glymur-gxclkctl - - qcom,kaanapali-gxclkctl - - qcom,sm8750-gxclkctl + oneOf: + - enum: + - qcom,glymur-gxclkctl + - qcom,kaanapali-gxclkctl + - qcom,sm8750-gxclkctl + - items: + - enum: + - qcom,hawi-gxclkctl + - qcom,maili-gxclkctl + - const: qcom,kaanapali-gxclkctl power-domains: description:
diff --git a/Documentation/devicetree/bindings/clock/qcom,milos-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,milos-camcc.yaml index 707b25d..0655cea 100644 --- a/Documentation/devicetree/bindings/clock/qcom,milos-camcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,milos-camcc.yaml
@@ -8,16 +8,23 @@ maintainers: - Luca Weiss <luca.weiss@fairphone.com> + - Taniya Das <taniya.das@oss.qualcomm.com> description: | Qualcomm camera clock control module provides the clocks, resets and power domains on Milos. - See also: include/dt-bindings/clock/qcom,milos-camcc.h + See also: + include/dt-bindings/clock/qcom,eliza-cambistmclkcc.h + include/dt-bindings/clock/qcom,eliza-camcc.h + include/dt-bindings/clock/qcom,milos-camcc.h properties: compatible: - const: qcom,milos-camcc + enum: + - qcom,eliza-cambistmclkcc + - qcom,eliza-camcc + - qcom,milos-camcc clocks: items: @@ -29,12 +36,33 @@ items: - description: Interconnect path to enable the MultiMedia NoC + power-domains: + items: + - description: CX power domain + - description: MX power domain + + required-opps: + items: + - description: CX performance point + - description: MX performance point + required: - compatible - clocks + - power-domains + - required-opps allOf: - $ref: qcom,gcc.yaml# + - if: + not: + properties: + compatible: + contains: + const: qcom,eliza-cambistmclkcc + then: + required: + - '#power-domain-cells' unevaluatedProperties: false @@ -43,6 +71,7 @@ #include <dt-bindings/clock/qcom,milos-gcc.h> #include <dt-bindings/interconnect/qcom,icc.h> #include <dt-bindings/interconnect/qcom,milos-rpmh.h> + #include <dt-bindings/power/qcom,rpmhpd.h> clock-controller@adb0000 { compatible = "qcom,milos-camcc"; reg = <0x0adb0000 0x40000>; @@ -51,6 +80,12 @@ <&gcc GCC_CAMERA_AHB_CLK>; interconnects = <&mmss_noc MASTER_CAMNOC_HF QCOM_ICC_TAG_ALWAYS &mmss_noc SLAVE_MNOC_HF_MEM_NOC QCOM_ICC_TAG_ALWAYS>; + + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MX>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>;
diff --git a/Documentation/devicetree/bindings/clock/qcom,milos-videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,milos-videocc.yaml index 14c31ef..08898f1 100644 --- a/Documentation/devicetree/bindings/clock/qcom,milos-videocc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,milos-videocc.yaml
@@ -8,16 +8,21 @@ maintainers: - Luca Weiss <luca.weiss@fairphone.com> + - Taniya Das <taniya.das@oss.qualcomm.com> description: | Qualcomm video clock control module provides the clocks, resets and power domains on Milos. - See also: include/dt-bindings/clock/qcom,milos-videocc.h + See also: + include/dt-bindings/clock/qcom,eliza-videocc.h + include/dt-bindings/clock/qcom,milos-videocc.h properties: compatible: - const: qcom,milos-videocc + enum: + - qcom,eliza-videocc + - qcom,milos-videocc clocks: items: @@ -26,9 +31,22 @@ - description: Sleep clock source - description: Video AHB clock from GCC + power-domains: + items: + - description: CX power domain + - description: MX power domain + + required-opps: + items: + - description: CX performance point + - description: MX performance point + required: - compatible - clocks + - power-domains + - required-opps + - '#power-domain-cells' allOf: - $ref: qcom,gcc.yaml# @@ -38,6 +56,7 @@ examples: - | #include <dt-bindings/clock/qcom,milos-gcc.h> + #include <dt-bindings/power/qcom,rpmhpd.h> clock-controller@aaf0000 { compatible = "qcom,milos-videocc"; reg = <0x0aaf0000 0x10000>; @@ -45,6 +64,12 @@ <&bi_tcxo_ao_div2>, <&sleep_clk>, <&gcc GCC_VIDEO_AHB_CLK>; + + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MX>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>;
diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml index b41247b..64f5002 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-camcc.yaml
@@ -16,8 +16,10 @@ domains on SM8450. See also: + include/dt-bindings/clock/qcom,hawi-camcc.h include/dt-bindings/clock/qcom,kaanapali-camcc.h include/dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h + include/dt-bindings/clock/qcom,nord-camcc.h include/dt-bindings/clock/qcom,sm8450-camcc.h include/dt-bindings/clock/qcom,sm8550-camcc.h include/dt-bindings/clock/qcom,sm8650-camcc.h @@ -26,15 +28,24 @@ properties: compatible: - enum: - - qcom,kaanapali-cambistmclkcc - - qcom,kaanapali-camcc - - qcom,sm8450-camcc - - qcom,sm8475-camcc - - qcom,sm8550-camcc - - qcom,sm8650-camcc - - qcom,sm8750-cambistmclkcc - - qcom,sm8750-camcc + oneOf: + - enum: + - qcom,hawi-camcc + - qcom,kaanapali-cambistmclkcc + - qcom,kaanapali-camcc + - qcom,maili-camcc + - qcom,nord-camcc + - qcom,sm8450-camcc + - qcom,sm8475-camcc + - qcom,sm8550-camcc + - qcom,sm8650-camcc + - qcom,sm8750-cambistmclkcc + - qcom,sm8750-camcc + - items: + - enum: + - qcom,hawi-cambistmclkcc + - qcom,maili-cambistmclkcc + - const: qcom,kaanapali-cambistmclkcc clocks: items: @@ -43,6 +54,10 @@ - description: Board active XO source - description: Sleep clock source + interconnects: + items: + - description: Interconnect path to enable the MultiMedia NoC + power-domains: description: Power domains required for the clock controller to operate @@ -78,12 +93,24 @@ then: required: - required-opps + - if: + properties: + compatible: + contains: + enum: + - qcom,hawi-camcc + - qcom,maili-camcc + then: + required: + - interconnects unevaluatedProperties: false examples: - | #include <dt-bindings/clock/qcom,gcc-sm8450.h> + #include <dt-bindings/interconnect/qcom,icc.h> + #include <dt-bindings/interconnect/qcom,sm8450.h> #include <dt-bindings/clock/qcom,rpmh.h> #include <dt-bindings/power/qcom,rpmhpd.h> clock-controller@ade0000 { @@ -97,6 +124,8 @@ <&rpmhpd RPMHPD_MXC>; required-opps = <&rpmhpd_opp_low_svs>, <&rpmhpd_opp_low_svs>; + interconnects = <&mmss_noc MASTER_CAMNOC_HF QCOM_ICC_TAG_ALWAYS + &mmss_noc SLAVE_MNOC_HF_MEM_NOC QCOM_ICC_TAG_ALWAYS>; #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>;
diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml index 2a2d37c..7eca456 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-gpucc.yaml
@@ -15,6 +15,7 @@ domains on Qualcomm SoCs. See also: + include/dt-bindings/clock/qcom,eliza-gpucc.h include/dt-bindings/clock/qcom,glymur-gpucc.h include/dt-bindings/clock/qcom,kaanapali-gpucc.h include/dt-bindings/clock/qcom,milos-gpucc.h @@ -32,6 +33,7 @@ properties: compatible: enum: + - qcom,eliza-gpucc - qcom,glymur-gpucc - qcom,kaanapali-gpucc - qcom,milos-gpucc @@ -75,6 +77,7 @@ compatible: contains: enum: + - qcom,eliza-gpucc - qcom,sm8750-gpucc then: required:
diff --git a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml index 910c6d5..e985a45 100644 --- a/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml +++ b/Documentation/devicetree/bindings/clock/qcom,sm8450-videocc.yaml
@@ -19,6 +19,7 @@ include/dt-bindings/clock/qcom,hawi-videocc.h include/dt-bindings/clock/qcom,kaanapali-videocc.h include/dt-bindings/clock/qcom,maili-videocc.h + include/dt-bindings/clock/qcom,nord-videocc.h include/dt-bindings/clock/qcom,sm8450-videocc.h include/dt-bindings/clock/qcom,sm8650-videocc.h include/dt-bindings/clock/qcom,sm8750-videocc.h @@ -31,6 +32,7 @@ - qcom,hawi-videocc - qcom,kaanapali-videocc - qcom,maili-videocc + - qcom,nord-videocc - qcom,sm8450-videocc - qcom,sm8475-videocc - qcom,sm8550-videocc
diff --git a/Documentation/devicetree/bindings/clock/starfive,jhb100-per0crg.yaml b/Documentation/devicetree/bindings/clock/starfive,jhb100-per0crg.yaml new file mode 100644 index 0000000..db43e03 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/starfive,jhb100-per0crg.yaml
@@ -0,0 +1,70 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/starfive,jhb100-per0crg.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive JHB100 Peripheral-0 Clock and Reset Generator + +maintainers: + - Changhuang Liang <changhuang.liang@starfivetech.com> + +properties: + compatible: + const: starfive,jhb100-per0crg + + reg: + maxItems: 1 + + clocks: + items: + - description: Main Oscillator (25 MHz) + - description: PLL6 + - description: Configure 400MHz + - description: Configure 800MHZ + - description: Non Coherent NOC Initiator + - description: Non Coherent NOC Target + + clock-names: + items: + - const: osc + - const: pll6 + - const: cfg_400 + - const: cfg_800 + - const: ncnoc_init + - const: ncnoc_targ + + '#clock-cells': + const: 1 + description: + See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices. + + '#reset-cells': + const: 1 + description: + See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices. + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + +additionalProperties: false + +examples: + - | + clock-controller@11a08000 { + compatible = "starfive,jhb100-per0crg"; + reg = <0x11a08000 0x1000>; + clocks = <&osc>, <&pll6>, <&sys0crg 71>, + <&sys0crg 72>, <&sys0crg 70>, + <&sys2crg 23>; + clock-names = "osc", "pll6", "cfg_400", + "cfg_800", "ncnoc_init", + "ncnoc_targ"; + #clock-cells = <1>; + #reset-cells = <1>; + };
diff --git a/Documentation/devicetree/bindings/clock/starfive,jhb100-per1crg.yaml b/Documentation/devicetree/bindings/clock/starfive,jhb100-per1crg.yaml new file mode 100644 index 0000000..c72a355 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/starfive,jhb100-per1crg.yaml
@@ -0,0 +1,70 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/starfive,jhb100-per1crg.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive JHB100 Peripheral-1 Clock and Reset Generator + +maintainers: + - Changhuang Liang <changhuang.liang@starfivetech.com> + +properties: + compatible: + const: starfive,jhb100-per1crg + + reg: + maxItems: 1 + + clocks: + items: + - description: PLL7 + - description: Non Coherent NOC Initiator + - description: Configure 800MHz + - description: Non Coherent NOC Target + - description: Configure 143MHz + + clock-names: + items: + - const: pll7 + - const: ncnoc_init + - const: cfg_800 + - const: ncnoc_targ + - const: cfg_143 + + '#clock-cells': + const: 1 + description: + See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices. + + '#reset-cells': + const: 1 + description: + See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices. + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + +additionalProperties: false + +examples: + - | + clock-controller@11b40000 { + compatible = "starfive,jhb100-per1crg"; + reg = <0x11b40000 0x1000>; + clocks = <&pll7>, + <&sys0crg 68>, + <&sys0crg 69>, + <&sys2crg 19>, + <&sys2crg 22>; + clock-names = "pll7", "ncnoc_init", + "cfg_800", "ncnoc_targ", + "cfg_143"; + #clock-cells = <1>; + #reset-cells = <1>; + };
diff --git a/Documentation/devicetree/bindings/clock/starfive,jhb100-per2crg.yaml b/Documentation/devicetree/bindings/clock/starfive,jhb100-per2crg.yaml new file mode 100644 index 0000000..1756546 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/starfive,jhb100-per2crg.yaml
@@ -0,0 +1,76 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/starfive,jhb100-per2crg.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive JHB100 Peripheral-2 Clock and Reset Generator + +maintainers: + - Changhuang Liang <changhuang.liang@starfivetech.com> + +properties: + compatible: + const: starfive,jhb100-per2crg + + reg: + maxItems: 1 + + clocks: + items: + - description: Non Coherent NOC Initiator + - description: Configure 400MHz + - description: Configure 125MHz + - description: GMAC2 RGMII RX + - description: GMAC2 RMII Reference + - description: GMAC3 SGMII TX + - description: GMAC3 SGMII RX + - description: Main Oscillator (25 MHz) + + clock-names: + items: + - const: ncnoc_init + - const: cfg_400 + - const: cfg_125 + - const: gmac2_rgmii_rx + - const: gmac2_rmii_ref + - const: gmac3_sgmii_tx + - const: gmac3_sgmii_rx + - const: osc + + '#clock-cells': + const: 1 + description: + See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices. + + '#reset-cells': + const: 1 + description: + See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices. + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + +additionalProperties: false + +examples: + - | + clock-controller@11bc0000 { + compatible = "starfive,jhb100-per2crg"; + reg = <0x11bc0000 0x1000>; + clocks = <&sys0crg 52>, <&sys0crg 54>, <&sys0crg 55>, + <&per2_gmac2_rgmii_rx>, <&per2_gmac2_rmii_ref>, + <&per2_gmac3_sgmii_tx>, <&per2_gmac3_sgmii_rx>, + <&osc>; + clock-names = "ncnoc_init", "cfg_400", "cfg_125", + "gmac2_rgmii_rx", "gmac2_rmii_ref", + "gmac3_sgmii_tx", "gmac3_sgmii_rx", + "osc"; + #clock-cells = <1>; + #reset-cells = <1>; + };
diff --git a/Documentation/devicetree/bindings/clock/starfive,jhb100-per3crg.yaml b/Documentation/devicetree/bindings/clock/starfive,jhb100-per3crg.yaml new file mode 100644 index 0000000..2c3b9f4 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/starfive,jhb100-per3crg.yaml
@@ -0,0 +1,76 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/starfive,jhb100-per3crg.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive JHB100 Peripheral-3 Clock and Reset Generator + +maintainers: + - Changhuang Liang <changhuang.liang@starfivetech.com> + +properties: + compatible: + const: starfive,jhb100-per3crg + + reg: + maxItems: 1 + + clocks: + items: + - description: Non Coherent NOC Initiator + - description: Non Coherent NOC Target + - description: Configure 125MHz + - description: GMAC0 RMII Reference clock + - description: GMAC1 SGMII TX + - description: GMAC1 SGMII RX + - description: Main Oscillator (25 MHz) + + clock-names: + items: + - const: ncnoc_init + - const: ncnoc_targ + - const: cfg_125 + - const: gmac0_rmii_rclki + - const: gmac1_sgmii_tx + - const: gmac1_sgmii_rx + - const: osc + + '#clock-cells': + const: 1 + description: + See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices. + + '#reset-cells': + const: 1 + description: + See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices. + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + +additionalProperties: false + +examples: + - | + clock-controller@11c40000 { + compatible = "starfive,jhb100-per3crg"; + reg = <0x11c40000 0x1000>; + clocks = <&sys0crg 65>, + <&sys1crg 18>, + <&sys1crg 19>, + <&per3_gmac0_rmii_rclki>, + <&per3_gmac1_sgmii_tx>, + <&per3_gmac1_sgmii_rx>, + <&osc>; + clock-names = "ncnoc_init", "ncnoc_targ", "cfg_125", + "gmac0_rmii_rclki", "gmac1_sgmii_tx", + "gmac1_sgmii_rx", "osc"; + #clock-cells = <1>; + #reset-cells = <1>; + };
diff --git a/Documentation/devicetree/bindings/clock/starfive,jhb100-sys0crg.yaml b/Documentation/devicetree/bindings/clock/starfive,jhb100-sys0crg.yaml new file mode 100644 index 0000000..cf1b017 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/starfive,jhb100-sys0crg.yaml
@@ -0,0 +1,63 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/starfive,jhb100-sys0crg.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive JHB100 System-0 Clock and Reset Generator + +maintainers: + - Changhuang Liang <changhuang.liang@starfivetech.com> + +properties: + compatible: + const: starfive,jhb100-sys0crg + + reg: + maxItems: 1 + + clocks: + items: + - description: Main Oscillator (25 MHz) + - description: PLL0 + - description: PLL1 + - description: PLL2 + + clock-names: + items: + - const: osc + - const: pll0 + - const: pll1 + - const: pll2 + + '#clock-cells': + const: 1 + description: + See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices. + + '#reset-cells': + const: 1 + description: + See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices. + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + +additionalProperties: false + +examples: + - | + clock-controller@13000000 { + compatible = "starfive,jhb100-sys0crg"; + reg = <0x13000000 0x4000>; + clocks = <&osc>, <&pll0>, <&pll1>, + <&syspll 0>; + clock-names = "osc", "pll0", "pll1", "pll2"; + #clock-cells = <1>; + #reset-cells = <1>; + };
diff --git a/Documentation/devicetree/bindings/clock/starfive,jhb100-sys1crg.yaml b/Documentation/devicetree/bindings/clock/starfive,jhb100-sys1crg.yaml new file mode 100644 index 0000000..70cbfa3 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/starfive,jhb100-sys1crg.yaml
@@ -0,0 +1,71 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/starfive,jhb100-sys1crg.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive JHB100 System-1 Clock and Reset Generator + +maintainers: + - Changhuang Liang <changhuang.liang@starfivetech.com> + +properties: + compatible: + const: starfive,jhb100-sys1crg + + reg: + maxItems: 1 + + clocks: + items: + - description: Main Oscillator (25 MHz) + - description: PLL0 + - description: PLL1 + - description: PLL2 + - description: PLL4 + - description: PLL5 + - description: NPU Non Coherent NOC Initiator + + clock-names: + items: + - const: osc + - const: pll0 + - const: pll1 + - const: pll2 + - const: pll4 + - const: pll5 + - const: npu_ncnoc_init + + '#clock-cells': + const: 1 + description: + See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices. + + '#reset-cells': + const: 1 + description: + See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices. + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + +additionalProperties: false + +examples: + - | + clock-controller@13004000 { + compatible = "starfive,jhb100-sys1crg"; + reg = <0x13004000 0x4000>; + clocks = <&osc>, <&pll0>, <&pll1>, + <&syspll 0>, <&syspll 2>, + <&syspll 3>, <&sys0crg 61>; + clock-names = "osc", "pll0", "pll1", "pll2", + "pll4", "pll5", "npu_ncnoc_init"; + #clock-cells = <1>; + #reset-cells = <1>; + };
diff --git a/Documentation/devicetree/bindings/clock/starfive,jhb100-sys2crg.yaml b/Documentation/devicetree/bindings/clock/starfive,jhb100-sys2crg.yaml new file mode 100644 index 0000000..a63809c --- /dev/null +++ b/Documentation/devicetree/bindings/clock/starfive,jhb100-sys2crg.yaml
@@ -0,0 +1,64 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/starfive,jhb100-sys2crg.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive JHB100 System-2 Clock and Reset Generator + +maintainers: + - Changhuang Liang <changhuang.liang@starfivetech.com> + +properties: + compatible: + const: starfive,jhb100-sys2crg + + reg: + maxItems: 1 + + clocks: + items: + - description: Main Oscillator (25 MHz) + - description: PLL1 + - description: GPU0 Non Coherent NOC Initiator + - description: GPU1 Non Coherent NOC Initiator + + clock-names: + items: + - const: osc + - const: pll1 + - const: gpu0_ncnoc_init + - const: gpu1_ncnoc_init + + '#clock-cells': + const: 1 + description: + See <dt-bindings/clock/starfive,jhb100-crg.h> for valid indices. + + '#reset-cells': + const: 1 + description: + See <dt-bindings/reset/starfive,jhb100-crg.h> for valid indices. + +required: + - compatible + - reg + - clocks + - clock-names + - '#clock-cells' + - '#reset-cells' + +additionalProperties: false + +examples: + - | + clock-controller@13008000 { + compatible = "starfive,jhb100-sys2crg"; + reg = <0x13008000 0x4000>; + clocks = <&osc>, <&pll1>, <&sys0crg 73>, + <&sys0crg 74>; + clock-names = "osc", "pll1", "gpu0_ncnoc_init", + "gpu1_ncnoc_init"; + #clock-cells = <1>; + #reset-cells = <1>; + };
diff --git a/Documentation/devicetree/bindings/clock/ti,am62-audio-refclk.yaml b/Documentation/devicetree/bindings/clock/ti,am62-audio-refclk.yaml index b2e40bd..6c8fb07 100644 --- a/Documentation/devicetree/bindings/clock/ti,am62-audio-refclk.yaml +++ b/Documentation/devicetree/bindings/clock/ti,am62-audio-refclk.yaml
@@ -11,8 +11,12 @@ properties: compatible: - items: - - const: ti,am62-audio-refclk + oneOf: + - items: + - const: ti,am62-audio-refclk + - items: + - const: ti,j721s2-audio-refclk + - const: ti,am62-audio-refclk reg: maxItems: 1
diff --git a/Documentation/devicetree/bindings/crypto/hisilicon,hip06-sec.yaml b/Documentation/devicetree/bindings/crypto/hisilicon,hip06-sec.yaml deleted file mode 100644 index 2bfac9d..0000000 --- a/Documentation/devicetree/bindings/crypto/hisilicon,hip06-sec.yaml +++ /dev/null
@@ -1,134 +0,0 @@ -# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) -%YAML 1.2 ---- -$id: http://devicetree.org/schemas/crypto/hisilicon,hip06-sec.yaml# -$schema: http://devicetree.org/meta-schemas/core.yaml# - -title: Hisilicon hip06/hip07 Security Accelerator - -maintainers: - - Jonathan Cameron <Jonathan.Cameron@huawei.com> - -properties: - compatible: - enum: - - hisilicon,hip06-sec - - hisilicon,hip07-sec - - reg: - items: - - description: Registers for backend processing engines - - description: Registers for common functionality - - description: Registers for queue 0 - - description: Registers for queue 1 - - description: Registers for queue 2 - - description: Registers for queue 3 - - description: Registers for queue 4 - - description: Registers for queue 5 - - description: Registers for queue 6 - - description: Registers for queue 7 - - description: Registers for queue 8 - - description: Registers for queue 9 - - description: Registers for queue 10 - - description: Registers for queue 11 - - description: Registers for queue 12 - - description: Registers for queue 13 - - description: Registers for queue 14 - - description: Registers for queue 15 - - interrupts: - items: - - description: SEC unit error queue interrupt - - description: Completion interrupt for queue 0 - - description: Error interrupt for queue 0 - - description: Completion interrupt for queue 1 - - description: Error interrupt for queue 1 - - description: Completion interrupt for queue 2 - - description: Error interrupt for queue 2 - - description: Completion interrupt for queue 3 - - description: Error interrupt for queue 3 - - description: Completion interrupt for queue 4 - - description: Error interrupt for queue 4 - - description: Completion interrupt for queue 5 - - description: Error interrupt for queue 5 - - description: Completion interrupt for queue 6 - - description: Error interrupt for queue 6 - - description: Completion interrupt for queue 7 - - description: Error interrupt for queue 7 - - description: Completion interrupt for queue 8 - - description: Error interrupt for queue 8 - - description: Completion interrupt for queue 9 - - description: Error interrupt for queue 9 - - description: Completion interrupt for queue 10 - - description: Error interrupt for queue 10 - - description: Completion interrupt for queue 11 - - description: Error interrupt for queue 11 - - description: Completion interrupt for queue 12 - - description: Error interrupt for queue 12 - - description: Completion interrupt for queue 13 - - description: Error interrupt for queue 13 - - description: Completion interrupt for queue 14 - - description: Error interrupt for queue 14 - - description: Completion interrupt for queue 15 - - description: Error interrupt for queue 15 - - dma-coherent: true - - iommus: - maxItems: 1 - -required: - - compatible - - reg - - interrupts - - dma-coherent - -additionalProperties: false - -examples: - - | - bus { - #address-cells = <2>; - #size-cells = <2>; - - crypto@400d2000000 { - compatible = "hisilicon,hip07-sec"; - reg = <0x400 0xd0000000 0x0 0x10000 - 0x400 0xd2000000 0x0 0x10000 - 0x400 0xd2010000 0x0 0x10000 - 0x400 0xd2020000 0x0 0x10000 - 0x400 0xd2030000 0x0 0x10000 - 0x400 0xd2040000 0x0 0x10000 - 0x400 0xd2050000 0x0 0x10000 - 0x400 0xd2060000 0x0 0x10000 - 0x400 0xd2070000 0x0 0x10000 - 0x400 0xd2080000 0x0 0x10000 - 0x400 0xd2090000 0x0 0x10000 - 0x400 0xd20a0000 0x0 0x10000 - 0x400 0xd20b0000 0x0 0x10000 - 0x400 0xd20c0000 0x0 0x10000 - 0x400 0xd20d0000 0x0 0x10000 - 0x400 0xd20e0000 0x0 0x10000 - 0x400 0xd20f0000 0x0 0x10000 - 0x400 0xd2100000 0x0 0x10000>; - interrupts = <576 4>, - <577 1>, <578 4>, - <579 1>, <580 4>, - <581 1>, <582 4>, - <583 1>, <584 4>, - <585 1>, <586 4>, - <587 1>, <588 4>, - <589 1>, <590 4>, - <591 1>, <592 4>, - <593 1>, <594 4>, - <595 1>, <596 4>, - <597 1>, <598 4>, - <599 1>, <600 4>, - <601 1>, <602 4>, - <603 1>, <604 4>, - <605 1>, <606 4>, - <607 1>, <608 4>; - dma-coherent; - iommus = <&p1_smmu_alg_a 0x600>; - }; - };
diff --git a/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml b/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml index 7f38087..e5a8870 100644 --- a/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml +++ b/Documentation/devicetree/bindings/display/bridge/fsl,ldb.yaml
@@ -28,9 +28,11 @@ const: ldb reg: + minItems: 1 maxItems: 2 reg-names: + minItems: 1 items: - const: ldb - const: lvds @@ -83,15 +85,6 @@ ports: properties: port@2: false - - if: - not: - properties: - compatible: - contains: - const: fsl,imx6sx-ldb - then: - required: - - reg-names - if: properties: @@ -100,7 +93,19 @@ const: fsl,imx6sx-ldb then: properties: + reg: + maxItems: 1 + reg-names: + maxItems: 1 nxp,enable-termination-resistor: false + else: + required: + - reg-names + properties: + reg: + minItems: 2 + reg-names: + minItems: 2 additionalProperties: false
diff --git a/Documentation/devicetree/bindings/display/fsl,lcdif.yaml b/Documentation/devicetree/bindings/display/fsl,lcdif.yaml index 2dd0411..2b123dd 100644 --- a/Documentation/devicetree/bindings/display/fsl,lcdif.yaml +++ b/Documentation/devicetree/bindings/display/fsl,lcdif.yaml
@@ -182,6 +182,7 @@ contains: enum: - fsl,imx28-lcdif + - fsl,imx6ul-lcdif then: properties: dmas: false
diff --git a/Documentation/devicetree/bindings/embedded-controller/qcom,hamoa-crd-ec.yaml b/Documentation/devicetree/bindings/embedded-controller/qcom,hamoa-crd-ec.yaml index ac5a08f..aa23382 100644 --- a/Documentation/devicetree/bindings/embedded-controller/qcom,hamoa-crd-ec.yaml +++ b/Documentation/devicetree/bindings/embedded-controller/qcom,hamoa-crd-ec.yaml
@@ -20,8 +20,11 @@ oneOf: - items: - enum: + - lenovo,yoga-slim7x-ec - qcom,glymur-crd-ec + - qcom,glymur-qcb-ec - qcom,hamoa-iot-evk-ec + - qcom,purwa-iot-evk-ec - const: qcom,hamoa-crd-ec - enum: - qcom,hamoa-crd-ec
diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml index 037d4ad..40a267c 100644 --- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml
@@ -37,6 +37,7 @@ - qcom,scm-ipq9574 - qcom,scm-ipq9650 - qcom,scm-kaanapali + - qcom,scm-kuno - qcom,scm-maili - qcom,scm-mdm9607 - qcom,scm-milos @@ -44,6 +45,7 @@ - qcom,scm-msm8660 - qcom,scm-msm8916 - qcom,scm-msm8937 + - qcom,scm-msm8952 - qcom,scm-msm8953 - qcom,scm-msm8960 - qcom,scm-msm8974 @@ -152,6 +154,7 @@ - qcom,scm-msm8660 - qcom,scm-msm8916 - qcom,scm-msm8937 + - qcom,scm-msm8952 - qcom,scm-msm8953 - qcom,scm-msm8960 - qcom,scm-msm8974 @@ -198,6 +201,7 @@ - qcom,scm-msm8226 - qcom,scm-msm8916 - qcom,scm-msm8937 + - qcom,scm-msm8952 - qcom,scm-msm8953 - qcom,scm-msm8974 - qcom,scm-msm8976
diff --git a/Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.yaml b/Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.yaml index 02f0b04..bf9923b 100644 --- a/Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.yaml +++ b/Documentation/devicetree/bindings/fuse/nvidia,tegra20-fuse.yaml
@@ -22,6 +22,7 @@ - nvidia,tegra186-efuse - nvidia,tegra194-efuse - nvidia,tegra234-efuse + - nvidia,tegra264-efuse - items: - const: nvidia,tegra132-efuse
diff --git a/Documentation/devicetree/bindings/gpio/axiado,ax3005-sgpio.yaml b/Documentation/devicetree/bindings/gpio/axiado,ax3005-sgpio.yaml new file mode 100644 index 0000000..47ae128 --- /dev/null +++ b/Documentation/devicetree/bindings/gpio/axiado,ax3005-sgpio.yaml
@@ -0,0 +1,112 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/gpio/axiado,ax3005-sgpio.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Axiado AX3005 SGPIO Controller + +maintainers: + - Petar Stepanovic <pstepanovic@axiado.com> + - SriNavmani A <srinavmani@axiado.com> + - Prasad Bolisetty <pbolisetty@axiado.com> + +description: | + The Axiado SGPIO controller provides a serial GPIO expansion interface + that multiplexes multiple GPIO signals over a small set of physical lines. + + The controller serializes output values on a data output line (DOUT) and + samples input values from a data input line (DIN) in synchronization with + a shift clock (SCLK). A latch signal (LATCH) updates the output states + after each transfer cycle. + + SGPIO positions are organized in banks of 32, with registers controlling + output values, input sampling, and interrupt status. The number of SGPIO + positions supported depends on the controller configuration. + + The controller detects changes on input GPIOs. Interrupt events are + aggregated and signaled through a single interrupt line to the parent + interrupt controller. + + Register access is performed over the APB bus. The SGPIO shift clock is + derived from the APB clock using a programmable divider. + + Each SGPIO position provides one input and one output, and both are + exposed as GPIO lines. Position N is described by two consecutive lines: + line 2 * N is the input and line 2 * N + 1 is the output. Directions are + fixed by the hardware, so even lines are always inputs and odd lines are + always outputs. + + Only input lines can generate interrupts. Rising, falling, and both-edge + interrupts are supported. + +properties: + compatible: + const: axiado,ax3005-sgpio + + reg: + maxItems: 1 + + clocks: + description: APB interface clock + maxItems: 1 + + bus-frequency: + description: Desired SGPIO shift clock frequency in Hz + minimum: 1 + + gpio-controller: true + + '#gpio-cells': + const: 2 + + interrupt-controller: true + + '#interrupt-cells': + const: 2 + + interrupts: + maxItems: 1 + + ngpios: + description: | + Total number of GPIO lines provided by the controller. Each SGPIO + position wired up on the board contributes one input and one output + line, so this is twice the number of positions and must be even. It + may be lower than the maximum supported by the hardware. + minimum: 2 + maximum: 1024 + multipleOf: 2 + +required: + - compatible + - reg + - clocks + - bus-frequency + - gpio-controller + - '#gpio-cells' + - interrupts + - interrupt-controller + - '#interrupt-cells' + - ngpios + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/interrupt-controller/irq.h> + + gpio@33201c00 { + compatible = "axiado,ax3005-sgpio"; + reg = <0x33201c00 0x400>; + clocks = <&apb_clk>; + bus-frequency = <1000000>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&gic500>; + interrupts = <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>; + ngpios = <256>; + };
diff --git a/Documentation/devicetree/bindings/gpio/fsl,qoriq-gpio.yaml b/Documentation/devicetree/bindings/gpio/fsl,qoriq-gpio.yaml index 4cb2a6b..1e61e17 100644 --- a/Documentation/devicetree/bindings/gpio/fsl,qoriq-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/fsl,qoriq-gpio.yaml
@@ -63,6 +63,13 @@ GPIO registers are used as little endian. If not present registers are used as big endian by default. +patternProperties: + "^.+-hog(-[0-9]+)?$": + type: object + + required: + - gpio-hog + required: - compatible - reg
diff --git a/Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml b/Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml index 4631388..d671aaf83 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml +++ b/Documentation/devicetree/bindings/gpio/gpio-pca95xx.yaml
@@ -26,6 +26,9 @@ - const: kinetic,kts1622 - const: ti,tcal6416 - items: + - const: onnn,pca9655 + - const: nxp,pca9555 + - items: - enum: - exar,xra1202 - maxim,max7310
diff --git a/Documentation/devicetree/bindings/gpio/gpio-zynq.yaml b/Documentation/devicetree/bindings/gpio/gpio-zynq.yaml index de24bb3..fffeb5e 100644 --- a/Documentation/devicetree/bindings/gpio/gpio-zynq.yaml +++ b/Documentation/devicetree/bindings/gpio/gpio-zynq.yaml
@@ -45,6 +45,12 @@ power-domains: maxItems: 1 +patternProperties: + "^.+-hog(-[0-9]+)?$": + type: object + required: + - gpio-hog + allOf: - if: properties:
diff --git a/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.yaml b/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.yaml index adeb3b3..fac53e6 100644 --- a/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/nvidia,tegra186-gpio.yaml
@@ -91,6 +91,9 @@ - nvidia,tegra264-gpio - nvidia,tegra264-gpio-uphy - nvidia,tegra264-gpio-aon + - nvidia,tegra268-gpio + - nvidia,tegra268-gpio-uphy + - nvidia,tegra268-gpio-aon reg-names: items: @@ -169,6 +172,8 @@ - nvidia,tegra256-gpio - nvidia,tegra264-gpio - nvidia,tegra264-gpio-uphy + - nvidia,tegra268-gpio + - nvidia,tegra268-gpio-uphy then: properties: interrupts: @@ -185,6 +190,7 @@ - nvidia,tegra234-gpio-aon - nvidia,tegra238-gpio-aon - nvidia,tegra264-gpio-aon + - nvidia,tegra268-gpio-aon then: properties: interrupts: @@ -201,6 +207,9 @@ - nvidia,tegra264-gpio - nvidia,tegra264-gpio-uphy - nvidia,tegra264-gpio-aon + - nvidia,tegra268-gpio + - nvidia,tegra268-gpio-uphy + - nvidia,tegra268-gpio-aon then: required: - wakeup-parent
diff --git a/Documentation/devicetree/bindings/gpio/realtek,otto-gpio.yaml b/Documentation/devicetree/bindings/gpio/realtek,otto-gpio.yaml index b18f8f0..33c25df 100644 --- a/Documentation/devicetree/bindings/gpio/realtek,otto-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/realtek,otto-gpio.yaml
@@ -40,6 +40,8 @@ gpio-controller: true + gpio-ranges: true + ngpios: minimum: 1 maximum: 32
diff --git a/Documentation/devicetree/bindings/gpio/renesas,rcar-gpio.yaml b/Documentation/devicetree/bindings/gpio/renesas,rcar-gpio.yaml index d32e103..95f5175c 100644 --- a/Documentation/devicetree/bindings/gpio/renesas,rcar-gpio.yaml +++ b/Documentation/devicetree/bindings/gpio/renesas,rcar-gpio.yaml
@@ -56,6 +56,11 @@ - renesas,gpio-r8a779h0 # R-Car V4M - const: renesas,rcar-gen4-gpio # R-Car Gen4 + - items: + - enum: + - renesas,gpio-r8a78000 # R-Car X5H + - const: renesas,rcar-gen5-gpio # R-Car Gen5 + reg: maxItems: 1
diff --git a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml index 9db9f84..ece2b63 100644 --- a/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml +++ b/Documentation/devicetree/bindings/gpu/arm,mali-bifrost.yaml
@@ -34,6 +34,7 @@ - rockchip,rk3562-mali - rockchip,rk3568-mali - rockchip,rk3576-mali + - samsung,exynos850-mali - const: arm,mali-bifrost # Mali Bifrost GPU model/revision is fully discoverable - items: - enum:
diff --git a/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml b/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml index b9cdfe5..619faf3 100644 --- a/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml +++ b/Documentation/devicetree/bindings/hwinfo/samsung,exynos-chipid.yaml
@@ -25,6 +25,7 @@ - items: - enum: - samsung,exynos2200-chipid + - samsung,exynos5515-chipid - samsung,exynos7885-chipid - samsung,exynos8895-chipid - samsung,exynos9610-chipid
diff --git a/Documentation/devicetree/bindings/i2c/apple,i2c.yaml b/Documentation/devicetree/bindings/i2c/apple,i2c.yaml index d39f5e3..641f24b 100644 --- a/Documentation/devicetree/bindings/i2c/apple,i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/apple,i2c.yaml
@@ -27,6 +27,7 @@ - apple,t6030-i2c - apple,t6031-i2c - apple,t8122-i2c + - apple,t8132-i2c - const: apple,t8103-i2c - items: - enum:
diff --git a/Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml b/Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml index c4efcef..2a9e723 100644 --- a/Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/marvell,mv64xxx-i2c.yaml
@@ -34,6 +34,7 @@ - allwinner,sun50i-h616-i2c - allwinner,sun50i-r329-i2c - allwinner,sun55i-a523-i2c + - allwinner,sun60i-a733-i2c - const: allwinner,sun8i-v536-i2c - const: allwinner,sun6i-a31-i2c - const: marvell,mv64xxx-i2c
diff --git a/Documentation/devicetree/bindings/i2c/novatek,nt72676-i2c.yaml b/Documentation/devicetree/bindings/i2c/novatek,nt72676-i2c.yaml new file mode 100644 index 0000000..7d9275b --- /dev/null +++ b/Documentation/devicetree/bindings/i2c/novatek,nt72676-i2c.yaml
@@ -0,0 +1,76 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/i2c/novatek,nt72676-i2c.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Novatek NT72676 I2C Controller + +maintainers: + - Ben Huang <ben_huang@novatek.com.tw> + - Jason JJ Wu <jason_jj_wu@novatek.com.tw> + +description: > + Novatek NT72676 SoC provides multiple I2C controller instances that share + the same register layout and transfer programming model. + + Generic I2C controllers are directly accessible by the host CPU and driven + by a 96 MHz AHB clock. + + STBC I2C controllers are driven by a 12 MHz clock from the STBC (Standby + Controller, an 8051-based microcontroller). Before accessing an STBC I2C + controller, the host CPU must authenticate with the STBC and switch + ownership of the controller to the host CPU. The presence of the + novatek,stbc-syscon property identifies an STBC I2C controller requiring + this initialization sequence. + +properties: + compatible: + const: novatek,nt72676-i2c + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-frequency: + default: 100000 + enum: [ 100000, 400000 ] + + novatek,stbc-syscon: + $ref: /schemas/types.yaml#/definitions/phandle + description: > + Phandle to the STBC system controller used to authenticate host + access and switch ownership of the STBC I2C controller to the host + CPU during initialization. + +required: + - compatible + - reg + - interrupts + - clocks + +allOf: + - $ref: /schemas/i2c/i2c-controller.yaml# + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/interrupt-controller/irq.h> + + i2c@fc040a00 { + compatible = "novatek,nt72676-i2c"; + reg = <0xfc040a00 0x40>; + interrupts = <GIC_SPI 77 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&stbc_i2c_clock>; + clock-frequency = <400000>; + novatek,stbc-syscon = <&stbc>; + #address-cells = <1>; + #size-cells = <0>; + };
diff --git a/Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml b/Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml index f9ede03c..4148081 100644 --- a/Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/renesas,rcar-i2c.yaml
@@ -83,14 +83,14 @@ dmas: minItems: 2 - maxItems: 4 + maxItems: 6 description: Must contain a list of pairs of references to DMA specifiers, one for transmission, and one for reception. dma-names: minItems: 2 - maxItems: 4 + maxItems: 6 items: enum: - tx
diff --git a/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml b/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml index 467bdcb..a73e2a6 100644 --- a/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml +++ b/Documentation/devicetree/bindings/i2c/snps,designware-i2c.yaml
@@ -21,6 +21,20 @@ properties: reg: maxItems: 1 + - if: + properties: + compatible: + contains: + const: ultrarisc,dp1000-i2c + then: + properties: + clocks: + minItems: 2 + clock-names: + minItems: 2 + required: + - clocks + - clock-names properties: compatible: @@ -43,7 +57,9 @@ - mobileye,eyeq6lplus-i2c - mscc,ocelot-i2c - sophgo,sg2044-i2c + - syna,sl2610-i2c - thead,th1520-i2c + - ultrarisc,dp1000-i2c - const: snps,designware-i2c reg:
diff --git a/Documentation/devicetree/bindings/i2c/xlnx,xps-iic-2.00.a.yaml b/Documentation/devicetree/bindings/i2c/xlnx,xps-iic-2.00.a.yaml index 658ae92..d1f26d5 100644 --- a/Documentation/devicetree/bindings/i2c/xlnx,xps-iic-2.00.a.yaml +++ b/Documentation/devicetree/bindings/i2c/xlnx,xps-iic-2.00.a.yaml
@@ -7,7 +7,7 @@ title: Xilinx IIC controller maintainers: - - info@mocean-labs.com + - Michal Simek <michal.simek@amd.com> allOf: - $ref: /schemas/i2c/i2c-controller.yaml#
diff --git a/Documentation/devicetree/bindings/input/omap-keypad.txt b/Documentation/devicetree/bindings/input/omap-keypad.txt deleted file mode 100644 index 34ed1c6..0000000 --- a/Documentation/devicetree/bindings/input/omap-keypad.txt +++ /dev/null
@@ -1,28 +0,0 @@ -* TI's Keypad Controller device tree bindings - -TI's Keypad controller is used to interface a SoC with a matrix-type -keypad device. The keypad controller supports multiple row and column lines. -A key can be placed at each intersection of a unique row and a unique column. -The keypad controller can sense a key-press and key-release and report the -event using a interrupt to the cpu. - -This binding is based on the matrix-keymap binding with the following -changes: - -keypad,num-rows and keypad,num-columns are required. - -Required SoC Specific Properties: -- compatible: should be one of the following - - "ti,omap4-keypad": For controllers compatible with omap4 keypad - controller. - -Optional Properties specific to linux: -- linux,keypad-no-autorepeat: do no enable autorepeat feature. - -Example: - keypad@4ae1c000{ - compatible = "ti,omap4-keypad"; - keypad,num-rows = <2>; - keypad,num-columns = <8>; - linux,keypad-no-autorepeat; - };
diff --git a/Documentation/devicetree/bindings/input/samsung,s3c6410-keypad.yaml b/Documentation/devicetree/bindings/input/samsung,s3c6410-keypad.yaml index a53569a..2498c62 100644 --- a/Documentation/devicetree/bindings/input/samsung,s3c6410-keypad.yaml +++ b/Documentation/devicetree/bindings/input/samsung,s3c6410-keypad.yaml
@@ -37,6 +37,10 @@ wakeup-source: true + keypad,num-columns: true + keypad,num-rows: true + linux,keymap: true + linux,input-no-autorepeat: type: boolean description: @@ -81,12 +85,33 @@ - keypad,row - linux,code +dependencies: + linux,keymap: [ "keypad,num-columns", "keypad,num-rows" ] + required: - compatible - reg - interrupts - - samsung,keypad-num-columns - - samsung,keypad-num-rows + +allOf: + - $ref: input.yaml# + - $ref: matrix-keymap.yaml# + - if: + required: + - linux,keymap + then: + properties: + samsung,keypad-num-columns: false + samsung,keypad-num-rows: false + patternProperties: + '^key-[0-9a-z]+$': false + else: + properties: + keypad,num-columns: false + keypad,num-rows: false + required: + - samsung,keypad-num-columns + - samsung,keypad-num-rows additionalProperties: false @@ -94,8 +119,9 @@ - | #include <dt-bindings/clock/exynos4.h> #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/input/input.h> - keypad@100a0000 { + keypad1@100a0000 { compatible = "samsung,s5pv210-keypad"; reg = <0x100a0000 0x100>; interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>; @@ -119,3 +145,24 @@ linux,code = <3>; }; }; + - | + #include <dt-bindings/clock/exynos4.h> + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/input/input.h> + + keypad2@100a0000 { + compatible = "samsung,s5pv210-keypad"; + reg = <0x100a0000 0x100>; + interrupts = <GIC_SPI 109 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clock CLK_KEYIF>; + clock-names = "keypad"; + + keypad,num-rows = <2>; + keypad,num-columns = <8>; + linux,keymap = < + MATRIX_KEY(0, 3, 2) + MATRIX_KEY(0, 4, 3) + >; + linux,input-no-autorepeat; + wakeup-source; + };
diff --git a/Documentation/devicetree/bindings/input/ti,omap4-keypad.yaml b/Documentation/devicetree/bindings/input/ti,omap4-keypad.yaml new file mode 100644 index 0000000..5e0c101 --- /dev/null +++ b/Documentation/devicetree/bindings/input/ti,omap4-keypad.yaml
@@ -0,0 +1,63 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/input/ti,omap4-keypad.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments Keypad Controller + +maintainers: + - Eduard Bostina <egbostina@gmail.com> + +description: + TI's Keypad controller is used to interface a SoC with a matrix-type + keypad device. The keypad controller supports multiple row and column lines. + A key can be placed at each intersection of a unique row and a unique column. + The keypad controller can sense a key-press and key-release and report the + event using a interrupt to the cpu. + +allOf: + - $ref: /schemas/input/matrix-keymap.yaml# + +properties: + compatible: + const: ti,omap4-keypad + + reg: + maxItems: 1 + + reg-names: + const: mpu + + interrupts: + maxItems: 1 + + linux,input-no-autorepeat: + type: boolean + description: Do not enable autorepeat feature. + +required: + - compatible + - reg + - interrupts + - keypad,num-rows + - keypad,num-columns + - linux,keymap + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + + keypad@4ae1c000 { + compatible = "ti,omap4-keypad"; + reg = <0x4ae1c000 0x400>; + reg-names = "mpu"; + interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; + keypad,num-rows = <2>; + keypad,num-columns = <8>; + linux,keymap = <0x00000011 /* KEY_W */ + 0x0001001f>; /* KEY_S */ + linux,input-no-autorepeat; + };
diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml index 21b4e04..f696991 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml
@@ -50,6 +50,7 @@ - enum: - qcom,eliza-llcc-bwmon - qcom,hawi-llcc-bwmon + - qcom,milos-cpu-bwmon - qcom,qcs615-llcc-bwmon - qcom,qcs8300-llcc-bwmon - qcom,sa8775p-llcc-bwmon
diff --git a/Documentation/devicetree/bindings/interrupt-controller/apple,aic2.yaml b/Documentation/devicetree/bindings/interrupt-controller/apple,aic2.yaml index 726a672..e3cadc5 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/apple,aic2.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/apple,aic2.yaml
@@ -45,6 +45,8 @@ - enum: - apple,t6030-aic3 - apple,t6031-aic3 + - apple,t8132-aic3 + - apple,t8140-aic3 - const: apple,t8122-aic3 - const: apple,t8122-aic3
diff --git a/Documentation/devicetree/bindings/interrupt-controller/thead,c900-aclint-mswi.yaml b/Documentation/devicetree/bindings/interrupt-controller/thead,c900-aclint-mswi.yaml index 62fd220..d17f561 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/thead,c900-aclint-mswi.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/thead,c900-aclint-mswi.yaml
@@ -12,6 +12,7 @@ properties: compatible: oneOf: + - const: spacemit,k3-aclint-mswi - items: - enum: - sophgo,sg2042-aclint-mswi
diff --git a/Documentation/devicetree/bindings/interrupt-controller/thead,c900-aclint-sswi.yaml b/Documentation/devicetree/bindings/interrupt-controller/thead,c900-aclint-sswi.yaml index d02c688..0b34ed5 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/thead,c900-aclint-sswi.yaml +++ b/Documentation/devicetree/bindings/interrupt-controller/thead,c900-aclint-sswi.yaml
@@ -24,13 +24,14 @@ properties: compatible: oneOf: + - enum: + - mips,p8700-aclint-sswi + - spacemit,k3-aclint-sswi - items: - enum: - sophgo,sg2044-aclint-sswi - const: thead,c900-aclint-sswi - items: - - const: mips,p8700-aclint-sswi - - items: - enum: - anlogic,dr1v90-aclint-sswi - const: nuclei,ux900-aclint-sswi
diff --git a/Documentation/devicetree/bindings/mailbox/hisilicon,hi3660-mailbox.txt b/Documentation/devicetree/bindings/mailbox/hisilicon,hi3660-mailbox.txt deleted file mode 100644 index 3e5b453..0000000 --- a/Documentation/devicetree/bindings/mailbox/hisilicon,hi3660-mailbox.txt +++ /dev/null
@@ -1,51 +0,0 @@ -Hisilicon Hi3660 Mailbox Controller - -Hisilicon Hi3660 mailbox controller supports up to 32 channels. Messages -are passed between processors, including application & communication -processors, MCU, HIFI, etc. Each channel is unidirectional and accessed -by using MMIO registers; it supports maximum to 8 words message. - -Controller ----------- - -Required properties: -- compatible: : Shall be "hisilicon,hi3660-mbox" -- reg: : Offset and length of the device's register set -- #mbox-cells: : Must be 3 - <&phandle channel dst_irq ack_irq> - phandle : Label name of controller - channel : Channel number - dst_irq : Remote interrupt vector - ack_irq : Local interrupt vector - -- interrupts: : Contains the two IRQ lines for mailbox. - -Example: - -mailbox: mailbox@e896b000 { - compatible = "hisilicon,hi3660-mbox"; - reg = <0x0 0xe896b000 0x0 0x1000>; - interrupts = <0x0 0xc0 0x4>, - <0x0 0xc1 0x4>; - #mbox-cells = <3>; -}; - -Client ------- - -Required properties: -- compatible : See the client docs -- mboxes : Standard property to specify a Mailbox (See ./mailbox.txt) - Cells must match 'mbox-cells' (See Controller docs above) - -Optional properties -- mbox-names : Name given to channels seen in the 'mboxes' property. - -Example: - -stub_clock: stub_clock@e896b500 { - compatible = "hisilicon,hi3660-stub-clk"; - reg = <0x0 0xe896b500 0x0 0x0100>; - #clock-cells = <1>; - mboxes = <&mailbox 13 3 0>; -};
diff --git a/Documentation/devicetree/bindings/mailbox/hisilicon,hi3660-mbox.yaml b/Documentation/devicetree/bindings/mailbox/hisilicon,hi3660-mbox.yaml new file mode 100644 index 0000000..c42ce57 --- /dev/null +++ b/Documentation/devicetree/bindings/mailbox/hisilicon,hi3660-mbox.yaml
@@ -0,0 +1,57 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/hisilicon,hi3660-mbox.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Hisilicon Hi3660 Mailbox Controller + +maintainers: + - Wei Xu <xuwei5@hisilicon.com> + +description: + Hisilicon Hi3660 mailbox controller supports up to 32 channels. Messages + are passed between processors, including application & communication + processors, MCU, HIFI, etc. Each channel is unidirectional and accessed + by using MMIO registers; it supports maximum to 8 words message. + +properties: + compatible: + items: + - const: hisilicon,hi3660-mbox + + reg: + maxItems: 1 + + interrupts: + description: Mailbox interrupt vectors for message processing + maxItems: 2 + + '#mbox-cells': + description: > + The cells content are as follows: + - Channel number + - Remote destination interrupt vector + - Local ack interrupt vector + const: 3 + +required: + - compatible + - reg + - interrupts + - '#mbox-cells' + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/interrupt-controller/irq.h> + + mailbox@e896b000 { + compatible = "hisilicon,hi3660-mbox"; + reg = <0xe896b000 0x1000>; + interrupts = <GIC_SPI 0xc0 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xc1 IRQ_TYPE_LEVEL_HIGH>; + #mbox-cells = <3>; + };
diff --git a/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt b/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt deleted file mode 100644 index 044b17f..0000000 --- a/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mailbox.txt +++ /dev/null
@@ -1,74 +0,0 @@ -Hisilicon Hi6220 Mailbox Driver -=============================== - -Hisilicon Hi6220 mailbox supports up to 32 channels. Each channel -is unidirectional with a maximum message size of 8 words. I/O is -performed using register access (there is no DMA) and the cell -raises an interrupt when messages are received. - -Mailbox Device Node: -==================== - -Required properties: --------------------- -- compatible: Shall be "hisilicon,hi6220-mbox" -- reg: Contains the mailbox register address range (base - address and length); the first item is for IPC - registers, the second item is shared buffer for - slots. -- #mbox-cells: Common mailbox binding property to identify the number - of cells required for the mailbox specifier. Must be 3. - <&phandle slot_id dst_irq ack_irq> - phandle: Label name of mailbox controller - slot_id: Slot id used either for TX or RX - dst_irq: IRQ identifier index number which used by MCU - ack_irq: IRQ identifier index number with generating a - TX/RX interrupt to application processor, - mailbox driver uses it to acknowledge interrupt -- interrupts: Contains the interrupt information for the mailbox - device. The format is dependent on which interrupt - controller the SoCs use. - -Optional Properties: --------------------- -- hi6220,mbox-tx-noirq: Property of MCU firmware's feature, so mailbox driver - use this flag to ask MCU to enable "automatic idle - flag" mode or IRQ generated mode to acknowledge a TX - completion. - -Example: --------- - - mailbox: mailbox@f7510000 { - compatible = "hisilicon,hi6220-mbox"; - reg = <0x0 0xf7510000 0x0 0x1000>, /* IPC_S */ - <0x0 0x06dff800 0x0 0x0800>; /* Mailbox */ - interrupt-parent = <&gic>; - interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; - #mbox-cells = <3>; - }; - - -Mailbox client -=============== - -Required properties: --------------------- -- compatible: Many (See the client docs). -- mboxes: Standard property to specify a Mailbox (See ./mailbox.txt) - Cells must match 'mbox-cells' (See Mailbox Device Node above). - -Optional Properties: --------------------- -- mbox-names: Name given to channels seen in the 'mboxes' property. - -Example: --------- - - stub_clock: stub_clock { - compatible = "hisilicon,hi6220-stub-clk"; - hisilicon,hi6220-clk-sram = <&sram>; - #clock-cells = <1>; - mbox-names = "mbox-tx", "mbox-rx"; - mboxes = <&mailbox 1 0 11>, <&mailbox 0 1 10>; - };
diff --git a/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mbox.yaml b/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mbox.yaml new file mode 100644 index 0000000..f4c8f1f --- /dev/null +++ b/Documentation/devicetree/bindings/mailbox/hisilicon,hi6220-mbox.yaml
@@ -0,0 +1,63 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mailbox/hisilicon,hi6220-mbox.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Hisilicon Hi6220 Mailbox Controller + +maintainers: + - Wei Xu <xuwei5@hisilicon.com> + +description: + Hisilicon Hi6220 mailbox supports up to 32 channels. Each channel is + unidirectional with a maximum message size of 8 words. I/O is performed using + register access (there is no DMA) and the cell raises an interrupt when + messages are received. + +properties: + compatible: + const: hisilicon,hi6220-mbox + + reg: + items: + - description: IPC registers + - description: Shared buffer for mailbox slots + + interrupts: + maxItems: 1 + + "#mbox-cells": + const: 3 + description: > + The cells content are as follows: + - Slot number + - Remote destination interrupt vector + - Local ack interrupt vector + + hi6220,mbox-tx-noirq: + description: + Flag to request MCU to enable automatic idle flag mode instead of IRQ for + TX completion. + type: boolean + +required: + - compatible + - reg + - interrupts + - "#mbox-cells" + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + #include <dt-bindings/interrupt-controller/irq.h> + + mailbox@f7510000 { + compatible = "hisilicon,hi6220-mbox"; + reg = <0xf7510000 0x1000>, + <0x06dff800 0x0800>; + interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; + #mbox-cells = <3>; + };
diff --git a/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml b/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml index 39bc374..5110363 100644 --- a/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml +++ b/Documentation/devicetree/bindings/mailbox/qcom,apcs-kpss-global.yaml
@@ -39,6 +39,7 @@ - const: syscon - items: - enum: + - qcom,ipq9650-apcs-apps-global - qcom,msm8998-apcs-hmss-global - qcom,sdm660-apcs-hmss-global - qcom,sm4250-apcs-hmss-global @@ -50,6 +51,7 @@ - qcom,qcs615-apss-shared - qcom,sc7180-apss-shared - qcom,sc8180x-apss-shared + - qcom,sdm670-apss-shared - qcom,shikra-apss-shared - qcom,sm7150-apss-shared - qcom,sm8150-apss-shared
diff --git a/Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml b/Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml index 0335947..2185920 100644 --- a/Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml +++ b/Documentation/devicetree/bindings/mailbox/qcom,cpucp-mbox.yaml
@@ -21,6 +21,7 @@ - qcom,glymur-cpucp-mbox - qcom,hawi-cpucp-mbox - qcom,kaanapali-cpucp-mbox + - qcom,maili-cpucp-mbox - qcom,nord-cpucp-mbox - qcom,sm8750-cpucp-mbox - const: qcom,x1e80100-cpucp-mbox
diff --git a/Documentation/devicetree/bindings/mailbox/ti,secure-proxy.yaml b/Documentation/devicetree/bindings/mailbox/ti,secure-proxy.yaml index c321b69..5252669 100644 --- a/Documentation/devicetree/bindings/mailbox/ti,secure-proxy.yaml +++ b/Documentation/devicetree/bindings/mailbox/ti,secure-proxy.yaml
@@ -22,7 +22,9 @@ pattern: "^mailbox@[0-9a-f]+$" compatible: - const: ti,am654-secure-proxy + enum: + - ti,am654-secure-proxy + - ti,tda54-main-secure-proxy "#mbox-cells": const: 1
diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml index 0762e0ff..33c989f 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-common.yaml
@@ -16,7 +16,7 @@ MediaTek SMI have two generations of HW architecture, here is the list which generation the SoCs use: generation 1: mt2701 and mt7623. - generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8186, mt8188, mt8192 and mt8195. + generation 2: mt2712, mt6779, mt8167, mt8173, mt8183, mt8186, mt8188, mt8189, mt8192 and mt8195. There's slight differences between the two SMI, for generation 2, the register which control the iommu port is at each larb's register base. But @@ -25,6 +25,21 @@ SMI generation 1 to transform the smi clock into emi clock domain, but that is not needed for SMI generation 2. + The smi-common connects with smi-larb and IOMMU. The maximum inputs number of + a smi-common is 8. In SMI generation 2, the engines number may be over 8. + In this case, we use a smi-sub-common to merge some larbs. + The block diagram something is like: + + IOMMU + | | + smi-common + --------------------------- + | | ... + larb0 sub-common ... <-max number is 8 + ---------------- + | | ... + larb1 larbX ... <-max number is 8 + properties: compatible: oneOf: @@ -40,6 +55,8 @@ - mediatek,mt8186-smi-common - mediatek,mt8188-smi-common-vdo - mediatek,mt8188-smi-common-vpp + - mediatek,mt8189-smi-common + - mediatek,mt8189-smi-sub-common - mediatek,mt8192-smi-common - mediatek,mt8195-smi-common-vdo - mediatek,mt8195-smi-common-vpp @@ -108,6 +125,7 @@ compatible: contains: enum: + - mediatek,mt8189-smi-sub-common - mediatek,mt8195-smi-sub-common then: required: @@ -157,6 +175,7 @@ - mediatek,mt6795-smi-common - mediatek,mt8167-smi-common - mediatek,mt8173-smi-common + - mediatek,mt8189-smi-common then: properties:
diff --git a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml index 2e7fac4..9a5dafd 100644 --- a/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml +++ b/Documentation/devicetree/bindings/memory-controllers/mediatek,smi-larb.yaml
@@ -27,6 +27,7 @@ - mediatek,mt8183-smi-larb - mediatek,mt8186-smi-larb - mediatek,mt8188-smi-larb + - mediatek,mt8189-smi-larb - mediatek,mt8192-smi-larb - mediatek,mt8195-smi-larb @@ -85,6 +86,7 @@ - mediatek,mt8183-smi-larb - mediatek,mt8186-smi-larb - mediatek,mt8188-smi-larb + - mediatek,mt8189-smi-larb - mediatek,mt8195-smi-larb then: @@ -119,6 +121,7 @@ - mediatek,mt6779-smi-larb - mediatek,mt8186-smi-larb - mediatek,mt8188-smi-larb + - mediatek,mt8189-smi-larb - mediatek,mt8192-smi-larb - mediatek,mt8195-smi-larb
diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml index 9398aae..8e0c67d 100644 --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-emc.yaml
@@ -16,9 +16,13 @@ properties: compatible: - enum: - - nvidia,tegra114-emc - - nvidia,tegra124-emc + oneOf: + - enum: + - nvidia,tegra114-emc + - nvidia,tegra124-emc + - items: + - const: nvidia,tegra132-emc + - const: nvidia,tegra124-emc reg: maxItems: 1
diff --git a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml index f8747ce..2f1ffd2 100644 --- a/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml +++ b/Documentation/devicetree/bindings/memory-controllers/nvidia,tegra124-mc.yaml
@@ -22,6 +22,7 @@ enum: - nvidia,tegra114-mc - nvidia,tegra124-mc + - nvidia,tegra132-mc reg: maxItems: 1
diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd71815-pmic.yaml b/Documentation/devicetree/bindings/mfd/rohm,bd71815-pmic.yaml index 4fc78ef..0a67de0 100644 --- a/Documentation/devicetree/bindings/mfd/rohm,bd71815-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/rohm,bd71815-pmic.yaml
@@ -15,6 +15,9 @@ for LED and a 500 mA single-cell linear charger. Also included is a Coulomb counter, a real-time clock (RTC), and a 32.768 kHz clock gate and two GPOs. +allOf: + - $ref: rohm,pmic-pins.yaml# + properties: compatible: const: rohm,bd71815 @@ -44,11 +47,7 @@ clock-output-names: const: bd71815-32k-out - rohm,clkout-open-drain: - description: clk32kout mode. Set to 1 for "open-drain" or 0 for "cmos". - $ref: /schemas/types.yaml#/definitions/uint32 - minimum: 0 - maximum: 1 + rohm,clkout-open-drain: true rohm,charger-sense-resistor-micro-ohms: minimum: 10000
diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml b/Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml index 09e7d68e..e5043de 100644 --- a/Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/rohm,bd71828-pmic.yaml
@@ -15,6 +15,9 @@ single-cell linear charger. Also included is a Coulomb counter, a real-time clock (RTC), and a 32.768 kHz clock gate. +allOf: + - $ref: rohm,pmic-pins.yaml# + properties: compatible: oneOf: @@ -49,11 +52,7 @@ clock-output-names: const: bd71828-32k-out - rohm,clkout-open-drain: - description: clk32kout mode. Set to 1 for "open-drain" or 0 for "cmos". - $ref: /schemas/types.yaml#/definitions/uint32 - minimum: 0 - maximum: 1 + rohm,clkout-open-drain: true rohm,charger-sense-resistor-micro-ohms: minimum: 10000
diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd72720-pmic.yaml b/Documentation/devicetree/bindings/mfd/rohm,bd72720-pmic.yaml index b094542..52d0f6e 100644 --- a/Documentation/devicetree/bindings/mfd/rohm,bd72720-pmic.yaml +++ b/Documentation/devicetree/bindings/mfd/rohm,bd72720-pmic.yaml
@@ -15,6 +15,9 @@ and a 3000 mA switching charger. ICs also include a Coulomb counter, a real-time clock (RTC), GPIOs and a 32.768 kHz clock gate. +allOf: + - $ref: rohm,pmic-pins.yaml# + # In addition to the properties found from the charger node, PMICs # use properties from a static battery node. Please see the: # Documentation/devicetree/bindings/power/supply/battery.yaml @@ -80,10 +83,7 @@ clock-output-names: const: bd71828-32k-out - rohm,clkout-open-drain: - description: clk32kout mode. Set to 1 for "open-drain" or 0 for "cmos". - $ref: /schemas/types.yaml#/definitions/uint32 - maximum: 1 + rohm,clkout-open-drain: true rohm,charger-sense-resistor-micro-ohms: minimum: 10000 @@ -103,14 +103,6 @@ $ref: /schemas/leds/rohm,bd71828-leds.yaml rohm,pin-fault_b: - $ref: /schemas/types.yaml#/definitions/string - description: - PMIC has an OTP option to use fault_b-pin for different - purposes. Set this property accordingly. OTP options are - OTP0 - bi-directional FAULT_B or READY indicator depending on a - 'sub option' - OTP1 - GPO - OTP2 - Power sequencer output. enum: - faultb - readyind @@ -119,14 +111,6 @@ patternProperties: "^rohm,pin-dvs[0-1]$": - $ref: /schemas/types.yaml#/definitions/string - description: - PMIC has 4 different OTP options to determine the use of dvs<X>-pins. - OTP0 - regulator RUN state control. - OTP1 - GPI. - OTP2 - GPO. - OTP3 - Power sequencer output. - This property specifies the use of the pin. enum: - dvs-input - gpi @@ -134,11 +118,6 @@ - pwrseq "^rohm,pin-exten[0-1]$": - $ref: /schemas/types.yaml#/definitions/string - description: PMIC has an OTP option to use exten0-pin for different - purposes. Set this property accordingly. - OTP0 - GPO - OTP1 - Power sequencer output. enum: - gpo - pwrseq
diff --git a/Documentation/devicetree/bindings/mfd/rohm,bd73800-pmic.yaml b/Documentation/devicetree/bindings/mfd/rohm,bd73800-pmic.yaml new file mode 100644 index 0000000..8371e7f --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/rohm,bd73800-pmic.yaml
@@ -0,0 +1,218 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/rohm,bd73800-pmic.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ROHM BD73800 Power Management Integrated Circuit + +maintainers: + - Matti Vaittinen <mazziesaccount@gmail.com> + +description: + BD73800GW is a single-chip power management IC for battery-powered + portable devices. It integrates 8 buck converters, 4 LDOs and a current + sense amplifier with ADC. Also included is a Real Time Clock (RTC) and a + 32.768 kHz clock gate. Depending on the OTP configuration the BD73800 + may also have interrupt controller and GPIOs. + + There are also different variants called BD71851 and BD71885 which are + almost identical from the software point of view. + +allOf: + - $ref: rohm,pmic-pins.yaml# + +properties: + compatible: + oneOf: + - const: rohm,bd73800 + + - items: + - enum: + - rohm,bd71851 + - rohm,bd71885 + - const: rohm,bd73800 + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + # The GPIO1, CLKOUT (GPIO2), FAULT_B and EXTEN_OUT pins can be + # configured to interrupt pins by OTP. + interrupt-controller: true + + "#interrupt-cells": + const: 1 + description: + The IRQ number. 0 is GPIO1, 1 CLKOUT (GPIO2), 2 FAULT_B and 3 EXTEN_OUT. + NOTE, A pin can operate as IRQ source only when the OTP + configuration for it has been set to GPI. + + gpio-controller: true + + "#gpio-cells": + const: 2 + + rohm,pin-gpio1: + $ref: /schemas/types.yaml#/definitions/string + description: + Indicate if the GPIO1 pin has been set to GPI or GPO at manufacturing. + The GPIO1, CLKOUT, FAULT_B and EXTEN_OUT pins may be configured for a + specific purpose (like ADC input, 32.768 clk output, fault indicator or + delivering power sequence to a companion PMIC when multiple PMICs are + used) - but also to be either a GPO or GPI. (When used as a GPI the pin + can also be used as an IRQ source). The pin purpose is determined by + OTP (One Time Programmable memory), typically during device + manufacturing. The OTP can't be read at runtime so device-tree should + describe the GPIO pins. + enum: [gpi, gpo] + + rohm,pin-clkout: + enum: [gpi, gpo] + + rohm,pin-fault_b: + enum: [gpi, gpo] + + rohm,pin-exten: + enum: [gpi, gpo] + + clocks: + description: + The CLKOUT pin may have its purpose overridden by OTP configuration. It + is possible the BD73800 does not output a clock signal. Hence the clk + properties are optional. + maxItems: 1 + + "#clock-cells": + const: 0 + + clock-output-names: + maxItems: 1 + + rohm,clkout-open-drain: true + + regulators: + $ref: /schemas/regulator/rohm,bd73800-regulator.yaml + description: + List of child nodes that specify the regulators. + +required: + - compatible + - reg + - interrupts + - regulators + +additionalProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/leds/common.h> + i2c { + #address-cells = <1>; + #size-cells = <0>; + pmic: pmic@4b { + compatible = "rohm,bd73800"; + reg = <0x4b>; + + interrupt-parent = <&gpio1>; + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + + clocks = <&osc 0>; + #clock-cells = <0>; + clock-output-names = "bd73800-32k-out"; + + gpio-controller; + #gpio-cells = <2>; + + rohm,pin-gpio1 = "gpo"; + rohm,pin-exten = "gpi"; + + regulators { + buck1: buck1 { + regulator-name = "buck1"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <2000000>; + regulator-always-on; + regulator-ramp-delay = <1250>; + rohm,dvs-run-voltage = <1150000>; + rohm,dvs-suspend-voltage = <950000>; + }; + buck2: buck2 { + regulator-name = "buck2"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <2000000>; + regulator-always-on; + regulator-ramp-delay = <1250>; + rohm,dvs-run-voltage = <1150000>; + rohm,dvs-suspend-voltage = <950000>; + }; + buck3: buck3 { + regulator-name = "buck3"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <2700000>; + rohm,dvs-run-voltage = <1150000>; + rohm,dvs-idle-voltage = <1100000>; + rohm,dvs-suspend-voltage = <950000>; + regulator-always-on; + }; + buck4: buck4 { + regulator-name = "buck4"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1850000>; + regulator-always-on; + }; + buck5: buck5 { + regulator-name = "buck5"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + buck6: buck6 { + regulator-name = "buck6"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + buck7: buck7 { + regulator-name = "buck7"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + buck8: buck8 { + regulator-name = "buck8"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1300000>; + regulator-always-on; + }; + ldo1: ldo1 { + regulator-name = "ldo1"; + rohm,ldo-range-high; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + ldo2: ldo2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + ldo3: ldo3 { + regulator-name = "ldo3"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + ldo4: ldo4 { + regulator-name = "ldo4"; + regulator-min-microvolt = <650000>; + regulator-max-microvolt = <1750000>; + regulator-always-on; + }; + }; + }; + };
diff --git a/Documentation/devicetree/bindings/mfd/rohm,pmic-pins.yaml b/Documentation/devicetree/bindings/mfd/rohm,pmic-pins.yaml new file mode 100644 index 0000000..0d10828 --- /dev/null +++ b/Documentation/devicetree/bindings/mfd/rohm,pmic-pins.yaml
@@ -0,0 +1,72 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mfd/rohm,pmic-pins.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ROHM PMICs' OTP configured pin descriptions + +maintainers: + - Matti Vaittinen <mazziesaccount@gmail.com> + +description: + Collection of properties which are commonly used to describe various + ROHM PMIC's pins. + +properties: + rohm,clkout-open-drain: + description: clk32kout mode. Set to 1 for "open-drain" or 0 for "cmos" + a.k.a "push-pull". + $ref: /schemas/types.yaml#/definitions/uint32 + maximum: 1 + + rohm,pin-clkout: + $ref: /schemas/types.yaml#/definitions/string + description: + The IC has different OTP options to use clkout-pin for different + purposes. Set this property to indicate the OTP variant. + + Many of the ROHM ICs have pins, which function can be defined in + OTP. Some of them provide no means to detect the pin configuration + at run-time, leaving software unaware of which features the IC + really has. These properties can be used to inform which pins + provide which functionality. IOW, these properties aren't used to + configure pin, they are used to tell what functionality pins on + this specific IC have. + + # Supported functionalities depend on the exact IC model. Following + # values are already defined: gpi, gpo. + # Please, re-use them when adding new ICs. + + rohm,pin-fault_b: + $ref: /schemas/types.yaml#/definitions/string + description: + The IC has different OTP options to use fault_b-pin for different + purposes. Set this property to indicate the OTP variant. + + # Supported functionalities depend on the exact IC model. Following + # values are already defined: gpi, gpo, faultb, readyind, pwrseq. + # Please, re-use them when adding new ICs. + +patternProperties: + "^rohm,pin-dvs[0-1]$": + $ref: /schemas/types.yaml#/definitions/string + description: + The IC has different OTP options to use dvs<X>-pins for different + purposes. Set this property to indicate the OTP variant. + # Supported functionalities depend on the exact IC model. Following + # values are already defined: dvs-input, gpi, gpo, pwrseq. + # Please, re-use them when adding new ICs. + + "^rohm,pin-exten([0-1])?$": + $ref: /schemas/types.yaml#/definitions/string + description: + The IC has an OTP option to use exten -pin(s) for different purposes. + Set this property to indicate the OTP variant. + # Supported functionalities depend on the exact IC model. Following + # values are already defined: gpi, gpo, pwrseq. + # Please, re-use them when adding new ICs. + +# The schema is expected to be reference by IC schemas, which may introduce +# other properties that must be allowed. +additionalProperties: true
diff --git a/Documentation/devicetree/bindings/mfd/st,stmpe.yaml b/Documentation/devicetree/bindings/mfd/st,stmpe.yaml index ddb27ae..6fde068 100644 --- a/Documentation/devicetree/bindings/mfd/st,stmpe.yaml +++ b/Documentation/devicetree/bindings/mfd/st,stmpe.yaml
@@ -141,6 +141,30 @@ compatible: const: st,stmpe-ts + st,sample-time: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1, 2, 3, 4, 5, 6 ] + deprecated: true + description: See top layer st,sample-time. + + st,mod-12b: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1 ] + deprecated: true + description: See top layer st,mod-12b + + st,ref-sel: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1 ] + deprecated: true + description: See top layer st,ref-sel + + st,adc-freq: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [ 0, 1, 2, 3 ] + deprecated: true + description: See top layer st,adc-freq + st,ave-ctrl: $ref: /schemas/types.yaml#/definitions/uint32 enum: [ 0, 1, 2, 3 ] @@ -201,7 +225,6 @@ required: - compatible - reg - - interrupts examples: - |
diff --git a/Documentation/devicetree/bindings/mfd/syscon.yaml b/Documentation/devicetree/bindings/mfd/syscon.yaml index 945a168..33e0b1b 100644 --- a/Documentation/devicetree/bindings/mfd/syscon.yaml +++ b/Documentation/devicetree/bindings/mfd/syscon.yaml
@@ -107,6 +107,7 @@ - nxp,s32g3-gpr - qcom,apq8064-mmss-sfpb - qcom,apq8064-sps-sic + - qcom,msm8960-sps-sic - rockchip,px30-qos - rockchip,rk3036-qos - rockchip,rk3066-qos
diff --git a/Documentation/devicetree/bindings/mfd/ti,tps65910.yaml b/Documentation/devicetree/bindings/mfd/ti,tps65910.yaml index f1a76f8..209dc97 100644 --- a/Documentation/devicetree/bindings/mfd/ti,tps65910.yaml +++ b/Documentation/devicetree/bindings/mfd/ti,tps65910.yaml
@@ -97,7 +97,9 @@ patternProperties: "^(vrtc|vio|vpll|vdac|vmmc|vbb|vddctrl)$": type: object - $ref: /schemas/regulator/regulator.yaml# + allOf: + - $ref: /schemas/regulator/regulator.yaml# + - $ref: /schemas/regulator/nvidia,tegra-regulators-coupling.yaml# properties: ti,regulator-ext-sleep-control: description: | @@ -110,7 +112,9 @@ "^(vdd[1-3]|vaux([1-2]|33)|vdig[1-2])$": type: object - $ref: /schemas/regulator/regulator.yaml# + allOf: + - $ref: /schemas/regulator/regulator.yaml# + - $ref: /schemas/regulator/nvidia,tegra-regulators-coupling.yaml# properties: ti,regulator-ext-sleep-control: description: | @@ -123,7 +127,9 @@ "^ldo[1-8]$": type: object - $ref: /schemas/regulator/regulator.yaml# + allOf: + - $ref: /schemas/regulator/regulator.yaml# + - $ref: /schemas/regulator/nvidia,tegra-regulators-coupling.yaml# properties: ti,regulator-ext-sleep-control: description: |
diff --git a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml index 9e9610b..c2ec715 100644 --- a/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml +++ b/Documentation/devicetree/bindings/mmc/allwinner,sun4i-a10-mmc.yaml
@@ -32,10 +32,12 @@ - items: - enum: - allwinner,sun8i-a83t-mmc + - allwinner,sun8i-b288-mmc - allwinner,suniv-f1c100s-mmc - const: allwinner,sun7i-a20-mmc - items: - enum: + - allwinner,sun8i-b288-emmc - allwinner,sun8i-r40-emmc - allwinner,sun50i-h5-emmc - allwinner,sun50i-h6-emmc
diff --git a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml index 976f36d..12342b1 100644 --- a/Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml +++ b/Documentation/devicetree/bindings/mmc/amlogic,meson-gx-mmc.yaml
@@ -15,6 +15,23 @@ allOf: - $ref: mmc-controller.yaml# + - if: + properties: + compatible: + contains: + const: amlogic,t7-mmc + then: + properties: + clocks: + minItems: 4 + clock-names: + minItems: 4 + else: + properties: + clocks: + maxItems: 3 + clock-names: + maxItems: 3 properties: compatible: @@ -38,13 +55,23 @@ - description: card detect clocks: - maxItems: 3 + minItems: 3 + items: + - description: core clock + - description: clock input 0 of the internal mux + - description: clock input 1 of the internal mux + - description: + clock of the pipeline stage inserted in the bus path between + the controller and the DRAM. Without it, the controller cannot + complete DMA transfers. clock-names: + minItems: 3 items: - const: core - const: clkin0 - const: clkin1 + - const: pipeline resets: maxItems: 1
diff --git a/Documentation/devicetree/bindings/mmc/cdns,sd6hc.yaml b/Documentation/devicetree/bindings/mmc/cdns,sd6hc.yaml new file mode 100644 index 0000000..d5ea271 --- /dev/null +++ b/Documentation/devicetree/bindings/mmc/cdns,sd6hc.yaml
@@ -0,0 +1,105 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/mmc/cdns,sd6hc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cadence SD6HC SD/SDIO/eMMC Host Controller + +maintainers: + - Tanmay Kathpalia <tanmay.kathpalia@altera.com> + +description: + Cadence SD6HC is a sixth-generation SD/SDIO/eMMC host controller with an + interface to a Cadence Combo PHY. The controller has separate card interface + and bus interface clock domains. + +properties: + compatible: + items: + - const: altr,agilex5-sd6hc + - const: cdns,sd6hc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + items: + - description: card interface unit (CIU / SDMCLK) clock + - description: bus interface unit (BIU) clock + + clock-names: + items: + - const: ciu + - const: biu + + resets: + items: + - description: SDHC controller reset + - description: Combo PHY reset + - description: SDMMC OCP/AXI reset + + reset-names: + items: + - const: sdhc-reset + - const: combophy + - const: sdmmc-ocp + + iommus: + maxItems: 1 + + dma-coherent: true + + cdns,iocell-input-delay-ps: + description: + Input delay across the IO cells, used for SD6HC PHY timing calculations. + minimum: 0 + maximum: 20000 + default: 2500 + + cdns,iocell-output-delay-ps: + description: + Output delay across the IO cells, used for SD6HC PHY timing calculations. + minimum: 0 + maximum: 20000 + default: 2500 + + cdns,delay-element-ps: + description: + DLL delay element size, used for SD6HC PHY timing calculations. + minimum: 1 + maximum: 1000 + default: 24 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - resets + - reset-names + +allOf: + - $ref: sdhci-common.yaml# + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/arm-gic.h> + + mmc@10808000 { + compatible = "altr,agilex5-sd6hc", "cdns,sd6hc"; + reg = <0x10808000 0x1000>; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clkmgr 0>, <&clkmgr 1>; + clock-names = "ciu", "biu"; + resets = <&rst 0>, <&rst 1>, <&rst 2>; + reset-names = "sdhc-reset", "combophy", "sdmmc-ocp"; + iommus = <&smmu 5>; + dma-coherent; + };
diff --git a/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml b/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml index 3d7195e..8b9b3b0 100644 --- a/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml +++ b/Documentation/devicetree/bindings/mmc/mmc-controller-common.yaml
@@ -275,6 +275,16 @@ not available. default: 10 + power-off-delay-us: + description: + Delay in microseconds after card power is deasserted during a power + cycle to allow time for proper power discharge. Larger values can be + configured to work around hardware issues such as slow RC discharge + on MMC VDD rails. + minimum: 0 + maximum: 10000000 + default: 1000 + supports-cqe: $ref: /schemas/types.yaml#/definitions/flag description:
diff --git a/Documentation/devicetree/bindings/mmc/qcom,sdhci-msm.yaml b/Documentation/devicetree/bindings/mmc/qcom,sdhci-msm.yaml index b3fcc16..cc43a3e 100644 --- a/Documentation/devicetree/bindings/mmc/qcom,sdhci-msm.yaml +++ b/Documentation/devicetree/bindings/mmc/qcom,sdhci-msm.yaml
@@ -26,6 +26,7 @@ - qcom,ipq4019-sdhci - qcom,ipq8074-sdhci - qcom,msm8226-sdhci + - qcom,msm8952-sdhci - qcom,msm8953-sdhci - qcom,msm8974-sdhci - qcom,msm8976-sdhci @@ -38,6 +39,7 @@ - items: - enum: - qcom,eliza-sdhci + - qcom,glymur-sdhci - qcom,hawi-sdhci - qcom,ipq5018-sdhci - qcom,ipq5210-sdhci @@ -47,6 +49,7 @@ - qcom,ipq9574-sdhci - qcom,ipq9650-sdhci - qcom,kaanapali-sdhci + - qcom,maili-sdhci - qcom,milos-sdhci - qcom,qcm2290-sdhci - qcom,qcs404-sdhci
diff --git a/Documentation/devicetree/bindings/net/bluetooth/qcom,wcn6750-bt.yaml b/Documentation/devicetree/bindings/net/bluetooth/qcom,wcn6750-bt.yaml index 8606a45..7952240 100644 --- a/Documentation/devicetree/bindings/net/bluetooth/qcom,wcn6750-bt.yaml +++ b/Documentation/devicetree/bindings/net/bluetooth/qcom,wcn6750-bt.yaml
@@ -12,8 +12,14 @@ properties: compatible: - enum: - - qcom,wcn6750-bt + oneOf: + - items: + - enum: + - qcom,wcn6755-bt + - const: qcom,wcn6750-bt + + - enum: + - qcom,wcn6750-bt enable-gpios: maxItems: 1
diff --git a/Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml b/Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml index d4aa56e..929a3d6 100644 --- a/Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml +++ b/Documentation/devicetree/bindings/net/wireless/qcom,ath11k.yaml
@@ -16,11 +16,17 @@ properties: compatible: - enum: - - qcom,ipq8074-wifi - - qcom,ipq6018-wifi - - qcom,wcn6750-wifi - - qcom,ipq5018-wifi + oneOf: + - items: + - enum: + - qcom,wcn6755-wifi + - const: qcom,wcn6750-wifi + + - enum: + - qcom,ipq8074-wifi + - qcom,ipq6018-wifi + - qcom,wcn6750-wifi + - qcom,ipq5018-wifi reg: maxItems: 1
diff --git a/Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml index f08d2c4..bc6d41b 100644 --- a/Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml +++ b/Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
@@ -23,6 +23,7 @@ - apple,t6030-pinctrl - apple,t6031-pinctrl - apple,t8122-pinctrl + - apple,t8132-pinctrl - const: apple,t8103-pinctrl - items: # Do not add additional SoC to this list.
diff --git a/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml b/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml index e269f43..dcffdd1 100644 --- a/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml +++ b/Documentation/devicetree/bindings/power/apple,pmgr-pwrstate.yaml
@@ -48,6 +48,8 @@ - apple,t6030-pmgr-pwrstate - apple,t6031-pmgr-pwrstate - apple,t8122-pmgr-pwrstate + - apple,t8132-pmgr-pwrstate + - apple,t8140-pmgr-pwrstate - const: apple,t8103-pmgr-pwrstate reg:
diff --git a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml index 0a45e1f..8ee1c25 100644 --- a/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml +++ b/Documentation/devicetree/bindings/power/qcom,rpmpd.yaml
@@ -21,6 +21,7 @@ - qcom,glymur-rpmhpd - qcom,hawi-rpmhpd - qcom,kaanapali-rpmhpd + - qcom,kuno-rpmhpd - qcom,mdm9607-rpmpd - qcom,milos-rpmhpd - qcom,msm8226-rpmpd @@ -63,6 +64,7 @@ - qcom,sm6350-rpmhpd - qcom,sm6375-rpmpd - qcom,sm7150-rpmhpd + - qcom,sm7250-rpmhpd - qcom,sm8150-rpmhpd - qcom,sm8250-rpmhpd - qcom,sm8350-rpmhpd @@ -74,6 +76,7 @@ - items: - enum: - qcom,msm8937-rpmpd + - qcom,msm8952-rpmpd - const: qcom,msm8917-rpmpd - items: - enum:
diff --git a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.yaml b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.yaml index b67aa17..68b4696d 100644 --- a/Documentation/devicetree/bindings/power/renesas,rcar-sysc.yaml +++ b/Documentation/devicetree/bindings/power/renesas,rcar-sysc.yaml
@@ -13,8 +13,11 @@ description: | The R-Car (RZ/G) System Controller provides power management for the CPU cores and various coprocessors. - The power domain IDs for consumers are defined in header files: - include/dt-bindings/power/r8*-sysc.h + The power domain IDs for consumers are defined in the below header files + (where the asterisk serves as a wildcard matching the specific SoC + identifier): + include/dt-bindings/power/r8*-sysc.h or + include/dt-bindings/power/renesas,r8*-sysc.h properties: compatible:
diff --git a/Documentation/devicetree/bindings/power/riscv,rpmi-device-power.yaml b/Documentation/devicetree/bindings/power/riscv,rpmi-device-power.yaml new file mode 100644 index 0000000..5afdc40 --- /dev/null +++ b/Documentation/devicetree/bindings/power/riscv,rpmi-device-power.yaml
@@ -0,0 +1,65 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/power/riscv,rpmi-device-power.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: RISC-V RPMI device power service group based power domain controller + +maintainers: + - Joshua Yeong <joshua.yeong@starfivetech.com> + +description: | + The RISC-V Platform Management Interface (RPMI) [1] defines a + messaging protocol which is modular and extensible. The supervisor + software can send/receive RPMI messages via SBI MPXY extension [2] + or some dedicated supervisor-mode RPMI transport. + + The RPMI specification [1] defines device power service group for + accessing and controlling the power state of platform devices managed + by a platform microcontroller. The supervisor software can access RPMI + device power service group via SBI MPXY channel or some dedicated + supervisor-mode RPMI transport. + + =========================================== + References + =========================================== + + [1] RISC-V Platform Management Interface (RPMI) v1.0 (or higher) + https://github.com/riscv-non-isa/riscv-rpmi/releases + + [2] RISC-V Supervisor Binary Interface (SBI) v3.0 (or higher) + https://github.com/riscv-non-isa/riscv-sbi-doc/releases + +properties: + compatible: + description: + Intended for use by the supervisor software. + const: riscv,rpmi-device-power + + mboxes: + maxItems: 1 + description: + Mailbox channel of the underlying RPMI transport or SBI message proxy channel. + + "#power-domain-cells": + const: 1 + description: + Platform specific DOMAIN_ID as defined by the RISC-V Platform Management + Interface (RPMI) specification. + +required: + - compatible + - mboxes + - "#power-domain-cells" + +additionalProperties: false + +examples: + - | + power-controller { + compatible = "riscv,rpmi-device-power"; + mboxes = <&mpxy_mbox 0x1002 0x0>; + #power-domain-cells = <1>; + }; +...
diff --git a/Documentation/devicetree/bindings/power/riscv,rpmi-mpxy-device-power.yaml b/Documentation/devicetree/bindings/power/riscv,rpmi-mpxy-device-power.yaml new file mode 100644 index 0000000..2b7df66 --- /dev/null +++ b/Documentation/devicetree/bindings/power/riscv,rpmi-mpxy-device-power.yaml
@@ -0,0 +1,65 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/power/riscv,rpmi-mpxy-device-power.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: RISC-V RPMI device power service group based message proxy + +maintainers: + - Joshua Yeong <joshua.yeong@starfivetech.com> + +description: | + The RISC-V Platform Management Interface (RPMI) [1] defines a + messaging protocol which is modular and extensible. The supervisor + software can send/receive RPMI messages via SBI MPXY extension [2] + or some dedicated supervisor-mode RPMI transport. + + The RPMI specification [1] defines device power service group for + accessing and controlling the power state of platform devices managed + by a platform microcontroller. The SBI implementation (machine mode + firmware or hypervisor) can implement an SBI MPXY channel to allow RPMI + device power service group access to the supervisor software. + + =========================================== + References + =========================================== + + [1] RISC-V Platform Management Interface (RPMI) v1.0 (or higher) + https://github.com/riscv-non-isa/riscv-rpmi/releases + + [2] RISC-V Supervisor Binary Interface (SBI) v3.0 (or higher) + https://github.com/riscv-non-isa/riscv-sbi-doc/releases + +properties: + compatible: + description: + Intended for use by the SBI implementation. + const: riscv,rpmi-mpxy-device-power + + mboxes: + maxItems: 1 + description: + Mailbox channel of the underlying RPMI transport. + + riscv,sbi-mpxy-channel-id: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + The SBI MPXY channel id to be used for providing RPMI access to + the supervisor software. + +required: + - compatible + - mboxes + - riscv,sbi-mpxy-channel-id + +additionalProperties: false + +examples: + - | + device-power-service { + compatible = "riscv,rpmi-mpxy-device-power"; + mboxes = <&rpmi_shmem_mbox 0x9>; + riscv,sbi-mpxy-channel-id = <0x1002>; + }; +...
diff --git a/Documentation/devicetree/bindings/power/stericsson,ux500-pm-domains.yaml b/Documentation/devicetree/bindings/power/stericsson,ux500-pm-domains.yaml new file mode 100644 index 0000000..bf83ce3 --- /dev/null +++ b/Documentation/devicetree/bindings/power/stericsson,ux500-pm-domains.yaml
@@ -0,0 +1,41 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/power/stericsson,ux500-pm-domains.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ST-Ericsson UX500 power domains + +maintainers: + - Linus Walleij <linusw@kernel.org> + - Ulf Hansson <ulfh@kernel.org> + +description: + The UX500 power domain controller gates power to one or more peripherals on + the SoC. Domain specifiers use one cell containing one of the DOMAIN_* + indexes defined in include/dt-bindings/arm/ux500_pm_domains.h. + +allOf: + - $ref: power-domain.yaml# + +properties: + compatible: + const: stericsson,ux500-pm-domains + + '#power-domain-cells': + const: 1 + +required: + - compatible + - '#power-domain-cells' + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/arm/ux500_pm_domains.h> + + pm_domains: power-controller { + compatible = "stericsson,ux500-pm-domains"; + #power-domain-cells = <1>; + };
diff --git a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml index dd95037..ae8baa5 100644 --- a/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml +++ b/Documentation/devicetree/bindings/pwm/apple,s5l-fpwm.yaml
@@ -19,6 +19,7 @@ - apple,t8103-fpwm - apple,t8112-fpwm - apple,t8122-fpwm + - apple,t8132-fpwm - apple,t6000-fpwm - apple,t6020-fpwm - apple,t6030-fpwm
diff --git a/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt b/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt deleted file mode 100644 index 4633697..0000000 --- a/Documentation/devicetree/bindings/pwm/pwm-tipwmss.txt +++ /dev/null
@@ -1,58 +0,0 @@ -TI SOC based PWM Subsystem - -Required properties: -- compatible: Must be "ti,<soc>-pwmss". - for am33xx - compatible = "ti,am33xx-pwmss"; - for am4372 - compatible = "ti,am4372-pwmss","ti,am33xx-pwmss"; - for dra746 - compatible = "ti,dra746-pwmss", "ti,am33xx-pwmss" - -- reg: physical base address and size of the registers map. -- address-cells: Specify the number of u32 entries needed in child nodes. - Should set to 1. -- size-cells: specify number of u32 entries needed to specify child nodes size - in reg property. Should set to 1. -- ranges: describes the address mapping of a memory-mapped bus. Should set to - physical address map of child's base address, physical address within - parent's address space and length of the address map. For am33xx, - 3 set of child register maps present, ECAP register space, EQEP - register space, EHRPWM register space. - -Also child nodes should also populated under PWMSS DT node. - -Example: -epwmss0: epwmss@48300000 { /* PWMSS for am33xx */ - compatible = "ti,am33xx-pwmss"; - reg = <0x48300000 0x10>; - ti,hwmods = "epwmss0"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x48300100 0x48300100 0x80 /* ECAP */ - 0x48300180 0x48300180 0x80 /* EQEP */ - 0x48300200 0x48300200 0x80>; /* EHRPWM */ - - /* child nodes go here */ -}; - -epwmss0: epwmss@48300000 { /* PWMSS for am4372 */ - compatible = "ti,am4372-pwmss","ti,am33xx-pwmss" - reg = <0x48300000 0x10>; - ti,hwmods = "epwmss0"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0x48300100 0x48300100 0x80 /* ECAP */ - 0x48300180 0x48300180 0x80 /* EQEP */ - 0x48300200 0x48300200 0x80>; /* EHRPWM */ - - /* child nodes go here */ -}; - -epwmss0: epwmss@4843e000 { /* PWMSS for DRA7xx */ - compatible = "ti,dra746-pwmss", "ti,am33xx-pwmss"; - reg = <0x4843e000 0x30>; - ti,hwmods = "epwmss0"; - #address-cells = <1>; - #size-cells = <1>; - ranges; - - /* child nodes go here */ -};
diff --git a/Documentation/devicetree/bindings/pwm/qcom,ipq6018-pwm.yaml b/Documentation/devicetree/bindings/pwm/qcom,ipq6018-pwm.yaml index f9f1f65..c6b9004 100644 --- a/Documentation/devicetree/bindings/pwm/qcom,ipq6018-pwm.yaml +++ b/Documentation/devicetree/bindings/pwm/qcom,ipq6018-pwm.yaml
@@ -15,6 +15,7 @@ - items: - enum: - qcom,ipq5018-pwm + - qcom,ipq5210-pwm - qcom,ipq5332-pwm - qcom,ipq9574-pwm - const: qcom,ipq6018-pwm
diff --git a/Documentation/devicetree/bindings/pwm/ti,am33xx-pwmss.yaml b/Documentation/devicetree/bindings/pwm/ti,am33xx-pwmss.yaml new file mode 100644 index 0000000..89ce6b0 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/ti,am33xx-pwmss.yaml
@@ -0,0 +1,82 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pwm/ti,am33xx-pwmss.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments SoC PWM Subsystem + +maintainers: + - Eduard Bostina <egbostina@gmail.com> + +properties: + compatible: + oneOf: + - const: ti,am33xx-pwmss + - items: + - enum: + - ti,am4372-pwmss + - ti,dra746-pwmss + - const: ti,am33xx-pwmss + + reg: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 1 + + ranges: true + +patternProperties: + "^(ecap|eqep|pwm|counter)@[0-9a-f]+$": + type: object + description: Child nodes for ECAP, EQEP (counter), and EHRPWM + required: + - compatible + +required: + - compatible + - reg + - "#address-cells" + - "#size-cells" + - ranges + +additionalProperties: false + +examples: + - | + pwm@48300000 { + compatible = "ti,am33xx-pwmss"; + reg = <0x48300000 0x10>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x48300100 0x48300100 0x80>, /* ECAP */ + <0x48300180 0x48300180 0x80>, /* EQEP */ + <0x48300200 0x48300200 0x80>; /* EHRPWM */ + + pwm@48300100 { + compatible = "ti,am3352-ecap"; + #pwm-cells = <3>; + reg = <0x48300100 0x80>; + clocks = <&l4ls_gclk>; + clock-names = "fck"; + }; + + counter@48300180 { + compatible = "ti,am3352-eqep"; + reg = <0x48300180 0x80>; + clocks = <&l4ls_gclk>; + interrupts = <79>; + }; + + pwm@48300200 { + compatible = "ti,am3352-ehrpwm"; + #pwm-cells = <3>; + reg = <0x48300200 0x80>; + clocks = <&ehrpwm0_tbclk>, <&l4ls_gclk>; + clock-names = "tbclk", "fck"; + }; + };
diff --git a/Documentation/devicetree/bindings/regulator/lp872x.txt b/Documentation/devicetree/bindings/regulator/lp872x.txt deleted file mode 100644 index ab895cd..0000000 --- a/Documentation/devicetree/bindings/regulator/lp872x.txt +++ /dev/null
@@ -1,161 +0,0 @@ -Binding for TI/National Semiconductor LP872x Driver - -Required properties: - - compatible: "ti,lp8720" or "ti,lp8725" - - reg: I2C slave address. 0x7d = LP8720, 0x7a = LP8725 - -Optional properties: - - ti,general-config: the value of LP872X_GENERAL_CFG register (u8) - (LP8720) - bit[2]: BUCK output voltage control by external DVS pin or register - 1 = external pin, 0 = bit7 of register 08h - bit[1]: sleep control by external DVS pin or register - 1 = external pin, 0 = bit6 of register 08h - bit[0]: time step unit(usec). 1 = 25, 0 = 50 - - (LP8725) - bit[7:6]: time step unit(usec). 00 = 32, 01 = 64, 10 = 128, 11 = 256 - bit[4]: BUCK2 enable control. 1 = enable, 0 = disable - bit[3]: BUCK2 output voltage register address. 1 = 0Ah, 0 = 0Bh - bit[2]: BUCK1 output voltage control by external DVS pin or register - 1 = register 08h, 0 = DVS - bit[1]: LDO sleep control. 1 = sleep mode, 0 = normal - bit[0]: BUCK1 enable control, 1 = enable, 0 = disable - - For more details, please see the datasheet. - - - ti,update-config: define it when LP872X_GENERAL_CFG register should be set - - ti,dvs-gpio: GPIO specifier for external DVS pin control of LP872x devices. - - ti,dvs-vsel: DVS selector. 0 = SEL_V1, 1 = SEL_V2. - - ti,dvs-state: initial DVS pin state. 0 = DVS_LOW, 1 = DVS_HIGH. - - enable-gpios: GPIO specifier for EN pin control of LP872x devices. - - Sub nodes for regulator_init_data - LP8720 has maximum 6 nodes. (child name: ldo1 ~ 5 and buck) - LP8725 has maximum 9 nodes. (child name: ldo1 ~ 5, lilo1,2 and buck1,2) - For more details, please see the following binding document. - (Documentation/devicetree/bindings/regulator/regulator.txt) - -Datasheet - - LP8720: https://www.ti.com/lit/ds/symlink/lp8720.pdf - - LP8725: https://www.ti.com/lit/ds/symlink/lp8725.pdf - -Example 1) LP8720 - -lp8720@7d { - compatible = "ti,lp8720"; - reg = <0x7d>; - - /* external DVS pin used, timestep is 25usec */ - ti,general-config = /bits/ 8 <0x03>; - ti,update-config; - - /* - * The dvs-gpio depends on the processor environment. - * For example, following GPIO specifier means GPIO134 in OMAP4. - */ - ti,dvs-gpio = <&gpio5 6 0>; - ti,dvs-vsel = /bits/ 8 <1>; /* SEL_V2 */ - ti,dvs-state = /bits/ 8 <1>; /* DVS_HIGH */ - - vaf: ldo1 { - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <3300000>; - }; - - vmmc: ldo2 { - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <3300000>; - }; - - vcam_io: ldo3 { - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - }; - - vcam_core: ldo4 { - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <2850000>; - regulator-boot-on; - }; - - vcam: ldo5 { - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <3300000>; - }; - - vcc: buck { - regulator-name = "VBUCK"; - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <2300000>; - }; -}; - -Example 2) LP8725 - -lp8725@7a { - compatible = "ti,lp8725"; - reg = <0x7a>; - - /* Enable BUCK1,2, no DVS, normal LDO mode, timestep is 256usec */ - ti,general-config = /bits/ 8 <0xdd>; - ti,update-config; - - vcam_io: ldo1 { - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <3300000>; - }; - - vcam_core: ldo2 { - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <3300000>; - }; - - vcam: ldo3 { - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <3300000>; - }; - - vcmmb_io: ldo4 { - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - }; - - vcmmb_core: ldo5 { - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <3300000>; - regulator-boot-on; - }; - - vaux1: lilo1 { - regulator-name = "VAUX1"; - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <3300000>; - }; - - vaux2: lilo2 { - regulator-name = "VAUX2"; - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <3300000>; - }; - - vcc1: buck1 { - regulator-name = "VBUCK1"; - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <3000000>; - regulator-min-microamp = <460000>; - regulator-max-microamp = <1370000>; - regulator-boot-on; - }; - - vcc2: buck2 { - regulator-name = "VBUCK2"; - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <3000000>; - regulator-min-microamp = <460000>; - regulator-max-microamp = <1370000>; - regulator-boot-on; - }; -};
diff --git a/Documentation/devicetree/bindings/regulator/max8925-regulator.txt b/Documentation/devicetree/bindings/regulator/max8925-regulator.txt deleted file mode 100644 index 0057695a..0000000 --- a/Documentation/devicetree/bindings/regulator/max8925-regulator.txt +++ /dev/null
@@ -1,40 +0,0 @@ -Max8925 Voltage regulators - -Required nodes: --nodes: - - SDV1 for SDV SDV1 - - SDV2 for SDV SDV2 - - SDV3 for SDV SDV3 - - LDO1 for LDO LDO1 - - LDO2 for LDO LDO2 - - LDO3 for LDO LDO3 - - LDO4 for LDO LDO4 - - LDO5 for LDO LDO5 - - LDO6 for LDO LDO6 - - LDO7 for LDO LDO7 - - LDO8 for LDO LDO8 - - LDO9 for LDO LDO9 - - LDO10 for LDO LDO10 - - LDO11 for LDO LDO11 - - LDO12 for LDO LDO12 - - LDO13 for LDO LDO13 - - LDO14 for LDO LDO14 - - LDO15 for LDO LDO15 - - LDO16 for LDO LDO16 - - LDO17 for LDO LDO17 - - LDO18 for LDO LDO18 - - LDO19 for LDO LDO19 - - LDO20 for LDO LDO20 - -Optional properties: -- Any optional property defined in bindings/regulator/regulator.txt - -Example: - - SDV1 { - regulator-min-microvolt = <637500>; - regulator-max-microvolt = <1425000>; - regulator-boot-on; - regulator-always-on; - }; -
diff --git a/Documentation/devicetree/bindings/regulator/maxim,max77620-regulator.yaml b/Documentation/devicetree/bindings/regulator/maxim,max77620-regulator.yaml index 7118c34..a2778c3 100644 --- a/Documentation/devicetree/bindings/regulator/maxim,max77620-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/maxim,max77620-regulator.yaml
@@ -10,19 +10,22 @@ - Svyatoslav Ryhel <clamor95@gmail.com> description: - Device has multiple DCDC(sd[0-3]) and LDOs(ldo[0-8]). The input supply - of these regulators are defined under parent device node. Details of - regulator properties are defined as child node under sub-node "regulators" - which is child node of device node. + Device has multiple DCDC (sd[0-3], plus sd4 on MAX20024) and LDOs + (ldo[0-8]). The input supply of these regulators are defined under parent + device node. Details of regulator properties are defined as child node under + sub-node "regulators" which is child node of device node. patternProperties: - "^in-(sd[0-3]|ldo(0-1|2|3-5|4-6|7-8))-supply$": + "^in-(sd[0-4]|ldo(0-1|2|3-5|4-6|7-8))-supply$": $ref: /schemas/types.yaml#/definitions/phandle description: Input supply for DCDC or LDO - "^(sd[0-3]|ldo[0-8])$": + "^(sd[0-4]|ldo[0-8])$": type: object - $ref: /schemas/regulator/regulator.yaml# + allOf: + - $ref: /schemas/regulator/regulator.yaml# + - $ref: /schemas/regulator/nvidia,tegra-regulators-coupling.yaml# + unevaluatedProperties: false properties:
diff --git a/Documentation/devicetree/bindings/regulator/maxim,max77826.yaml b/Documentation/devicetree/bindings/regulator/maxim,max77826.yaml index 6d6bbfb..3c02f98 100644 --- a/Documentation/devicetree/bindings/regulator/maxim,max77826.yaml +++ b/Documentation/devicetree/bindings/regulator/maxim,max77826.yaml
@@ -62,6 +62,6 @@ regulator-max-microvolt = <3587500>; }; }; - }; - }; + }; + }; ...
diff --git a/Documentation/devicetree/bindings/regulator/maxim,max77838.yaml b/Documentation/devicetree/bindings/regulator/maxim,max77838.yaml index bed36af..bbfc06f 100644 --- a/Documentation/devicetree/bindings/regulator/maxim,max77838.yaml +++ b/Documentation/devicetree/bindings/regulator/maxim,max77838.yaml
@@ -63,6 +63,6 @@ regulator-max-microvolt = <1800000>; }; }; - }; - }; + }; + }; ...
diff --git a/Documentation/devicetree/bindings/regulator/mediatek,mt6380-regulator.yaml b/Documentation/devicetree/bindings/regulator/mediatek,mt6380-regulator.yaml new file mode 100644 index 0000000..0b3c604 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/mediatek,mt6380-regulator.yaml
@@ -0,0 +1,117 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/mediatek,mt6380-regulator.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: MediaTek MT6380 Regulator + +maintainers: + - Sean Wang <sean.wang@mediatek.com> + +properties: + compatible: + const: mediatek,mt6380-regulator + +patternProperties: + '^buck-(vcore1?|vrf)$': + description: BUCK regulators + $ref: regulator.yaml# + unevaluatedProperties: false + + required: + - regulator-min-microvolt + - regulator-max-microvolt + - regulator-ramp-delay + + '^ldo-v([mat]|phy|ddr)$': + type: object + description: LDO regulators + $ref: regulator.yaml# + unevaluatedProperties: false + + required: + - regulator-min-microvolt + - regulator-max-microvolt + - regulator-ramp-delay + +required: + - compatible + +additionalProperties: false + +examples: + - | + regulators { + compatible = "mediatek,mt6380-regulator"; + + buck-vcore1 { + regulator-name = "vcore1"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1393750>; + regulator-ramp-delay = <6250>; + regulator-always-on; + regulator-boot-on; + }; + + buck-vcore { + regulator-name = "vcore"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <1393750>; + regulator-ramp-delay = <6250>; + }; + + buck-vrf { + regulator-name = "vrf"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1575000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + ldo-vm { + regulator-name = "vm"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1400000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + ldo-va { + regulator-name = "va"; + regulator-min-microvolt = <2200000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + ldo-vphy { + regulator-name = "vphy"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + ldo-vddr { + regulator-name = "vddr"; + regulator-min-microvolt = <1240000>; + regulator-max-microvolt = <1840000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + ldo-vt { + regulator-name = "vt"; + regulator-min-microvolt = <2200000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + };
diff --git a/Documentation/devicetree/bindings/regulator/mps,mp5416.yaml b/Documentation/devicetree/bindings/regulator/mps,mp5416.yaml index f825ee9..4b05e07 100644 --- a/Documentation/devicetree/bindings/regulator/mps,mp5416.yaml +++ b/Documentation/devicetree/bindings/regulator/mps,mp5416.yaml
@@ -53,26 +53,26 @@ #size-cells = <0>; pmic@69 { - compatible = "mps,mp5416"; - reg = <0x69>; + compatible = "mps,mp5416"; + reg = <0x69>; - regulators { + regulators { - buck1 { - regulator-name = "buck1"; - regulator-min-microvolt = <600000>; - regulator-max-microvolt = <2187500>; - regulator-min-microamp = <3800000>; - regulator-max-microamp = <6800000>; - regulator-boot-on; + buck1 { + regulator-name = "buck1"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <2187500>; + regulator-min-microamp = <3800000>; + regulator-max-microamp = <6800000>; + regulator-boot-on; + }; + + ldo2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3975000>; + }; }; - - ldo2 { - regulator-name = "ldo2"; - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <3975000>; - }; - }; - }; - }; + }; + }; ...
diff --git a/Documentation/devicetree/bindings/regulator/mps,mp886x.yaml b/Documentation/devicetree/bindings/regulator/mps,mp886x.yaml index 374a4f6..68f64e8 100644 --- a/Documentation/devicetree/bindings/regulator/mps,mp886x.yaml +++ b/Documentation/devicetree/bindings/regulator/mps,mp886x.yaml
@@ -4,17 +4,30 @@ $id: http://devicetree.org/schemas/regulator/mps,mp886x.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Monolithic Power Systems MP8867/MP8869 voltage regulator +title: Monolithic Power Systems MP8864/MP8867/MP8869 voltage regulator maintainers: - Jisheng Zhang <jszhang@kernel.org> allOf: - $ref: regulator.yaml# + - if: + properties: + compatible: + const: mps,mp8864 + then: + properties: + mps,switch-frequency-hz: + enum: [600000, 850000, 1100000, 1600000] + else: + properties: + mps,switch-frequency-hz: + enum: [500000, 750000, 1000000, 1250000, 1500000] properties: compatible: enum: + - mps,mp8864 - mps,mp8867 - mps,mp8869 @@ -33,7 +46,6 @@ mps,switch-frequency-hz: description: The valid switch frequency in Hertz. - enum: [500000, 750000, 1000000, 1250000, 1500000] required: - compatible @@ -50,13 +62,13 @@ #address-cells = <1>; #size-cells = <0>; regulator@62 { - compatible = "mps,mp8869"; - regulator-name = "vcpu"; - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <1150000>; - enable-gpios = <&porta 1 GPIO_ACTIVE_LOW>; - mps,fb-voltage-divider = <80 240>; - reg = <0x62>; + compatible = "mps,mp8869"; + regulator-name = "vcpu"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1150000>; + enable-gpios = <&porta 1 GPIO_ACTIVE_LOW>; + mps,fb-voltage-divider = <80 240>; + reg = <0x62>; }; };
diff --git a/Documentation/devicetree/bindings/regulator/mps,mpq4210.yaml b/Documentation/devicetree/bindings/regulator/mps,mpq4210.yaml new file mode 100644 index 0000000..c1914aa --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/mps,mpq4210.yaml
@@ -0,0 +1,68 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/mps,mpq4210.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Monolithic Power Systems MPQ4210 buck-boost regulator + +maintainers: + - Tapio Reijonen <tapio.reijonen@vaisala.com> + +description: + The MPQ4210 is a synchronous four-switch buck-boost controller with an I2C + interface. The output voltage is programmed through an 11-bit feedback + reference DAC and scaled by an external feedback resistor divider. + + The controller ramps the feedback reference at 38, 50, 75 or 150 mV/ms. + The divider scales the ramp rate along with the voltage, so the output + ramp rates that regulator-ramp-delay can select are those values + multiplied by (R1 + R2) / R2. + +allOf: + - $ref: regulator.yaml# + +properties: + compatible: + const: mps,mpq4210 + + reg: + maxItems: 1 + + enable-gpios: + description: GPIO connected to the EN pin. If absent, EN is assumed to + be permanently asserted. + maxItems: 1 + + mps,fb-voltage-divider-ohms: + description: An array of two integers containing the resistor values R1 + and R2 of the output feedback voltage divider. + maxItems: 2 + +required: + - compatible + - reg + - mps,fb-voltage-divider-ohms + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + i2c { + #address-cells = <1>; + #size-cells = <0>; + + regulator@64 { + compatible = "mps,mpq4210"; + reg = <0x64>; + regulator-name = "vout"; + regulator-min-microvolt = <4000000>; + regulator-max-microvolt = <20000000>; + enable-gpios = <&gpio0 2 GPIO_ACTIVE_LOW>; + /* R1 = 82 kOhm, R2 = 9.1 kOhm */ + mps,fb-voltage-divider-ohms = <82000 9100>; + /* 50 mV/ms reference ramp x (82000 + 9100) / 9100 */ + regulator-ramp-delay = <500>; + }; + };
diff --git a/Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml b/Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml index 0d34af9..726aaea 100644 --- a/Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml +++ b/Documentation/devicetree/bindings/regulator/mps,mpq7920.yaml
@@ -88,30 +88,30 @@ #size-cells = <0>; pmic@69 { - compatible = "mps,mpq7920"; - reg = <0x69>; + compatible = "mps,mpq7920"; + reg = <0x69>; - regulators { - mps,switch-freq = /bits/ 8 <1>; + regulators { + mps,switch-freq = /bits/ 8 <1>; - buck1 { - regulator-name = "buck1"; - regulator-min-microvolt = <400000>; - regulator-max-microvolt = <3587500>; - regulator-min-microamp = <460000>; - regulator-max-microamp = <7600000>; - regulator-boot-on; - mps,buck-ovp-disable; - mps,buck-phase-delay = /bits/ 8 <2>; - mps,buck-softstart = /bits/ 8 <1>; + buck1 { + regulator-name = "buck1"; + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <3587500>; + regulator-min-microamp = <460000>; + regulator-max-microamp = <7600000>; + regulator-boot-on; + mps,buck-ovp-disable; + mps,buck-phase-delay = /bits/ 8 <2>; + mps,buck-softstart = /bits/ 8 <1>; + }; + + ldo2 { + regulator-name = "ldo2"; + regulator-min-microvolt = <650000>; + regulator-max-microvolt = <3587500>; + }; }; - - ldo2 { - regulator-name = "ldo2"; - regulator-min-microvolt = <650000>; - regulator-max-microvolt = <3587500>; - }; - }; - }; - }; + }; + }; ...
diff --git a/Documentation/devicetree/bindings/regulator/mt6380-regulator.txt b/Documentation/devicetree/bindings/regulator/mt6380-regulator.txt deleted file mode 100644 index 0058441..0000000 --- a/Documentation/devicetree/bindings/regulator/mt6380-regulator.txt +++ /dev/null
@@ -1,89 +0,0 @@ -MediaTek MT6380 Regulator - -All voltage regulators provided by the MT6380 PMIC are described as the -subnodes of the MT6380 regulators node. Each regulator is named according -to its regulator type, buck-<name> and ldo-<name>. The definition for each -of these nodes is defined using the standard binding for regulators at -Documentation/devicetree/bindings/regulator/regulator.txt. - -The valid names for regulators are: -BUCK: - buck-core1, buck-vcore, buck-vrf -LDO: - ldo-vm ,ldo-va , ldo-vphy, ldo-vddr, ldo-vt - -Example: - - regulators { - compatible = "mediatek,mt6380-regulator"; - - mt6380_vcpu_reg: buck-vcore1 { - regulator-name = "vcore1"; - regulator-min-microvolt = < 600000>; - regulator-max-microvolt = <1393750>; - regulator-ramp-delay = <6250>; - regulator-always-on; - regulator-boot-on; - }; - - mt6380_vcore_reg: buck-vcore { - regulator-name = "vcore"; - regulator-min-microvolt = <600000>; - regulator-max-microvolt = <1393750>; - regulator-ramp-delay = <6250>; - }; - - mt6380_vrf_reg: buck-vrf { - regulator-name = "vrf"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1575000>; - regulator-ramp-delay = <0>; - regulator-always-on; - regulator-boot-on; - }; - - mt6380_vm_reg: ldo-vm { - regulator-name = "vm"; - regulator-min-microvolt = <1050000>; - regulator-max-microvolt = <1400000>; - regulator-ramp-delay = <0>; - regulator-always-on; - regulator-boot-on; - }; - - mt6380_va_reg: ldo-va { - regulator-name = "va"; - regulator-min-microvolt = <2200000>; - regulator-max-microvolt = <3300000>; - regulator-ramp-delay = <0>; - regulator-always-on; - regulator-boot-on; - }; - - mt6380_vphy_reg: ldo-vphy { - regulator-name = "vphy"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-ramp-delay = <0>; - regulator-always-on; - regulator-boot-on; - }; - - mt6380_vddr_reg: ldo-vddr { - regulator-name = "vddr"; - regulator-min-microvolt = <1240000>; - regulator-max-microvolt = <1840000>; - regulator-ramp-delay = <0>; - regulator-always-on; - regulator-boot-on; - }; - - mt6380_vt_reg: ldo-vt { - regulator-name = "vt"; - regulator-min-microvolt = <2200000>; - regulator-max-microvolt = <3300000>; - regulator-ramp-delay = <0>; - regulator-always-on; - regulator-boot-on; - }; - };
diff --git a/Documentation/devicetree/bindings/regulator/nexperia,nex10000ub.yaml b/Documentation/devicetree/bindings/regulator/nexperia,nex10000ub.yaml new file mode 100644 index 0000000..3c0db59 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/nexperia,nex10000ub.yaml
@@ -0,0 +1,69 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/nexperia,nex10000ub.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Nexperia NEX10000UB dual output LCD bias power supply + +maintainers: + - Neil Armstrong <neil.armstrong@linaro.org> + +description: + The NEX10000UB is designed to supply positive/negative supplies for display Panels. + +properties: + compatible: + enum: + - nexperia,nex10000ub + + reg: + maxItems: 1 + + vin-supply: true + +patternProperties: + "^(vpos|vneg)$": + type: object + $ref: regulator.yaml# + unevaluatedProperties: false + + properties: + enable-gpios: + maxItems: 1 + + required: + - enable-gpios + +required: + - compatible + - reg + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + regulator@3e { + compatible = "nexperia,nex10000ub"; + reg = <0x3e>; + vin-supply = <&supply>; + + vpos { + regulator-name = "outp"; + regulator-boot-on; + enable-gpios = <&gpio 23 GPIO_ACTIVE_HIGH>; + }; + + vneg { + regulator-name = "outn"; + regulator-boot-on; + enable-gpios = <&gpio 40 GPIO_ACTIVE_HIGH>; + }; + }; + };
diff --git a/Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.txt b/Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.txt deleted file mode 100644 index 4bf2dbf..0000000 --- a/Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.txt +++ /dev/null
@@ -1,65 +0,0 @@ -NVIDIA Tegra Regulators Coupling -================================ - -NVIDIA Tegra SoC's have a mandatory voltage-coupling between regulators. -Thus on Tegra20 there are 3 coupled regulators and on NVIDIA Tegra30 -there are 2. - -Tegra20 voltage coupling ------------------------- - -On Tegra20 SoC's there are 3 coupled regulators: CORE, RTC and CPU. -The CORE and RTC voltages shall be in a range of 170mV from each other -and they both shall be higher than the CPU voltage by at least 120mV. - -Tegra30 voltage coupling ------------------------- - -On Tegra30 SoC's there are 2 coupled regulators: CORE and CPU. The CORE -and CPU voltages shall be in a range of 300mV from each other and CORE -voltage shall be higher than the CPU by N mV, where N depends on the CPU -voltage. - -Required properties: -- nvidia,tegra-core-regulator: Boolean property that designates regulator - as the "Core domain" voltage regulator. -- nvidia,tegra-rtc-regulator: Boolean property that designates regulator - as the "RTC domain" voltage regulator. -- nvidia,tegra-cpu-regulator: Boolean property that designates regulator - as the "CPU domain" voltage regulator. - -Example: - - pmic { - regulators { - core_vdd_reg: core { - regulator-name = "vdd_core"; - regulator-min-microvolt = <950000>; - regulator-max-microvolt = <1300000>; - regulator-coupled-with = <&rtc_vdd_reg &cpu_vdd_reg>; - regulator-coupled-max-spread = <170000 550000>; - - nvidia,tegra-core-regulator; - }; - - rtc_vdd_reg: rtc { - regulator-name = "vdd_rtc"; - regulator-min-microvolt = <950000>; - regulator-max-microvolt = <1300000>; - regulator-coupled-with = <&core_vdd_reg &cpu_vdd_reg>; - regulator-coupled-max-spread = <170000 550000>; - - nvidia,tegra-rtc-regulator; - }; - - cpu_vdd_reg: cpu { - regulator-name = "vdd_cpu"; - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <1125000>; - regulator-coupled-with = <&core_vdd_reg &rtc_vdd_reg>; - regulator-coupled-max-spread = <550000 550000>; - - nvidia,tegra-cpu-regulator; - }; - }; - };
diff --git a/Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.yaml b/Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.yaml new file mode 100644 index 0000000..f5637a5 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/nvidia,tegra-regulators-coupling.yaml
@@ -0,0 +1,38 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/nvidia,tegra-regulators-coupling.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: NVIDIA Tegra Regulators Coupling + +description: > + NVIDIA Tegra SoC's have a mandatory voltage-coupling between regulators. Thus + on Tegra20 there are 3 coupled regulators and on NVIDIA Tegra30 there are 2. + + On Tegra20 SoC's - there are 3 coupled regulators:CORE, RTC and CPU. The CORE + and RTC voltages shall be in a range of 170mV from each other and they both + shall be higher than the CPU voltage by at least 120mV. + + On Tegra30 SoC's - there are 2 coupled regulators:CORE and CPU. The CORE and + CPU voltages shall be in a range of 300mV from each other and CORE voltage + shall be higher than the CPU by N mV, where N depends on the CPU voltage. + +maintainers: + - Dmitry Osipenko <digetx@gmail.com> + - Thierry Reding <treding@nvidia.com> + +properties: + nvidia,tegra-core-regulator: + description: designates regulator as the "Core domain" voltage regulator. + type: boolean + + nvidia,tegra-rtc-regulator: + description: designates regulator as the "RTC domain" voltage regulator. + type: boolean + + nvidia,tegra-cpu-regulator: + description: designates regulator as the "CPU domain" voltage regulator. + type: boolean + +additionalProperties: true
diff --git a/Documentation/devicetree/bindings/regulator/nxp,pf0900.yaml b/Documentation/devicetree/bindings/regulator/nxp,pf0900.yaml index 8c8fc2c..38fe807 100644 --- a/Documentation/devicetree/bindings/regulator/nxp,pf0900.yaml +++ b/Documentation/devicetree/bindings/regulator/nxp,pf0900.yaml
@@ -160,4 +160,4 @@ }; }; }; - }; + };
diff --git a/Documentation/devicetree/bindings/regulator/onnn,fan53880.yaml b/Documentation/devicetree/bindings/regulator/onnn,fan53880.yaml index b518171..1618e8f 100644 --- a/Documentation/devicetree/bindings/regulator/onnn,fan53880.yaml +++ b/Documentation/devicetree/bindings/regulator/onnn,fan53880.yaml
@@ -82,6 +82,6 @@ regulator-max-microvolt = <1200000>; }; }; - }; - }; + }; + }; ...
diff --git a/Documentation/devicetree/bindings/regulator/pwm-regulator.yaml b/Documentation/devicetree/bindings/regulator/pwm-regulator.yaml index 80ecf93..a7f48d3 100644 --- a/Documentation/devicetree/bindings/regulator/pwm-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/pwm-regulator.yaml
@@ -116,7 +116,7 @@ regulator-max-microvolt = <1114000>; regulator-name = "vdd_logic"; - /* Voltage Duty-Cycle */ + /* Voltage Duty-Cycle */ voltage-table = <1114000 0>, <1095000 10>, <1076000 20>,
diff --git a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml index eed2ce7..9115885e 100644 --- a/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/qcom,rpmh-regulator.yaml
@@ -191,6 +191,22 @@ properties: compatible: enum: + - qcom,pm6350-rpmh-regulators + then: + properties: + vdd-l2-l5-l7-supply: true + vdd-l3-l6-l8-l9-l10-supply: true + vdd-l12-l14-supply: true + vdd-l15-l19-l22-supply: true + vdd-l18-l20-l21-supply: true + patternProperties: + "^vdd-l([14]|1[1367])-supply$": true + "^vdd-s[1-6]-supply$": true + + - if: + properties: + compatible: + enum: - qcom,pm660-rpmh-regulators then: properties:
diff --git a/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml b/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml index fec3d39..1526cd0 100644 --- a/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml +++ b/Documentation/devicetree/bindings/regulator/richtek,rtmv20-regulator.yaml
@@ -151,9 +151,9 @@ richtek,vsync-polarity-high; lsw { - regulator-name = "rtmv20,lsw"; - regulator-min-microamp = <0>; - regulator-max-microamp = <6000000>; + regulator-name = "rtmv20,lsw"; + regulator-min-microamp = <0>; + regulator-max-microamp = <6000000>; }; }; };
diff --git a/Documentation/devicetree/bindings/regulator/rohm,bd73800-regulator.yaml b/Documentation/devicetree/bindings/regulator/rohm,bd73800-regulator.yaml new file mode 100644 index 0000000..2db4585 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/rohm,bd73800-regulator.yaml
@@ -0,0 +1,99 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/rohm,bd73800-regulator.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: ROHM BD73800 Power Management Integrated Circuit regulators + +maintainers: + - Matti Vaittinen <mazziesaccount@gmail.com> + +description: | + This module is part of the ROHM BD73800 MFD device. For more details + see Documentation/devicetree/bindings/mfd/rohm,bd73800-pmic.yaml. + + The regulator controller is represented as a sub-node of the PMIC node + on the device tree. + + Regulator nodes should be named to buck<number> and ldo<number>. + The valid names for BD73800 regulator nodes are + buck1, buck2, buck3, buck4, buck5, buck6, buck7, buck8 + ldo1, ldo2, ldo3, ldo4 + +patternProperties: + "^buck[1-8]$": + type: object + description: + Properties for a single BUCK regulator. + allOf: + - $ref: regulator.yaml# + - $ref: rohm,pmic-states.yaml# + + properties: + regulator-name: + pattern: "^buck[1-8]$" + description: + should be "buck1", ..., "buck8" + + rohm,dvs-run-voltage: + minimum: 0 + maximum: 3500000 + + rohm,dvs-idle-voltage: + minimum: 0 + maximum: 3500000 + + rohm,dvs-suspend-voltage: + minimum: 0 + maximum: 3500000 + + # BUCKs 1,2,3,4 and 8 support voltages 0.5 - 1.3V + # BUCK 5 supports voltages 0.3 - 1.3V + # BUCKs 6 and 7 support voltages 1.5 - 3.5V + + required: + - regulator-name + + unevaluatedProperties: false + + "^ldo[1-4]$": + type: object + description: + Properties for single LDO regulator. + allOf: + - $ref: regulator.yaml# + - $ref: rohm,pmic-states.yaml# + + properties: + regulator-name: + pattern: "^ldo[1-4]$" + description: + should be "ldo1", ..., "ldo4" + + rohm,dvs-run-voltage: + minimum: 0 + maximum: 1 + + rohm,dvs-idle-voltage: + minimum: 0 + maximum: 1 + + rohm,dvs-suspend-voltage: + minimum: 0 + maximum: 1 + + rohm,ldo-range-high: + type: boolean + description: + LDO1 and LDO3 voltage ranges can be "high" or "low" depending on + OTP. Indicate that the "high" range is used. See comment below + for voltages. + + # LDOs 2 and 4 support voltages 0.75 - 3.3V + # LDOs 1 and 3 may support different ranges depending on OTP. + # either 0.6 - 1.8V or 0.75 - 3.3V. + + unevaluatedProperties: false + +additionalProperties: false
diff --git a/Documentation/devicetree/bindings/regulator/silergy,sy8824x.yaml b/Documentation/devicetree/bindings/regulator/silergy,sy8824x.yaml index 82af4d6..0da920f 100644 --- a/Documentation/devicetree/bindings/regulator/silergy,sy8824x.yaml +++ b/Documentation/devicetree/bindings/regulator/silergy,sy8824x.yaml
@@ -35,10 +35,10 @@ #address-cells = <1>; #size-cells = <0>; regulator@60 { - compatible = "silergy,sy8824c"; - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <1150000>; - reg = <0x60>; + compatible = "silergy,sy8824c"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1150000>; + reg = <0x60>; }; };
diff --git a/Documentation/devicetree/bindings/regulator/silergy,sy8827n.yaml b/Documentation/devicetree/bindings/regulator/silergy,sy8827n.yaml index b222adab..362dd88 100644 --- a/Documentation/devicetree/bindings/regulator/silergy,sy8827n.yaml +++ b/Documentation/devicetree/bindings/regulator/silergy,sy8827n.yaml
@@ -31,7 +31,10 @@ - compatible - reg -additionalProperties: false +allOf: + - $ref: regulator.yaml# + +unevaluatedProperties: false examples: - | @@ -39,8 +42,8 @@ #address-cells = <1>; #size-cells = <0>; regulator@60 { - compatible = "silergy,sy8827n"; - reg = <0x60>; + compatible = "silergy,sy8827n"; + reg = <0x60>; }; };
diff --git a/Documentation/devicetree/bindings/regulator/ti,lp872x.yaml b/Documentation/devicetree/bindings/regulator/ti,lp872x.yaml new file mode 100644 index 0000000..df25102 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/ti,lp872x.yaml
@@ -0,0 +1,204 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/ti,lp872x.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI/National Semiconductor LP872x + +maintainers: + - Milo Kim <milo.kim@ti.com> + +description: + See Datasheet + LP8720 https://www.ti.com/lit/ds/symlink/lp8720.pdf + LP8725 https://www.ti.com/lit/ds/symlink/lp8725.pdf + +properties: + compatible: + enum: + - ti,lp8720 + - ti,lp8725 + + reg: + enum: [0x7a, 0x7d] + + ti,general-config: + $ref: /schemas/types.yaml#/definitions/uint8 + description: | + the value of LP872X_GENERAL_CFG register (u8) + (LP8720) + bit[2]: BUCK output voltage control by external DVS pin or register + 1 = external pin, 0 = bit7 of register 08h + bit[1]: sleep control by external DVS pin or register + 1 = external pin, 0 = bit6 of register 08h + bit[0]: time step unit(usec). 1 = 25, 0 = 50 + + (LP8725) + bit[7:6]: time step unit(usec). 00 = 32, 01 = 64, 10 = 128, 11 = 256 + bit[4]: BUCK2 enable control. 1 = enable, 0 = disable + bit[3]: BUCK2 output voltage register address. 1 = 0Ah, 0 = 0Bh + bit[2]: BUCK1 output voltage control by external DVS pin or register + 1 = register 08h, 0 = DVS + bit[1]: LDO sleep control. 1 = sleep mode, 0 = normal + bit[0]: BUCK1 enable control, 1 = enable, 0 = disable + + For more details, please see the datasheet. + + ti,update-config: + type: boolean + deprecated: true + description: define it when LP872X_GENERAL_CFG register should be set + + ti,dvs-gpio: + maxItems: 1 + deprecated: true + description: GPIO specifier for external DVS pin control of LP872x devices. + + ti,dvs-vsel: + $ref: /schemas/types.yaml#/definitions/uint8 + enum: [0, 1] + description: DVS selector. 0 = SEL_V1, 1 = SEL_V2. + + ti,dvs-state: + $ref: /schemas/types.yaml#/definitions/uint8 + enum: [0, 1] + description: initial DVS pin state. 0 = DVS_LOW, 1 = DVS_HIGH. + + enable-gpios: + maxItems: 1 + description: GPIO specifier for EN pin control of LP872x devices. + + dvs-gpios: + description: GPIO specifier for external DVS pin control. + maxItems: 1 + + buck: + type: object + $ref: regulator.yaml# + unevaluatedProperties: false + description: + Single BUCK regulator for LP8720. + +patternProperties: + "^(vbatt|vin([1-3]|b|lilo[1-2]))-supply$": + $ref: /schemas/types.yaml#/definitions/phandle + description: | + vbatt - input supply for ldo1 and all internal circuitry (lp8720 only). + vin1 - input supply for ldo2 - ldo3 (lp8720) or ldo1 (lp8725). + vin2 - input supply for ldo4 - ldo5 (lp8720) or ldo2 - ldo3 (lp8725). + vin3 - input supply for ldo4 - ldo5 (lp8725). + vinb - input supply for buck. + vinlilo1 and vinlilo2 - input supply for lilo1 and lilo2. + + "^(buck[1-2]?|ldo[1-5]|lilo[1-2])$": + type: object + $ref: regulator.yaml# + unevaluatedProperties: false + +required: + - compatible + - reg + +allOf: + - if: + properties: + compatible: + contains: + const: ti,lp8720 + then: + properties: + reg: + const: 0x7d + patternProperties: + "^(vin(3|lilo[1-2]))-supply$": false + "^(buck[1-2]|lilo[1-2])$": false + + - if: + properties: + compatible: + contains: + const: ti,lp8725 + then: + properties: + reg: + const: 0x7a + vbatt-supply: false + buck: false + +additionalProperties: false + +examples: + - | + #include <dt-bindings/gpio/gpio.h> + + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pmic@7a { + compatible = "ti,lp8725"; + reg = <0x7a>; + + /* Enable BUCK1,2, no DVS, normal LDO mode, timestep is 256usec */ + ti,general-config = /bits/ 8 <0xdd>; + ti,update-config; + + ldo1 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; + }; + + ldo2 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; + }; + + ldo3 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; + }; + + ldo4 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + + ldo5 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + }; + + lilo1 { + regulator-name = "VAUX1"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3300000>; + }; + + lilo2 { + regulator-name = "VAUX2"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3300000>; + }; + + buck1 { + regulator-name = "VBUCK1"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3000000>; + regulator-min-microamp = <460000>; + regulator-max-microamp = <1370000>; + regulator-boot-on; + }; + + buck2 { + regulator-name = "VBUCK2"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <3000000>; + regulator-min-microamp = <460000>; + regulator-max-microamp = <1370000>; + regulator-boot-on; + }; + }; + };
diff --git a/Documentation/devicetree/bindings/regulator/ti,tps62360.yaml b/Documentation/devicetree/bindings/regulator/ti,tps62360.yaml index 90c3927..6768fc6 100644 --- a/Documentation/devicetree/bindings/regulator/ti,tps62360.yaml +++ b/Documentation/devicetree/bindings/regulator/ti,tps62360.yaml
@@ -20,6 +20,7 @@ allOf: - $ref: regulator.yaml# + - $ref: /schemas/regulator/nvidia,tegra-regulators-coupling.yaml# properties: compatible:
diff --git a/Documentation/devicetree/bindings/regulator/ti,tps65023.yaml b/Documentation/devicetree/bindings/regulator/ti,tps65023.yaml new file mode 100644 index 0000000..9286985 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/ti,tps65023.yaml
@@ -0,0 +1,90 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/ti,tps65023.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Texas Instruments TPS65023 Regulator + +maintainers: + - Eduard Bostina <egbostina@gmail.com> + +properties: + compatible: + enum: + - ti,tps65020 + - ti,tps65021 + - ti,tps65023 + + reg: + maxItems: 1 + + regulators: + type: object + description: > + List of child nodes that specify the regulator initialization data. + Must be named after their hardware counterparts: VDCDC[1-3] and LDO[1-2]. + + patternProperties: + "^(VDCDC[1-3]|LDO[1-2])$": + type: object + $ref: regulator.yaml# + unevaluatedProperties: false + + additionalProperties: false + +required: + - compatible + - reg + - regulators + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + tps65023@48 { + compatible = "ti,tps65023"; + reg = <0x48>; + + regulators { + VDCDC1 { + regulator-name = "vdd_mpu"; + regulator-always-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + VDCDC2 { + regulator-name = "vdd_core"; + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + VDCDC3 { + regulator-name = "vdd_io"; + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + LDO1 { + regulator-name = "vdd_usb18"; + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + LDO2 { + regulator-name = "vdd_usb33"; + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + }; + }; + };
diff --git a/Documentation/devicetree/bindings/regulator/ti,tps6586x.yaml b/Documentation/devicetree/bindings/regulator/ti,tps6586x.yaml new file mode 100644 index 0000000..1f7c7b3 --- /dev/null +++ b/Documentation/devicetree/bindings/regulator/ti,tps6586x.yaml
@@ -0,0 +1,196 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/regulator/ti,tps6586x.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI TPS6586x family of regulators + +maintainers: + - Thierry Reding <thierry.reding@avionic-design.de> + +properties: + compatible: + const: ti,tps6586x + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + "#gpio-cells": + const: 2 + + gpio-controller: true + + sys-supply: + description: The input supply for SYS. + + ti,system-power-controller: + type: boolean + description: + Whether or not this PMIC is controlling the system power. + + regulators: + type: object + additionalProperties: false + description: + list of regulators provided by this controller, LDO5 and LDO_RTC is + supplied by SYS regulator internally and driver take care of making + proper parent child relationship. + + properties: + sys: + type: object + $ref: regulator.yaml# + unevaluatedProperties: false + + patternProperties: + "^ldo([0-9]|_rtc)$": + type: object + allOf: + - $ref: /schemas/regulator/regulator.yaml# + - $ref: /schemas/regulator/nvidia,tegra-regulators-coupling.yaml# + unevaluatedProperties: false + + "^sm[0-2]$": + type: object + allOf: + - $ref: /schemas/regulator/regulator.yaml# + - $ref: /schemas/regulator/nvidia,tegra-regulators-coupling.yaml# + unevaluatedProperties: false + +patternProperties: + "^vin-sm[0-2]-supply$": + description: The input supply for the corresponding SM (SM0, SM1, or SM2). + + "^vinldo(01|23|4|678|9)-supply$": + description: The input supply for the corresponding LDO or group of LDOs. + +required: + - compatible + - reg + - interrupts + - regulators + - "#gpio-cells" + - gpio-controller + - sys-supply + - vin-sm0-supply + - vin-sm1-supply + - vin-sm2-supply + - vinldo01-supply + - vinldo23-supply + - vinldo4-supply + - vinldo678-supply + - vinldo9-supply + +additionalProperties: false + +examples: + - | + i2c { + #address-cells = <1>; + #size-cells = <0>; + + pmic@34 { + compatible = "ti,tps6586x"; + reg = <0x34>; + interrupts = <0 88 0x4>; + + #gpio-cells = <2>; + gpio-controller; + + ti,system-power-controller; + + sys-supply = <&vdd_5v0_sys>; + vin-sm0-supply = <&sys_reg>; + vin-sm1-supply = <&sys_reg>; + vin-sm2-supply = <&sys_reg>; + vinldo01-supply = <&sm2_reg>; + vinldo23-supply = <&sm2_reg>; + vinldo4-supply = <&sm2_reg>; + vinldo678-supply = <&sm2_reg>; + vinldo9-supply = <&sm2_reg>; + + regulators { + sys { + regulator-name = "vdd_sys"; + regulator-boot-on; + regulator-always-on; + }; + + sm0 { + regulator-min-microvolt = < 725000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-always-on; + }; + + sm1 { + regulator-min-microvolt = < 725000>; + regulator-max-microvolt = <1500000>; + regulator-boot-on; + regulator-always-on; + }; + + sm2 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <4550000>; + regulator-boot-on; + regulator-always-on; + }; + + ldo0 { + regulator-name = "PCIE CLK"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + ldo1 { + regulator-min-microvolt = < 725000>; + regulator-max-microvolt = <1500000>; + }; + + ldo2 { + regulator-min-microvolt = < 725000>; + regulator-max-microvolt = <1500000>; + }; + + ldo3 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <3300000>; + }; + + ldo4 { + regulator-min-microvolt = <1700000>; + regulator-max-microvolt = <2475000>; + }; + + ldo5 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <3300000>; + }; + + ldo6 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <3300000>; + }; + + ldo7 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <3300000>; + }; + + ldo8 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <3300000>; + }; + + ldo9 { + regulator-min-microvolt = <1250000>; + regulator-max-microvolt = <3300000>; + }; + }; + }; + };
diff --git a/Documentation/devicetree/bindings/regulator/tps65023.txt b/Documentation/devicetree/bindings/regulator/tps65023.txt deleted file mode 100644 index a4714e4..0000000 --- a/Documentation/devicetree/bindings/regulator/tps65023.txt +++ /dev/null
@@ -1,60 +0,0 @@ -TPS65023 family of regulators - -Required properties: -- compatible: Must be one of the following. - "ti,tps65020", - "ti,tps65021", - "ti,tps65023", -- reg: I2C slave address -- regulators: list of regulators provided by this controller, must be named - after their hardware counterparts: VDCDC[1-3] and LDO[1-2] -- regulators: This is the list of child nodes that specify the regulator - initialization data for defined regulators. The definition for each of - these nodes is defined using the standard binding for regulators found at - Documentation/devicetree/bindings/regulator/regulator.txt. - -Each regulator is defined using the standard binding for regulators. - -Example: - - tps65023@48 { - compatible = "ti,tps65023"; - reg = <0x48>; - - regulators { - VDCDC1 { - regulator-name = "vdd_mpu"; - regulator-always-on; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - }; - - VDCDC2 { - regulator-name = "vdd_core"; - regulator-always-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - - VDCDC3 { - regulator-name = "vdd_io"; - regulator-always-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - - LDO1 { - regulator-name = "vdd_usb18"; - regulator-always-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - }; - - LDO2 { - regulator-name = "vdd_usb33"; - regulator-always-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - }; - };
diff --git a/Documentation/devicetree/bindings/regulator/tps6586x.txt b/Documentation/devicetree/bindings/regulator/tps6586x.txt deleted file mode 100644 index 8b40cac..0000000 --- a/Documentation/devicetree/bindings/regulator/tps6586x.txt +++ /dev/null
@@ -1,135 +0,0 @@ -TPS6586x family of regulators - -Required properties: -- compatible: "ti,tps6586x" -- reg: I2C slave address -- interrupts: the interrupt outputs of the controller -- #gpio-cells: number of cells to describe a GPIO -- gpio-controller: mark the device as a GPIO controller -- regulators: A node that houses a sub-node for each regulator within the - device. Each sub-node is identified using the node's name (or the deprecated - regulator-compatible property if present), with valid values listed below. - The content of each sub-node is defined by the standard binding for - regulators; see regulator.txt. - sys, sm[0-2], ldo[0-9] and ldo_rtc -- sys-supply: The input supply for SYS. -- vin-sm0-supply: The input supply for the SM0. -- vin-sm1-supply: The input supply for the SM1. -- vin-sm2-supply: The input supply for the SM2. -- vinldo01-supply: The input supply for the LDO1 and LDO2 -- vinldo23-supply: The input supply for the LDO2 and LDO3 -- vinldo4-supply: The input supply for the LDO4 -- vinldo678-supply: The input supply for the LDO6, LDO7 and LDO8 -- vinldo9-supply: The input supply for the LDO9 - -Optional properties: -- ti,system-power-controller: Telling whether or not this pmic is controlling - the system power. - -Each regulator is defined using the standard binding for regulators. - -Note: LDO5 and LDO_RTC is supplied by SYS regulator internally and driver - take care of making proper parent child relationship. - -Example: - - pmu: tps6586x@34 { - compatible = "ti,tps6586x"; - reg = <0x34>; - interrupts = <0 88 0x4>; - - #gpio-cells = <2>; - gpio-controller; - - ti,system-power-controller; - - sys-supply = <&some_reg>; - vin-sm0-supply = <&some_reg>; - vin-sm1-supply = <&some_reg>; - vin-sm2-supply = <&some_reg>; - vinldo01-supply = <...>; - vinldo23-supply = <...>; - vinldo4-supply = <...>; - vinldo678-supply = <...>; - vinldo9-supply = <...>; - - regulators { - sys_reg: sys { - regulator-name = "vdd_sys"; - regulator-boot-on; - regulator-always-on; - }; - - sm0_reg: sm0 { - regulator-min-microvolt = < 725000>; - regulator-max-microvolt = <1500000>; - regulator-boot-on; - regulator-always-on; - }; - - sm1_reg: sm1 { - regulator-min-microvolt = < 725000>; - regulator-max-microvolt = <1500000>; - regulator-boot-on; - regulator-always-on; - }; - - sm2_reg: sm2 { - regulator-min-microvolt = <3000000>; - regulator-max-microvolt = <4550000>; - regulator-boot-on; - regulator-always-on; - }; - - ldo0_reg: ldo0 { - regulator-name = "PCIE CLK"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - }; - - ldo1_reg: ldo1 { - regulator-min-microvolt = < 725000>; - regulator-max-microvolt = <1500000>; - }; - - ldo2_reg: ldo2 { - regulator-min-microvolt = < 725000>; - regulator-max-microvolt = <1500000>; - }; - - ldo3_reg: ldo3 { - regulator-min-microvolt = <1250000>; - regulator-max-microvolt = <3300000>; - }; - - ldo4_reg: ldo4 { - regulator-min-microvolt = <1700000>; - regulator-max-microvolt = <2475000>; - }; - - ldo5_reg: ldo5 { - regulator-min-microvolt = <1250000>; - regulator-max-microvolt = <3300000>; - }; - - ldo6_reg: ldo6 { - regulator-min-microvolt = <1250000>; - regulator-max-microvolt = <3300000>; - }; - - ldo7_reg: ldo7 { - regulator-min-microvolt = <1250000>; - regulator-max-microvolt = <3300000>; - }; - - ldo8_reg: ldo8 { - regulator-min-microvolt = <1250000>; - regulator-max-microvolt = <3300000>; - }; - - ldo9_reg: ldo9 { - regulator-min-microvolt = <1250000>; - regulator-max-microvolt = <3300000>; - }; - }; - };
diff --git a/Documentation/devicetree/bindings/riscv/thead.yaml b/Documentation/devicetree/bindings/riscv/thead.yaml index 301912d..e817091 100644 --- a/Documentation/devicetree/bindings/riscv/thead.yaml +++ b/Documentation/devicetree/bindings/riscv/thead.yaml
@@ -17,9 +17,11 @@ const: '/' compatible: oneOf: - - description: BeagleV Ahead single board computer + - description: TH1520 single board computers items: - - const: beagle,beaglev-ahead + - enum: + - beagle,beaglev-ahead + - milkv,meles - const: thead,th1520 - description: Sipeed Lichee Pi 4A board for the Sipeed Lichee Module 4A items:
diff --git a/Documentation/devicetree/bindings/soc/amlogic/amlogic,meson-gx-clk-measure.yaml b/Documentation/devicetree/bindings/soc/amlogic/amlogic,meson-gx-clk-measure.yaml index b1200e6..16893f4 100644 --- a/Documentation/devicetree/bindings/soc/amlogic/amlogic,meson-gx-clk-measure.yaml +++ b/Documentation/devicetree/bindings/soc/amlogic/amlogic,meson-gx-clk-measure.yaml
@@ -16,15 +16,21 @@ properties: compatible: enum: - - amlogic,meson-gx-clk-measure - - amlogic,meson8-clk-measure - - amlogic,meson8b-clk-measure + - amlogic,a1-clk-measure + - amlogic,a4-clk-measure + - amlogic,a5-clk-measure + - amlogic,a9-clk-measure + - amlogic,c3-clk-measure - amlogic,meson-axg-clk-measure - amlogic,meson-g12a-clk-measure + - amlogic,meson-gx-clk-measure - amlogic,meson-sm1-clk-measure - - amlogic,c3-clk-measure + - amlogic,meson8-clk-measure + - amlogic,meson8b-clk-measure - amlogic,s4-clk-measure - - amlogic,a1-clk-measure + - amlogic,s6-clk-measure + - amlogic,s7-clk-measure + - amlogic,s7d-clk-measure - amlogic,t7-clk-measure reg:
diff --git a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml index 721a67e..49813ad 100644 --- a/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml +++ b/Documentation/devicetree/bindings/soc/imx/fsl,imx-iomuxc-gpr.yaml
@@ -47,10 +47,23 @@ reg: maxItems: 1 + '#address-cells': + const: 1 + + '#size-cells': + const: 1 + + ranges: true + mux-controller: type: object $ref: /schemas/mux/reg-mux.yaml + bridge@18: + type: object + $ref: /schemas/display/bridge/fsl,ldb.yaml# + unevaluatedProperties: false + patternProperties: "^ipu[12]_csi[01]_mux$": type: object @@ -67,6 +80,19 @@ patternProperties: '^ipu[12]_csi[01]_mux$': false + - if: + properties: + compatible: + not: + contains: + const: fsl,imx6sx-iomuxc-gpr + then: + properties: + bridge@18: false + '#address-cells': false + '#size-cells': false + ranges: false + additionalProperties: false required: @@ -87,4 +113,40 @@ }; }; + - | + #include <dt-bindings/clock/imx6sx-clock.h> + + syscon@20e4000 { + compatible = "fsl,imx6sx-iomuxc-gpr", "fsl,imx6q-iomuxc-gpr", "syscon", "simple-mfd"; + reg = <0x020e4000 0x4000>; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + bridge@18 { + compatible = "fsl,imx6sx-ldb"; + reg = <0x18 0x4>; + clocks = <&clks IMX6SX_CLK_LDB_DI0>; + clock-names = "ldb"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + endpoint { + }; + }; + + port@1 { + reg = <1>; + + endpoint { + }; + }; + }; + }; + }; ...
diff --git a/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml b/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml index e7c4a39..79b7558 100644 --- a/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml +++ b/Documentation/devicetree/bindings/soc/mediatek/mediatek,pwrap.yaml
@@ -105,6 +105,9 @@ pmic: type: object + regulators: + $ref: /schemas/regulator/mediatek,mt6380-regulator.yaml# + required: - compatible - reg
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom,apr.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom,apr.yaml index e51acdc..01250b5 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom,apr.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom,apr.yaml
@@ -120,7 +120,9 @@ properties: qcom,glink-channels: items: - - const: adsp_apps + - enum: + - adsp_apps + - modem_apps power-domains: false else: properties:
diff --git a/Documentation/devicetree/bindings/soc/qcom/qcom-stats.yaml b/Documentation/devicetree/bindings/soc/qcom/qcom-stats.yaml index 686a7ef..b384a598 100644 --- a/Documentation/devicetree/bindings/soc/qcom/qcom-stats.yaml +++ b/Documentation/devicetree/bindings/soc/qcom/qcom-stats.yaml
@@ -18,15 +18,22 @@ properties: compatible: - enum: - - qcom,rpmh-stats - - qcom,sdm845-rpmh-stats - - qcom,rpm-stats - # For older RPM firmware versions with fixed offset for the sleep stats - - qcom,apq8084-rpm-stats - - qcom,msm8226-rpm-stats - - qcom,msm8916-rpm-stats - - qcom,msm8974-rpm-stats + oneOf: + - enum: + - qcom,rpmh-stats + - qcom,sdm845-rpmh-stats + - qcom,rpm-stats + # For older RPM firmware versions with fixed offset for the sleep stats + - qcom,apq8084-rpm-stats + - qcom,msm8226-rpm-stats + - qcom,msm8916-rpm-stats + - qcom,msm8974-rpm-stats + # SoC-specific compatibles that also read subsystem-level stats, + # falling back to "qcom,rpm-stats" for SoC-level stats only + - items: + - enum: + - qcom,shikra-rpm-stats + - const: qcom,rpm-stats reg: maxItems: 1
diff --git a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml index eeef34e..1673005 100644 --- a/Documentation/devicetree/bindings/soc/renesas/renesas.yaml +++ b/Documentation/devicetree/bindings/soc/renesas/renesas.yaml
@@ -508,6 +508,14 @@ - renesas,r9a07g043u12 # RZ/G2UL Type-2 - const: renesas,r9a07g043 + - description: SolidRun RZ/G2UL based boards + items: + - enum: + - solidrun,rzg2ul-hummingboard-ripple # SolidRun RZ/G2UL HummingBoard Ripple + - const: solidrun,rzg2ul-sr-som + - const: renesas,r9a07g043u12 # RZ/G2UL Type-2 + - const: renesas,r9a07g043 + - description: RZ/G2{L,LC} (R9A07G044) items: - enum: @@ -519,6 +527,25 @@ - renesas,r9a07g044l2 # Dual Cortex-A55 RZ/G2L - const: renesas,r9a07g044 + - description: SolidRun RZ/G2L based boards + items: + - enum: + - solidrun,rzg2l-hummingboard-iiot # SolidRun RZ/G2L HummingBoard IIoT + - solidrun,rzg2l-hummingboard-pro # SolidRun RZ/G2L HummingBoard Pro + - solidrun,rzg2l-hummingboard-ripple # SolidRun RZ/G2L HummingBoard Ripple + - const: solidrun,rzg2l-sr-som + - const: renesas,r9a07g044l2 # Dual Cortex-A55 RZ/G2L + - const: renesas,r9a07g044 + + - description: SolidRun RZ/G2LC based boards + items: + - enum: + - solidrun,rzg2lc-hummingboard-iiot # SolidRun RZ/G2LC HummingBoard IIoT + - solidrun,rzg2lc-hummingboard-ripple # SolidRun RZ/G2LC HummingBoard Ripple + - const: solidrun,rzg2lc-sr-som + - const: renesas,r9a07g044c2 # Dual Cortex-A55 RZ/G2LC + - const: renesas,r9a07g044 + - items: - enum: # MYIR Remi Pi SBC (MYB-YG2LX-REMI) @@ -535,6 +562,16 @@ - renesas,r9a07g054l2 # Dual Cortex-A55 RZ/V2L - const: renesas,r9a07g054 + - description: SolidRun RZ/V2L based boards + items: + - enum: + - solidrun,rzv2l-hummingboard-iiot # SolidRun RZ/V2L HummingBoard IIoT + - solidrun,rzv2l-hummingboard-pro # SolidRun RZ/V2L HummingBoard Pro + - solidrun,rzv2l-hummingboard-ripple # SolidRun RZ/V2L HummingBoard Ripple + - const: solidrun,rzv2l-sr-som + - const: renesas,r9a07g054l2 # Dual Cortex-A55 RZ/V2L + - const: renesas,r9a07g054 + - description: RZ/G3S (R9A08G045) items: - enum:
diff --git a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml index 7bcb4e2..e94c83d 100644 --- a/Documentation/devicetree/bindings/soc/rockchip/grf.yaml +++ b/Documentation/devicetree/bindings/soc/rockchip/grf.yaml
@@ -32,6 +32,7 @@ - rockchip,rk3568-usb2phy-grf - rockchip,rk3576-bigcore-grf - rockchip,rk3576-cci-grf + - rockchip,rk3576-csidphy-grf - rockchip,rk3576-dcphy-grf - rockchip,rk3576-gpu-grf - rockchip,rk3576-hdptxphy-grf
diff --git a/Documentation/devicetree/bindings/soc/starfive/starfive,jhb100-syscon.yaml b/Documentation/devicetree/bindings/soc/starfive/starfive,jhb100-syscon.yaml new file mode 100644 index 0000000..000f53a --- /dev/null +++ b/Documentation/devicetree/bindings/soc/starfive/starfive,jhb100-syscon.yaml
@@ -0,0 +1,115 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/soc/starfive/starfive,jhb100-syscon.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: StarFive JHB100 SoC system controller + +maintainers: + - Kevin Xie <kevin.xie@starfivetech.com> + - Changhuang Liang <changhuang.liang@starfivetech.com> + +description: + The StarFive JHB100 SoC system controller contains MMIO registers used by + other hardware modules (e.g., PLL, eMMC, PCIe). These modules access + specific register offsets, bit masks, and shifts within the system + controller region for configuration and status. + +properties: + compatible: + items: + - enum: + - starfive,jhb100-b2h-syscon + - starfive,jhb100-gpu-syscon + - starfive,jhb100-h2b-syscon + - starfive,jhb100-host-syscon + - starfive,jhb100-husb-syscon + - starfive,jhb100-husbcmn-syscon + - starfive,jhb100-husbd-syscon + - starfive,jhb100-npu-syscon + - starfive,jhb100-pcieep-ecsr-syscon + - starfive,jhb100-pcierp-ecsr-syscon + - starfive,jhb100-pcierp-syscon + - starfive,jhb100-per0-syscon + - starfive,jhb100-per1-syscon + - starfive,jhb100-per2-syscon + - starfive,jhb100-per3-syscon + - starfive,jhb100-sfc-filter-syscon + - starfive,jhb100-strap-syscon + - starfive,jhb100-sys0-syscon + - starfive,jhb100-sys1-syscon + - starfive,jhb100-sys2-syscon + - starfive,jhb100-usb-syscon + - starfive,jhb100-vout-syscon + - const: syscon + + reg: + maxItems: 1 + + clocks: + maxItems: 1 + + '#clock-cells': + const: 1 + + '#reset-cells': + const: 1 + +required: + - compatible + - reg + +allOf: + - if: + properties: + compatible: + contains: + enum: + - starfive,jhb100-per0-syscon + - starfive,jhb100-per1-syscon + - starfive,jhb100-sys0-syscon + then: + required: + - clocks + - '#clock-cells' + else: + properties: + clocks: false + '#clock-cells': false + + - if: + properties: + compatible: + contains: + const: starfive,jhb100-pcierp-syscon + then: + required: + - '#reset-cells' + else: + properties: + '#reset-cells': false + +additionalProperties: false + +examples: + - | + syscon@13010000 { + compatible = "starfive,jhb100-sys0-syscon", "syscon"; + reg = <0x13010000 0x2000>; + clocks = <&osc>; + #clock-cells = <1>; + }; + + syscon@13014000 { + compatible = "starfive,jhb100-sys1-syscon", "syscon"; + reg = <0x13014000 0x4000>; + }; + + syscon@11719000 { + compatible = "starfive,jhb100-pcierp-syscon", "syscon"; + reg = <0x11719000 0x1000>; + #reset-cells = <1>; + }; + +...
diff --git a/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra20-pmc.yaml b/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra20-pmc.yaml index f516960..8ec36c4 100644 --- a/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra20-pmc.yaml +++ b/Documentation/devicetree/bindings/soc/tegra/nvidia,tegra20-pmc.yaml
@@ -18,6 +18,7 @@ - nvidia,tegra114-pmc - nvidia,tegra124-pmc - nvidia,tegra210-pmc + - nvidia,tegra210b01-pmc reg: maxItems: 1 @@ -346,7 +347,9 @@ properties: compatible: contains: - const: nvidia,tegra210-pmc + enum: + - nvidia,tegra210-pmc + - nvidia,tegra210b01-pmc then: properties: pinmux:
diff --git a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml index f3bd0be..364be49 100644 --- a/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml +++ b/Documentation/devicetree/bindings/soc/ti/ti,j721e-system-controller.yaml
@@ -53,9 +53,11 @@ "^clock-controller@[0-9a-f]+$": type: object - $ref: /schemas/clock/ti,am654-ehrpwm-tbclk.yaml# + oneOf: + - $ref: /schemas/clock/ti,am62-audio-refclk.yaml# + - $ref: /schemas/clock/ti,am654-ehrpwm-tbclk.yaml# description: - Clock provider for TI EHRPWM nodes. + Clock provider for TI EHRPWM or Audio Reference Clock nodes. "phy@[0-9a-f]+$": type: object
diff --git a/Documentation/devicetree/bindings/spi/amlogic,a4-spisg.yaml b/Documentation/devicetree/bindings/spi/amlogic,a4-spisg.yaml index 9bfb808..427d888 100644 --- a/Documentation/devicetree/bindings/spi/amlogic,a4-spisg.yaml +++ b/Documentation/devicetree/bindings/spi/amlogic,a4-spisg.yaml
@@ -11,12 +11,11 @@ - Xianwei Zhao <xianwei.zhao@amlogic.com> - Sunny Luo <sunny.luo@amlogic.com> -allOf: - - $ref: spi-controller.yaml# - properties: compatible: - const: amlogic,a4-spisg + enum: + - amlogic,a4-spisg + - amlogic,a9-spisg reg: maxItems: 1 @@ -35,6 +34,16 @@ resets: maxItems: 1 + amlogic,mo-idle-output: + description: | + Controls the MOSI output level when the controller is idle. + 0 - Drive MOSI low + 1 - Drive MOSI high + 2 - Follow the last transmitted bit + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1, 2] + default: 0 + required: - compatible - reg @@ -42,6 +51,19 @@ - clocks - clock-names +allOf: + - $ref: spi-controller.yaml# + - if: + not: + properties: + compatible: + contains: + enum: + - amlogic,a9-spisg + then: + properties: + amlogic,mo-idle-output: false + unevaluatedProperties: false examples:
diff --git a/Documentation/devicetree/bindings/spi/amlogic,meson-gx-spicc.yaml b/Documentation/devicetree/bindings/spi/amlogic,meson-gx-spicc.yaml index 4e28e6e..f0ba1540 100644 --- a/Documentation/devicetree/bindings/spi/amlogic,meson-gx-spicc.yaml +++ b/Documentation/devicetree/bindings/spi/amlogic,meson-gx-spicc.yaml
@@ -16,10 +16,15 @@ properties: compatible: - enum: - - amlogic,meson-gx-spicc # SPICC controller on Amlogic GX and compatible SoCs - - amlogic,meson-axg-spicc # SPICC controller on Amlogic AXG and compatible SoCs - - amlogic,meson-g12a-spicc # SPICC controller on Amlogic G12A and compatible SoCs + oneOf: + - items: + - enum: + - amlogic,t7-spicc + - const: amlogic,meson-g12a-spicc + - enum: + - amlogic,meson-gx-spicc # SPICC controller on Amlogic GX and compatible SoCs + - amlogic,meson-axg-spicc # SPICC controller on Amlogic AXG and compatible SoCs + - amlogic,meson-g12a-spicc # SPICC controller on Amlogic G12A and compatible SoCs interrupts: maxItems: 1
diff --git a/Documentation/devicetree/bindings/spi/microchip,pic32mzda-spi.yaml b/Documentation/devicetree/bindings/spi/microchip,pic32mzda-spi.yaml new file mode 100644 index 0000000..4669b52 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/microchip,pic32mzda-spi.yaml
@@ -0,0 +1,82 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spi/microchip,pic32mzda-spi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Microchip PIC32MZDA SPI Controller + +maintainers: + - Thomas Bogendoerfer <tsbogend@alpha.franken.de> + +allOf: + - $ref: spi-controller.yaml# + +properties: + compatible: + const: microchip,pic32mzda-spi + + reg: + maxItems: 1 + + interrupts: + items: + - description: Fault interrupt + - description: Receive interrupt + - description: Transmit interrupt + + interrupt-names: + items: + - const: fault + - const: rx + - const: tx + + clocks: + maxItems: 1 + + clock-names: + items: + - const: mck0 + + cs-gpios: + maxItems: 1 + + dmas: + items: + - description: RX DMA channel + - description: TX DMA channel + + dma-names: + items: + - const: spi-rx + - const: spi-tx + +required: + - compatible + - reg + - interrupts + - interrupt-names + - clocks + - clock-names + - cs-gpios + +unevaluatedProperties: false + +examples: + - | + #include <dt-bindings/interrupt-controller/irq.h> + #include <dt-bindings/gpio/gpio.h> + + spi@1f821000 { + compatible = "microchip,pic32mzda-spi"; + reg = <0x1f821000 0x200>; + interrupts = <109 IRQ_TYPE_LEVEL_HIGH>, + <110 IRQ_TYPE_LEVEL_HIGH>, + <111 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "fault", "rx", "tx"; + clocks = <&PBCLK2>; + clock-names = "mck0"; + cs-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; + dmas = <&dma 134>, <&dma 135>; + dma-names = "spi-rx", "spi-tx"; + };
diff --git a/Documentation/devicetree/bindings/spi/microchip,spi-pic32.txt b/Documentation/devicetree/bindings/spi/microchip,spi-pic32.txt deleted file mode 100644 index 79de379f..0000000 --- a/Documentation/devicetree/bindings/spi/microchip,spi-pic32.txt +++ /dev/null
@@ -1,34 +0,0 @@ -Microchip PIC32 SPI Master controller - -Required properties: -- compatible: Should be "microchip,pic32mzda-spi". -- reg: Address and length of register space for the device. -- interrupts: Should contain all three spi interrupts in sequence - of <fault-irq>, <receive-irq>, <transmit-irq>. -- interrupt-names: Should be "fault", "rx", "tx" in order. -- clocks: Phandle of the clock generating SPI clock on the bus. -- clock-names: Should be "mck0". -- cs-gpios: Specifies the gpio pins to be used for chipselects. - See: Documentation/devicetree/bindings/spi/spi-bus.txt - -Optional properties: -- dmas: Two or more DMA channel specifiers following the convention outlined - in Documentation/devicetree/bindings/dma/dma.txt -- dma-names: Names for the dma channels. There must be at least one channel - named "spi-tx" for transmit and named "spi-rx" for receive. - -Example: - -spi1: spi@1f821000 { - compatible = "microchip,pic32mzda-spi"; - reg = <0x1f821000 0x200>; - interrupts = <109 IRQ_TYPE_LEVEL_HIGH>, - <110 IRQ_TYPE_LEVEL_HIGH>, - <111 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "fault", "rx", "tx"; - clocks = <&PBCLK2>; - clock-names = "mck0"; - cs-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; - dmas = <&dma 134>, <&dma 135>; - dma-names = "spi-rx", "spi-tx"; -};
diff --git a/Documentation/devicetree/bindings/spi/nuvoton,ma35d1-qspi.yaml b/Documentation/devicetree/bindings/spi/nuvoton,ma35d1-qspi.yaml index 40965ec..9ee61f8 100644 --- a/Documentation/devicetree/bindings/spi/nuvoton,ma35d1-qspi.yaml +++ b/Documentation/devicetree/bindings/spi/nuvoton,ma35d1-qspi.yaml
@@ -4,7 +4,17 @@ $id: http://devicetree.org/schemas/spi/nuvoton,ma35d1-qspi.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Nuvoton MA35D1 Quad SPI Controller +title: Nuvoton MA35D1 SPI and Quad SPI Controllers + +description: | + The Nuvoton MA35D1 SoC contains separate SPI and QSPI controller IPs. + Both controllers expose the same Devicetree-visible resources and provide + two native chip-select signals. GPIO chip selects are supported through the + generic SPI controller binding. + + The QSPI controller additionally supports dual, quad and DTR transfers and + a target-mode timeout function. These capability differences do not require + additional controller properties. maintainers: - Chi-Wen Weng <cwweng@nuvoton.com> @@ -14,7 +24,9 @@ properties: compatible: - const: nuvoton,ma35d1-qspi + enum: + - nuvoton,ma35d1-spi + - nuvoton,ma35d1-qspi reg: maxItems: 1 @@ -33,8 +45,6 @@ maximum: 2 default: 2 - cs-gpios: false - required: - compatible - reg @@ -59,7 +69,10 @@ interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk QSPI0_GATE>; resets = <&sys MA35D1_RESET_QSPI0>; + #address-cells = <1>; #size-cells = <0>; }; }; + +...
diff --git a/Documentation/devicetree/bindings/spi/qcom,sa8255p-geni-spi.yaml b/Documentation/devicetree/bindings/spi/qcom,sa8255p-geni-spi.yaml index 6552303..33eddb3 100644 --- a/Documentation/devicetree/bindings/spi/qcom,sa8255p-geni-spi.yaml +++ b/Documentation/devicetree/bindings/spi/qcom,sa8255p-geni-spi.yaml
@@ -39,6 +39,12 @@ - const: power - const: perf + ready-gpios: + description: + GPIO used by the SPI target to notify the SPI master when it is + ready to service a transfer. Only applicable in target (slave) mode. + maxItems: 1 + required: - compatible - reg @@ -46,6 +52,9 @@ - power-domains - power-domain-names +dependencies: + ready-gpios: [ spi-slave ] + allOf: - $ref: /schemas/spi/spi-controller.yaml#
diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml index edf3996..8d1c787 100644 --- a/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml +++ b/Documentation/devicetree/bindings/spi/qcom,spi-geni-qcom.yaml
@@ -67,6 +67,12 @@ reg: maxItems: 1 + ready-gpios: + description: + GPIO used by the SPI target to notify the SPI master when it is + ready to service a transfer. Only applicable in target (slave) mode. + maxItems: 1 + required: - compatible - clocks @@ -74,6 +80,9 @@ - interrupts - reg +dependencies: + ready-gpios: [ spi-slave ] + unevaluatedProperties: false examples:
diff --git a/Documentation/devicetree/bindings/spi/qcom,spi-qpic-snand.yaml b/Documentation/devicetree/bindings/spi/qcom,spi-qpic-snand.yaml index 829da22..071e533 100644 --- a/Documentation/devicetree/bindings/spi/qcom,spi-qpic-snand.yaml +++ b/Documentation/devicetree/bindings/spi/qcom,spi-qpic-snand.yaml
@@ -28,6 +28,7 @@ - qcom,ipq5210-snand - qcom,ipq5332-snand - qcom,ipq5424-snand + - qcom,ipq9650-snand - const: qcom,ipq9574-snand - const: qcom,ipq9574-snand
diff --git a/Documentation/devicetree/bindings/spi/realtek,rtd1625-nor.yaml b/Documentation/devicetree/bindings/spi/realtek,rtd1625-nor.yaml new file mode 100644 index 0000000..014ddfe --- /dev/null +++ b/Documentation/devicetree/bindings/spi/realtek,rtd1625-nor.yaml
@@ -0,0 +1,65 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spi/realtek,rtd1625-nor.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Realtek RTD1625 SPI NOR Flash Controller + +maintainers: + - Jyan Chou <jyanchou@realtek.com> + - Yu-Chun Lin <eleanor.lin@realtek.com> + +properties: + compatible: + enum: + - realtek,rtd1625-nor + + reg: + maxItems: 3 + + reg-names: + items: + - const: ctrl + - const: dma + - const: dirmap + + clocks: + maxItems: 1 + + resets: + maxItems: 1 + + "#address-cells": + const: 1 + + "#size-cells": + const: 0 + +required: + - compatible + - reg + - reg-names + - clocks + - resets + - "#address-cells" + - "#size-cells" + +allOf: + - $ref: /schemas/spi/spi-controller.yaml# + +unevaluatedProperties: false + +examples: + - | + spi@14b000 { + compatible = "realtek,rtd1625-nor"; + reg = <0x14b000 0x50>, <0x14bf00 0x30>, <0x88100000 0x2000000>; + reg-names = "ctrl", "dma", "dirmap"; + clocks = <&cc 18>; + resets = <&cc 26>; + pinctrl-0 = <&spi_pins>; + pinctrl-names = "default"; + #address-cells = <1>; + #size-cells = <0>; + };
diff --git a/Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml b/Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml index e0c7047..41e423a 100644 --- a/Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml +++ b/Documentation/devicetree/bindings/spi/renesas,sh-msiof.yaml
@@ -55,6 +55,11 @@ - const: renesas,rcar-gen4-msiof # generic R-Car Gen4 # compatible device - items: + - enum: + - renesas,msiof-r8a78000 # R-Car X5H + - const: renesas,rcar-gen5-msiof # generic R-Car Gen5 + # compatible device + - items: - const: renesas,sh-msiof # deprecated reg: @@ -100,11 +105,11 @@ dmas: minItems: 2 - maxItems: 4 + maxItems: 6 dma-names: minItems: 2 - maxItems: 4 + maxItems: 6 items: enum: [ tx, rx ]
diff --git a/Documentation/devicetree/bindings/spi/spi-davinci.txt b/Documentation/devicetree/bindings/spi/spi-davinci.txt deleted file mode 100644 index f012888..0000000 --- a/Documentation/devicetree/bindings/spi/spi-davinci.txt +++ /dev/null
@@ -1,100 +0,0 @@ -Davinci SPI controller device bindings - -Links on DM: -Keystone 2 - https://www.ti.com/lit/ug/sprugp2a/sprugp2a.pdf -dm644x - https://www.ti.com/lit/ug/sprue32a/sprue32a.pdf -OMAP-L138/da830 - http://www.ti.com/lit/ug/spruh77a/spruh77a.pdf - -Required properties: -- #address-cells: number of cells required to define a chip select - address on the SPI bus. Should be set to 1. -- #size-cells: should be zero. -- compatible: - - "ti,dm6441-spi" for SPI used similar to that on DM644x SoC family - - "ti,da830-spi" for SPI used similar to that on DA8xx SoC family - - "ti,keystone-spi" for SPI used similar to that on Keystone2 SoC - family -- reg: Offset and length of SPI controller register space -- num-cs: Number of chip selects. This includes internal as well as - GPIO chip selects. -- ti,davinci-spi-intr-line: interrupt line used to connect the SPI - IP to the interrupt controller within the SoC. Possible values - are 0 and 1. Manual says one of the two possible interrupt - lines can be tied to the interrupt controller. Set this - based on a specific SoC configuration. -- interrupts: interrupt number mapped to CPU. -- clocks: spi clk phandle - For 66AK2G this property should be set per binding, - Documentation/devicetree/bindings/clock/ti,sci-clk.yaml - -SoC-specific Required Properties: - -The following are mandatory properties for Keystone 2 66AK2G SoCs only: - -- power-domains: Should contain a phandle to a PM domain provider node - and an args specifier containing the SPI device id - value. This property is as per the binding, - -Optional: -- cs-gpios: gpio chip selects - For example to have 3 internal CS and 2 GPIO CS, user could define - cs-gpios = <0>, <0>, <0>, <&gpio1 30 0>, <&gpio1 31 0>; - where first three are internal CS and last two are GPIO CS. - -Optional properties for slave devices: -SPI slave nodes can contain the following properties. -Not all SPI Peripherals from Texas Instruments support this. -Please check SPI peripheral documentation for a device before using these. - -- ti,spi-wdelay : delay between transmission of words - (SPIFMTn.WDELAY, SPIDAT1.WDEL) must be specified in number of SPI module - clock periods. - - delay = WDELAY * SPI_module_clock_period + 2 * SPI_module_clock_period - -Below is timing diagram which shows functional meaning of -"ti,spi-wdelay" parameter. - - +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ -SPI_CLK | | | | | | | | | | | | | | | | - +----------+ +-+ +-+ +-+ +-+ +---------------------------+ +-+ +-+ +- - -SPI_SOMI/SIMO+-----------------+ +----------- - +----------+ word1 +---------------------------+word2 - +-----------------+ +----------- - WDELAY - <--------------------------> - -Example of a NOR flash slave device (n25q032) connected to DaVinci -SPI controller device over the SPI bus. - -spi0:spi@20bf0000 { - #address-cells = <1>; - #size-cells = <0>; - compatible = "ti,dm6446-spi"; - reg = <0x20BF0000 0x1000>; - num-cs = <4>; - ti,davinci-spi-intr-line = <0>; - interrupts = <338>; - clocks = <&clkspi>; - - flash: flash@0 { - #address-cells = <1>; - #size-cells = <1>; - compatible = "st,m25p32"; - spi-max-frequency = <25000000>; - reg = <0>; - ti,spi-wdelay = <8>; - - partition@0 { - label = "u-boot-spl"; - reg = <0x0 0x80000>; - read-only; - }; - - partition@1 { - label = "test"; - reg = <0x80000 0x380000>; - }; - }; -};
diff --git a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml index 880a9f6..a0f3256 100644 --- a/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml +++ b/Documentation/devicetree/bindings/spi/spi-peripheral-props.yaml
@@ -91,6 +91,14 @@ The delay from the default sample time before the actual sample of the rxd input signal occurs. + This describes the board rather than the peripheral, namely the extra + delay this particular design needs, for example because of the flight time + of the clock and data signals between controller and peripheral. + + Timing parameters of the peripheral itself, such as its + clock-to-output-valid time, are the same on every board using that chip + and should be described with the chip. + spi-tx-bus-width: description: Bus width to the SPI bus used for write transfers. @@ -155,5 +163,6 @@ - $ref: fsl,dspi-peripheral-props.yaml# - $ref: samsung,spi-peripheral-props.yaml# - $ref: nvidia,tegra210-quad-peripheral-props.yaml# + - $ref: ti,davinci-spi-peripheral-props.yaml# additionalProperties: true
diff --git a/Documentation/devicetree/bindings/spi/ti,davinci-spi-peripheral-props.yaml b/Documentation/devicetree/bindings/spi/ti,davinci-spi-peripheral-props.yaml new file mode 100644 index 0000000..1060f17 --- /dev/null +++ b/Documentation/devicetree/bindings/spi/ti,davinci-spi-peripheral-props.yaml
@@ -0,0 +1,25 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spi/ti,davinci-spi-peripheral-props.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI DaVinci/Keystone SPI Peripheral Properties + +maintainers: + - Bartosz Golaszewski <brgl@kernel.org> + +description: + Peripheral-specific properties for SPI devices attached to a TI + DaVinci/Keystone SPI controller. + +properties: + ti,spi-wdelay: + $ref: /schemas/types.yaml#/definitions/uint32 + minimum: 0 + maximum: 63 + description: + delay between transmission of words (SPIFMTn.WDELAY, SPIDAT1.WDEL) + must be specified in number of SPI module clock periods. + +additionalProperties: true
diff --git a/Documentation/devicetree/bindings/spi/ti,davinci-spi.yaml b/Documentation/devicetree/bindings/spi/ti,davinci-spi.yaml new file mode 100644 index 0000000..1c7544d --- /dev/null +++ b/Documentation/devicetree/bindings/spi/ti,davinci-spi.yaml
@@ -0,0 +1,125 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/spi/ti,davinci-spi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: TI DaVinci/Keystone SPI Controller + +maintainers: + - Bartosz Golaszewski <brgl@kernel.org> + +properties: + compatible: + oneOf: + - enum: + - ti,da830-spi + - ti,keystone-spi + - ti,dm6441-spi + - items: + - const: ti,keystone-spi + - const: ti,dm6441-spi + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + power-domains: + maxItems: 1 + description: + Should contain a phandle to a PM domain provider node + and an args specifier containing the SPI device id + value. + + num-cs: + minimum: 1 + default: 1 + description: + Number of chip selects supported by the controller. This + includes both internal and GPIO chip selects. + + ti,davinci-spi-intr-line: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [0, 1] + description: + Interrupt line used to connect the SPI IP to the interrupt + controller within the SoC. The SPI peripheral can route its + interrupt output to one of two lines (INT0 or INT1). Set + this based on the SoC-specific wiring to the interrupt + controller. + + dmas: + items: + - description: RX DMA channel + - description: TX DMA channel + + dma-names: + items: + - const: rx + - const: tx + + "#address-cells": + const: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - ti,davinci-spi-intr-line + - num-cs + - "#address-cells" + - "#size-cells" + +allOf: + - $ref: spi-controller.yaml# + - if: + properties: + compatible: + items: + - const: ti,keystone-spi + then: + required: + - power-domains + +unevaluatedProperties: false + +examples: + - | + spi@20bf0000 { + compatible = "ti,keystone-spi", "ti,dm6441-spi"; + reg = <0x20bf0000 0x1000>; + num-cs = <4>; + ti,davinci-spi-intr-line = <0>; + interrupts = <338>; + clocks = <&clkspi>; + #address-cells = <1>; + #size-cells = <0>; + + flash@0 { + compatible = "jedec,spi-nor"; + spi-max-frequency = <25000000>; + reg = <0>; + ti,spi-wdelay = <8>; + }; + }; + + - | + spi@41000 { + compatible = "ti,da830-spi"; + reg = <0x41000 0x1000>; + num-cs = <6>; + ti,davinci-spi-intr-line = <1>; + interrupts = <20>; + dmas = <&edma0 14 0>, <&edma0 15 0>; + dma-names = "rx", "tx"; + clocks = <&psc0 4>; + power-domains = <&psc0 4>; + #address-cells = <1>; + #size-cells = <0>; + };
diff --git a/Documentation/devicetree/bindings/spmi/qcom,glymur-spmi-pmic-arb.yaml b/Documentation/devicetree/bindings/spmi/qcom,glymur-spmi-pmic-arb.yaml index 1593a11..44c864f 100644 --- a/Documentation/devicetree/bindings/spmi/qcom,glymur-spmi-pmic-arb.yaml +++ b/Documentation/devicetree/bindings/spmi/qcom,glymur-spmi-pmic-arb.yaml
@@ -27,6 +27,7 @@ - enum: - qcom,hawi-spmi-pmic-arb - qcom,kaanapali-spmi-pmic-arb + - qcom,maili-spmi-pmic-arb - const: qcom,glymur-spmi-pmic-arb - enum: - qcom,glymur-spmi-pmic-arb
diff --git a/Documentation/devicetree/bindings/sram/qcom,imem.yaml b/Documentation/devicetree/bindings/sram/qcom,imem.yaml index b4f082f..2f12037 100644 --- a/Documentation/devicetree/bindings/sram/qcom,imem.yaml +++ b/Documentation/devicetree/bindings/sram/qcom,imem.yaml
@@ -18,7 +18,6 @@ items: - enum: - qcom,apq8064-imem - - qcom,ipq5424-imem - qcom,msm8226-imem - qcom,msm8974-imem - qcom,msm8976-imem
diff --git a/Documentation/devicetree/bindings/sram/sram.yaml b/Documentation/devicetree/bindings/sram/sram.yaml index b83fc68..6ee0b14 100644 --- a/Documentation/devicetree/bindings/sram/sram.yaml +++ b/Documentation/devicetree/bindings/sram/sram.yaml
@@ -37,12 +37,14 @@ - qcom,eliza-imem - qcom,glymur-imem - qcom,hawi-imem + - qcom,ipq5424-imem - qcom,kaanapali-imem - qcom,maili-imem - qcom,milos-imem - qcom,rpm-msg-ram - qcom,shikra-imem - rockchip,rk3288-pmu-sram + - samsung,exynos850-acpm-sram reg: maxItems: 1 @@ -159,6 +161,7 @@ enum: - qcom,rpm-msg-ram - rockchip,rk3288-pmu-sram + - samsung,exynos850-acpm-sram then: required: - "#address-cells"
diff --git a/Documentation/devicetree/bindings/timer/sifive,clint.yaml b/Documentation/devicetree/bindings/timer/sifive,clint.yaml index 3673836..d53f52e 100644 --- a/Documentation/devicetree/bindings/timer/sifive,clint.yaml +++ b/Documentation/devicetree/bindings/timer/sifive,clint.yaml
@@ -34,7 +34,6 @@ - microchip,pic64gx-clint # Microchip PIC64GX - sifive,fu540-c000-clint # SiFive FU540 - spacemit,k1-clint # SpacemiT K1 - - spacemit,k3-clint # SpacemiT K3 - starfive,jh7100-clint # StarFive JH7100 - starfive,jh7110-clint # StarFive JH7110 - starfive,jh8100-clint # StarFive JH8100
diff --git a/Documentation/devicetree/bindings/timer/thead,c900-aclint-mtimer.yaml b/Documentation/devicetree/bindings/timer/thead,c900-aclint-mtimer.yaml index cf7c82e..082378b 100644 --- a/Documentation/devicetree/bindings/timer/thead,c900-aclint-mtimer.yaml +++ b/Documentation/devicetree/bindings/timer/thead,c900-aclint-mtimer.yaml
@@ -12,6 +12,7 @@ properties: compatible: oneOf: + - const: spacemit,k3-aclint-mtimer - items: - enum: - sophgo,sg2042-aclint-mtimer
diff --git a/Documentation/devicetree/bindings/trivial-devices.yaml b/Documentation/devicetree/bindings/trivial-devices.yaml index 2de8eb0..3b7876c 100644 --- a/Documentation/devicetree/bindings/trivial-devices.yaml +++ b/Documentation/devicetree/bindings/trivial-devices.yaml
@@ -69,6 +69,8 @@ - asteralabs,pt5161l # ATECC508A - i2c h/w elliptic curve crypto module - atmel,atecc508a + # ATECC608A - i2c h/w elliptic curve crypto module + - atmel,atecc608a # ATECC608B - i2c h/w elliptic curve crypto module - atmel,atecc608b # ATSHA204 - i2c h/w symmetric crypto module
diff --git a/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml b/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml index ea60f72..de50d7a 100644 --- a/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml +++ b/Documentation/devicetree/bindings/usb/qcom,snps-dwc3.yaml
@@ -27,6 +27,7 @@ - qcom,eliza-dwc3 - qcom,glymur-dwc3 - qcom,glymur-dwc3-mp + - qcom,hawi-dwc3 - qcom,ipq4019-dwc3 - qcom,ipq5018-dwc3 - qcom,ipq5210-dwc3 @@ -206,6 +207,7 @@ compatible: contains: enum: + - qcom,hawi-dwc3 - qcom,ipq5210-dwc3 - qcom,ipq5424-dwc3 - qcom,ipq9574-dwc3 @@ -547,6 +549,7 @@ contains: enum: - qcom,eliza-dwc3 + - qcom,hawi-dwc3 - qcom,ipq4019-dwc3 - qcom,ipq8064-dwc3 - qcom,kaanapali-dwc3
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index ba20029..539aa1c 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml
@@ -327,6 +327,8 @@ description: ChipOne "^chipspark,.*": description: ChipSPARK + "^chipwealth,.*": + description: Chip Wealth Technology "^chongzhou,.*": description: Shenzhen Chongzhou Electronic Technology Co., Ltd "^chrontel,.*": @@ -626,6 +628,8 @@ description: Freebox SAS "^freecom,.*": description: Freecom Gmbh + "^freemobile,.*": + description: Free Mobile "^frida,.*": description: Shenzhen Frida LCD Co., Ltd. "^friendlyarm,.*": @@ -662,6 +666,8 @@ description: Gemei Digital Technology Co., Ltd. "^gemtek,.*": description: Gemtek Technology Co., Ltd. + "^generalmobile,.*": + description: General Mobile Fzc. "^genesys,.*": description: Genesys Logic, Inc. "^genexis,.*": @@ -949,6 +955,8 @@ description: Shenzen LC Technology Co., Ltd. "^leadtek,.*": description: Shenzhen Leadtek Technology Co., Ltd. + "^leeco,.*": + description: Leshi Holding Beijing. "^leez,.*": description: Leez "^lego,.*": @@ -1192,6 +1200,8 @@ description: New Vision Display (Shenzhen) Co., Ltd. "^nexbox,.*": description: Nexbox + "^nexperia,.*": + description: Nexperia B.V. "^nextthing,.*": description: Next Thing Co. "^ni,.*": @@ -1419,6 +1429,8 @@ description: Renesas Electronics Corporation "^rervision,.*": description: Shenzhen Rervision Technology Co., Ltd. + "^retroidpocket,.*": + description: Retroid Pocket "^retronix,.*": description: Retronix Technology Inc. "^revotics,.*": @@ -1595,6 +1607,8 @@ description: Sony Corporation "^sophgo,.*": description: Sophgo Technology Inc. + "^sophos,.*": + description: Sophos Ltd. "^sourceparts,.*": description: Source Parts Inc. "^spacemit,.*": @@ -1694,6 +1708,8 @@ description: Techvision Intelligent Technology Co., Ltd "^techwell,.*": description: Techwell, Inc. + "^teclast,.*": + description: Teclast "^teejet,.*": description: TeeJet "^teltonika,.*":
diff --git a/Documentation/devicetree/bindings/watchdog/apple,wdt.yaml b/Documentation/devicetree/bindings/watchdog/apple,wdt.yaml index ca4cf01..1af9241 100644 --- a/Documentation/devicetree/bindings/watchdog/apple,wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/apple,wdt.yaml
@@ -22,6 +22,7 @@ - apple,t6031-wdt - apple,t8122-wdt - apple,t8132-wdt + - apple,t8140-wdt - const: apple,t8103-wdt - items: - enum:
diff --git a/Documentation/devicetree/bindings/watchdog/mediatek,mtk-wdt.yaml b/Documentation/devicetree/bindings/watchdog/mediatek,mtk-wdt.yaml index 953629c..f9b7255 100644 --- a/Documentation/devicetree/bindings/watchdog/mediatek,mtk-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/mediatek,mtk-wdt.yaml
@@ -26,6 +26,7 @@ - mediatek,mt6795-wdt - mediatek,mt7986-wdt - mediatek,mt7988-wdt + - mediatek,mt8167-wdt - mediatek,mt8183-wdt - mediatek,mt8186-wdt - mediatek,mt8188-wdt @@ -40,6 +41,7 @@ - mediatek,mt7622-wdt - mediatek,mt7623-wdt - mediatek,mt7629-wdt + - mediatek,mt8127-wdt - mediatek,mt8173-wdt - mediatek,mt8188-wdt - mediatek,mt8189-wdt
diff --git a/Documentation/devicetree/bindings/watchdog/renesas,r9a09g057-wdt.yaml b/Documentation/devicetree/bindings/watchdog/renesas,r9a09g057-wdt.yaml index 975c5aa..322b692 100644 --- a/Documentation/devicetree/bindings/watchdog/renesas,r9a09g057-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/renesas,r9a09g057-wdt.yaml
@@ -48,6 +48,17 @@ resets: maxItems: 1 + renesas,sysc: + description: + System controller registers control the start/stop of the WDT, and halt debug. + $ref: /schemas/types.yaml#/definitions/phandle-array + items: + - items: + - description: phandle to system controller + - description: watchdog IP instance index + minimum: 0 + maximum: 5 + timeout-sec: true required: @@ -73,15 +84,29 @@ minItems: 2 clock-names: minItems: 2 + renesas,sysc: false else: properties: clocks: maxItems: 1 clock-names: maxItems: 1 - reg: - minItems: 2 resets: false + allOf: + - if: + required: + - renesas,sysc + then: + properties: + reg: + maxItems: 1 + else: + properties: + reg: + description: Deprecated. Use the renesas,sysc property along with + the watchdog IP instance index instead. + minItems: 2 + deprecated: true additionalProperties: false
diff --git a/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml b/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml index 41aee16..a32c4783 100644 --- a/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml +++ b/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml
@@ -22,6 +22,7 @@ - samsung,s3c6410-wdt # for S3C6410, S5PV210 and Exynos4 - samsung,exynos5250-wdt # for Exynos5250 - samsung,exynos5420-wdt # for Exynos5420 + - samsung,exynos5515-wdt - samsung,exynos7-wdt # for Exynos7 - samsung,exynos850-wdt # for Exynos850 - samsung,exynos990-wdt # for Exynos990 @@ -57,7 +58,7 @@ $ref: /schemas/types.yaml#/definitions/phandle description: Phandle to the PMU system controller node (in case of Exynos5250, - Exynos5420, Exynos7, Exynos850, Exynos990 and gs101). + Exynos5420, Exynos5515, Exynos7, Exynos850, Exynos990 and gs101). required: - compatible @@ -98,6 +99,26 @@ compatible: contains: enum: + - samsung,exynos5515-wdt + then: + properties: + clocks: + items: + - description: Bus clock, used for register interface + - description: Source clock (driving watchdog counter) + clock-names: + items: + - const: watchdog + - const: watchdog_src + samsung,cluster-index: false + required: + - samsung,syscon-phandle + + - if: + properties: + compatible: + contains: + enum: - samsung,exynos990-wdt then: properties:
diff --git a/Documentation/driver-api/driver-model/devres.rst b/Documentation/driver-api/driver-model/devres.rst index 5067500..4f0b90e 100644 --- a/Documentation/driver-api/driver-model/devres.rst +++ b/Documentation/driver-api/driver-model/devres.rst
@@ -460,8 +460,6 @@ devm_spi_alloc_target() devm_spi_optimize_message() devm_spi_register_controller() - devm_spi_register_host() - devm_spi_register_target() WATCHDOG devm_watchdog_register_device()
diff --git a/Documentation/driver-api/gpio/board.rst b/Documentation/driver-api/gpio/board.rst index 4ac1e12..83b7484 100644 --- a/Documentation/driver-api/gpio/board.rst +++ b/Documentation/driver-api/gpio/board.rst
@@ -55,7 +55,7 @@ Internally, the GPIO subsystem prefixes the GPIO suffix ("gpios" or "gpio") with the string passed in con_id to get the resulting string -(``snprintf(... "%s-%s", con_id, gpio_suffixes[]``). +(``snprintf(... "%s-%s", con_id, gpio_suffixes[])``). ACPI ----
diff --git a/Documentation/driver-api/gpio/driver.rst b/Documentation/driver-api/gpio/driver.rst index a4f160b..3e53374 100644 --- a/Documentation/driver-api/gpio/driver.rst +++ b/Documentation/driver-api/gpio/driver.rst
@@ -134,6 +134,13 @@ closer to the actual pins. This way the pin controller can manage the below listed GPIO configurations. +The optional .get_config() callback reads a configuration back: the packed +parameter to query goes in, its bare argument comes out, the way +pinctrl_gpio_get_config() answers. gpiochip_generic_get_config() is its pin +control backed counterpart. Nothing in gpiolib calls it; it is for the GPIO +driver's own use, for example to learn the direction of a line when the pin +controller owns it. + If a pin controller back-end is used, the GPIO controller or hardware description needs to provide "GPIO ranges" mapping the GPIO line offsets to pin numbers on the pin controller so they can properly cross-reference each other.
diff --git a/Documentation/driver-api/mmc/mmc-async-req.rst b/Documentation/driver-api/mmc/mmc-async-req.rst index 0f7197c..d9d4ac7 100644 --- a/Documentation/driver-api/mmc/mmc-async-req.rst +++ b/Documentation/driver-api/mmc/mmc-async-req.rst
@@ -23,7 +23,7 @@ MMC block driver ================ -The mmc_blk_issue_rw_rq() in the MMC block driver is made non-blocking. +The mmc_blk_mq_issue_rw_rq() in the MMC block driver is made non-blocking. The increase in throughput is proportional to the time it takes to prepare (major part of preparations are dma_map_sg() and dma_unmap_sg()) @@ -34,21 +34,20 @@ preparation may cost even more. As long as these slower preparations are run in parallel with the transfer performance won't be affected. -Details on measurements from IOZone and mmc_test -================================================ +MMC core API +============ -https://wiki.linaro.org/WorkingGroups/Kernel/Specs/StoragePerfMMC-async-req +The preparation of a request is separated from starting the transfer, so +that a host can prepare a request while another one is still in progress: -MMC core API extension -====================== - -There is one new public function mmc_start_req(). - -It starts a new MMC command request for a host. The function isn't -truly non-blocking. If there is an ongoing async request it waits -for completion of that request and starts the new one and returns. It -doesn't wait for the new request to complete. If there is no ongoing -request it starts the new request and returns immediately. + * mmc_pre_req() prepares a request before it is started. It may be called + while another request is running on the host. + * mmc_start_request() starts a prepared request without waiting for it to + complete. mmc_wait_for_req() starts a request and waits for it to + complete as well. + * mmc_post_req() releases the resources allocated by mmc_pre_req() after + the request has completed. It may likewise run while another request is + active. MMC host extensions =================== @@ -59,40 +58,3 @@ In the DMA case pre_req() may do dma_map_sg() and prepare the DMA descriptor, and post_req() runs the dma_unmap_sg(). - -Optimize for the first request -============================== - -The first request in a series of requests can't be prepared in parallel -with the previous transfer, since there is no previous request. - -The argument is_first_req in pre_req() indicates that there is no previous -request. The host driver may optimize for this scenario to minimize -the performance loss. A way to optimize for this is to split the current -request in two chunks, prepare the first chunk and start the request, -and finally prepare the second chunk and start the transfer. - -Pseudocode to handle is_first_req scenario with minimal prepare overhead:: - - if (is_first_req && req->size > threshold) - /* start MMC transfer for the complete transfer size */ - mmc_start_command(MMC_CMD_TRANSFER_FULL_SIZE); - - /* - * Begin to prepare DMA while cmd is being processed by MMC. - * The first chunk of the request should take the same time - * to prepare as the "MMC process command time". - * If prepare time exceeds MMC cmd time - * the transfer is delayed, guesstimate max 4k as first chunk size. - */ - prepare_1st_chunk_for_dma(req); - /* flush pending desc to the DMAC (dmaengine.h) */ - dma_issue_pending(req->dma_desc); - - prepare_2nd_chunk_for_dma(req); - /* - * The second issue_pending should be called before MMC runs out - * of the first chunk. If the MMC runs out of the first data chunk - * before this call, the transfer is delayed. - */ - dma_issue_pending(req->dma_desc);
diff --git a/Documentation/driver-api/mmc/mmc-tools.rst b/Documentation/driver-api/mmc/mmc-tools.rst index eee1c2c..728d3aa 100644 --- a/Documentation/driver-api/mmc/mmc-tools.rst +++ b/Documentation/driver-api/mmc/mmc-tools.rst
@@ -32,6 +32,7 @@ - Write to rpmb device from data file. - Enable the eMMC cache feature. - Disable the eMMC cache feature. + - Print the eMMC health status. - Print and parse CID data. - Print and parse CSD data. - Print and parse SCR data.
diff --git a/Documentation/driver-api/pwm.rst b/Documentation/driver-api/pwm.rst index 0d27a40..b6b67f7 100644 --- a/Documentation/driver-api/pwm.rst +++ b/Documentation/driver-api/pwm.rst
@@ -177,7 +177,7 @@ Most functions in the PWM consumer API might sleep and so must not be called from atomic context. The notable exception is pwm_apply_atomic() which has the same semantics as pwm_apply_might_sleep() but can be called from atomic context. -(The price for that is that it doesn't work for all PWM devices, use +The price for that is that it doesn't work for all PWM devices. Use pwm_might_sleep() to check if a given PWM supports atomic operation. Locking in the PWM core ensures that callbacks related to a single chip are
diff --git a/Documentation/i2c/writing-clients.rst b/Documentation/i2c/writing-clients.rst index 121e618..8bab8b1 100644 --- a/Documentation/i2c/writing-clients.rst +++ b/Documentation/i2c/writing-clients.rst
@@ -258,7 +258,7 @@ :: /* Substitute your own name and email address */ - MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>" + MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>"); MODULE_DESCRIPTION("Driver for Barf Inc. Foo I2C devices"); /* a few non-GPL license types are also allowed */
diff --git a/Documentation/scheduler/sched-ext.rst b/Documentation/scheduler/sched-ext.rst index 794ae80..13ba2cb 100644 --- a/Documentation/scheduler/sched-ext.rst +++ b/Documentation/scheduler/sched-ext.rst
@@ -503,6 +503,19 @@ class, in which case it will exit the tick-dispatch loop even though it is runnable and has a non-zero slice. +* Under proxy execution, sched_ext continues to observe the donor as the + current scheduling context. Accordingly, ``ops.running()`` and + ``ops.stopping()`` report when the donor's scheduling context becomes active + and inactive, even when the donor is blocked and a lock owner executes on its + behalf. The physical execution context is intentionally not reported through + these callbacks. + + A blocked donor enters a running session only after proxy resolution finds + an execution context. The session remains active if only the physical + execution context changes while the donor remains the same. Running sessions + are tracked so that ``ops.running()`` and ``ops.stopping()`` remain paired + and are not emitted recursively. + See the "Scheduling Cycle" section for a more detailed description of how a freshly woken up task gets on a CPU.
diff --git a/Documentation/security/ipe.rst b/Documentation/security/ipe.rst index 5eb3e62..4490aed 100644 --- a/Documentation/security/ipe.rst +++ b/Documentation/security/ipe.rst
@@ -442,5 +442,5 @@ CONFIG_SECURITY_IPE_KUNIT_TEST=y In addition, IPE has a python based integration -`test suite <https://github.com/microsoft/ipe/tree/test-suite>`_ that +`test suite <https://github.com/Integrity-Policy-Enforcement/ci>`_ that can test both user interfaces and enforcement functionalities.
diff --git a/Documentation/security/landlock.rst b/Documentation/security/landlock.rst index 2d6e107..d81f1c2 100644 --- a/Documentation/security/landlock.rst +++ b/Documentation/security/landlock.rst
@@ -8,7 +8,7 @@ ================================== :Author: Mickaël Salaün -:Date: August 2026 +:Date: October 2026 Landlock's goal is to create scoped access-control (i.e. sandboxing). To harden a whole system, this feature should be available to any process, @@ -130,6 +130,166 @@ restrictions, because access within the same scope is already allowed based on ``LANDLOCK_ACCESS_FS_RESOLVE_UNIX``. +Composability with user namespaces +---------------------------------- + +Landlock domain-based scoping and the kernel's user-namespace-based capability +scoping enforce isolation over independent hierarchies. Landlock checks domain +ancestry; the kernel's ``ns_capable()`` checks user namespace ancestry. These +hierarchies are orthogonal: Landlock enforcement is deterministic with respect +to its own configuration, regardless of namespace or capability state, and vice +versa. This orthogonality is a design invariant that must hold for all Landlock +access controls. + +Design philosophy +----------------- + +Landlock's goal is to restrict a sandboxed process's access to three kinds of +resources: data (files, sockets, pipes), other processes (signals, ptrace), and +kernel-internal resources whose use widens the kernel attack surface +(capabilities, namespace types). Each access right or permission gates one or +more operations that grant such access; restricting the operations is how +Landlock restricts the underlying access. + +When designing a new access control, identify the protected resource kind +first (data, processes, or kernel-internal resources). The operations to +restrict follow from the protected resource, by identifying which kernel code +paths grant access to the resource and at which place in the code the access to +the resource can be gated. Do not design a permission around +"restrict the unshare(2) syscall" or similar mechanism-centric framings; design +it around "restrict the process from acquiring access to namespace types" (the +protected resource), letting the operation set follow. + +Ruleset restriction models +-------------------------- + +Landlock provides three restriction models that differ in how rules identify the +resource being restricted. + +In general, the ``struct landlock_ruleset_attr`` specifies the operations to be +denied by default under the enforced policy. The *rules* added to the ruleset +define the exceptions to these restrictions, allow-listing specific conditions +under which these operations are still permitted. + +Per-object access rights (``handled_access_*``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Per-object access rights control operations on a specific resource instance, +identified in the rule key by a value drawn from an open-ended space: a file +hierarchy referenced by ``parent_fd``, or a network port identified by its +16-bit number. + +Each ``handled_access_*`` field declares a set of access rights, operations +which are to be denied by default once the ruleset is enforced. + +The rule body declares which of the multiple distinct operations on that object +instance are allowed (open, read, write, truncate; bind, connect). + +Operations are grouped by object type in the respective ``handled_access_*`` +field: a new operation on an existing type extends that field, and a new object +type gets its own ``handled_access_*`` field. + +Per-category permissions (``handled_permissions``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Per-category permissions control the process's exercise of category members, +where the category is a small kernel-defined enumeration (a Linux capability +number ``CAP_*``, a namespace type ``CLONE_NEW*``). Unlike per-object access +rights, which restrict specific operations on a single resource instance, +per-category permissions gate the prerequisite operation itself (exercising a +capability, acquiring access to a namespace), so gating it transitively covers a +broad set of downstream operations (e.g. denying ``CAP_SYS_ADMIN`` blocks all +admin operations such as mounts). + +These category members are the LSM-level access-control objects (the entities +the process is authorized against) even though they are enum values rather than +externally-instantiated kernel data structures. Per-category permissions apply +where the controlled operation collapses to "may the process use this category +member at all" (use a capability; acquire access to a namespace), so the rule +body lists which category members the process may exercise. + +Each ``LANDLOCK_PERMISSION_*`` flag maps to its own rule type and covers every +kernel path that exercises a member. When a ruleset handles a permission, all +uses of category members are denied unless explicitly allowed by a rule. + +Logging of a denied member can be suppressed at the same granularity as the +restriction itself: per rule and per member. A rule names the members whose +denial should not be audited; suppression only affects the audit record, never +the denial or its trace event, which reports ``logged=0``. Suppression only +applies when the layer owning the rule is the one that denied the member. + +See Documentation/userspace-api/landlock.rst for the concrete syscall paths +covered by each permission. + +The category enum is owned by the corresponding kernel subsystem (capabilities, +namespaces, etc.). Userspace policy authors query category member availability +via the relevant non-Landlock interfaces: + +* For capabilities: ``<linux/capability.h>``, + ``/proc/sys/kernel/cap_last_cap``, ``prctl(PR_CAPBSET_READ)``. +* For namespaces: ``<linux/sched.h>``, ``/proc/$$/ns/*``, + :manpage:`unshare(2)` runtime probe. + +The Landlock ABI version does not encode this availability; ABI versioning +describes which Landlock features (rule types, access rights, scopes, +permissions) the kernel implements, not which category members the kernel knows +about. + +Forward compatibility for new category members follows a simple rule set: + +* New members in future kernels are automatically denied: rules whitelist + specific values, and a member not in any rule is denied. +* Kernel-side compatibility for split categories is handled by the owning + subsystem (e.g., when ``CAP_BPF`` was split from ``CAP_SYS_ADMIN``, either + capability became sufficient for the affected operations, so a rule allowing + ``CAP_SYS_ADMIN`` continues to allow operations now gated by + ``CAP_SYS_ADMIN || CAP_BPF``). +* Unknown values in the rule body are silently accepted rather than rejected. + Rejecting them would tie Landlock policy semantics to the running kernel's + category-member set: a rule built against future headers would fail to load + on older kernels, forcing policy authors to know each kernel's enumeration. + Acceptance is fail-safe in both directions: a rule referring to a value the + running kernel does not yet know has no effect (deny-by-default still applies + to that operation), and a rule written against future headers loads + identically across kernels so the same policy keeps the same restrictions. + When a value becomes real on a future kernel, the policy activates as written + by the author. +* In contrast, unknown ``LANDLOCK_PERMISSION_*`` flags in + ``handled_permissions`` are rejected (``-EINVAL``), since Landlock owns that + bit space. + +Cross-domain scopes (``scoped``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Scopes restrict **cross-domain interactions** categorically, without rules. +Setting a scope flag (e.g. ``LANDLOCK_SCOPE_SIGNAL``) denies the operation to +targets outside the Landlock domain or its children. Like per-category +permissions, scopes provide complete coverage of the controlled operation. + +Choosing a model for a new feature +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +* If the new feature controls operations on resource objects supplied by the + sandbox author, extend or add a per-object access right + (``handled_access_*``). +* If the new feature controls a per-category operation gated by an enum (a + Linux capability, a namespace type, a socket family, etc.), use a + per-category permission (``handled_permissions``). When several such enums + could classify the operation, prefer the enum the originating subsystem + already uses for capability/access checks (e.g. ``CAP_*`` for ``capable()`` + hooks, ``CLONE_NEW*`` for namespace hooks). +* When an operation is gated by multiple kernel-defined enums (a classic + example being ``CAP_SYS_ADMIN`` plus a ``CLONE_NEW*`` flag for non-user + namespace creation), define one per-category permission per enum dimension. + Sandbox authors handle each dimension's permission in ``handled_permissions`` + and add rules for each; the kernel enforces each dimension at its own LSM + hook. ``LANDLOCK_PERMISSION_NAMESPACE_USE`` and + ``LANDLOCK_PERMISSION_CAPABILITY_USE`` follow this pattern. +* If the new feature restricts a categorical cross-domain interaction with no + per-target granularity, use a cross-domain scope (``scoped``). +* For all three models, confirm a single LSM hook (or small set of related + hooks) covers every kernel path that exercises the operation. + Tests ===== @@ -151,6 +311,18 @@ .. kernel-doc:: security/landlock/fs.h :identifiers: +Namespace +--------- + +.. kernel-doc:: security/landlock/ns.h + :identifiers: + +Capability +---------- + +.. kernel-doc:: security/landlock/cap.h + :identifiers: + Process credential ------------------ @@ -198,7 +370,8 @@ tracepoints-only build reports the selection audit would make. A quiet rule (``LANDLOCK_ADD_RULE_QUIET`` with the access in the ``quiet_*`` fields of ``struct landlock_ruleset_attr``) suppresses logging by -setting ``logged=0`` the same way. +setting ``logged=0`` the same way, as do the per-member ``quiet_*`` +masks of capability and namespace rules. See Documentation/admin-guide/LSM/landlock.rst for audit record format, tracepoint usage, and filtering examples.
diff --git a/Documentation/spi/multiple-data-lanes.rst b/Documentation/spi/multiple-data-lanes.rst index 69cb532..802aece 100644 --- a/Documentation/spi/multiple-data-lanes.rst +++ b/Documentation/spi/multiple-data-lanes.rst
@@ -127,7 +127,7 @@ The possible values for this field have the following semantics: -- :c:macro:`SPI_MULTI_BUS_MODE_SINGLE`: Only use the first lane. Other lanes are +- :c:macro:`SPI_MULTI_LANE_MODE_SINGLE`: Only use the first lane. Other lanes are ignored. This means that it is operating just like a conventional SPI peripheral. This is the default, so it does not need to be explicitly set. @@ -149,7 +149,7 @@ ---------- ---------------- ---------- SDO 0 0-0-0-1-0-0-0-1 SDI 0 -- :c:macro:`SPI_MULTI_BUS_MODE_MIRROR`: Send a single data word over all of the +- :c:macro:`SPI_MULTI_LANE_MODE_MIRROR`: Send a single data word over all of the lanes at the same time. This only makes sense for writes and not for reads. @@ -160,7 +160,7 @@ struct spi_transfer xfer = { .tx_buf = tx_buf, .len = 1, - .multi_lane_mode = SPI_MULTI_BUS_MODE_MIRROR, + .multi_lane_mode = SPI_MULTI_LANE_MODE_MIRROR, }; spi_sync_transfer(spi, &xfer, 1); @@ -172,7 +172,7 @@ SDO 0 0-0-0-1-0-0-0-1 SDI 0 SDO 1 0-0-0-1-0-0-0-1 SDI 1 -- :c:macro:`SPI_MULTI_BUS_MODE_STRIPE`: Send or receive two different data words +- :c:macro:`SPI_MULTI_LANE_MODE_STRIPE`: Send or receive two different data words at the same time, one on each lane. This means that the buffer needs to be sized to hold data for all lanes. Data is interleaved in the buffer, with the first word corresponding to lane 0, the second to lane 1, and so on. @@ -185,7 +185,7 @@ struct spi_transfer xfer = { .rx_buf = rx_buf, .len = 2, - .multi_lane_mode = SPI_MULTI_BUS_MODE_STRIPE, + .multi_lane_mode = SPI_MULTI_LANE_MODE_STRIPE, }; spi_sync_transfer(spi, &xfer, 1);
diff --git a/Documentation/trace/events-landlock.rst b/Documentation/trace/events-landlock.rst index 304a8d0..9ccf276 100644 --- a/Documentation/trace/events-landlock.rst +++ b/Documentation/trace/events-landlock.rst
@@ -6,7 +6,7 @@ ===================== :Author: Mickaël Salaün -:Date: September 2026 +:Date: October 2026 Landlock emits trace events for sandbox lifecycle operations and access denials. These events can be consumed by ftrace (for human-readable @@ -35,6 +35,8 @@ - ``landlock_add_rule_net_port``: a network port rule is added to a ruleset - ``landlock_create_domain``: a new domain is created from a ruleset - ``landlock_enforce_domain``: a domain is enforced on a thread +- ``landlock_add_rule_namespace``: a namespace rule is added to a ruleset +- ``landlock_add_rule_capability``: a capability rule is added to a ruleset **Denial events** are emitted when an access is denied: @@ -44,6 +46,8 @@ - ``landlock_deny_scope_signal``: signal delivery denied - ``landlock_deny_scope_abstract_unix_socket``: abstract unix socket access denied +- ``landlock_deny_permission_namespace``: namespace use denied +- ``landlock_deny_permission_capability``: capability use denied **Rule evaluation events** are emitted during rule matching: @@ -84,7 +88,7 @@ $ LC_ALL=C LL_FS_RO=/usr:/lib:/lib64:/bin:/etc/ld.so.cache LL_FS_RW=/tmp \ ./sandboxer cat /etc/passwd $ cat /sys/kernel/tracing/trace_pipe - cat-127 [...] landlock_create_ruleset: ruleset=195cc6b76.0 handled_fs=execute|write_file|read_file|read_dir|remove_dir|remove_file|make_char|make_dir|make_reg|make_sock|make_fifo|make_block|make_sym|refer|truncate|ioctl_dev|resolve_unix handled_net= scoped= + cat-127 [...] landlock_create_ruleset: ruleset=195cc6b76.0 handled_fs=execute|write_file|read_file|read_dir|remove_dir|remove_file|make_char|make_dir|make_reg|make_sock|make_fifo|make_block|make_sym|refer|truncate|ioctl_dev|resolve_unix handled_net= scoped= handled_permissions= cat-127 [...] landlock_create_domain: domain=195cc6b7c parent=0 ruleset=195cc6b76.6 cat-127 [...] landlock_enforce_domain: domain=195cc6b7c complete=1 process_wide=1 no_new_privs=1 cat-127 [...] landlock_deny_access_fs: domain=195cc6b7c same_exec=0 logged=0 blockers=read_file dev=0:17 ino=5901179 path=/etc/passwd @@ -119,10 +123,13 @@ Audit uses string ``dev="<s_id>"``. Numeric format is more precise for machine parsing. -- **Denied access field**: The ``deny_access_fs`` and ``deny_access_net`` - tracepoints use the ``blockers=`` field name (same as audit). Both - render the blocked access rights as names: audit prefixes the category - and separates with commas (e.g., ``blockers=fs.read_file``), while the +- **Blocker field**: Denial tracepoints that carry a blocker use the + ``blockers=`` field name (same as audit). The ``deny_access_fs`` and + ``deny_access_net`` tracepoints render the blocked access rights, the + ``deny_permission_namespace`` and ``deny_permission_capability`` + tracepoints render the blocked permission, and a ``change_topology`` + denial renders its request type. Audit prefixes the category and + separates with commas (e.g., ``blockers=fs.read_file``), while the tracepoints omit the category (carried by the event name) and separate with ``|`` (e.g., ``blockers=read_file``). Scope and ptrace tracepoints omit ``blockers`` because the event name identifies the @@ -160,10 +167,34 @@ ================== Syscall events include a ruleset version (``ruleset=<hex_id>.<version>``) -that tracks the number of rules added to the ruleset. The version is -incremented on each ``landlock_add_rule()`` call and frozen at -``landlock_restrict_self()`` time. This enables trace consumers to -correlate a domain with the exact set of rules it was created from. +that tracks the number of successful add-rule calls on the ruleset. The +version is incremented on each successful ``landlock_add_rule()`` call and +frozen at ``landlock_restrict_self()`` time. Namespace and capability calls +increment it even when their effective known masks are empty or already +present, so the event stream preserves every successful call. This enables +trace consumers to correlate a domain with the exact rule history from which +it was created. + +Permission rule and denial events +================================= + +``landlock_create_ruleset`` reports handled permissions as symbolic names in +``handled_permissions=``. ``landlock_add_rule_namespace`` and +``landlock_add_rule_capability`` report ``permissions=`` plus the effective +known allowed and quiet member masks. Capability masks and the raw +``CLONE_NEW*`` namespace masks are printed in hexadecimal. Unknown-only input +therefore appears as zero while still advancing the ruleset version, and adding +a member already present still emits an event. + +``landlock_deny_permission_namespace`` reports the denied raw +``CLONE_NEW*`` value. ``namespace_id`` is zero for namespace creation and is +the exact target namespace ID for :manpage:`setns(2)`. +``landlock_deny_permission_capability`` reports the denied ``CAP_*`` number. +Like every denial event, both include the denying domain, ``same_exec``, and +``logged``. + +Per-member quiet masks suppress audit submission but never these trace events, +which report ``logged=0``. Domain enforcement ================== @@ -290,8 +321,8 @@ ``domain=`` key (join to the ``create_domain`` recorded in step 1), building the per-domain thread set; filter ``complete==1`` for a one-event-per-operation summary. -3. On ``landlock_deny_access_*``: look up the domain, decide whether - to count, alert, or ignore the denial based on custom policy. +3. On ``landlock_deny_*``: look up the domain, decide whether to count, + alert, or ignore the denial based on custom policy. 4. On ``landlock_free_domain``: clean up the per-domain state, log final statistics. @@ -304,11 +335,12 @@ Audit filtering equivalence =========================== -The ``logged`` field reflects the domain's log policy but not the global -``audit_enabled`` toggle, so it does not change when audit is turned on -or off. When audit is enabled, ``logged==1`` selects the denials the -domain submits to audit (audit-side rate-limiting and exclude rules may -still drop some), so a stateless ftrace filter can select them:: +The ``logged`` field reflects the domain's log policy and per-request quiet +selection, but not the global ``audit_enabled`` toggle, so it does not +change when audit is turned on or off. When audit is enabled, ``logged==1`` +selects the denials the domain submits to audit (audit-side rate-limiting and +exclude rules may still drop some), so a stateless ftrace filter can select +them:: # Show only denials that audit would also log: echo 'logged==1' > \
diff --git a/Documentation/userspace-api/landlock.rst b/Documentation/userspace-api/landlock.rst index 84cb7bf..3d45b95 100644 --- a/Documentation/userspace-api/landlock.rst +++ b/Documentation/userspace-api/landlock.rst
@@ -8,7 +8,7 @@ ===================================== :Author: Mickaël Salaün -:Date: August 2026 +:Date: October 2026 The goal of Landlock is to enable restriction of ambient rights (e.g. global filesystem or network access) for a set of processes. Because Landlock @@ -29,21 +29,30 @@ Landlock rules ============== -A Landlock rule describes an action on an object which the process intends to -perform. A set of rules is aggregated in a ruleset, which can then restrict -the thread enforcing it, and its future children. +A Landlock rule describes the actions a process is allowed to perform on a +specific resource. A set of rules is aggregated in a ruleset, which can then +restrict the thread enforcing it, and its future children. -The two existing types of rules are: +The existing types of rules are: Filesystem rules - For these rules, the object is a file hierarchy, - and the related filesystem actions are defined with - `filesystem access rights`. + The rule key is a file hierarchy, and the actions it allows are + defined with `filesystem access rights`. Network rules (since ABI v4 for TCP and v10 for UDP) For these rules, the object is a TCP or UDP port, and the related actions are defined with `network access rights`. +Capability rules (since ABI v12) + The rule body lists which Linux capabilities (see + :manpage:`capabilities(7)`) the process may exercise; the action is + defined with `permission flags`. + +Namespace rules (since ABI v12) + The rule body lists which namespace types (see + :manpage:`namespaces(7)`) the process may use; the action is defined + with `permission flags`. + Defining and enforcing a security policy ---------------------------------------- @@ -87,6 +96,9 @@ .scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET | LANDLOCK_SCOPE_SIGNAL, + .handled_permissions = + LANDLOCK_PERMISSION_NAMESPACE_USE | + LANDLOCK_PERMISSION_CAPABILITY_USE, }; Because we may not know which kernel version an application will be executed @@ -140,6 +152,13 @@ ruleset_attr.handled_access_net &= ~(LANDLOCK_ACCESS_NET_BIND_UDP | LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP); + __attribute__((fallthrough)); + case 10: + case 11: + /* Removes LANDLOCK_PERMISSION_* for ABI < 12 */ + ruleset_attr.handled_permissions &= + ~(LANDLOCK_PERMISSION_NAMESPACE_USE | + LANDLOCK_PERMISSION_CAPABILITY_USE); } This enables the creation of an inclusive ruleset that will contain our rules. @@ -242,6 +261,56 @@ err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, &udp_bind, 0); +Capability and namespace rules use a different attribute layout: +``permissions`` identifies the permission category (a single +``LANDLOCK_PERMISSION_*`` flag) and a type-specific value field carries the +bitmask to allow within it. See `Capability and namespace restrictions`_ for +the model. + +For capability access-control, we can add rules that allow specific +capabilities (see :manpage:`capabilities(7)` for the list of ``CAP_*`` +values). For instance, to allow ``CAP_SYS_CHROOT`` (so the sandboxed +process can call :manpage:`chroot(2)` inside a user namespace): + +.. code-block:: c + + struct landlock_capability_attr cap_attr = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + .allowed_capabilities = (1ULL << CAP_SYS_CHROOT), + }; + + cap_attr.permissions &= ruleset_attr.handled_permissions; + if (cap_attr.permissions) + err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &cap_attr, 0); + +For namespace access-control, we can add rules that allow using specific +namespace types (see :manpage:`namespaces(7)` for the list of ``CLONE_NEW*`` +values): creating them via :manpage:`unshare(2)` / :manpage:`clone(2)` / +:manpage:`clone3(2)`, joining them via :manpage:`setns(2)`, or acquiring an fd +reference via :manpage:`open_tree(2)` / :manpage:`fsmount(2)`. For instance, +to allow creating user namespaces (which grants all capabilities inside the new +namespace): + +.. code-block:: c + + struct landlock_namespace_attr ns_attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + .allowed_namespace_types = CLONE_NEWUSER, + }; + + ns_attr.permissions &= ruleset_attr.handled_permissions; + if (ns_attr.permissions) + err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &ns_attr, 0); + +Together, these two rules allow an unprivileged process to create a user +namespace and call :manpage:`chroot(2)` inside it, while denying all other +capabilities and namespace types. User namespace creation is the one operation +that does not require ``CAP_SYS_ADMIN``, so no capability rule is needed for it. +See `Capability and namespace restrictions`_ for details on capability +requirements. + When passing a non-zero ``flags`` argument to ``landlock_restrict_self()``, a similar backwards compatibility check is needed for the restrict flags (see sys_landlock_restrict_self() documentation for available flags): @@ -442,9 +511,139 @@ A :manpage:`sendto(2)` on a socket which was previously connected will not be restricted. This works for both datagram and stream sockets. -IPC scoping does not support exceptions via :manpage:`landlock_add_rule(2)`. -If an operation is scoped within a domain, no rules can be added to allow access -to resources or processes outside of the scope. +Scoping does not support exceptions via :manpage:`landlock_add_rule(2)`. If an +operation is scoped within a domain, no rules can be added to allow access to +resources or processes outside of the scope. + +Capability and namespace restrictions +------------------------------------- + +``handled_permissions`` declares per-category permissions: each permission +selects which members of a kernel-defined category (CAP_* capabilities, +CLONE_NEW* namespace types) the process may use. Unlike per-object access +rights (``handled_access_*``) or cross-domain scopes (``scoped``), per-category +permissions constrain the sandboxed process's own use of these enums; members +not allowed by a rule are denied by default. + +``LANDLOCK_PERMISSION_NAMESPACE_USE`` gates *acquisition of access* to +namespaces: creation via :manpage:`unshare(2)` / :manpage:`clone(2)` +/ :manpage:`clone3(2)`, entry via :manpage:`setns(2)`, and fd-reference +acquisition via :manpage:`open_tree(2)` / :manpage:`fsmount(2)`. Namespaces +the process is already a member of when the domain is enforced are implicitly +allowed (the process could not continue running otherwise); rules describe +which new namespace types the process may acquire. +``LANDLOCK_PERMISSION_CAPABILITY_USE`` gates every exercise of a capability +after the domain is enforced, regardless +of how the capability was obtained (inherited credentials, ``CLONE_NEWUSER`` +grant, ``setuid``/file-cap-bearing :manpage:`execve(2)`, etc.). Configuring +both together restricts what privileges are available *and* the namespaces in +which they take effect, which matters because user namespace creation has no +capability check and grants all capabilities within the new namespace: gating +only one of the two leaves a kernel attack-surface widening path open. When a +domain handles both permissions, an operation is allowed only if each +independently allows it: :manpage:`unshare(2)` with ``CLONE_NEWNET`` then +requires both a rule allowing ``CLONE_NEWNET`` and a rule allowing +``CAP_SYS_ADMIN``. + +``LANDLOCK_PERMISSION_CAPABILITY_USE`` complements :manpage:`prctl(2)` +``PR_SET_NO_NEW_PRIVS`` but does not replace it. ``PR_SET_NO_NEW_PRIVS`` +prevents privilege *acquisition* via :manpage:`execve(2)` (setuid, file +capability xattrs, privilege-elevating LSM transitions) and is a prerequisite +for unprivileged Landlock self-sandboxing. +``LANDLOCK_PERMISSION_CAPABILITY_USE`` restricts *exercise* of capabilities the +process already holds, including those +gained via ``CLONE_NEWUSER`` which ``PR_SET_NO_NEW_PRIVS`` does not block. +Sandboxes typically set both. + +Rules are added with ``LANDLOCK_RULE_CAPABILITY`` and &struct +landlock_capability_attr (each rule lists ``CAP_*`` values to allow), and with +``LANDLOCK_RULE_NAMESPACE`` and &struct landlock_namespace_attr (each rule +lists ``CLONE_NEW*`` flags to allow). Landlock is purely restrictive: it can +only deny what the traditional check would have allowed, never grant additional +privileges. + +Denials of specific capabilities or namespace types can be excluded from audit +logging per rule, by listing them in the ``quiet_capabilities`` or +``quiet_namespace_types`` field of the rule (independently of the allowed +members). Quieting requires the permission to be handled, is member-granular, +and only suppresses the audit record of a denial attributed to the rule's own +layer; it never changes the denial itself or suppresses its trace event, which +reports ``logged=0``. Sandboxes should quiet only specific members known to be +requested but expected to be denied (for example for compatibility with older +callers), never a blanket set: a blanket set follows the running kernel's known +members and would hide surprising or future denials from audit. + +Rule bodies silently accept values unknown to the current kernel (capabilities +above ``CAP_LAST_CAP``, unrecognised ``CLONE_NEW*`` bits): they have no runtime +effect, so a rule compiled against future kernel headers loads without error on +older kernels. Future kernels gain new members denied by default until a rule +explicitly allows them. + +The single ``LANDLOCK_PERMISSION_NAMESPACE_USE`` bit gates every kernel path +that grants the calling process access to a namespace of the controlled types, +whether by becoming a member of the namespace or by holding a file descriptor +that references it. The covered syscall paths are: + +* :manpage:`unshare(2)` with ``CLONE_NEW*``: the caller becomes a member of a + newly-created namespace. +* :manpage:`clone(2)` (or :manpage:`clone3(2)`) with ``CLONE_NEW*``: the + child becomes a member of a newly-created namespace. +* :manpage:`setns(2)`: the caller becomes a member of an existing namespace + referenced by file descriptor. +* :manpage:`open_tree(2)` with ``OPEN_TREE_NAMESPACE``: the caller obtains a + file descriptor referring to a newly-created mount namespace. +* :manpage:`open_tree(2)` with ``OPEN_TREE_CLONE``: the caller obtains a file + descriptor referring to a newly-created anonymous mount namespace. +* :manpage:`fsmount(2)` with ``FSMOUNT_NAMESPACE``: the caller obtains a file + descriptor referring to a newly-created mount namespace. +* :manpage:`fsmount(2)` (default): the caller obtains a file descriptor + referring to a newly-created anonymous mount namespace. + +Anonymous mount namespaces (created by ``open_tree(OPEN_TREE_CLONE)`` and the +default :manpage:`fsmount(2)`) are intentionally covered by the bit even though +the calling process does not become a member of them. Without this coverage, a +sandboxed process could combine ``open_tree(OPEN_TREE_CLONE)`` with +:manpage:`move_mount(2)` to graft mounts from a freshly-allocated mount +namespace into its current namespace, bypassing a ``CLONE_NEWNS`` restriction +(these mount operations require ``CAP_SYS_ADMIN``, which a sandboxed process +typically obtains by first creating a user namespace). + +In practice, unprivileged processes first create a user namespace (which +requires no capability and grants all capabilities within it), then use those +capabilities to create other namespace types. All non-user namespace types +require ``CAP_SYS_ADMIN`` for both creation and :manpage:`setns(2)` entry; mount +namespace entry additionally requires ``CAP_SYS_CHROOT``. For +:manpage:`setns(2)`, capabilities are checked relative to the target namespace, +so a process in an ancestor user namespace naturally satisfies them; this +includes joining user namespaces, which requires ``CAP_SYS_ADMIN``. When +``LANDLOCK_PERMISSION_CAPABILITY_USE`` is also handled, each of these +capabilities must be explicitly allowed by a rule. + +Creating a non-user namespace always requires ``CAP_SYS_ADMIN``, and +``LANDLOCK_PERMISSION_CAPABILITY_USE`` (when handled) gates that check +regardless of which user namespace it targets. This is true whether the +namespace is created +on its own, combined with ``CLONE_NEWUSER`` in a single :manpage:`unshare(2)` +call, or in a separate :manpage:`unshare(2)` call after a user namespace: in +all cases the kernel checks ``CAP_SYS_ADMIN`` against the owning user +namespace, and Landlock denies it unless a rule allows +``CAP_SYS_ADMIN``. Combining ``CLONE_NEWUSER`` with another ``CLONE_NEW*`` +flag therefore does not avoid the capability check; only user namespace +creation itself needs no capability rule. + +When creating child user namespaces, it is recommended to also create a +dedicated Landlock domain with restrictions relevant to each namespace context. + +Note that ``LANDLOCK_PERMISSION_CAPABILITY_USE`` restricts the *use* of +capabilities, not their presence in the process's credential. Capability sets +can change +after a domain is enforced through user namespace entry or :manpage:`capset(2)`; +privileged sandboxes that did not set ``PR_SET_NO_NEW_PRIVS`` may also gain +capabilities through :manpage:`execve(2)` of binaries with file capabilities. +In all cases, :manpage:`capget(2)` will report the credential's capability sets, +but any denied capability will fail with ``EPERM`` when exercised. Do not rely +on :manpage:`capget(2)` to determine whether the policy permits a given +capability; only the actual operation will return ``EPERM`` upon denial. Truncating files ---------------- @@ -610,7 +809,7 @@ ------------- .. kernel-doc:: include/uapi/linux/landlock.h - :identifiers: fs_access net_access scope + :identifiers: fs_access net_access scope permission Creating a new ruleset ---------------------- @@ -629,7 +828,8 @@ .. kernel-doc:: include/uapi/linux/landlock.h :identifiers: landlock_rule_type landlock_path_beneath_attr - landlock_net_port_attr + landlock_net_port_attr landlock_capability_attr + landlock_namespace_attr Enforcing a ruleset ------------------- @@ -834,6 +1034,23 @@ of the process. As explained in the tutorial above, leaving no_new_privs unset is risky even when Landlock does not require it. +Capability (ABI < 12) +--------------------- + +Starting with the Landlock ABI version 12, it is possible to restrict +:manpage:`capabilities(7)` with the new ``LANDLOCK_PERMISSION_CAPABILITY_USE`` +permission flag and ``LANDLOCK_RULE_CAPABILITY`` rule type. + +Namespace (ABI < 12) +-------------------- + +Starting with the Landlock ABI version 12, it is possible to restrict namespace +use (see :manpage:`namespaces(7)`) across creation (:manpage:`unshare(2)`, +:manpage:`clone(2)`, :manpage:`clone3(2)`), entry (:manpage:`setns(2)`), and +fd-reference acquisition (:manpage:`open_tree(2)`, :manpage:`fsmount(2)`) with +the new ``LANDLOCK_PERMISSION_NAMESPACE_USE`` permission flag and +``LANDLOCK_RULE_NAMESPACE`` rule type. + .. _kernel_support: Kernel support
diff --git a/Documentation/virt/index.rst b/Documentation/virt/index.rst index c1f0bbc..142134e 100644 --- a/Documentation/virt/index.rst +++ b/Documentation/virt/index.rst
@@ -9,6 +9,7 @@ kvm/index uml/user_mode_linux_howto_v2 + uml/nommu-uml paravirt_ops guest-halt-polling ne_overview
diff --git a/Documentation/virt/uml/nommu-uml.rst b/Documentation/virt/uml/nommu-uml.rst new file mode 100644 index 0000000..105e596 --- /dev/null +++ b/Documentation/virt/uml/nommu-uml.rst
@@ -0,0 +1,54 @@ +.. SPDX-License-Identifier: GPL-2.0 + +.. contents:: :local: + +Execution model +=============== + +When emulating a system with an MMU, UML gives every ``mm_struct`` its own +host process with its own host address space, and keeps that address space +in sync with the kernel's page tables by issuing ``mmap()``/``munmap()`` +into it. + +NOMMU has no per-process address spaces: there is a single "physical" address +space that the kernel and every userspace process share. UML models this with +a **userspace runner** - an ordinary uml-userspace stub host process, started +exactly like an MMU userspace process, but with the whole of "physical" memory +(the physmem file) mapped into it at the kernel's addresses: + +- The runner ``exec()``'s the stub just like the MMU case. The only extra step + is that, once it is up, the kernel maps the entire physmem file into it in one + go, at the same addresses the kernel uses. +- Because NOMMU never remaps, that single mapping is all a runner ever needs: + there is no per-mm host process, no TLB sync and no ``mmap()`` of individual + page-table entries into a child. Userspace code and data - placed in memory + by the loader - are directly executable and accessible. +- The runner processes hold no per-task state: the kernel loads a task's state + on every entry, so there's just one process per CPU. + +Running a task's userspace therefore only means pointing a runner at that +task's code and letting it run until the next syscall or signal + +Building and running +==================== + +Configure and build the ARCH=um kernel normally, but deselect CONFIG_MMU. + +KUnit tests can be run in NOMMU mode with:: + + ./tools/testing/kunit/kunit.py run \ + --kconfig_add CONFIG_MMU=n --kconfig_add CONFIG_KUNIT_UML_PCI=n + +Running a normal userspace requires NOMMU-aware binaries. There is no stock +x86_64 NOMMU distribution, but a prebuilt Alpine image with musl-libc and +busybox built for NOMMU is available and can be turned into a root image:: + + cid=$(docker create ghcr.io/thehajime/alpine:3.20.3-um-nommu) + docker export "$cid" > alpine.tar + docker rm "$cid" + mkdir alpine-root && tar xf alpine.tar -C alpine-root + mke2fs -q -F -t ext4 -d alpine-root alpine.ext4 1200M + +Then boot it:: + + ./linux ubd0=./alpine.ext4 root=/dev/ubda rw mem=1024m init=/sbin/init
diff --git a/Documentation/watchdog/watchdog-parameters.rst b/Documentation/watchdog/watchdog-parameters.rst index 502cb6a..348229f 100644 --- a/Documentation/watchdog/watchdog-parameters.rst +++ b/Documentation/watchdog/watchdog-parameters.rst
@@ -515,6 +515,8 @@ nowayout: Watchdog cannot be stopped once started (default=kernel config parameter) + early_enable: + Watchdog is started on module insertion (default=0) -------------------------------------------------
diff --git a/MAINTAINERS b/MAINTAINERS index 0e9fe9c..f802c67 100644 --- a/MAINTAINERS +++ b/MAINTAINERS
@@ -1088,7 +1088,6 @@ AMD CRYPTOGRAPHIC COPROCESSOR (CCP) DRIVER M: Tom Lendacky <thomas.lendacky@amd.com> -M: John Allen <john.allen@amd.com> L: linux-crypto@vger.kernel.org S: Supported F: drivers/crypto/ccp/ @@ -1333,6 +1332,7 @@ M: Basavaraj Natikar <basavaraj.natikar@amd.com> L: linux-input@vger.kernel.org S: Maintained +F: Documentation/ABI/testing/sysfs-driver-amd-sfh F: Documentation/hid/amd-sfh* F: drivers/hid/amd-sfh-hid/ F: drivers/input/misc/amd_sfh_tabletmode.c @@ -3283,6 +3283,7 @@ F: Documentation/devicetree/bindings/arm/ux500/ F: Documentation/devicetree/bindings/gpio/st,nomadik-gpio.yaml F: Documentation/devicetree/bindings/i2c/st,nomadik-i2c.yaml +F: Documentation/devicetree/bindings/power/stericsson,ux500-pm-domains.yaml F: arch/arm/boot/dts/st/ste-* F: arch/arm/mach-nomadik/ F: arch/arm/mach-ux500/ @@ -3442,6 +3443,7 @@ ARM/QUALCOMM SUPPORT M: Bjorn Andersson <andersson@kernel.org> M: Konrad Dybcio <konradybcio@kernel.org> +R: Abel Vesa <abelvesa@kernel.org> L: linux-arm-msm@vger.kernel.org S: Maintained C: irc://irc.oftc.net/linux-msm @@ -3636,7 +3638,6 @@ F: arch/arm/configs/socfpga_defconfig F: arch/arm/mach-socfpga/ F: arch/arm64/boot/dts/altera/ -F: arch/arm64/boot/dts/intel/ ARM/SOCFPGA CLOCK FRAMEWORK SUPPORT M: Dinh Nguyen <dinguyen@kernel.org> @@ -3799,6 +3800,7 @@ M: Tero Kristo <kristo@kernel.org> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) S: Supported +T: git git://git.kernel.org/pub/scm/linux/kernel/git/ti/linux.git F: Documentation/devicetree/bindings/arm/ti/k3.yaml F: Documentation/devicetree/bindings/hwinfo/ti,k3-socinfo.yaml F: arch/arm64/boot/dts/ti/Makefile @@ -3816,7 +3818,7 @@ ARM/TOSHIBA VISCONTI ARCHITECTURE M: Nobuhiro Iwamatsu <nobuhiro.iwamatsu.x90@mail.toshiba> L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) -S: Supported +S: Odd Fixes T: git git://git.kernel.org/pub/scm/linux/kernel/git/iwamatsu/linux-visconti.git F: Documentation/devicetree/bindings/arm/toshiba.yaml F: Documentation/devicetree/bindings/clock/toshiba,tmpv770x-pipllct.yaml @@ -4455,6 +4457,15 @@ F: Documentation/devicetree/bindings/sound/axentia,* F: sound/soc/atmel/tse850-pcm5142.c +AXIADO SGPIO DRIVER +M: Petar Stepanovic <pstepanovic@axiado.com> +M: SriNavmani A <srinavmani@axiado.com> +M: Prasad Bolisetty <pbolisetty@axiado.com> +L: linux-gpio@vger.kernel.org +S: Supported +F: Documentation/devicetree/bindings/gpio/axiado,ax3005-sgpio.yaml +F: drivers/gpio/gpio-axiado-sgpio.c + AXIS ARTPEC ARM64 SoC SUPPORT M: Jesper Nilsson <jesper.nilsson@axis.com> M: Lars Persson <lars.persson@axis.com> @@ -7590,11 +7601,12 @@ DH ELECTRONICS DHSOM SOM AND BOARD SUPPORT M: Christoph Niedermaier <cniedermaier@dh-electronics.com> -M: Marek Vasut <marex@denx.de> +M: Marek Vasut <marex@nabladev.com> L: kernel@dh-electronics.com S: Maintained N: dhcom N: dhcor +N: dhcos N: dhsom DIALOG SEMICONDUCTOR DRIVERS @@ -10407,7 +10419,7 @@ FREESCALE CAAM (Cryptographic Acceleration and Assurance Module) DRIVER M: Horia Geantă <horia.geanta@nxp.com> M: Pankaj Gupta <pankaj.gupta@nxp.com> -M: Gaurav Jain <gaurav.jain@nxp.com> +M: Sahil Malhotra <sahil.malhotra@nxp.com> L: linux-crypto@vger.kernel.org S: Maintained F: Documentation/devicetree/bindings/crypto/fsl,sec-v4.0* @@ -11209,6 +11221,7 @@ F: Documentation/devicetree/bindings/soc/google/google,gs101-pmu-intr-gen.yaml F: Documentation/devicetree/bindings/usb/google,lga-dwc3.yaml F: arch/arm64/boot/dts/exynos/google/ +F: arch/arm64/boot/dts/google/ F: drivers/clk/samsung/clk-gs101.c F: drivers/phy/phy-google-usb.c F: drivers/soc/samsung/gs101-pmu.c @@ -11686,6 +11699,12 @@ S: Supported F: drivers/hid/hid-playstation.c +HID PULSAR DRIVER +M: Nikolas Koesling <nikolas@koesling.info> +L: linux-input@vger.kernel.org +S: Maintained +F: drivers/hid/hid-pulsar.c + HID SENSOR HUB DRIVERS M: Jiri Kosina <jikos@kernel.org> M: Jonathan Cameron <jic23@kernel.org> @@ -12503,6 +12522,7 @@ F: drivers/crypto/nx/nx-842* F: include/linux/sw842.h F: lib/842/ +F: lib/tests/842_decompress_kunit.c IBM Power in-Nest Crypto Acceleration M: Breno Leitão <leitao@debian.org> @@ -14535,7 +14555,7 @@ F: include/keys/trusted_dcp.h F: security/keys/trusted-keys/trusted_dcp.c -KEYS-TRUSTED-PLPKS +KEYS-TRUSTED-PKWM M: Srish Srinivasan <ssrish@linux.ibm.com> M: Nayna Jain <nayna@linux.ibm.com> L: linux-integrity@vger.kernel.org @@ -18433,6 +18453,12 @@ F: tools/testing/selftests/kmod/ F: tools/testing/selftests/module/ +MONOLITHIC POWER SYSTEM MPQ4210 REGULATOR DRIVER +M: Tapio Reijonen <tapio.reijonen@vaisala.com> +S: Maintained +F: Documentation/devicetree/bindings/regulator/mps,mpq4210.yaml +F: drivers/regulator/mpq4210.c + MONOLITHIC POWER SYSTEM PMIC DRIVER M: Saravanan Sekar <sravanhome@gmail.com> S: Maintained @@ -19434,6 +19460,7 @@ NINTENDO HID DRIVER M: Daniel J. Ogorchock <djogorchock@gmail.com> +M: Vicki Pfau <vi@endrift.com> L: linux-input@vger.kernel.org S: Maintained F: drivers/hid/hid-nintendo* @@ -19506,6 +19533,13 @@ F: tools/include/nolibc/ F: tools/testing/selftests/nolibc/ +NOVATEK NT72676 I2C CONTROLLER DRIVER +M: Ben Huang <ben_huang@novatek.com.tw> +L: linux-i2c@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/i2c/novatek,nt72676-i2c.yaml +F: drivers/i2c/busses/i2c-nt72676.c + NOVATEK NVT-TS I2C TOUCHSCREEN DRIVER M: Hans de Goede <hansg@kernel.org> L: linux-input@vger.kernel.org @@ -22548,6 +22582,15 @@ F: Documentation/devicetree/bindings/i2c/qcom,i2c-cci.yaml F: drivers/i2c/busses/i2c-qcom-cci.c +QUALCOMM INLINE CRYPTO ENGINE DRIVER +M: Abel Vesa <abelvesa@kernel.org> +L: linux-arm-msm@vger.kernel.org +L: linux-crypto@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/crypto/qcom,inline-crypto-engine.yaml +F: drivers/soc/qcom/ice.c +F: include/soc/qcom/ice.h + QUALCOMM INTERCONNECT BWMON DRIVER M: Krzysztof Kozlowski <krzk@kernel.org> L: linux-arm-msm@vger.kernel.org @@ -23076,6 +23119,12 @@ F: Documentation/devicetree/bindings/spi/realtek,rtl9301-snand.yaml F: drivers/spi/spi-realtek-rtl-snand.c +REALTEK SPI-NOR +M: Jyan Chou <jyanchou@realtek.com> +M: Yu-Chun Lin <eleanor.lin@realtek.com> +S: Supported +F: drivers/spi/spi-rtk-nor.c + REALTEK SYSTIMER DRIVER M: Hao-Wen Ting <haowen.ting@realtek.com> S: Maintained @@ -23579,7 +23628,8 @@ RISC-V MICROCHIP SUPPORT M: Conor Dooley <conor.dooley@microchip.com> -M: Daire McNamara <daire.mcnamara@microchip.com> +R: Valentina Fernandez <valentina.fernandezalanis@microchip.com> +R: Daire McNamara <daire.mcnamara@microchip.com> L: linux-riscv@lists.infradead.org S: Supported T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ (dts, soc, firmware) @@ -23659,8 +23709,17 @@ F: drivers/mailbox/riscv-sbi-mpxy-mbox.c F: include/linux/mailbox/riscv-rpmi-message.h +RISC-V RPMI DEVICE POWER DRIVER +M: Joshua Yeong <joshua.yeong@starfivetech.com> +L: linux-riscv@lists.infradead.org +S: Maintained +F: Documentation/devicetree/bindings/power/riscv,rpmi-device-power.yaml +F: Documentation/devicetree/bindings/power/riscv,rpmi-mpxy-device-power.yaml +F: drivers/pmdomain/riscv/ + RISC-V SPACEMIT SoC Support M: Yixun Lan <dlan@kernel.org> +R: Troy Mitchell <troy.mitchell@linux.spacemit.com> L: linux-riscv@lists.infradead.org L: spacemit@lists.linux.dev S: Maintained @@ -23691,7 +23750,7 @@ L: linux-riscv@lists.infradead.org S: Maintained Q: https://patchwork.kernel.org/project/riscv-thead/list/ -T: git https://github.com/pdp7/linux.git +T: git https://git.kernel.org/pub/scm/linux/kernel/git/fustini/linux.git F: Documentation/devicetree/bindings/clock/thead,th1520-clk-ap.yaml F: Documentation/devicetree/bindings/firmware/thead,th1520-aon.yaml F: Documentation/devicetree/bindings/mailbox/thead,th1520-mbox.yaml @@ -23893,6 +23952,7 @@ F: drivers/gpio/gpio-bd71815.c F: drivers/gpio/gpio-bd71828.c F: drivers/gpio/gpio-bd72720.c +F: drivers/gpio/gpio-bd73800.c F: drivers/mfd/rohm-bd71828.c F: drivers/mfd/rohm-bd718x7.c F: drivers/mfd/rohm-bd9576.c @@ -23912,6 +23972,7 @@ F: include/linux/mfd/rohm-bd71828.h F: include/linux/mfd/rohm-bd718x7.h F: include/linux/mfd/rohm-bd72720.h +F: include/linux/mfd/rohm-bd73800.h F: include/linux/mfd/rohm-bd957x.h F: include/linux/mfd/rohm-bd96801.h F: include/linux/mfd/rohm-bd96802.h @@ -24784,6 +24845,13 @@ S: Maintained F: drivers/mmc/host/sdhci-brcmstb* +SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) CADENCE DRIVER +M: Tanmay Kathpalia <tanmay.kathpalia@altera.com> +L: linux-mmc@vger.kernel.org +S: Supported +F: Documentation/devicetree/bindings/mmc/cdns,sd6hc.yaml +F: drivers/mmc/host/sdhci-cadence* + SECURE DIGITAL HOST CONTROLLER INTERFACE (SDHCI) DRIVER M: Adrian Hunter <adrian.hunter@intel.com> L: linux-mmc@vger.kernel.org @@ -25822,6 +25890,14 @@ F: Documentation/devicetree/bindings/sound/spacemit,k1-i2s.yaml F: sound/soc/spacemit/k1_i2s.c +SPACEMIT RESET CONTROLLER DRIVER +M: Guodong Xu <docular.xu@gmail.com> +L: linux-riscv@lists.infradead.org +L: spacemit@lists.linux.dev +S: Maintained +F: drivers/reset/spacemit/ +F: include/dt-bindings/reset/spacemit,k3-resets.h + SPANISH DOCUMENTATION M: Carlos Bilbao <carlos.bilbao@kernel.org> R: Avadhut Naik <avadhut.naik@amd.com> @@ -26708,6 +26784,7 @@ F: drivers/powercap/arm_scmi_powercap.c F: drivers/regulator/scmi-regulator.c F: drivers/reset/reset-scmi.c +F: include/linux/device-id/scmi.h F: include/linux/sc[mp]i_protocol.h F: include/trace/events/scmi.h F: include/uapi/linux/virtio_scmi.h @@ -27883,7 +27960,10 @@ F: Documentation/devicetree/bindings/trigger-source/* TRUSTED EXECUTION ENVIRONMENT SECURITY MANAGER (TSM) -M: Dan Williams <djbw@kernel.org> +M: Alexey Kardashevskiy <aik@amd.com> +M: Aneesh Kumar K.V <aneesh.kumar@kernel.org> +M: Jason Gunthorpe <jgg@nvidia.com> +R: Lukas Wunner <lukas@wunner.de> L: linux-coco@lists.linux.dev S: Maintained F: Documentation/ABI/testing/configfs-tsm-report @@ -29394,11 +29474,6 @@ S: Maintained F: drivers/hwmon/vt8231.c -VUB300 USB to SDIO/SD/MMC bridge chip -L: linux-mmc@vger.kernel.org -S: Orphan -F: drivers/mmc/host/vub300.c - W1 DALLAS'S 1-WIRE BUS M: Krzysztof Kozlowski <krzk@kernel.org> S: Maintained
diff --git a/arch/alpha/include/asm/sfp-machine.h b/arch/alpha/include/asm/sfp-machine.h index 5fe63af..bff1ad9 100644 --- a/arch/alpha/include/asm/sfp-machine.h +++ b/arch/alpha/include/asm/sfp-machine.h
@@ -59,6 +59,10 @@ R##_c = FP_CLS_NAN; \ } while (0) +/* Alpha determines tininess after rounding, so the emulation must do the + same as the hardware does for the results it produces itself. */ +#define _FP_TININESS_AFTER_ROUNDING 1 + /* Obtain the current rounding mode. */ #define FP_ROUNDMODE mode #define FP_RND_NEAREST (FPCR_DYN_NORMAL >> FPCR_DYN_SHIFT)
diff --git a/arch/arm/boot/compressed/Makefile b/arch/arm/boot/compressed/Makefile index 5f0a1a2..777b035 100644 --- a/arch/arm/boot/compressed/Makefile +++ b/arch/arm/boot/compressed/Makefile
@@ -41,14 +41,6 @@ OBJS += head-sharpsl.o endif -ifeq ($(CONFIG_CPU_ENDIAN_BE32),y) -ifeq ($(CONFIG_CPU_CP15),y) -OBJS += big-endian.o -else -# The endian should be set by h/w design. -endif -endif - # # We now have a PIC decompressor implementation. Decompressors running # from RAM should not define ZTEXTADDR. Decompressors running directly
diff --git a/arch/arm/boot/compressed/big-endian.S b/arch/arm/boot/compressed/big-endian.S deleted file mode 100644 index 0e092c3..0000000 --- a/arch/arm/boot/compressed/big-endian.S +++ /dev/null
@@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* - * linux/arch/arm/boot/compressed/big-endian.S - * - * Switch CPU into big endian mode. - * Author: Nicolas Pitre - */ - - .section ".start", "ax" - - mrc p15, 0, r0, c1, c0, 0 @ read control reg - orr r0, r0, #(1 << 7) @ enable big endian mode - mcr p15, 0, r0, c1, c0, 0 @ write control reg -
diff --git a/arch/arm/boot/compressed/head-xscale.S b/arch/arm/boot/compressed/head-xscale.S index 20fa44d5..d6c3d0a 100644 --- a/arch/arm/boot/compressed/head-xscale.S +++ b/arch/arm/boot/compressed/head-xscale.S
@@ -7,6 +7,7 @@ */ #include <linux/linkage.h> +#include <asm/cp15.h> .section ".start", "ax" @@ -14,6 +15,23 @@ @ Preserve r8/r7 i.e. kernel entry values + @ set correct endianness for ixp4xx regardless of bootloader + mrc p15, 0, r0, c1, c0, 0 +#ifdef CONFIG_CPU_BIG_ENDIAN + orr r0, r0, #CR_B @ enable big endian mode +#else + bic r0, r0, #CR_B +#endif + mcr p15, 0, r0, c1, c0, 0 +0: mrc p15, 0, r0, c1, c0, 0 + tst r0, #0x80 +#ifdef CONFIG_CPU_BIG_ENDIAN + beq 0b +#else + bne 0b +#endif + sub pc, pc, #4 @ flush instruction pipeline + @ Data cache might be active. @ Be sure to flush kernel binary out of the cache, @ whatever state it is, before it is turned off.
diff --git a/arch/arm/boot/dts/actions/owl-s500.dtsi b/arch/arm/boot/dts/actions/owl-s500.dtsi index 739b4b9..f921654 100644 --- a/arch/arm/boot/dts/actions/owl-s500.dtsi +++ b/arch/arm/boot/dts/actions/owl-s500.dtsi
@@ -61,9 +61,9 @@ cpu3: cpu@3 { arm-pmu { compatible = "arm,cortex-a9-pmu"; interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; }; @@ -247,9 +247,9 @@ timer: timer@b0168000 { compatible = "actions,s500-timer"; reg = <0xb0168000 0x8000>; interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "2hz0", "2hz1", "timer0", "timer1"; };
diff --git a/arch/arm/boot/dts/allwinner/sun7i-a20.dtsi b/arch/arm/boot/dts/allwinner/sun7i-a20.dtsi index 5f44f09..adb9ee5 100644 --- a/arch/arm/boot/dts/allwinner/sun7i-a20.dtsi +++ b/arch/arm/boot/dts/allwinner/sun7i-a20.dtsi
@@ -873,7 +873,7 @@ gmac_mii_pins: gmac-mii-pins { gmac_rgmii_pins: gmac-rgmii-pins { pins = "PA0", "PA1", "PA2", "PA3", "PA4", "PA5", "PA6", - "PA7", "PA8", "PA10", + "PA7", "PA8", "PA10", "PA11", "PA12", "PA13", "PA15", "PA16"; function = "gmac";
diff --git a/arch/arm/boot/dts/arm/vexpress-v2p-ca5s.dts b/arch/arm/boot/dts/arm/vexpress-v2p-ca5s.dts index e389625..41a98ba 100644 --- a/arch/arm/boot/dts/arm/vexpress-v2p-ca5s.dts +++ b/arch/arm/boot/dts/arm/vexpress-v2p-ca5s.dts
@@ -106,7 +106,7 @@ timer@2c000600 { timer@2c000200 { compatible = "arm,cortex-a5-global-timer", - "arm,cortex-a9-global-timer"; + "arm,cortex-a9-global-timer"; reg = <0x2c000200 0x20>; interrupts = <1 11 0x304>; clocks = <&cpu_clk>;
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-witherspoon.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-witherspoon.dts index 89907b6..d235ebc 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-witherspoon.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-opp-witherspoon.dts
@@ -213,7 +213,7 @@ &gpio { /*L0-L7*/ "","","","","","","","", /*M0-M7*/ "","","","","","","","", /*N0-N7*/ "presence-ps1","","led-rear-fault","led-rear-power", - "led-rear-id","","","", + "led-rear-id","","","", /*O0-O7*/ "","","","","","","","", /*P0-P7*/ "","","","","","","","presence-ps0", /*Q0-Q7*/ "","","","","","","","",
diff --git a/arch/arm/boot/dts/aspeed/aspeed-bmc-supermicro-x11spi.dts b/arch/arm/boot/dts/aspeed/aspeed-bmc-supermicro-x11spi.dts index b961dff..154a2ea 100644 --- a/arch/arm/boot/dts/aspeed/aspeed-bmc-supermicro-x11spi.dts +++ b/arch/arm/boot/dts/aspeed/aspeed-bmc-supermicro-x11spi.dts
@@ -75,7 +75,7 @@ &mac0 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_rmii1_default>; clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>, - <&syscon ASPEED_CLK_MAC1RCLK>; + <&syscon ASPEED_CLK_MAC1RCLK>; clock-names = "MACCLK", "RCLK"; use-ncsi; };
diff --git a/arch/arm/boot/dts/gemini/gemini.dtsi b/arch/arm/boot/dts/gemini/gemini.dtsi index 23e68e1..5714302 100644 --- a/arch/arm/boot/dts/gemini/gemini.dtsi +++ b/arch/arm/boot/dts/gemini/gemini.dtsi
@@ -245,7 +245,7 @@ spi@4a000000 { status = "disabled"; }; - power-controller@4b000000 { + poweroff@4b000000 { compatible = "cortina,gemini-power-controller"; reg = <0x4b000000 0x100>; interrupts = <26 IRQ_TYPE_EDGE_RISING>; @@ -445,7 +445,7 @@ dma-controller@67000000 { display-controller@6a000000 { compatible = "cortina,gemini-tvc", "faraday,tve200"; reg = <0x6a000000 0x1000>; - interrupts = <13 IRQ_TYPE_EDGE_RISING>; + interrupts = <13 IRQ_TYPE_LEVEL_HIGH>; resets = <&syscon GEMINI_RESET_TVC>; clocks = <&syscon GEMINI_CLK_GATE_TVC>, <&syscon GEMINI_CLK_TVC>;
diff --git a/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr.dtsi b/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr.dtsi index 7aa71a9..16e9a25 100644 --- a/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr.dtsi +++ b/arch/arm/boot/dts/marvell/armada-385-clearfog-gtr.dtsi
@@ -235,7 +235,7 @@ sdhci@d8000 { pinctrl-0 = <&cf_gtr_sdhci_pins>; pinctrl-names = "default"; status = "okay"; - vmmc = <®_3p3v>; + vmmc-supply = <®_3p3v>; wp-inverted; };
diff --git a/arch/arm/boot/dts/marvell/armada-388-helios4.dts b/arch/arm/boot/dts/marvell/armada-388-helios4.dts index 003b070..78268833 100644 --- a/arch/arm/boot/dts/marvell/armada-388-helios4.dts +++ b/arch/arm/boot/dts/marvell/armada-388-helios4.dts
@@ -140,11 +140,13 @@ fan2: j17-pwm { usb2_phy: usb2-phy { compatible = "usb-nop-xceiv"; - vbus-regulator = <®_5p0v_usb>; + vbus-supply = <®_5p0v_usb>; + #phy-cells = <0>; }; usb3_phy: usb3-phy { compatible = "usb-nop-xceiv"; + #phy-cells = <0>; }; soc { @@ -198,9 +200,9 @@ usb3-ilimit-hog { }; temp_sensor: temp@4c { - compatible = "ti,lm75"; + compatible = "national,lm75"; reg = <0x4c>; - vcc-supply = <®_3p3v>; + vs-supply = <®_3p3v>; }; eeprom@53 { @@ -254,13 +256,6 @@ sata3: sata-port@1 { }; }; - spi@10680 { - pinctrl-0 = <&spi1_pins - µsom_spi1_cs_pins>; - pinctrl-names = "default"; - status = "okay"; - }; - sdhci@d8000 { bus-width = <4>; cd-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; @@ -269,7 +264,7 @@ sdhci@d8000 { &helios_sdhci_cd_pins>; pinctrl-names = "default"; status = "okay"; - vmmc = <®_3p3v>; + vmmc-supply = <®_3p3v>; wp-inverted; }; @@ -327,11 +322,13 @@ helios_fan2_pins: helios_fan2_pins { marvell,pins = "mpp48", "mpp55"; marvell,function = "gpio"; }; - microsom_spi1_cs_pins: spi1-cs-pins { - marvell,pins = "mpp59"; - marvell,function = "spi1"; - }; }; }; }; }; + +&spi1 { + pinctrl-0 = <&spi1_pins>; + pinctrl-names = "default"; + status = "okay"; +};
diff --git a/arch/arm/boot/dts/marvell/armada-38x.dtsi b/arch/arm/boot/dts/marvell/armada-38x.dtsi index 1d616ed..0618779 100644 --- a/arch/arm/boot/dts/marvell/armada-38x.dtsi +++ b/arch/arm/boot/dts/marvell/armada-38x.dtsi
@@ -627,6 +627,7 @@ sdhci: sdhci@d8000 { <0x18454 0x4>; interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; clocks = <&gateclk 17>; + clock-names = "io"; mrvl,clk-delay-cycles = <0x1F>; status = "disabled"; };
diff --git a/arch/arm/boot/dts/marvell/armada-395-gp.dts b/arch/arm/boot/dts/marvell/armada-395-gp.dts index 6dd9e90..9ea447c 100644 --- a/arch/arm/boot/dts/marvell/armada-395-gp.dts +++ b/arch/arm/boot/dts/marvell/armada-395-gp.dts
@@ -59,7 +59,6 @@ sata@a8000 { /* CON18 */ sdhci@d8000 { - clock-frequency = <200000000>; broken-cd; wp-inverted; bus-width = <8>;
diff --git a/arch/arm/boot/dts/marvell/armada-39x.dtsi b/arch/arm/boot/dts/marvell/armada-39x.dtsi index 6d05835..077f4b4 100644 --- a/arch/arm/boot/dts/marvell/armada-39x.dtsi +++ b/arch/arm/boot/dts/marvell/armada-39x.dtsi
@@ -381,6 +381,7 @@ sdhci@d8000 { <0x18454 0x4>; interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; clocks = <&gateclk 17>; + clock-names = "io"; mrvl,clk-delay-cycles = <0x1F>; status = "disabled"; };
diff --git a/arch/arm/boot/dts/marvell/dove.dtsi b/arch/arm/boot/dts/marvell/dove.dtsi index 062c863..75e2f9b 100644 --- a/arch/arm/boot/dts/marvell/dove.dtsi +++ b/arch/arm/boot/dts/marvell/dove.dtsi
@@ -100,12 +100,12 @@ pcie: pcie { msi-parent = <&intc>; bus-range = <0x00 0xff>; - ranges = <0x82000000 0x0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x2000 - 0x82000000 0x0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x2000 - 0x82000000 0x1 0x0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 Mem */ - 0x81000000 0x1 0x0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 I/O */ - 0x82000000 0x2 0x0 MBUS_ID(0x08, 0xe8) 0 1 0 /* Port 1.0 Mem */ - 0x81000000 0x2 0x0 MBUS_ID(0x08, 0xe0) 0 1 0>; /* Port 1.0 I/O */ + ranges = <0x82000000 0x0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x2000>, + <0x82000000 0x0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x2000>, + <0x82000000 0x1 0x0 MBUS_ID(0x04, 0xe8) 0 1 0>, /* Port 0.0 Mem */ + <0x81000000 0x1 0x0 MBUS_ID(0x04, 0xe0) 0 1 0>, /* Port 0.0 I/O */ + <0x82000000 0x2 0x0 MBUS_ID(0x08, 0xe8) 0 1 0>, /* Port 1.0 Mem */ + <0x81000000 0x2 0x0 MBUS_ID(0x08, 0xe0) 0 1 0>; /* Port 1.0 I/O */ pcie0: pcie@1 { device_type = "pci"; @@ -117,8 +117,8 @@ pcie0: pcie@1 { #address-cells = <3>; #size-cells = <2>; - ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0 - 0x81000000 0 0 0x81000000 0x1 0 1 0>; + ranges = <0x82000000 0 0 0x82000000 0x1 0 1 0>, + <0x81000000 0 0 0x81000000 0x1 0 1 0>; bus-range = <0x00 0xff>; #interrupt-cells = <1>; @@ -146,8 +146,8 @@ pcie1: pcie@2 { #address-cells = <3>; #size-cells = <2>; - ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0 - 0x81000000 0 0 0x81000000 0x2 0 1 0>; + ranges = <0x82000000 0 0 0x82000000 0x2 0 1 0>, + <0x81000000 0 0 0x81000000 0x2 0 1 0>; bus-range = <0x00 0xff>; #interrupt-cells = <1>; @@ -772,7 +772,7 @@ rtc: real-time-clock@8500 { gconf: global-config@e802c { compatible = "marvell,dove-global-config", - "syscon"; + "syscon"; reg = <0xe802c 0x14>; };
diff --git a/arch/arm/boot/dts/marvell/kirkwood-6282.dtsi b/arch/arm/boot/dts/marvell/kirkwood-6282.dtsi index e337231..9f63e3f 100644 --- a/arch/arm/boot/dts/marvell/kirkwood-6282.dtsi +++ b/arch/arm/boot/dts/marvell/kirkwood-6282.dtsi
@@ -11,14 +11,13 @@ pciec: pcie@82000000 { bus-range = <0x00 0xff>; - ranges = - <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000 - 0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000 - 0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000 - 0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */ - 0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */ - 0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 1.0 MEM */ - 0x81000000 0x2 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 1.0 IO */>; + ranges = <0x82000000 0 0x40000 MBUS_ID(0xf0, 0x01) 0x40000 0 0x00002000>, + <0x82000000 0 0x44000 MBUS_ID(0xf0, 0x01) 0x44000 0 0x00002000>, + <0x82000000 0 0x80000 MBUS_ID(0xf0, 0x01) 0x80000 0 0x00002000>, + <0x82000000 0x1 0 MBUS_ID(0x04, 0xe8) 0 1 0 /* Port 0.0 MEM */>, + <0x81000000 0x1 0 MBUS_ID(0x04, 0xe0) 0 1 0 /* Port 0.0 IO */>, + <0x82000000 0x2 0 MBUS_ID(0x04, 0xd8) 0 1 0 /* Port 1.0 MEM */>, + <0x81000000 0x2 0 MBUS_ID(0x04, 0xd0) 0 1 0 /* Port 1.0 IO */>; pcie0: pcie@1,0 { device_type = "pci";
diff --git a/arch/arm/boot/dts/marvell/kirkwood-guruplug-server-plus.dts b/arch/arm/boot/dts/marvell/kirkwood-guruplug-server-plus.dts index d5aa8b5..cc88d53 100644 --- a/arch/arm/boot/dts/marvell/kirkwood-guruplug-server-plus.dts +++ b/arch/arm/boot/dts/marvell/kirkwood-guruplug-server-plus.dts
@@ -104,14 +104,14 @@ &mdio { ethphy0: ethernet-phy@0 { /* Marvell 88E1121R */ compatible = "ethernet-phy-id0141.0cb0", - "ethernet-phy-ieee802.3-c22"; + "ethernet-phy-ieee802.3-c22"; reg = <0>; }; ethphy1: ethernet-phy@1 { /* Marvell 88E1121R */ compatible = "ethernet-phy-id0141.0cb0", - "ethernet-phy-ieee802.3-c22"; + "ethernet-phy-ieee802.3-c22"; reg = <1>; }; };
diff --git a/arch/arm/boot/dts/marvell/kirkwood-lsxl.dtsi b/arch/arm/boot/dts/marvell/kirkwood-lsxl.dtsi index 5e0b139..4206529 100644 --- a/arch/arm/boot/dts/marvell/kirkwood-lsxl.dtsi +++ b/arch/arm/boot/dts/marvell/kirkwood-lsxl.dtsi
@@ -168,8 +168,8 @@ gpio_fan { compatible = "gpio-fan"; pinctrl-0 = <&pmx_fan_low &pmx_fan_high &pmx_fan_lock>; pinctrl-names = "default"; - gpios = <&gpio0 19 GPIO_ACTIVE_LOW - &gpio0 18 GPIO_ACTIVE_LOW>; + gpios = <&gpio0 19 GPIO_ACTIVE_LOW>, + <&gpio0 18 GPIO_ACTIVE_LOW>; gpio-fan,speed-map = <0 3>, <1500 2>,
diff --git a/arch/arm/boot/dts/marvell/kirkwood-synology.dtsi b/arch/arm/boot/dts/marvell/kirkwood-synology.dtsi index 6b7c521..de34bc2 100644 --- a/arch/arm/boot/dts/marvell/kirkwood-synology.dtsi +++ b/arch/arm/boot/dts/marvell/kirkwood-synology.dtsi
@@ -281,7 +281,7 @@ gpio-fan-150-32-35 { status = "disabled"; compatible = "gpio-fan"; pinctrl-0 = <&pmx_fanctrl_32 &pmx_fanctrl_33 &pmx_fanctrl_34 - &pmx_fanalarm_35>; + &pmx_fanalarm_35>; pinctrl-names = "default"; gpios = <&gpio1 0 GPIO_ACTIVE_HIGH &gpio1 1 GPIO_ACTIVE_HIGH @@ -301,7 +301,7 @@ gpio-fan-150-15-18 { status = "disabled"; compatible = "gpio-fan"; pinctrl-0 = <&pmx_fanctrl_15 &pmx_fanctrl_16 &pmx_fanctrl_17 - &pmx_fanalarm_18>; + &pmx_fanalarm_18>; pinctrl-names = "default"; gpios = <&gpio0 15 GPIO_ACTIVE_HIGH &gpio0 16 GPIO_ACTIVE_HIGH @@ -322,7 +322,7 @@ gpio-fan-100-32-35 { status = "disabled"; compatible = "gpio-fan"; pinctrl-0 = <&pmx_fanctrl_32 &pmx_fanctrl_33 &pmx_fanctrl_34 - &pmx_fanalarm_35>; + &pmx_fanalarm_35>; pinctrl-names = "default"; gpios = <&gpio1 0 GPIO_ACTIVE_HIGH &gpio1 1 GPIO_ACTIVE_HIGH @@ -343,7 +343,7 @@ gpio-fan-100-15-18 { status = "disabled"; compatible = "gpio-fan"; pinctrl-0 = <&pmx_fanctrl_15 &pmx_fanctrl_16 &pmx_fanctrl_17 - &pmx_fanalarm_18>; + &pmx_fanalarm_18>; pinctrl-names = "default"; gpios = <&gpio0 15 GPIO_ACTIVE_HIGH &gpio0 16 GPIO_ACTIVE_HIGH @@ -364,7 +364,7 @@ gpio-fan-100-15-35-1 { status = "disabled"; compatible = "gpio-fan"; pinctrl-0 = <&pmx_fanctrl_15 &pmx_fanctrl_16 &pmx_fanctrl_17 - &pmx_fanalarm_35>; + &pmx_fanalarm_35>; pinctrl-names = "default"; gpios = <&gpio0 15 GPIO_ACTIVE_HIGH &gpio0 16 GPIO_ACTIVE_HIGH @@ -385,7 +385,7 @@ gpio-fan-100-15-35-3 { status = "disabled"; compatible = "gpio-fan"; pinctrl-0 = <&pmx_fanctrl_15 &pmx_fanctrl_16 &pmx_fanctrl_17 - &pmx_fanalarm_35 &pmx_fanalarm_44 &pmx_fanalarm_45>; + &pmx_fanalarm_35 &pmx_fanalarm_44 &pmx_fanalarm_45>; pinctrl-names = "default"; gpios = <&gpio0 15 GPIO_ACTIVE_HIGH &gpio0 16 GPIO_ACTIVE_HIGH
diff --git a/arch/arm/boot/dts/marvell/orion5x-rd88f5182-nas.dts b/arch/arm/boot/dts/marvell/orion5x-rd88f5182-nas.dts index 75ab913..1d803d1 100644 --- a/arch/arm/boot/dts/marvell/orion5x-rd88f5182-nas.dts +++ b/arch/arm/boot/dts/marvell/orion5x-rd88f5182-nas.dts
@@ -22,7 +22,7 @@ chosen { soc { ranges = <MBUS_ID(0xf0, 0x01) 0 0xf1000000 0x100000>, - <MBUS_ID(0x09, 0x00) 0 0xf2200000 0x800>, + <MBUS_ID(0x09, 0x00) 0 0xf2200000 0x800>, <MBUS_ID(0x01, 0x0f) 0 0xf4000000 0x80000>, <MBUS_ID(0x01, 0x1d) 0 0xfc000000 0x1000000>; };
diff --git a/arch/arm/boot/dts/mediatek/Makefile b/arch/arm/boot/dts/mediatek/Makefile index 37c4cde..a610bc7 100644 --- a/arch/arm/boot/dts/mediatek/Makefile +++ b/arch/arm/boot/dts/mediatek/Makefile
@@ -14,5 +14,6 @@ mt7623n-rfb-emmc.dtb \ mt7623n-bananapi-bpi-r2.dtb \ mt7629-rfb.dtb \ + mt8127-amazon-ford.dtb \ mt8127-moose.dtb \ mt8135-evbp1.dtb
diff --git a/arch/arm/boot/dts/mediatek/mt8127-amazon-ford.dts b/arch/arm/boot/dts/mediatek/mt8127-amazon-ford.dts new file mode 100644 index 0000000..4b138e8 --- /dev/null +++ b/arch/arm/boot/dts/mediatek/mt8127-amazon-ford.dts
@@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0 + +/dts-v1/; +#include "mt8127.dtsi" + +/ { + model = "Amazon Fire 7 2015 (Ford)"; + compatible = "amazon,ford", "mediatek,mt8127"; + chassis-type = "tablet"; + + aliases { + serial0 = &uart0; + }; + + chosen { + #address-cells = <2>; + #size-cells = <2>; + ranges; + stdout-path = "serial0:921600n8"; + + framebuffer0: framebuffer@b7a00000 { + compatible = "simple-framebuffer"; + memory-region = <&framebuffer_reserved>; + width = <1024>; + height = <600>; + stride = <(1024 * 2)>; + format = "r5g6b5"; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0 0x80000000 0 0x40000000>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + framebuffer_reserved: framebuffer@b7a00000 { + reg = <0 0xb7a00000 0 0x1000000>; + no-map; + }; + }; +}; + +&uart0 { + status = "okay"; +}; + +&watchdog { + status = "okay"; +};
diff --git a/arch/arm/boot/dts/mediatek/mt8127.dtsi b/arch/arm/boot/dts/mediatek/mt8127.dtsi index bd61ec7..9bdf55d 100644 --- a/arch/arm/boot/dts/mediatek/mt8127.dtsi +++ b/arch/arm/boot/dts/mediatek/mt8127.dtsi
@@ -99,6 +99,13 @@ soc { compatible = "simple-bus"; ranges; + watchdog: watchdog@10007000 { + compatible = "mediatek,mt8127-wdt", "mediatek,mt6589-wdt"; + reg = <0 0x10007000 0 0x100>; + interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_LOW>; + status = "disabled"; + }; + timer: timer@10008000 { compatible = "mediatek,mt8127-timer", "mediatek,mt6577-timer";
diff --git a/arch/arm/boot/dts/nvidia/Makefile b/arch/arm/boot/dts/nvidia/Makefile index faf5914..68c24ba 100644 --- a/arch/arm/boot/dts/nvidia/Makefile +++ b/arch/arm/boot/dts/nvidia/Makefile
@@ -21,6 +21,8 @@ tegra20-colibri-eval-v3.dtb \ tegra20-colibri-iris.dtb \ tegra20-medcom-wide.dtb \ + tegra20-motorola-daytona.dtb \ + tegra20-motorola-olympus.dtb \ tegra20-paz00.dtb \ tegra20-plutux.dtb \ tegra20-seaboard.dtb \
diff --git a/arch/arm/boot/dts/nvidia/tegra114-asus-tf701t.dts b/arch/arm/boot/dts/nvidia/tegra114-asus-tf701t.dts index e563bea..8e7713c 100644 --- a/arch/arm/boot/dts/nvidia/tegra114-asus-tf701t.dts +++ b/arch/arm/boot/dts/nvidia/tegra114-asus-tf701t.dts
@@ -4,6 +4,7 @@ #include <dt-bindings/input/gpio-keys.h> #include <dt-bindings/input/input.h> +#include <dt-bindings/thermal/thermal.h> #include "tegra114.dtsi" @@ -25,6 +26,10 @@ aliases { serial2 = &uartb; /* GPS */ }; + chosen { + stdout-path = "serial0:115200n8"; + }; + firmware { trusted-foundations { compatible = "tlm,trusted-foundations"; @@ -101,6 +106,89 @@ panel_secondary: panel@0 { }; }; + clock@60006000 { + emc-timings-0 { + nvidia,ram-code = <0>; + + timing-12750000 { + clock-frequency = <12750000>; + nvidia,parent-clock-frequency = <408000000>; + clocks = <&tegra_car TEGRA114_CLK_PLL_P>; + clock-names = "emc-parent"; + }; + + timing-20400000 { + clock-frequency = <20400000>; + nvidia,parent-clock-frequency = <408000000>; + clocks = <&tegra_car TEGRA114_CLK_PLL_P>; + clock-names = "emc-parent"; + }; + + timing-40800000 { + clock-frequency = <40800000>; + nvidia,parent-clock-frequency = <408000000>; + clocks = <&tegra_car TEGRA114_CLK_PLL_P>; + clock-names = "emc-parent"; + }; + + timing-68000000 { + clock-frequency = <68000000>; + nvidia,parent-clock-frequency = <408000000>; + clocks = <&tegra_car TEGRA114_CLK_PLL_P>; + clock-names = "emc-parent"; + }; + + timing-102000000 { + clock-frequency = <102000000>; + nvidia,parent-clock-frequency = <408000000>; + clocks = <&tegra_car TEGRA114_CLK_PLL_P>; + clock-names = "emc-parent"; + }; + + timing-204000000 { + clock-frequency = <204000000>; + nvidia,parent-clock-frequency = <408000000>; + clocks = <&tegra_car TEGRA114_CLK_PLL_P>; + clock-names = "emc-parent"; + }; + + timing-312000000 { + clock-frequency = <312000000>; + nvidia,parent-clock-frequency = <624000000>; + clocks = <&tegra_car TEGRA114_CLK_PLL_C>; + clock-names = "emc-parent"; + }; + + timing-408000000 { + clock-frequency = <408000000>; + nvidia,parent-clock-frequency = <408000000>; + clocks = <&tegra_car TEGRA114_CLK_PLL_P>; + clock-names = "emc-parent"; + }; + + timing-528000000 { + clock-frequency = <528000000>; + nvidia,parent-clock-frequency = <792000000>; + clocks = <&tegra_car TEGRA114_CLK_PLL_M>; + clock-names = "emc-parent"; + }; + + timing-624000000 { + clock-frequency = <624000000>; + nvidia,parent-clock-frequency = <624000000>; + clocks = <&tegra_car TEGRA114_CLK_PLL_C>; + clock-names = "emc-parent"; + }; + + timing-792000000 { + clock-frequency = <792000000>; + nvidia,parent-clock-frequency = <792000000>; + clocks = <&tegra_car TEGRA114_CLK_PLL_M>; + clock-names = "emc-parent"; + }; + }; + }; + vde@6001a000 { assigned-clocks = <&tegra_car TEGRA114_CLK_VDE>; assigned-clock-parents = <&tegra_car TEGRA114_CLK_PLL_P>; @@ -1199,6 +1287,11 @@ drive-gma { }; serial@70006040 { + compatible = "nvidia,tegra114-hsuart", "nvidia,tegra30-hsuart"; + reset-names = "serial"; + /delete-property/ reg-shift; + status = "okay"; + /* GPS */ }; @@ -1216,8 +1309,9 @@ bluetooth { compatible = "brcm,bcm4334-bt"; max-speed = <4000000>; - clocks = <&tegra_pmc TEGRA_PMC_CLK_BLINK>; - clock-names = "txco"; + clocks = <&tegra_pmc TEGRA_PMC_CLK_BLINK>, + <&palmas_clk32k>; + clock-names = "txco", "lpo"; interrupt-parent = <&gpio>; interrupts = <TEGRA_GPIO(U, 6) IRQ_TYPE_EDGE_RISING>; @@ -1225,7 +1319,6 @@ bluetooth { device-wakeup-gpios = <&gpio TEGRA_GPIO(EE, 1) GPIO_ACTIVE_HIGH>; shutdown-gpios = <&gpio TEGRA_GPIO(Q, 7) GPIO_ACTIVE_HIGH>; - reset-gpios = <&gpio TEGRA_GPIO(Q, 6) GPIO_ACTIVE_LOW>; vbat-supply = <&vdd_3v3_com>; vddio-supply = <&vdd_1v8_vio>; @@ -1307,6 +1400,9 @@ power-sensor@44 { reg = <0x44>; shunt-resistor = <5000>; + + vs-supply = <&vdd_3v3_sys>; + #io-channel-cells = <1>; }; }; @@ -1366,7 +1462,7 @@ palmas_gpio: gpio { #gpio-cells = <2>; }; - palmas_clk32kg@0 { + palmas_clk32k: palmas_clk32kg@0 { compatible = "ti,palmas-clk32kg"; #clock-cells = <0>; }; @@ -1379,52 +1475,52 @@ pinmux { pinctrl-0 = <&palmas_default>; palmas_default: pinmux { - pin_gpio0 { + gpio0 { pins = "gpio0"; function = "gpio"; }; - pin_gpio1 { + gpio1 { pins = "gpio1"; function = "gpio"; }; - pin_gpio2 { + gpio2 { pins = "gpio2"; function = "gpio"; }; - pin_gpio3 { + gpio3 { pins = "gpio3"; function = "gpio"; }; - pin_gpio4 { + gpio4 { pins = "gpio4"; function = "gpio"; }; - pin_gpio5 { + gpio5 { pins = "gpio5"; function = "gpio"; }; - pin_gpio6 { + gpio6 { pins = "gpio6"; function = "gpio"; }; - pin_gpio7 { + gpio7 { pins = "gpio7"; function = "gpio"; }; - pin_powergood { + powergood { pins = "powergood"; function = "powergood"; }; - pin_vac { + vac { pins = "vac"; function = "vac"; }; @@ -1561,9 +1657,9 @@ ldo8 { vddio_usd: ldo9 { regulator-name = "vddio_usd"; - /* min voltage of 1.8v is not stable */ - regulator-min-microvolt = <2900000>; + regulator-min-microvolt = <1800000>; regulator-max-microvolt = <2900000>; + regulator-boot-on; }; avdd_hdmi: ldoln { @@ -1599,6 +1695,7 @@ pmc@7000e400 { nvidia,core-pwr-off-time = <2000>; nvidia,core-power-req-active-high; nvidia,sys-clock-req-active-high; + core-supply = <&vdd_core>; /* Clear DEV_ON bit in DEV_CTRL register of TPS65913 PMIC */ i2c-thermtrip { @@ -1609,6 +1706,636 @@ i2c-thermtrip { }; }; + memory-controller@70019000 { + emc-timings-0 { + /* Mozart Rev B Hynix DDR3 792MHz */ + nvidia,ram-code = <0>; + + timing-12750000 { + clock-frequency = <12750000>; + + nvidia,emem-configuration = < 0x40040001 0x8000003f + 0x00000001 0x00000001 0x00000002 0x00000000 + 0x00000001 0x00000001 0x00000002 0x00000008 + 0x00000002 0x00000001 0x00000003 0x00000006 + 0x06030102 0x000a0402 0x77e30303 0x001f0000 >; + }; + + timing-20400000 { + clock-frequency = <20400000>; + + nvidia,emem-configuration = < 0x40020001 0x80000046 + 0x00000001 0x00000001 0x00000002 0x00000000 + 0x00000001 0x00000001 0x00000002 0x00000008 + 0x00000002 0x00000001 0x00000003 0x00000006 + 0x06030102 0x000a0402 0x76230303 0x001f0000 >; + }; + + timing-40800000 { + clock-frequency = <40800000>; + + nvidia,emem-configuration = < 0xa0000001 0x8000005b + 0x00000001 0x00000001 0x00000002 0x00000000 + 0x00000001 0x00000001 0x00000002 0x00000008 + 0x00000002 0x00000001 0x00000003 0x00000006 + 0x06030102 0x000a0402 0x74a30303 0x001f0000 >; + }; + + timing-68000000 { + clock-frequency = <68000000>; + + nvidia,emem-configuration = < 0x00000001 0x80000076 + 0x00000001 0x00000001 0x00000002 0x00000000 + 0x00000001 0x00000001 0x00000002 0x00000008 + 0x00000002 0x00000001 0x00000003 0x00000006 + 0x06030102 0x000a0402 0x74230403 0x001f0000 >; + }; + + timing-102000000 { + clock-frequency = <102000000>; + + nvidia,emem-configuration = < 0x08000001 0x80000098 + 0x00000001 0x00000001 0x00000003 0x00000000 + 0x00000002 0x00000001 0x00000002 0x00000008 + 0x00000002 0x00000001 0x00000003 0x00000006 + 0x06030102 0x000a0403 0x73c30504 0x001f0000 >; + }; + + timing-204000000 { + clock-frequency = <204000000>; + + nvidia,emem-configuration = < 0x01000003 0x800000fe + 0x00000001 0x00000001 0x00000005 0x00000002 + 0x00000004 0x00000001 0x00000002 0x00000008 + 0x00000002 0x00000001 0x00000003 0x00000006 + 0x06030102 0x000a0405 0x73840a06 0x001f0000 >; + }; + + timing-312000000 { + clock-frequency = <312000000>; + + nvidia,emem-configuration = < 0x0b000004 0x8000016a + 0x00000001 0x00000002 0x00000007 0x00000004 + 0x00000006 0x00000001 0x00000002 0x00000007 + 0x00000002 0x00000002 0x00000004 0x00000006 + 0x06040202 0x000b0607 0x76e50f08 0x001f0000 >; + }; + + timing-408000000 { + clock-frequency = <408000000>; + + nvidia,emem-configuration = < 0x02000006 0x80000190 + 0x00000001 0x00000002 0x0000000a 0x00000006 + 0x00000008 0x00000001 0x00000002 0x00000009 + 0x00000002 0x00000002 0x00000004 0x00000006 + 0x06040202 0x000e070a 0x7547130b 0x001f0000 >; + }; + + timing-528000000 { + clock-frequency = <528000000>; + + nvidia,emem-configuration = < 0x0f000007 0x80000190 + 0x00000002 0x00000003 0x0000000d 0x00000008 + 0x0000000a 0x00000001 0x00000002 0x00000009 + 0x00000002 0x00000002 0x00000005 0x00000006 + 0x06050202 0x0010090d 0x7428180e 0x001f0000 >; + }; + + timing-624000000 { + clock-frequency = <624000000>; + + nvidia,emem-configuration = < 0x06000009 0x80000190 + 0x00000003 0x00000004 0x0000000f 0x00000009 + 0x0000000c 0x00000001 0x00000003 0x0000000b + 0x00000002 0x00000002 0x00000005 0x00000007 + 0x07050202 0x00130b0f 0x736a1d10 0x001f0000 >; + }; + + timing-792000000 { + clock-frequency = <792000000>; + + nvidia,emem-configuration = < 0x0e00000b 0x80000190 + 0x00000004 0x00000005 0x00000013 0x0000000c + 0x0000000f 0x00000002 0x00000003 0x0000000c + 0x00000002 0x00000002 0x00000006 0x00000008 + 0x08060202 0x00160d13 0x734c2414 0x001f0000 >; + }; + }; + }; + + external-memory-controller@7001b000 { + emc-timings-0 { + /* Mozart Rev B Hynix DDR3 792MHz */ + nvidia,ram-code = <0>; + + timing-12750000 { + clock-frequency = <12750000>; + + nvidia,emc-zcal-cnt-long = <0x00000042>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-cfg = <0x7324000e>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-4 = <0x00000000>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-auto-cal-config = <0xa0f10f0f>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mrs-wait-cnt = <0x000c000c>; + nvidia,emc-sel-dpd-ctrl = <0x00040320>; + nvidia,emc-xm2dqspadctrl2 = <0x0000a11c>; + nvidia,emc-zcal-interval = <0x00000000>; + + nvidia,emc-configuration = < 0x00000000 + 0x00000003 0x00000000 0x00000000 0x00000004 + 0x0000000a 0x00000003 0x0000000b 0x00000000 + 0x00000000 0x00000003 0x00000001 0x00000000 + 0x00000005 0x0000000f 0x00000006 0x00000006 + 0x00000004 0x00000004 0x00010000 0x00000000 + 0x00000000 0x00000004 0x00000009 0x0000000d + 0x0000000f 0x00000060 0x00000000 0x00000018 + 0x00000002 0x00000002 0x00000001 0x00000000 + 0x00000007 0x0000000f 0x00000005 0x00000005 + 0x00000004 0x00000004 0x00000004 0x00000004 + 0x00000000 0x00000004 0x00000005 0x00000064 + 0x00000005 0x00000006 0x00000020 0x00000000 + 0x0000aa88 0x002c00a0 0x00008000 0x00064000 + 0x00064000 0x00064000 0x00064000 0x00064000 + 0x00064000 0x00064000 0x00064000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x0007c000 + 0x0007c000 0x0007c000 0x0007c000 0x001112a0 + 0x00000000 0x00000000 0x77ffc085 0x81f1f108 + 0x03037504 0x0000003f 0x20820800 0x00249249 + 0x0000003f 0x00000007 0x02000000 0x00000042 + 0x000c000c 0x00000000 0x00000000 0x800001c5 >; + }; + + timing-20400000 { + clock-frequency = <20400000>; + + nvidia,emc-zcal-cnt-long = <0x00000042>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-cfg = <0x7324000e>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-4 = <0x00000000>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-auto-cal-config = <0xa0f10f0f>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mrs-wait-cnt = <0x000c000c>; + nvidia,emc-sel-dpd-ctrl = <0x00040320>; + nvidia,emc-xm2dqspadctrl2 = <0x0000a11c>; + nvidia,emc-zcal-interval = <0x00000000>; + + nvidia,emc-configuration = < 0x00000000 + 0x00000005 0x00000000 0x00000000 0x00000004 + 0x0000000a 0x00000003 0x0000000b 0x00000000 + 0x00000000 0x00000003 0x00000001 0x00000000 + 0x00000005 0x0000000f 0x00000006 0x00000006 + 0x00000004 0x00000004 0x00010000 0x00000000 + 0x00000000 0x00000004 0x00000009 0x0000000d + 0x0000000f 0x0000009a 0x00000000 0x00000026 + 0x00000002 0x00000002 0x00000001 0x00000000 + 0x00000007 0x0000000f 0x00000006 0x00000006 + 0x00000004 0x00000004 0x00000004 0x00000004 + 0x00000000 0x00000004 0x00000005 0x000000a0 + 0x00000005 0x00000006 0x00000020 0x00000000 + 0x0000aa88 0x002c00a0 0x00008000 0x00064000 + 0x00064000 0x00064000 0x00064000 0x00064000 + 0x00064000 0x00064000 0x00064000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x0007c000 + 0x0007c000 0x0007c000 0x0007c000 0x001112a0 + 0x00000000 0x00000000 0x77ffc085 0x81f1f108 + 0x03037504 0x0000003f 0x20820800 0x00249249 + 0x0000003f 0x0000000b 0x02000000 0x00000042 + 0x000c000c 0x00000000 0x00000000 0x8000023a >; + }; + + timing-40800000 { + clock-frequency = <40800000>; + + nvidia,emc-zcal-cnt-long = <0x00000042>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-cfg = <0x7324000e>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-4 = <0x00000000>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-auto-cal-config = <0xa0f10f0f>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mrs-wait-cnt = <0x000c000c>; + nvidia,emc-sel-dpd-ctrl = <0x00040320>; + nvidia,emc-xm2dqspadctrl2 = <0x0000a11c>; + nvidia,emc-zcal-interval = <0x00000000>; + + nvidia,emc-configuration = < 0x00000001 + 0x0000000a 0x00000001 0x00000000 0x00000004 + 0x0000000a 0x00000003 0x0000000b 0x00000000 + 0x00000000 0x00000003 0x00000001 0x00000000 + 0x00000005 0x0000000f 0x00000006 0x00000006 + 0x00000004 0x00000004 0x00010000 0x00000000 + 0x00000000 0x00000004 0x00000009 0x0000000d + 0x0000000f 0x00000134 0x00000000 0x0000004d + 0x00000002 0x00000002 0x00000001 0x00000000 + 0x00000008 0x0000000f 0x0000000c 0x0000000c + 0x00000004 0x00000004 0x00000004 0x00000004 + 0x00000000 0x00000004 0x00000005 0x0000013f + 0x00000005 0x00000006 0x00000020 0x00000000 + 0x0000aa88 0x002c00a0 0x00008000 0x00064000 + 0x00064000 0x00064000 0x00064000 0x00064000 + 0x00064000 0x00064000 0x00064000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x0007c000 + 0x0007c000 0x0007c000 0x0007c000 0x001112a0 + 0x00000000 0x00000000 0x77ffc085 0x81f1f108 + 0x03037504 0x0000003f 0x20820800 0x00249249 + 0x0000003f 0x00000015 0x02000000 0x00000042 + 0x000c000c 0x00000000 0x00000000 0x80000370 >; + }; + + timing-68000000 { + clock-frequency = <68000000>; + + nvidia,emc-zcal-cnt-long = <0x00000042>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-cfg = <0x7324000e>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-4 = <0x00000000>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-auto-cal-config = <0xa0f10f0f>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mrs-wait-cnt = <0x000c000c>; + nvidia,emc-sel-dpd-ctrl = <0x00040320>; + nvidia,emc-xm2dqspadctrl2 = <0x0000a11c>; + nvidia,emc-zcal-interval = <0x00000000>; + + nvidia,emc-configuration = < 0x00000003 + 0x00000011 0x00000002 0x00000000 0x00000004 + 0x0000000a 0x00000003 0x0000000b 0x00000000 + 0x00000000 0x00000003 0x00000001 0x00000000 + 0x00000005 0x0000000f 0x00000006 0x00000006 + 0x00000004 0x00000004 0x00010000 0x00000000 + 0x00000000 0x00000004 0x00000009 0x0000000d + 0x0000000f 0x00000202 0x00000000 0x00000080 + 0x00000002 0x00000002 0x00000001 0x00000000 + 0x0000000f 0x0000000f 0x00000013 0x00000013 + 0x00000004 0x00000004 0x00000004 0x00000004 + 0x00000000 0x00000004 0x00000005 0x00000213 + 0x00000005 0x00000006 0x00000020 0x00000000 + 0x0000aa88 0x002c00a0 0x00008000 0x00064000 + 0x00064000 0x00064000 0x00064000 0x00064000 + 0x00064000 0x00064000 0x00064000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x0007c000 + 0x0007c000 0x0007c000 0x0007c000 0x001112a0 + 0x00000000 0x00000000 0x77ffc085 0x81f1f108 + 0x03037504 0x0000003f 0x20820800 0x00249249 + 0x0000003f 0x00000022 0x02000000 0x00000042 + 0x000c000c 0x00000000 0x00000000 0x8000050e >; + }; + + timing-102000000 { + clock-frequency = <102000000>; + + nvidia,emc-zcal-cnt-long = <0x00000042>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-cfg = <0x7324000e>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-4 = <0x00000000>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-auto-cal-config = <0xa0f10f0f>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mrs-wait-cnt = <0x000c000c>; + nvidia,emc-sel-dpd-ctrl = <0x00040320>; + nvidia,emc-xm2dqspadctrl2 = <0x0000a11c>; + nvidia,emc-zcal-interval = <0x00000000>; + + nvidia,emc-configuration = < 0x00000004 + 0x0000001a 0x00000003 0x00000001 0x00000004 + 0x0000000a 0x00000003 0x0000000b 0x00000001 + 0x00000001 0x00000003 0x00000001 0x00000000 + 0x00000005 0x0000000f 0x00000006 0x00000006 + 0x00000004 0x00000004 0x00010000 0x00000000 + 0x00000000 0x00000004 0x00000009 0x0000000d + 0x0000000f 0x00000303 0x00000000 0x000000c0 + 0x00000002 0x00000002 0x00000001 0x00000000 + 0x00000018 0x0000000f 0x0000001c 0x0000001c + 0x00000004 0x00000004 0x00000004 0x00000005 + 0x00000000 0x00000004 0x00000005 0x0000031c + 0x00000005 0x00000006 0x00000020 0x00000000 + 0x0000aa88 0x002c00a0 0x00008000 0x00064000 + 0x00064000 0x00064000 0x00064000 0x00064000 + 0x00064000 0x00064000 0x00064000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x0007c000 + 0x0007c000 0x0007c000 0x0007c000 0x001112a0 + 0x00000000 0x00000000 0x77ffc085 0x81f1f108 + 0x03037504 0x0000003f 0x20820800 0x00249249 + 0x0000003f 0x00000033 0x02000000 0x00000042 + 0x000c000c 0x00000000 0x00000000 0x80000713 >; + }; + + timing-204000000 { + clock-frequency = <204000000>; + + nvidia,emc-zcal-cnt-long = <0x00000042>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-cfg = <0x7320000e>; + nvidia,emc-mode-1 = <0x80100003>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-4 = <0x00000000>; + nvidia,emc-mode-reset = <0x80001221>; + nvidia,emc-auto-cal-config = <0xa0f10f0f>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mrs-wait-cnt = <0x000c000c>; + nvidia,emc-sel-dpd-ctrl = <0x00040320>; + nvidia,emc-xm2dqspadctrl2 = <0x0000a11c>; + nvidia,emc-zcal-interval = <0x00020000>; + + nvidia,emc-configuration = < 0x00000009 + 0x00000035 0x00000007 0x00000002 0x00000004 + 0x0000000a 0x00000003 0x0000000b 0x00000002 + 0x00000002 0x00000003 0x00000001 0x00000000 + 0x00000005 0x0000000f 0x00000007 0x00000006 + 0x00000004 0x00000004 0x00010000 0x00000000 + 0x00000000 0x00000004 0x00000009 0x0000000d + 0x0000000f 0x00000607 0x00000000 0x00000181 + 0x00000002 0x00000002 0x00000001 0x00000000 + 0x00000032 0x0000000f 0x00000038 0x00000038 + 0x00000004 0x00000004 0x00000004 0x00000009 + 0x00000000 0x00000004 0x00000005 0x00000638 + 0x00000006 0x00000004 0x00000020 0x00000000 + 0x0000aa88 0x002c00a0 0x00008000 0x00064000 + 0x00064000 0x00064000 0x00064000 0x00064000 + 0x00064000 0x00064000 0x00064000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x0007c000 + 0x0007c000 0x0007c000 0x0007c000 0x001112a0 + 0x00000000 0x00000000 0x77ffc085 0x81f1f108 + 0x03037504 0x0000003f 0x20820800 0x00249249 + 0x0000003f 0x00000000 0x02000000 0x00000100 + 0x000c000c 0x00000000 0x00000000 0x80000d22 >; + }; + + timing-312000000 { + clock-frequency = <312000000>; + + nvidia,emc-zcal-cnt-long = <0x00000042>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-cfg = <0x5300000e>; + nvidia,emc-mode-1 = <0x80100002>; + nvidia,emc-mode-2 = <0x80200000>; + nvidia,emc-mode-4 = <0x00000000>; + nvidia,emc-mode-reset = <0x80000321>; + nvidia,emc-auto-cal-config = <0xa0f10f0f>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mrs-wait-cnt = <0x0171000c>; + nvidia,emc-sel-dpd-ctrl = <0x00040320>; + nvidia,emc-xm2dqspadctrl2 = <0x0001013d>; + nvidia,emc-zcal-interval = <0x00020000>; + + nvidia,emc-configuration = < 0x0000000e + 0x00000050 0x00000009 0x00000003 0x00000004 + 0x00000008 0x00000002 0x00000009 0x00000003 + 0x00000003 0x00000002 0x00000001 0x00000000 + 0x00000004 0x0000000f 0x00000006 0x00000006 + 0x00000005 0x00000004 0x00010000 0x00000000 + 0x00000000 0x00000004 0x0000000b 0x0000000d + 0x0000000f 0x00000941 0x00000000 0x00000250 + 0x00000001 0x00000008 0x00000001 0x00000000 + 0x0000004d 0x0000000e 0x00000055 0x00000200 + 0x00000004 0x00000004 0x00000004 0x0000000d + 0x00000000 0x00000004 0x00000005 0x00000982 + 0x00000000 0x00000004 0x00000020 0x00000000 + 0x00005088 0x002c00a0 0x00008000 0x00030000 + 0x00030000 0x00030000 0x00030000 0x00030000 + 0x00030000 0x00030000 0x00030000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x0003c000 + 0x0003c000 0x0003c000 0x0003c000 0x001112a0 + 0x00000000 0x00000000 0x77ffc085 0x81f1f108 + 0x03037504 0x00000000 0x20820800 0x00249249 + 0x0000003f 0x00000000 0x02000000 0x00000100 + 0x0171000c 0x00000000 0x00000000 0x8000138d >; + }; + + timing-408000000 { + clock-frequency = <408000000>; + + nvidia,emc-zcal-cnt-long = <0x00000042>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-cfg = <0x53000006>; + nvidia,emc-mode-1 = <0x80100002>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-4 = <0x00000000>; + nvidia,emc-mode-reset = <0x80000731>; + nvidia,emc-auto-cal-config = <0xa0f10f0f>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mrs-wait-cnt = <0x0158000c>; + nvidia,emc-sel-dpd-ctrl = <0x00040320>; + nvidia,emc-xm2dqspadctrl2 = <0x0001013d>; + nvidia,emc-zcal-interval = <0x00020000>; + + nvidia,emc-configuration = < 0x00000012 + 0x00000069 0x0000000d 0x00000004 0x00000005 + 0x00000009 0x00000002 0x0000000c 0x00000004 + 0x00000004 0x00000002 0x00000001 0x00000000 + 0x00000004 0x0000000f 0x00000006 0x00000006 + 0x00000005 0x00000004 0x00010000 0x00000000 + 0x00000000 0x00000004 0x0000000c 0x0000000e + 0x00000010 0x00000c2e 0x00000000 0x0000030b + 0x00000001 0x00000008 0x00000001 0x00000000 + 0x00000066 0x00000011 0x0000006f 0x00000200 + 0x00000004 0x00000004 0x00000004 0x00000011 + 0x00000000 0x00000004 0x00000005 0x00000c6f + 0x00000000 0x00000004 0x00000020 0x00000000 + 0x00005088 0x002c0080 0x00008000 0x00030000 + 0x00030000 0x00030000 0x00030000 0x00030000 + 0x00030000 0x00030000 0x00030000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x0003c000 + 0x0003c000 0x0003c000 0x0003c000 0x001112a0 + 0x00000000 0x00000000 0x77ffc085 0x81f1f108 + 0x03037504 0x00000000 0x20820800 0x00249249 + 0x0000003f 0x00000000 0x02000000 0x00000100 + 0x0158000c 0x00000000 0x00000000 0x80001941 >; + }; + + timing-528000000 { + clock-frequency = <528000000>; + + nvidia,emc-zcal-cnt-long = <0x00000042>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-cfg = <0x53000004>; + nvidia,emc-mode-1 = <0x80100002>; + nvidia,emc-mode-2 = <0x80200008>; + nvidia,emc-mode-4 = <0x00000000>; + nvidia,emc-mode-reset = <0x80000941>; + nvidia,emc-auto-cal-config = <0xa0f10f0f>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mrs-wait-cnt = <0x013a000c>; + nvidia,emc-sel-dpd-ctrl = <0x00040320>; + nvidia,emc-xm2dqspadctrl2 = <0x0000013d>; + nvidia,emc-zcal-interval = <0x00020000>; + + nvidia,emc-configuration = < 0x00000018 + 0x00000088 0x00000011 0x00000006 0x00000006 + 0x00000009 0x00000002 0x0000000d 0x00000006 + 0x00000006 0x00000002 0x00000001 0x00000000 + 0x00000005 0x0000000f 0x00000008 0x00000009 + 0x00000007 0x00000004 0x00010000 0x00000000 + 0x00000000 0x00000006 0x0000000c 0x00000010 + 0x00000012 0x00000fd6 0x00000000 0x000003f5 + 0x00000002 0x0000000b 0x00000001 0x00000000 + 0x00000084 0x00000012 0x0000008f 0x00000200 + 0x00000004 0x00000004 0x00000004 0x00000016 + 0x00000000 0x00000005 0x00000006 0x00001017 + 0x00000000 0x00000006 0x00000020 0x00000000 + 0x00005088 0xf0120091 0x00008000 0x0000000a + 0x0000000a 0x0000000a 0x0000000a 0x0000000a + 0x0000000a 0x0000000a 0x0000000a 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x0000000c + 0x0000000b 0x0000000c 0x0000000c 0x001112a0 + 0x00000000 0x00000000 0x77ffc085 0x81f1f108 + 0x07077504 0x00000000 0x20820800 0x00249249 + 0x0000003f 0x00000000 0x02000000 0x00000100 + 0x013a000c 0x00000000 0x00000000 0x80002062 >; + }; + + timing-624000000 { + clock-frequency = <624000000>; + + nvidia,emc-zcal-cnt-long = <0x00000042>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-cfg = <0x53200000>; + nvidia,emc-mode-1 = <0x80100002>; + nvidia,emc-mode-2 = <0x80200410>; + nvidia,emc-mode-4 = <0x00000000>; + nvidia,emc-mode-reset = <0x80000b61>; + nvidia,emc-auto-cal-config = <0xa0f10f0f>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mrs-wait-cnt = <0x0122000c>; + nvidia,emc-sel-dpd-ctrl = <0x00040320>; + nvidia,emc-xm2dqspadctrl2 = <0x0000013d>; + nvidia,emc-zcal-interval = <0x00020000>; + + nvidia,emc-configuration = < 0x0000001d + 0x000000a1 0x00000014 0x00000007 0x00000007 + 0x0000000b 0x00000003 0x00000010 0x00000007 + 0x00000007 0x00000002 0x00000001 0x00000000 + 0x00000005 0x0000000f 0x00000009 0x0000000a + 0x00000008 0x00000004 0x00010000 0x00000000 + 0x00000000 0x00000007 0x0000000c 0x00000012 + 0x00000014 0x000012c3 0x00000000 0x000004b0 + 0x00000002 0x0000000d 0x00000001 0x00000000 + 0x0000009c 0x00000015 0x000000a9 0x00000200 + 0x00000005 0x00000005 0x00000005 0x00000019 + 0x00000000 0x00000006 0x00000007 0x00001304 + 0x00000009 0x00000006 0x80000000 0x00000000 + 0x0000ba88 0xf00d0191 0x00008000 0x0000000a + 0x0000000a 0x0000000a 0x0000000a 0x0000000a + 0x0000000a 0x0000000a 0x0000000a 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x0000000b + 0x0000000b 0x0000000b 0x0000000b 0x001112a0 + 0x00000000 0x00000000 0x77ffc085 0x81f1f108 + 0x07077504 0x00000000 0x20820800 0x0028a28a + 0x0000003f 0x00000000 0x02000000 0x00000100 + 0x0122000c 0x00000000 0x00000000 0x80002617 >; + }; + + timing-792000000 { + clock-frequency = <792000000>; + + nvidia,emc-zcal-cnt-long = <0x00000042>; + nvidia,emc-auto-cal-interval = <0x001fffff>; + nvidia,emc-cfg = <0x53000000>; + nvidia,emc-mode-1 = <0x80100002>; + nvidia,emc-mode-2 = <0x80200418>; + nvidia,emc-mode-4 = <0x00000000>; + nvidia,emc-mode-reset = <0x80000d71>; + nvidia,emc-auto-cal-config = <0xa0f10f0f>; + nvidia,emc-auto-cal-config2 = <0x00000000>; + nvidia,emc-auto-cal-config3 = <0x00000000>; + nvidia,emc-ctt-term-ctrl = <0x00000802>; + nvidia,emc-mrs-wait-cnt = <0x00f8000c>; + nvidia,emc-sel-dpd-ctrl = <0x00040000>; + nvidia,emc-xm2dqspadctrl2 = <0x0000013d>; + nvidia,emc-zcal-interval = <0x00020000>; + + nvidia,emc-configuration = < 0x00000025 + 0x000000cc 0x0000001a 0x00000009 0x00000008 + 0x0000000d 0x00000004 0x00000013 0x00000009 + 0x00000009 0x00000003 0x00000001 0x00000000 + 0x00000006 0x0000000f 0x0000000a 0x0000000b + 0x00000008 0x00000006 0x00010000 0x00000000 + 0x00000000 0x00000008 0x0000000d 0x00000014 + 0x00000016 0x000017e1 0x00000000 0x000005f8 + 0x00000003 0x00000011 0x00000001 0x00000000 + 0x000000c6 0x00000018 0x000000d6 0x00000200 + 0x00000005 0x00000005 0x00000005 0x00000020 + 0x00000000 0x00000007 0x00000008 0x00001822 + 0x00000000 0x00000006 0x80000000 0x00000000 + 0x00005088 0xf0070191 0x00008000 0x00000009 + 0x00000009 0x00000009 0x00000009 0x00000009 + 0x00000009 0x00000009 0x00000009 0x00018000 + 0x00018000 0x00018000 0x00018000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000000 0x0000000b + 0x0000000b 0x0000000b 0x0000000b 0x001112a0 + 0x00000000 0x00000000 0x77ffc085 0x81f1f108 + 0x07077504 0x00000000 0x1c71c700 0x0028a28a + 0x0000003f 0x00000000 0x02000000 0x00000100 + 0x00f8000c 0x00000000 0x00000000 0x80003012 >; + }; + }; + }; + ahub@70080000 { /* HIFI CODEC (i2s1) */ i2s@70080400 { @@ -1621,15 +2348,23 @@ i2s@70080600 { }; }; + /* CPU DFLL clock */ + clock@70110000 { + status = "okay"; + nvidia,sample-rate = <11500>; + nvidia,i2c-fs-rate = <400000>; + vdd-cpu-supply = <&vdd_cpu>; + }; + brcm_wifi_pwrseq: pwrseq-wifi { compatible = "mmc-pwrseq-simple"; clocks = <&tegra_pmc TEGRA_PMC_CLK_BLINK>; clock-names = "ext_clock"; - reset-gpios = <&gpio TEGRA_GPIO(X, 7) GPIO_ACTIVE_LOW>; - post-power-on-delay-ms = <300>; - power-off-delay-us = <300>; + reset-gpios = <&gpio TEGRA_GPIO(CC, 5) GPIO_ACTIVE_LOW>; + post-power-on-delay-ms = <100>; + power-off-delay-us = <100>; }; /* WiFi */ @@ -1649,9 +2384,7 @@ mmc@78000000 { non-removable; sd-uhs-ddr50; - mmc-ddr-1_8v; - - power-gpios = <&gpio TEGRA_GPIO(CC, 5) GPIO_ACTIVE_HIGH>; + sd-uhs-sdr104; nvidia,default-tap = <0x2>; nvidia,default-trim = <0x2>; @@ -1661,9 +2394,12 @@ mmc@78000000 { vqmmc-supply = <&vdd_1v8_vio>; wifi@1 { - compatible = "brcm,bcm4329-fmac"; + compatible = "brcm,bcm43340-fmac", "brcm,bcm4329-fmac"; reg = <1>; + clocks = <&palmas_clk32k>; + clock-names = "lpo"; + interrupt-parent = <&gpio>; interrupts = <TEGRA_GPIO(U, 5) IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "host-wake"; @@ -1673,14 +2409,18 @@ wifi@1 { /* MicroSD card */ mmc@78000400 { status = "okay"; - bus-width = <4>; + cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>; + power-gpios = <&gpio TEGRA_GPIO(K, 1) GPIO_ACTIVE_HIGH>; + + sd-uhs-ddr50; + sd-uhs-sdr104; nvidia,default-tap = <0x3>; nvidia,default-trim = <0x3>; - vmmc-supply = <&vdd_2v9_usd>; + vmmc-supply = <&vcore_emmc>; vqmmc-supply = <&vddio_usd>; }; @@ -1691,6 +2431,7 @@ mmc@78000600 { non-removable; mmc-ddr-1_8v; + mmc-hs200-1_8v; vmmc-supply = <&vcore_emmc>; vqmmc-supply = <&vdd_1v8_vio>; @@ -1885,17 +2626,6 @@ hdmi_5v0_sys: regulator-hdmi { vin-supply = <&vdd_smps10_out2>; }; - vdd_2v9_usd: regulator-vdd-usd { - compatible = "regulator-fixed"; - regulator-name = "vdd_sd_slot"; - regulator-min-microvolt = <2900000>; - regulator-max-microvolt = <2900000>; - regulator-boot-on; - gpio = <&gpio TEGRA_GPIO(K, 1) GPIO_ACTIVE_HIGH>; - enable-active-high; - vin-supply = <&vcore_emmc>; - }; - vdd_1v8_cam: regulator-cam-vio { compatible = "regulator-fixed"; regulator-name = "vdd_1v8_cam"; @@ -1932,7 +2662,6 @@ vdd_3v3_com: regulator-com { regulator-name = "vdd_3v3_com"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - regulator-always-on; regulator-boot-on; gpio = <&gpio TEGRA_GPIO(U, 1) GPIO_ACTIVE_HIGH>; enable-active-high; @@ -1960,4 +2689,86 @@ vdd_1v8_touch: regulator-touch-vio { enable-active-high; vin-supply = <&vdd_3v3_sys>; }; + + thermal-zones { + /* + * NCT72 has two sensors: + * + * 0: internal that monitors ambient/skin temperature + * 1: external that is connected to the CPU's diode + * + * Ideally we should use userspace thermal governor, + * but it's a much more complex solution. The "skin" + * zone exists as a simpler solution which prevents + * Transformer from getting too hot from a user's + * tactile perspective. The CPU zone is intended to + * protect silicon from damage. + */ + + nct72-skin-thermal { + polling-delay-passive = <1000>; /* milliseconds */ + polling-delay = <5000>; /* milliseconds */ + + thermal-sensors = <&temp_sensor 0>; + + trips { + skin_alert_trip: skin-alert { + /* throttle at 57C until temperature drops to 56.5C */ + temperature = <57000>; + hysteresis = <500>; + type = "passive"; + }; + + skin-crit { + /* shut down at 65C */ + temperature = <65000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map-skin { + trip = <&skin_alert_trip>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + nct72-cpu-thermal { + polling-delay-passive = <1000>; /* milliseconds */ + polling-delay = <5000>; /* milliseconds */ + + thermal-sensors = <&temp_sensor 1>; + + trips { + cpu_alert_trip: cpu-alert { + /* throttle at 75C until temperature drops to 74.5C */ + temperature = <75000>; + hysteresis = <500>; + type = "passive"; + }; + + cpu-crit { + /* shut down at 105C */ + temperature = <105000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map-cpu { + trip = <&cpu_alert_trip>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + }; };
diff --git a/arch/arm/boot/dts/nvidia/tegra114-dalmore.dts b/arch/arm/boot/dts/nvidia/tegra114-dalmore.dts index c06b52f..8d97a47 100644 --- a/arch/arm/boot/dts/nvidia/tegra114-dalmore.dts +++ b/arch/arm/boot/dts/nvidia/tegra114-dalmore.dts
@@ -969,7 +969,7 @@ smps45 { regulator-boot-on; }; - smps457 { + vdd_core: smps457 { regulator-name = "vdd-core"; regulator-min-microvolt = <900000>; regulator-max-microvolt = <1400000>; @@ -1095,6 +1095,8 @@ flash@0 { }; pmc@7000e400 { + core-supply = <&vdd_core>; + nvidia,invert-interrupt; nvidia,suspend-mode = <1>; nvidia,cpu-pwr-good-time = <500>;
diff --git a/arch/arm/boot/dts/nvidia/tegra114-roth.dts b/arch/arm/boot/dts/nvidia/tegra114-roth.dts index a89b165..f48d5c3 100644 --- a/arch/arm/boot/dts/nvidia/tegra114-roth.dts +++ b/arch/arm/boot/dts/nvidia/tegra114-roth.dts
@@ -837,7 +837,7 @@ vdd_1v8: smps3 { regulator-boot-on; }; - smps457 { + vdd_core: smps457 { regulator-name = "vdd-soc"; regulator-min-microvolt = <900000>; regulator-max-microvolt = <1400000>; @@ -960,6 +960,8 @@ rtc { }; pmc@7000e400 { + core-supply = <&vdd_core>; + nvidia,invert-interrupt; };
diff --git a/arch/arm/boot/dts/nvidia/tegra114-tn7.dts b/arch/arm/boot/dts/nvidia/tegra114-tn7.dts index 75fbafb..4b1e473 100644 --- a/arch/arm/boot/dts/nvidia/tegra114-tn7.dts +++ b/arch/arm/boot/dts/nvidia/tegra114-tn7.dts
@@ -95,7 +95,7 @@ smps123 { regulator-boot-on; }; - smps45 { + vdd_core: smps45 { regulator-name = "vd-soc"; regulator-min-microvolt = <1100000>; regulator-max-microvolt = <1100000>; @@ -241,6 +241,8 @@ rtc { }; pmc@7000e400 { + core-supply = <&vdd_core>; + nvidia,invert-interrupt; };
diff --git a/arch/arm/boot/dts/nvidia/tegra124.dtsi b/arch/arm/boot/dts/nvidia/tegra124.dtsi index ce4efa1..86956b9 100644 --- a/arch/arm/boot/dts/nvidia/tegra124.dtsi +++ b/arch/arm/boot/dts/nvidia/tegra124.dtsi
@@ -1114,13 +1114,13 @@ ahub@70300000 { "rx3", "tx3", "rx4", "tx4", "rx5", "tx5", "rx6", "tx6", "rx7", "tx7", "rx8", "tx8", "rx9", "tx9"; - ranges; - #address-cells = <2>; - #size-cells = <2>; + ranges = <0x70300000 0x0 0x70300000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; tegra_i2s0: i2s@70301000 { compatible = "nvidia,tegra124-i2s"; - reg = <0x0 0x70301000 0x0 0x100>; + reg = <0x70301000 0x100>; nvidia,ahub-cif-ids = <4 4>; clocks = <&tegra_car TEGRA124_CLK_I2S0>; resets = <&tegra_car 30>; @@ -1130,7 +1130,7 @@ tegra_i2s0: i2s@70301000 { tegra_i2s1: i2s@70301100 { compatible = "nvidia,tegra124-i2s"; - reg = <0x0 0x70301100 0x0 0x100>; + reg = <0x70301100 0x100>; nvidia,ahub-cif-ids = <5 5>; clocks = <&tegra_car TEGRA124_CLK_I2S1>; resets = <&tegra_car 11>; @@ -1140,7 +1140,7 @@ tegra_i2s1: i2s@70301100 { tegra_i2s2: i2s@70301200 { compatible = "nvidia,tegra124-i2s"; - reg = <0x0 0x70301200 0x0 0x100>; + reg = <0x70301200 0x100>; nvidia,ahub-cif-ids = <6 6>; clocks = <&tegra_car TEGRA124_CLK_I2S2>; resets = <&tegra_car 18>; @@ -1150,7 +1150,7 @@ tegra_i2s2: i2s@70301200 { tegra_i2s3: i2s@70301300 { compatible = "nvidia,tegra124-i2s"; - reg = <0x0 0x70301300 0x0 0x100>; + reg = <0x70301300 0x100>; nvidia,ahub-cif-ids = <7 7>; clocks = <&tegra_car TEGRA124_CLK_I2S3>; resets = <&tegra_car 101>; @@ -1160,7 +1160,7 @@ tegra_i2s3: i2s@70301300 { tegra_i2s4: i2s@70301400 { compatible = "nvidia,tegra124-i2s"; - reg = <0x0 0x70301400 0x0 0x100>; + reg = <0x70301400 0x100>; nvidia,ahub-cif-ids = <8 8>; clocks = <&tegra_car TEGRA124_CLK_I2S4>; resets = <&tegra_car 102>;
diff --git a/arch/arm/boot/dts/nvidia/tegra20-motorola-daytona.dts b/arch/arm/boot/dts/nvidia/tegra20-motorola-daytona.dts new file mode 100644 index 0000000..72dd915 --- /dev/null +++ b/arch/arm/boot/dts/nvidia/tegra20-motorola-daytona.dts
@@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "tegra20-motorola-mot.dtsi" + +/ { + model = "Motorola Droid X2 (MB870)"; + compatible = "motorola,daytona", "nvidia,tegra20"; + + i2c@7000c000 { + touchscreen@4a { + touchscreen-size-x = <1010>; + touchscreen-size-y = <1023>; + touchscreen-min-x = <25>; + }; + }; + + i2c@7000d000 { + accelerometer@f { + mount-matrix = "-1", "0", "0", + "0", "-1", "0", + "0", "0", "-1"; + }; + + light-sensor@44 { + compatible = "isil,isl29030"; + reg = <0x44>; + + interrupt-parent = <&gpio>; + interrupts = <TEGRA_GPIO(E, 1) IRQ_TYPE_LEVEL_LOW>; + + vdd-supply = <&vdd_hvio>; + }; + }; + + /* Motorola BH5X battery cell */ + battery: battery-cell { + compatible = "simple-battery"; + device-chemistry = "lithium-ion"; + + voltage-min-design-microvolt = <3200000>; + voltage-max-design-microvolt = <4200000>; + + charge-full-design-microamp-hours = <1500000>; + energy-full-design-microwatt-hours = <5600000>; + + constant-charge-voltage-max-microvolt = <4200000>; + operating-range-celsius = <0 45>; + }; + + extcon-keys { + compatible = "gpio-keys"; + + switch-dock-hall-sensor-north { + label = "Dock Hall sensor (north)"; + gpios = <&gpio TEGRA_GPIO(S, 2) GPIO_ACTIVE_LOW>; + linux,input-type = <EV_SW>; + linux,code = <SW_DOCK>; + debounce-interval = <500>; + wakeup-event-action = <EV_ACT_ASSERTED>; + wakeup-source; + }; + + switch-dock-hall-sensor-south { + label = "Dock Hall sensor (south)"; + gpios = <&gpio TEGRA_GPIO(S, 0) GPIO_ACTIVE_LOW>; + linux,input-type = <EV_SW>; + linux,code = <SW_DOCK>; + debounce-interval = <500>; + wakeup-event-action = <EV_ACT_ASSERTED>; + wakeup-source; + }; + }; + + matrix-keypad { + compatible = "gpio-matrix-keypad"; + + debounce-delay-ms = <10>; + col-scan-delay-us = <5>; + + row-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_LOW + &gpio TEGRA_GPIO(R, 1) GPIO_ACTIVE_LOW + &gpio TEGRA_GPIO(R, 2) GPIO_ACTIVE_LOW + &gpio TEGRA_GPIO(R, 3) GPIO_ACTIVE_LOW>; + col-gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW + &gpio TEGRA_GPIO(Q, 1) GPIO_ACTIVE_LOW + &gpio TEGRA_GPIO(Q, 2) GPIO_ACTIVE_LOW>; + + gpio-activelow; + + linux,keymap = <MATRIX_KEY(0x00, 0x00, KEY_VOLUMEUP) + + MATRIX_KEY(0x01, 0x00, KEY_VOLUMEDOWN) + + MATRIX_KEY(0x02, 0x00, KEY_BACK) + MATRIX_KEY(0x02, 0x01, KEY_SEARCH) + MATRIX_KEY(0x02, 0x02, KEY_HOME) + + MATRIX_KEY(0x03, 0x01, KEY_MENU)>; + + wakeup-source; + }; + + sound { + nvidia,model = "Motorola Droid X2 (MB870) CPCAP"; + }; +};
diff --git a/arch/arm/boot/dts/nvidia/tegra20-motorola-mot.dtsi b/arch/arm/boot/dts/nvidia/tegra20-motorola-mot.dtsi new file mode 100644 index 0000000..508b95e --- /dev/null +++ b/arch/arm/boot/dts/nvidia/tegra20-motorola-mot.dtsi
@@ -0,0 +1,1194 @@ +// SPDX-License-Identifier: GPL-2.0 + +#include <dt-bindings/input/atmel-maxtouch.h> +#include <dt-bindings/input/gpio-keys.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/thermal/thermal.h> + +#include "tegra20.dtsi" +#include "tegra20-cpu-opp.dtsi" +#include "tegra20-cpu-opp-microvolt.dtsi" + +/ { + chassis-type = "handset"; + + aliases { + mmc0 = &sdmmc4; /* eMMC */ + mmc1 = &sdmmc3; /* uSD slot */ + mmc2 = &sdmmc1; /* WiFi */ + + rtc0 = &cpcap_rtc; + rtc1 = "/rtc@7000e000"; + + serial0 = &uartb; /* Console */ + serial1 = &uartc; /* Bluetooth */ + }; + + /* + * The decompressor and also some bootloaders rely on a + * pre-existing /chosen node to be available to insert the + * command line and merge other ATAGS info. + */ + chosen { }; + + memory@0 { + reg = <0x00000000 0x40000000>; + }; + + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + linux,cma@20000000 { + compatible = "shared-dma-pool"; + alloc-ranges = <0x20000000 0x10000000>; + size = <0x10000000>; /* 256MiB */ + linux,cma-default; + reusable; + }; + }; + + host1x@50000000 { + vi@54080000 { + status = "okay"; + + csi@800 { + status = "okay"; + + avdd-dsi-csi-supply = <&avdd_dsi_csi>; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + vi_ppa_input: endpoint { + /* Link to the rear camera */ + }; + }; + + port@1 { + reg = <1>; + + vi_ppb_input: endpoint { + /* Link to the front camera */ + }; + }; + }; + }; + + hdmi@54280000 { + status = "okay"; + + /* + * Mot uses PLLD for both HDMI and DSI. HDMI does + * not support opps for frequencies used by DSI. + * Consequently, DSI works, but it causes HDMI to + * fail. Remove operating-points-v2 from HDMI. + */ + /delete-property/ operating-points-v2; + + vdd-supply = <&avdd_3v3_periph>; + pll-supply = <&vdd_hvio>; + hdmi-supply = <&vdd_hdmi_en>; + + port { + hdmi_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; + }; + }; + + dsi@54300000 { + status = "okay"; + + avdd-dsi-csi-supply = <&avdd_dsi_csi>; + + panel@0 { + compatible = "motorola,mot-panel"; + reg = <0>; + + reset-gpios = <&gpio TEGRA_GPIO(E, 3) GPIO_ACTIVE_LOW>; + + vdd-supply = <&vdd_5v0_panel>; + vddio-supply = <&vdd_1v8_vio>; + + backlight = <&backlight>; + }; + }; + }; + + gpio@6000d000 { + usb-mux-hog { + gpio-hog; + gpios = <TEGRA_GPIO(V, 6) GPIO_ACTIVE_HIGH>; + output-high; + }; + }; + + pinmux@70000014 { + pinctrl-names = "default"; + pinctrl-0 = <&state_default>; + + state_default: pinmux { + crt { + nvidia,pins = "crtp"; + nvidia,function = "crt"; + }; + + dap1 { + nvidia,pins = "dap1"; + nvidia,function = "dap1"; + }; + + dap2 { + nvidia,pins = "dap2"; + nvidia,function = "dap2"; + }; + + dap3 { + nvidia,pins = "dap3"; + nvidia,function = "dap3"; + }; + + dap4 { + nvidia,pins = "dap4"; + nvidia,function = "dap4"; + }; + + displaya { + nvidia,pins = "lcsn", "ld0", "ld1", "ld3", + "ld5", "ld6", "ld7", "ld8", + "ld9", "ld12", "ld13", "ld14", + "ld15", "ld16", "ld17", "ldi", + "lhp0", "lhp1", "lhp2", "lhs", + "lpp", "lsc0", "lpw1", "lsda", + "lspi"; + nvidia,function = "displaya"; + }; + + gmi { + nvidia,pins = "ata", "atc", "atd", "ate", + "gmb", "gmd", "gpu"; + nvidia,function = "gmi"; + }; + + hdmi { + nvidia,pins = "hdint"; + nvidia,function = "hdmi"; + }; + + i2c1 { + nvidia,pins = "rm"; + nvidia,function = "i2c1"; + }; + + i2c2 { + nvidia,pins = "ddc"; + nvidia,function = "i2c2"; + }; + + i2c3 { + nvidia,pins = "dtf"; + nvidia,function = "i2c3"; + }; + + i2cp { + nvidia,pins = "i2cp"; + nvidia,function = "i2cp"; + }; + + kbc { + nvidia,pins = "kbca", "kbcb", "kbcc", "kbcd", + "kbce", "kbcf"; + nvidia,function = "kbc"; + }; + + osc { + nvidia,pins = "cdev1", "cdev2"; + nvidia,function = "osc"; + }; + + owr { + nvidia,pins = "owc", "uac"; + nvidia,function = "owr"; + }; + + pcie { + nvidia,pins = "gpv"; + nvidia,function = "pcie"; + }; + + pwr-on { + nvidia,pins = "pmc"; + nvidia,function = "pwr_on"; + }; + + rsvd3 { + nvidia,pins = "lm1"; + nvidia,function = "rsvd3"; + }; + + rsvd4 { + nvidia,pins = "lvp0", "lvp1", "lvs", "ld10", + "ld11", "ld2", "ld4", "ldc"; + nvidia,function = "rsvd4"; + }; + + rtck { + nvidia,pins = "gpu7"; + nvidia,function = "rtck"; + }; + + sdio1 { + nvidia,pins = "sdio1"; + nvidia,function = "sdio1"; + }; + + sdio3 { + nvidia,pins = "sdb", "sdc", "sdd"; + nvidia,function = "sdio3"; + }; + + sdio4 { + nvidia,pins = "atb", "gma", "gme"; + nvidia,function = "sdio4"; + }; + + spdif { + nvidia,pins = "slxc", "slxd"; + nvidia,function = "spdif"; + }; + + spi1 { + nvidia,pins = "spid", "spie", "spif"; + nvidia,function = "spi1"; + }; + + spi2 { + nvidia,pins = "spia", "spib", "spic", "spig", + "spih"; + nvidia,function = "spi2"; + }; + + spi3 { + nvidia,pins = "lm0", "lpw0", "lpw2", "lsc1"; + nvidia,function = "spi3"; + }; + + uarta { + nvidia,pins = "irrx", "irtx"; + nvidia,function = "uarta"; + }; + + uartc { + nvidia,pins = "uca", "ucb"; + nvidia,function = "uartc"; + }; + + uartd { + nvidia,pins = "gmc"; + nvidia,function = "uartd"; + }; + + ulpi { + nvidia,pins = "uab"; + nvidia,function = "ulpi"; + }; + + vi { + nvidia,pins = "dta", "dtb", "dtc", "dtd", + "dte"; + nvidia,function = "vi"; + }; + + vi-sensor-clk { + nvidia,pins = "csus"; + nvidia,function = "vi_sensor_clk"; + }; + + conf-lcsn { + nvidia,pins = "lcsn", "lpw1", "lsck", "lsda", + "lsdi", "ldc", "hdint"; + nvidia,tristate = <TEGRA_PIN_ENABLE>; + }; + + conf-ata { + nvidia,pins = "ata", "atc", "ddc", "gmc", + "gpu", "kbca", "kbcb", "kbcc", + "kbcd", "kbce", "kbcf", "owc", + "sdc", "sdd", "sdio1", "uaa", + "uad", "uca", "ucb", "pmce"; + nvidia,pull = <TEGRA_PIN_PULL_UP>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + }; + + conf-crtp { + nvidia,pins = "crtp", "csus", "pta"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + }; + + conf-atd { + nvidia,pins = "atb", "atd", "ate", "cdev2", + "cdev1", "dte", "gma", "gmb", + "gmd", "gme", "gpu7", "gpv", + "i2cp", "irrx", "irtx", "rm", + "slxa", "slxc", "slxd", "slxk", + "spdi", "spdo", "spid", "spie", + "spif", "uda", "ck32", "ddrc", + "pmca", "pmcb", "pmcc", "pmcd", + "xm2c", "xm2d"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + }; + + conf-ld0 { + nvidia,pins = "ld0", "ld1", "ld2", "ld3", + "ld4", "ld5", "ld6", "ld7", + "ld8", "ld9", "ld10", "ld11", + "ld12", "ld13", "ld14", "ld15", + "ld16", "ld17", "ldi", "lhp0", + "lhp1", "lhp2", "lhs", "lm0", + "lpp", "lpw0", "lpw2", "lsc0", + "lsc1", "lspi", "lvp1", "lm1", + "lvp0", "lvs", "pmc", "sdb"; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + }; + + conf-dta { + nvidia,pins = "dap1", "dap2", "dap3", "dap4", + "dta", "dtb", "dtc", "dtd", "dtf"; + nvidia,pull = <TEGRA_PIN_PULL_DOWN>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + }; + + conf-spi2 { + nvidia,pins = "spia", "spib", "spic", "spig", + "spih"; + nvidia,pull = <TEGRA_PIN_PULL_NONE>; + nvidia,tristate = <TEGRA_PIN_DISABLE>; + }; + + drive-sdio1 { + nvidia,pins = "drive_sdio1", "drive_ddc", "drive_vi1", + "drive_vi2", "drive_dbg"; + nvidia,high-speed-mode = <TEGRA_PIN_DISABLE>; + nvidia,schmitt = <TEGRA_PIN_ENABLE>; + nvidia,low-power-mode = <TEGRA_PIN_LP_DRIVE_DIV_1>; + nvidia,pull-down-strength = <31>; + nvidia,pull-up-strength = <31>; + nvidia,slew-rate-rising = <TEGRA_PIN_SLEW_RATE_SLOWEST>; + nvidia,slew-rate-falling = <TEGRA_PIN_SLEW_RATE_SLOWEST>; + }; + }; + }; + + spdif@70002400 { + status = "okay"; + + nvidia,fixed-parent-rate; + }; + + tegra_i2s1: i2s@70002800 { + status = "okay"; + + nvidia,fixed-parent-rate; + }; + + uartb: serial@70006040 { + /delete-property/ dmas; + /delete-property/ dma-names; + status = "okay"; + + /* Console */ + }; + + uartc: serial@70006200 { + compatible = "nvidia,tegra20-hsuart"; + reset-names = "serial"; + /delete-property/ reg-shift; + status = "okay"; + + nvidia,adjust-baud-rates = <0 9600 100>, + <9600 115200 200>, + <1000000 4000000 136>; + + /* Broadcom BCM4329HKUBG */ + bluetooth { + compatible = "brcm,bcm4329-bt"; + + interrupt-parent = <&gpio>; + interrupts = <TEGRA_GPIO(U, 6) IRQ_TYPE_EDGE_RISING>; + interrupt-names = "host-wakeup"; + + /* PLLP 216MHz / 16 / 4 */ + max-speed = <3375000>; + + clocks = <&tegra_pmc TEGRA_PMC_CLK_BLINK>; + clock-names = "txco"; + + vbat-supply = <&vdd_3v3_sys>; + vddio-supply = <&vdd_1v8_vio>; + + device-wakeup-gpios = <&gpio TEGRA_GPIO(U, 1) GPIO_ACTIVE_HIGH>; + shutdown-gpios = <&gpio TEGRA_GPIO(U, 4) GPIO_ACTIVE_HIGH>; + reset-gpios = <&gpio TEGRA_GPIO(U, 0) GPIO_ACTIVE_LOW>; + }; + }; + + gen1_i2c: i2c@7000c000 { + status = "okay"; + clock-frequency = <400000>; + + led-controller@38 { + compatible = "ti,lm3532"; + reg = <0x38>; + + enable-gpios = <&gpio TEGRA_GPIO(E, 0) GPIO_ACTIVE_HIGH>; + + vin-supply = <&vdd_led>; + + ramp-up-us = <0>; + ramp-down-us = <0>; + + #address-cells = <1>; + #size-cells = <0>; + + backlight_led: led@0 { + reg = <0>; + + led-sources = <0>; + led-max-microamp = <26600>; + + ti,led-mode = <0>; + ti,linear-mapping-mode; + + label = ":backlight"; + }; + }; + + touchscreen@4a { + compatible = "atmel,maxtouch"; + reg = <0x4a>; + + interrupt-parent = <&gpio>; + interrupts = <TEGRA_GPIO(F, 5) IRQ_TYPE_LEVEL_LOW>; + + touchscreen-min-y = <10>; + touchscreen-swapped-x-y; + + reset-gpios = <&gpio TEGRA_GPIO(F, 4) GPIO_ACTIVE_LOW>; + + vdda-supply = <&vdd_3v3_sys>; + vdd-supply = <&vdd_3v3_sys>; + }; + }; + + hdmi_ddc: i2c@7000c400 { + status = "okay"; + clock-frequency = <100000>; + }; + + cam_i2c: i2c@7000c500 { + status = "okay"; + clock-frequency = <400000>; + }; + + sen_i2c: i2c@7000d000 { + status = "okay"; + clock-frequency = <400000>; + + magnetometer@c { + compatible = "asahi-kasei,ak8975"; + reg = <0xc>; + + interrupt-parent = <&gpio>; + interrupts = <TEGRA_GPIO(E, 2) IRQ_TYPE_EDGE_RISING>; + + reset-gpios = <&gpio TEGRA_GPIO(K, 5) GPIO_ACTIVE_LOW>; + + vdd-supply = <&vdd_hvio>; + vid-supply = <&vdd_1v8_vio>; + }; + + accelerometer@f { + compatible = "kionix,kxtf9"; + reg = <0xf>; + + interrupt-parent = <&gpio>; + interrupts = <TEGRA_GPIO(V, 3) IRQ_TYPE_EDGE_RISING>; + + vdd-supply = <&vdd_hvio>; + vddio-supply = <&vdd_1v8_vio>; + }; + + nct1008: temperature-sensor@4c { + compatible = "onnn,nct1008"; + reg = <0x4c>; + + interrupt-parent = <&gpio>; + interrupts = <TEGRA_GPIO(D, 1) IRQ_TYPE_EDGE_FALLING>; + + vcc-supply = <&vcore_emmc>; + #thermal-sensor-cells = <1>; + }; + }; + + spi@7000d600 { + status = "okay"; + spi-max-frequency = <25000000>; + + cpcap: pmic@0 { + compatible = "motorola,mot-cpcap"; + reg = <0>; + + spi-cs-high; + spi-max-frequency = <8000000>; + + interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; + + interrupt-controller; + #interrupt-cells = <2>; + + cpcap_adc: adc { + compatible = "motorola,mot-cpcap-adc"; + + interrupts-extended = <&cpcap 8 IRQ_TYPE_NONE>; + interrupt-names = "adcdone"; + + #io-channel-cells = <1>; + }; + + cpcap_audio: audio-codec { + interrupts-extended = <&cpcap 9 IRQ_TYPE_NONE>, + <&cpcap 10 IRQ_TYPE_NONE>; + interrupt-names = "hs", "mb2"; + + VAUDIO-supply = <&vdd_audio>; + + #sound-dai-cells = <1>; + }; + + /* CHARGE_NOW has to be dumped and preloaded on each reboot */ + battery { + compatible = "motorola,cpcap-battery"; + + interrupts-extended = + <&cpcap 6 IRQ_TYPE_NONE>, <&cpcap 5 IRQ_TYPE_NONE>, + <&cpcap 3 IRQ_TYPE_NONE>, <&cpcap 20 IRQ_TYPE_NONE>, + <&cpcap 54 IRQ_TYPE_NONE>, <&cpcap 57 IRQ_TYPE_NONE>; + interrupt-names = + "eol", "lowbph", "lowbpl", + "chrgcurr1", "battdetb", "cccal"; + + io-channels = <&cpcap_adc 0>, <&cpcap_adc 1>, + <&cpcap_adc 5>, <&cpcap_adc 6>; + io-channel-names = "battdetb", "battp", + "chg_isense", "batti"; + + monitored-battery = <&battery>; + }; + + key-power { + compatible = "motorola,cpcap-pwrbutton"; + + interrupt-parent = <&cpcap>; + interrupts = <23 IRQ_TYPE_NONE>; + }; + + led-red { + compatible = "motorola,cpcap-led-red"; + vdd-supply = <&vdd_led>; + label = "status-led::red"; + }; + + led-green { + compatible = "motorola,cpcap-led-green"; + vdd-supply = <&vdd_led>; + label = "status-led::green"; + }; + + led-blue { + compatible = "motorola,cpcap-led-blue"; + vdd-supply = <&vdd_led>; + label = "status-led::blue"; + }; + + led-adl { + compatible = "motorola,cpcap-led-adl"; + vdd-supply = <&vdd_led>; + label = "cpcap::keypad"; + }; + + regulator { + compatible = "motorola,mot-cpcap-regulator"; + + regulators { + vdd_cpu: SW1 { + regulator-name = "vdd_cpu"; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <1125000>; + regulator-coupled-with = <&vdd_core &vdd_rtc>; + regulator-coupled-max-spread = <550000 550000>; + regulator-enable-ramp-delay = <1500>; + regulator-always-on; + regulator-boot-on; + + nvidia,tegra-cpu-regulator; + }; + + vdd_core: SW2 { + regulator-name = "vdd_core"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1300000>; + regulator-coupled-with = <&vdd_rtc &vdd_cpu>; + regulator-coupled-max-spread = <170000 550000>; + regulator-enable-ramp-delay = <1500>; + regulator-always-on; + regulator-boot-on; + + nvidia,tegra-core-regulator; + }; + + vdd_1v8_vio: SW3 { + regulator-name = "vdd_1v8_vio"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <0>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_rtc: SW4 { + regulator-name = "vdd_aon"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1300000>; + regulator-coupled-with = <&vdd_core &vdd_cpu>; + regulator-coupled-max-spread = <170000 550000>; + regulator-enable-ramp-delay = <1500>; + regulator-always-on; + regulator-boot-on; + + nvidia,tegra-rtc-regulator; + }; + + vdd_led: SW5 { + regulator-name = "vdd_led"; + regulator-min-microvolt = <5050000>; + regulator-max-microvolt = <5050000>; + regulator-enable-ramp-delay = <1500>; + regulator-boot-on; + }; + + VCAM { + regulator-name = "vdd_cam1"; + regulator-min-microvolt = <2600000>; + regulator-max-microvolt = <2900000>; + regulator-enable-ramp-delay = <1000>; + }; + + avdd_dsi_csi: VCSI { + regulator-name = "avdd_dsi_csi"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-enable-ramp-delay = <1000>; + regulator-boot-on; + }; + + vdd_hvio: VHVIO { + regulator-name = "vdd_hvio"; + regulator-min-microvolt = <2775000>; + regulator-max-microvolt = <2775000>; + regulator-enable-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + }; + + vcore_emmc: VSDIO { + regulator-name = "vcore_emmc"; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <3000000>; + regulator-enable-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + }; + + VPLL { + regulator-name = "avdd_pll"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-enable-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + }; + + avdd_3v3_periph: VWLAN2 { + regulator-name = "avdd_3v3_periph"; + regulator-min-microvolt = <2775000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <1000>; + regulator-boot-on; + }; + + vddio_usd: VSIMCARD { + regulator-name = "vddio_usd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2900000>; + regulator-enable-ramp-delay = <1000>; + regulator-boot-on; + }; + + vdd_haptic: VVIB { + regulator-name = "vdd_haptic"; + regulator-min-microvolt = <1300000>; + regulator-max-microvolt = <3000000>; + regulator-enable-ramp-delay = <1000>; + }; + + vdd_usb_det: VUSB { + regulator-name = "vdd_usb_det"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-enable-ramp-delay = <1000>; + regulator-always-on; + regulator-boot-on; + }; + + vdd_audio: VAUDIO { + regulator-name = "vdd_audio"; + regulator-min-microvolt = <2775000>; + regulator-max-microvolt = <2775000>; + regulator-enable-ramp-delay = <1000>; + regulator-allowed-modes = <0x00>, <0x40>; + regulator-initial-mode = <0x00>; /* NORMAL */ + }; + }; + }; + + cpcap_rtc: rtc { + compatible = "motorola,cpcap-rtc"; + + interrupt-parent = <&cpcap>; + interrupts = <39 IRQ_TYPE_NONE>, <26 IRQ_TYPE_NONE>; + }; + }; + }; + + pmc@7000e400 { + nvidia,suspend-mode = <1>; + nvidia,cpu-pwr-good-time = <800>; + nvidia,cpu-pwr-off-time = <600>; + nvidia,core-pwr-good-time = <1842 1842>; + nvidia,core-pwr-off-time = <31>; + nvidia,core-power-req-active-high; + nvidia,sys-clock-req-active-high; + core-supply = <&vdd_core>; + }; + + memory-controller@7000f400 { + nvidia,use-ram-code; + + emc-tables@0 { + reg = <0>; + + #address-cells = <1>; + #size-cells = <0>; + + /* Elpida 1G 50nm */ + lpddr2 { + compatible = "elpida,B8132B2PB-6D-F", "jedec,lpddr2-s4"; + revision-id = <0 0>; + density = <2048>; + io-width = <16>; + }; + + emc-table@25000 { + reg = <25000>; + compatible = "nvidia,tegra20-emc-table"; + clock-frequency = <25000>; + nvidia,emc-registers = < 0x00000002 0x00000006 + 0x00000003 0x00000003 0x00000006 0x00000004 + 0x00000002 0x00000009 0x00000003 0x00000003 + 0x00000002 0x00000002 0x00000002 0x00000004 + 0x00000003 0x00000008 0x0000000b 0x0000004d + 0x00000000 0x00000003 0x00000003 0x00000003 + 0x00000008 0x00000001 0x0000000a 0x00000004 + 0x00000003 0x00000008 0x00000004 0x00000006 + 0x00000002 0x00000068 0x00000000 0x00000003 + 0x00000000 0x00000000 0x00000282 0xa06804ae + 0x00004810 0x00000000 0x00000000 0x00000003 + 0x00000000 0x00000000 0x00000000 0x00000000 >; + }; + + emc-table@50000 { + reg = <50000>; + compatible = "nvidia,tegra20-emc-table"; + clock-frequency = <50000>; + nvidia,emc-registers = < 0x00000003 0x00000007 + 0x00000003 0x00000003 0x00000006 0x00000004 + 0x00000002 0x00000009 0x00000003 0x00000003 + 0x00000002 0x00000002 0x00000002 0x00000005 + 0x00000003 0x00000008 0x0000000b 0x0000009f + 0x00000000 0x00000003 0x00000003 0x00000003 + 0x00000008 0x00000001 0x0000000a 0x00000007 + 0x00000003 0x00000008 0x00000004 0x00000006 + 0x00000002 0x000000d0 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000282 0xa06804ae + 0x00004810 0x00000000 0x00000000 0x00000005 + 0x00000000 0x00000000 0x00000000 0x00000000 >; + }; + + emc-table@75000 { + reg = <75000>; + compatible = "nvidia,tegra20-emc-table"; + clock-frequency = <75000>; + nvidia,emc-registers = < 0x00000005 0x0000000a + 0x00000004 0x00000003 0x00000006 0x00000004 + 0x00000002 0x00000009 0x00000003 0x00000003 + 0x00000002 0x00000002 0x00000002 0x00000005 + 0x00000003 0x00000008 0x0000000b 0x000000ff + 0x00000000 0x00000003 0x00000003 0x00000003 + 0x00000008 0x00000001 0x0000000a 0x0000000b + 0x00000003 0x00000008 0x00000004 0x00000006 + 0x00000002 0x00000138 0x00000000 0x00000000 + 0x00000000 0x00000000 0x00000282 0xa06804ae + 0x00004810 0x00000000 0x00000000 0x00000007 + 0x00000000 0x00000000 0x00000000 0x00000000 >; + }; + + emc-table@150000 { + reg = <150000>; + compatible = "nvidia,tegra20-emc-table"; + clock-frequency = <150000>; + nvidia,emc-registers = < 0x00000009 0x00000014 + 0x00000007 0x00000004 0x00000006 0x00000004 + 0x00000002 0x00000009 0x00000003 0x00000003 + 0x00000002 0x00000002 0x00000002 0x00000005 + 0x00000003 0x00000008 0x0000000b 0x0000021f + 0x00000000 0x00000003 0x00000003 0x00000004 + 0x00000008 0x00000001 0x0000000a 0x00000015 + 0x00000003 0x00000008 0x00000004 0x00000006 + 0x00000002 0x00000270 0x00000000 0x00000001 + 0x00000000 0x00000000 0x00000282 0xa04c04ae + 0x007fc010 0x00000000 0x00000000 0x0000000e + 0x00000000 0x00000000 0x00000000 0x00000000 >; + }; + + emc-table@300000 { + reg = <300000>; + compatible = "nvidia,tegra20-emc-table"; + clock-frequency = <300000>; + nvidia,emc-registers = < 0x00000012 0x00000027 + 0x0000000d 0x00000007 0x00000007 0x00000005 + 0x00000003 0x00000009 0x00000006 0x00000006 + 0x00000003 0x00000003 0x00000002 0x00000006 + 0x00000003 0x00000009 0x0000000c 0x0000045f + 0x00000000 0x00000004 0x00000004 0x00000007 + 0x00000008 0x00000001 0x0000000e 0x0000002a + 0x00000003 0x0000000f 0x00000008 0x00000005 + 0x00000002 0x000004e0 0x00000005 0x00000002 + 0x00000000 0x00000000 0x00000282 0xf04c040b + 0x007fe010 0x00000000 0x00000000 0x0000001b + 0x00000000 0x00000000 0x00000000 0x00000000 >; + }; + }; + }; + + usb@c5000000 { + compatible = "nvidia,tegra20-udc"; + status = "okay"; + dr_mode = "peripheral"; + }; + + usb-phy@c5000000 { + status = "okay"; + dr_mode = "peripheral"; + nvidia,xcvr-setup = <8>; + nvidia,xcvr-lsfslew = <2>; + nvidia,xcvr-lsrslew = <2>; + vbus-supply = <&avdd_3v3_periph>; + }; + + sdmmc1: mmc@c8000000 { + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + + assigned-clocks = <&tegra_car TEGRA20_CLK_SDMMC1>; + assigned-clock-parents = <&tegra_car TEGRA20_CLK_PLL_P>; + assigned-clock-rates = <50000000>; + + max-frequency = <50000000>; + keep-power-in-suspend; + bus-width = <4>; + non-removable; + + mmc-pwrseq = <&brcm_wifi_pwrseq>; + vmmc-supply = <&vdd_3v3_com>; + vqmmc-supply = <&vdd_1v8_vio>; + + /* Broadcom BCM4329HKUBG */ + wifi@1 { + compatible = "brcm,bcm4329-fmac"; + reg = <1>; + + interrupt-parent = <&gpio>; + interrupts = <TEGRA_GPIO(U, 5) IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "host-wake"; + }; + }; + + sdmmc3: mmc@c8000400 { + status = "okay"; + bus-width = <4>; + + cd-gpios = <&gpio TEGRA_GPIO(I, 5) GPIO_ACTIVE_LOW>; + disable-wp; + + vmmc-supply = <&vdd_usd>; + vqmmc-supply = <&vddio_usd>; + }; + + sdmmc4: mmc@c8000600 { + status = "okay"; + bus-width = <8>; + non-removable; + + vmmc-supply = <&vcore_emmc>; + vqmmc-supply = <&vdd_1v8_vio>; + }; + + backlight: backlight { + compatible = "led-backlight"; + + leds = <&backlight_led>; + + brightness-levels = <31 63 95 127 159 191 223 255>; + default-brightness-level = <6>; + }; + + /* 32KHz oscillator which is used by PMC */ + clk32k_in: clock-32k-in { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + clock-output-names = "ref-oscillator"; + }; + + cpus { + cpu0: cpu@0 { + cpu-supply = <&vdd_cpu>; + operating-points-v2 = <&cpu0_opp_table>; + #cooling-cells = <2>; + }; + + cpu1: cpu@1 { + cpu-supply = <&vdd_cpu>; + operating-points-v2 = <&cpu0_opp_table>; + #cooling-cells = <2>; + }; + }; + + gpio-poweroff { + compatible = "gpio-poweroff"; + gpios = <&gpio TEGRA_GPIO(V, 7) GPIO_ACTIVE_LOW>; + timeout-ms = <500>; + }; + + haptic-feedback { + compatible = "gpio-vibrator"; + enable-gpios = <&gpio TEGRA_GPIO(D, 0) GPIO_ACTIVE_HIGH>; + vcc-supply = <&vdd_haptic>; + }; + + hdmi-connector { + compatible = "hdmi-connector"; + type = "d"; + + hpd-gpios = <&gpio TEGRA_GPIO(N, 7) GPIO_ACTIVE_HIGH>; + ddc-i2c-bus = <&hdmi_ddc>; + + port { + hdmi_connector_in: endpoint { + remote-endpoint = <&hdmi_out>; + }; + }; + }; + + opp-table-emc { + /delete-node/ opp-666000000; + /delete-node/ opp-760000000; + }; + + brcm_wifi_pwrseq: pwrseq-wifi { + compatible = "mmc-pwrseq-simple"; + + clocks = <&tegra_pmc TEGRA_PMC_CLK_BLINK>; + clock-names = "ext_clock"; + + reset-gpios = <&gpio TEGRA_GPIO(U, 2) GPIO_ACTIVE_LOW>; + post-power-on-delay-ms = <200>; + power-off-delay-us = <200>; + }; + + vdd_5v0_sys: regulator-5v0 { + compatible = "regulator-fixed"; + regulator-name = "vdd_5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + }; + + vdd_3v3_sys: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "vdd_3v3_vs"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + vin-supply = <&vdd_5v0_sys>; + }; + + vdd_1v2_lpddr2: regulator-lpddr2 { + compatible = "regulator-fixed"; + regulator-name = "vddio_ddr"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-always-on; + regulator-boot-on; + vin-supply = <&vdd_hvio>; + }; + + vdd_5v0_panel: regulator-panel { + compatible = "regulator-fixed"; + regulator-name = "vdd_5v0_disp"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + gpio = <&gpio TEGRA_GPIO(F, 7) GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <&vdd_5v0_sys>; + }; + + vdd_usd: regulator-usd { + compatible = "regulator-fixed"; + regulator-name = "vdd_usd"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + gpio = <&gpio TEGRA_GPIO(F, 3) GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <&vdd_3v3_sys>; + }; + + vdd_3v3_com: regulator-com { + compatible = "regulator-fixed"; + regulator-name = "vdd_3v3_com"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + gpio = <&gpio TEGRA_GPIO(U, 3) GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <&vdd_3v3_sys>; + }; + + vdd_hdmi_en: regulator-hdmi { + compatible = "regulator-fixed"; + regulator-name = "vdd_5v0_hdmi_en"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio TEGRA_GPIO(F, 6) GPIO_ACTIVE_HIGH>; + enable-active-high; + vin-supply = <&vdd_5v0_sys>; + }; + + sound { + compatible = "motorola,tegra-audio-cpcap-mot", + "nvidia,tegra-audio-cpcap"; + + nvidia,audio-routing = + "Headphones", "HSR", + "Headphones", "HSL", + "Int Spk", "SPKR", + "Int Spk", "SPKL", + "Earpiece", "EP", + "HSMIC", "Mic Jack", + "MICR", "Internal Mic 1", + "MICL", "Internal Mic 2"; + + nvidia,i2s-controller = <&tegra_i2s1>; + nvidia,audio-codec = <&cpcap_audio>; + + clocks = <&tegra_car TEGRA20_CLK_PLL_A>, + <&tegra_car TEGRA20_CLK_PLL_A_OUT0>, + <&tegra_car TEGRA20_CLK_CDEV1>; + clock-names = "pll_a", "pll_a_out0", "mclk"; + }; + + thermal-zones { + skin-thermal { + polling-delay-passive = <1000>; /* milliseconds */ + polling-delay = <5000>; /* milliseconds */ + + thermal-sensors = <&nct1008 0>; + + trips { + trip0: skin-alert { + /* throttle at 57C until temperature drops to 56.8C */ + temperature = <57000>; + hysteresis = <200>; + type = "passive"; + }; + + trip1: skin-crit { + /* shut down at 65C */ + temperature = <65000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&trip0>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-thermal { + polling-delay-passive = <500>; /* milliseconds */ + polling-delay = <1500>; /* milliseconds */ + + thermal-sensors = <&nct1008 1>; + + trips { + trip2: cpu-alert { + /* throttle at 75C until temperature drops to 74.8C */ + temperature = <75000>; + hysteresis = <200>; + type = "passive"; + }; + + trip3: cpu-crit { + /* shut down at 90C */ + temperature = <90000>; + hysteresis = <2000>; + type = "critical"; + }; + }; + + cooling-maps { + map1 { + trip = <&trip2>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + }; +};
diff --git a/arch/arm/boot/dts/nvidia/tegra20-motorola-olympus.dts b/arch/arm/boot/dts/nvidia/tegra20-motorola-olympus.dts new file mode 100644 index 0000000..f53a057 --- /dev/null +++ b/arch/arm/boot/dts/nvidia/tegra20-motorola-olympus.dts
@@ -0,0 +1,108 @@ +// SPDX-License-Identifier: GPL-2.0 +/dts-v1/; + +#include "tegra20-motorola-mot.dtsi" + +/ { + model = "Motorola Atrix 4G (MB860)"; + compatible = "motorola,olympus", "nvidia,tegra20"; + + gpio@6000d000 { + volume-buttons-hog { + gpio-hog; + gpios = <TEGRA_GPIO(Q, 0) GPIO_ACTIVE_HIGH>; + output-low; + }; + }; + + i2c@7000c000 { + led-controller@38 { + led@1 { + reg = <1>; + + led-sources = <1 2>; + led-max-microamp = <8200>; + + ti,led-mode = <0>; + ti,linear-mapping-mode; + + label = ":keypad"; + }; + }; + + touchscreen@4a { + touchscreen-size-x = <930>; + touchscreen-size-y = <1018>; + touchscreen-min-x = <0>; + + /* Buttons are just a part of touchscreen */ + }; + + light-sensor@44 { + compatible = "isil,isl29030"; + reg = <0x44>; + + interrupt-parent = <&gpio>; + interrupts = <TEGRA_GPIO(E, 1) IRQ_TYPE_LEVEL_LOW>; + + vdd-supply = <&vdd_hvio>; + }; + }; + + i2c@7000d000 { + accelerometer@f { + mount-matrix = "1", "0", "0", + "0", "1", "0", + "0", "0", "-1"; + }; + }; + + spi@7000d600 { + pmic@0 { + led-adl { + status = "disabled"; + }; + }; + }; + + /* Motorola BH6X battery cell */ + battery: battery-cell { + compatible = "simple-battery"; + device-chemistry = "lithium-ion-polymer"; + + voltage-min-design-microvolt = <3200000>; + voltage-max-design-microvolt = <4200000>; + + charge-full-design-microamp-hours = <1880000>; + energy-full-design-microwatt-hours = <7000000>; + + constant-charge-voltage-max-microvolt = <4200000>; + operating-range-celsius = <0 45>; + }; + + gpio-keys { + compatible = "gpio-keys"; + + key-volume-down { + label = "Volume Down"; + gpios = <&gpio TEGRA_GPIO(R, 1) GPIO_ACTIVE_LOW>; + linux,code = <KEY_VOLUMEDOWN>; + debounce-interval = <10>; + wakeup-event-action = <EV_ACT_ASSERTED>; + wakeup-source; + }; + + key-volume-up { + label = "Volume Up"; + gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_LOW>; + linux,code = <KEY_VOLUMEUP>; + debounce-interval = <10>; + wakeup-event-action = <EV_ACT_ASSERTED>; + wakeup-source; + }; + }; + + sound { + nvidia,model = "Motorola Atrix 4G (MB860) CPCAP"; + }; +};
diff --git a/arch/arm/boot/dts/nvidia/tegra30-lg-p880.dts b/arch/arm/boot/dts/nvidia/tegra30-lg-p880.dts index 6b30e17..3a5e66d 100644 --- a/arch/arm/boot/dts/nvidia/tegra30-lg-p880.dts +++ b/arch/arm/boot/dts/nvidia/tegra30-lg-p880.dts
@@ -25,9 +25,6 @@ ports { }; pinmux@70000868 { - pinctrl-names = "default"; - pinctrl-0 = <&state_default>; - state_default: pinmux { /* WLAN SDIO pinmux */ host-wlan-wake { @@ -158,6 +155,8 @@ panel@1 { vdd-supply = <&vcc_3v0_lcd>; vddio-supply = <&iovcc_1v8_lcd>; + backlight = <&backlight>; + port { panel_input: endpoint { remote-endpoint = <&bridge_output>;
diff --git a/arch/arm/boot/dts/nvidia/tegra30-lg-p895.dts b/arch/arm/boot/dts/nvidia/tegra30-lg-p895.dts index 8966395..0d56fd2 100644 --- a/arch/arm/boot/dts/nvidia/tegra30-lg-p895.dts +++ b/arch/arm/boot/dts/nvidia/tegra30-lg-p895.dts
@@ -8,9 +8,6 @@ / { compatible = "lg,p895", "nvidia,tegra30"; pinmux@70000868 { - pinctrl-names = "default"; - pinctrl-0 = <&state_default>; - state_default: pinmux { /* GNSS UART-B pinmux */ uartb-cts-rxd { @@ -182,6 +179,8 @@ panel@1 { vcc-supply = <&vcc_3v0_lcd>; iovcc-supply = <&iovcc_1v8_lcd>; + backlight = <&backlight>; + port { panel_input: endpoint { remote-endpoint = <&bridge_output>;
diff --git a/arch/arm/boot/dts/nvidia/tegra30-lg-x3.dtsi b/arch/arm/boot/dts/nvidia/tegra30-lg-x3.dtsi index 60e8a19..781cf38 100644 --- a/arch/arm/boot/dts/nvidia/tegra30-lg-x3.dtsi +++ b/arch/arm/boot/dts/nvidia/tegra30-lg-x3.dtsi
@@ -1106,6 +1106,19 @@ nfc@28 { firmware-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_HIGH>; }; + light-sensor@39 { + compatible = "avago,apds9900"; + reg = <0x39>; + + interrupt-parent = <&gpio>; + interrupts = <TEGRA_GPIO(K, 2) IRQ_TYPE_EDGE_RISING>; + + vdd-supply = <&vdd_3v0_proxi>; + vddio-supply = <&vdd_1v8_sen>; + + led-max-microamp = <100000>; + }; + imu@68 { compatible = "invensense,mpu6050"; reg = <0x68>; @@ -1157,6 +1170,30 @@ rmi4-f11@11 { }; }; + led-controller@36 { + compatible = "ti,lm3533"; + reg = <0x36>; + + enable-gpios = <&gpio TEGRA_GPIO(N, 6) GPIO_ACTIVE_HIGH>; + vin-supply = <&vdd_3v3_vbat>; + + ti,boost-ovp-microvolt = <24000000>; + ti,boost-freq-hz = <500000>; + + #address-cells = <1>; + #size-cells = <0>; + + backlight: backlight@0 { + compatible = "ti,lm3533-backlight"; + reg = <0>; + + led-max-microamp = <23400>; + led-sources = <0 1>; + + ti,linear-mapping-mode; + }; + }; + max14526: muic@44 { compatible = "maxim,max14526"; reg = <0x44>; @@ -1220,6 +1257,7 @@ rear-camera@10 { rotation = <90>; nvmem = <&m24c08>; + flash-leds = <&lm3559_led0>, <&lm3559_led1>; lens-focus = <&dw9714>; assigned-clocks = <&tegra_car TEGRA30_CLK_VI_SENSOR>, @@ -1254,6 +1292,35 @@ m24c08: eeprom@50 { vcc-supply = <&vio_1v8_rear>; }; + led-controller@53 { + compatible = "ti,lm3559"; + reg = <0x53>; + + enable-gpios = <&gpio TEGRA_GPIO(BB, 3) GPIO_ACTIVE_HIGH>; + vin-supply = <&vdd_3v3_vbat>; + + flash-max-timeout-us = <1024000>; + ti,peak-current-microamp = <1400000>; + + #address-cells = <1>; + #size-cells = <0>; + + /* single flash led is on 2 lines */ + lm3559_led0: led@0 { + reg = <0>; + + flash-max-microamp = <393750>; + led-max-microamp = <140625>; + }; + + lm3559_led1: led@1 { + reg = <1>; + + flash-max-microamp = <393750>; + led-max-microamp = <140625>; + }; + }; + camera-pmic@7d { compatible = "ti,lp8720"; reg = <0x7d>; @@ -1525,6 +1592,30 @@ power-sensor@40 { vs-supply = <&vdd_3v0_sen>; }; + haptic-engine@49 { + compatible = "imagis,isa1200"; + reg = <0x49>; + + control-gpios = <&gpio TEGRA_GPIO(H, 1) GPIO_ACTIVE_HIGH>; + + pwms = <&pwm 3 53000>; + + vdd-supply = <&vdd_3v3_vbat>; + vddp-supply = <&vdd_1v8_vio>; + + imagis,clk-div = <128>; + imagis,pll-div = <1>; + + imagis,mode = <0>; /* LRA_MODE */ + imagis,duty-cycle-ns = <1250>; + + ldo { + regulator-name = "vdd_vib"; + regulator-min-microvolt = <2300000>; + regulator-max-microvolt = <2300000>; + }; + }; + nct72: temperature-sensor@4c { compatible = "onnn,nct1008"; reg = <0x4c>; @@ -1610,7 +1701,7 @@ bridge_output: endpoint { pmc@7000e400 { status = "okay"; nvidia,invert-interrupt; - nvidia,suspend-mode = <2>; + nvidia,suspend-mode = <1>; nvidia,cpu-pwr-good-time = <2000>; nvidia,cpu-pwr-off-time = <200>; nvidia,core-pwr-good-time = <3845 3845>; @@ -1669,9 +1760,12 @@ sdmmc1: mmc@78000000 { /* BCM4330B1 37.4 MHz Class 1.5 ExtLNA */ wifi@1 { - compatible = "brcm,bcm4329-fmac"; + compatible = "brcm,bcm4330-fmac", "brcm,bcm4329-fmac"; reg = <1>; + clocks = <&ext_lpo_in>; + clock-names = "lpo"; + interrupt-parent = <&gpio>; interrupts = <TEGRA_GPIO(U, 6) IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "host-wake"; @@ -1714,6 +1808,14 @@ clk32k_in: clock-32k { clock-output-names = "pmic-oscillator"; }; + /* PMIC's 32KHz oscillator for WiFi/GPS LPO input */ + ext_lpo_in: clock-32k-elpo { + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "ext-lpo-32k-in"; + #clock-cells = <0>; + }; + gps_refclk: clock-gps { compatible = "fixed-clock"; clock-frequency = <26000000>;
diff --git a/arch/arm/boot/dts/nxp/imx/Makefile b/arch/arm/boot/dts/nxp/imx/Makefile index 1a2539f..b5fad2b 100644 --- a/arch/arm/boot/dts/nxp/imx/Makefile +++ b/arch/arm/boot/dts/nxp/imx/Makefile
@@ -23,6 +23,7 @@ imx35-eukrea-mbimxsd35-baseboard.dtb \ imx35-pdk.dtb dtb-$(CONFIG_SOC_IMX50) += \ + imx50-amazon-yoshi.dtb \ imx50-evk.dtb \ imx50-kobo-aura.dtb dtb-$(CONFIG_SOC_IMX51) += \ @@ -136,6 +137,7 @@ imx6dl-mba6b.dtb \ imx6dl-nit6xlite.dtb \ imx6dl-nitrogen6x.dtb \ + imx6dl-phytec-mira-rdk-emmc.dtb \ imx6dl-phytec-mira-rdk-nand.dtb \ imx6dl-phytec-pbab01.dtb \ imx6dl-pico-dwarf.dtb \ @@ -419,13 +421,56 @@ imx6ull-var-som-concerto-full.dtb \ imx6ulz-14x14-evk.dtb \ imx6ulz-bsh-smm-m2.dtb + +imx7d-colibri-emmc-aster-panel-cap-touch-7inch-parallel-dtbs := \ + imx7d-colibri-emmc-aster.dtb \ + imx7d-colibri-emmc-panel-cap-touch-7inch-parallel.dtbo + +imx7d-colibri-emmc-iris-v2-panel-cap-touch-7inch-parallel-dtbs := \ + imx7d-colibri-emmc-iris-v2.dtb \ + imx7d-colibri-emmc-panel-cap-touch-7inch-parallel.dtbo + +imx7d-colibri-emmc-eval-v3-panel-cap-touch-7inch-parallel-touch-adapter-dtbs := \ + imx7d-colibri-emmc-eval-v3.dtb \ + imx7d-colibri-emmc-panel-cap-touch-7inch-parallel-touch-adapter.dtbo + +imx7d-colibri-emmc-eval-v3-panel-res-touch-7inch-parallel-dtbs := \ + imx7d-colibri-emmc-eval-v3.dtb \ + imx7d-colibri-emmc-panel-res-touch-7inch-parallel.dtbo + +imx7d-colibri-emmc-aster-vga-dtbs := \ + imx7d-colibri-emmc-aster.dtb \ + imx7d-colibri-emmc-vga.dtbo + +imx7d-colibri-emmc-eval-v3-vga-dtbs := \ + imx7d-colibri-emmc-eval-v3.dtb \ + imx7d-colibri-emmc-vga.dtbo + +imx7d-colibri-emmc-iris-vga-dtbs := \ + imx7d-colibri-emmc-iris.dtb \ + imx7d-colibri-emmc-vga.dtbo + +imx7d-colibri-emmc-iris-v2-vga-dtbs := \ + imx7d-colibri-emmc-iris-v2.dtb \ + imx7d-colibri-emmc-vga.dtbo + dtb-$(CONFIG_SOC_IMX7D) += \ imx7d-cl-som-imx7.dtb \ imx7d-colibri-aster.dtb \ imx7d-colibri-emmc-aster.dtb \ + imx7d-colibri-emmc-aster-panel-cap-touch-7inch-parallel.dtb \ + imx7d-colibri-emmc-aster-vga.dtb \ imx7d-colibri-emmc-iris.dtb \ + imx7d-colibri-emmc-iris-vga.dtb \ imx7d-colibri-emmc-iris-v2.dtb \ + imx7d-colibri-emmc-iris-v2-panel-cap-touch-7inch-parallel.dtb \ + imx7d-colibri-emmc-iris-v2-vga.dtb \ imx7d-colibri-emmc-eval-v3.dtb \ + imx7d-colibri-emmc-eval-v3-panel-cap-touch-7inch-parallel-touch-adapter.dtb \ + imx7d-colibri-emmc-eval-v3-panel-res-touch-7inch-parallel.dtb \ + imx7d-colibri-emmc-eval-v3-vga.dtb \ + imx7d-colibri-emmc-panel-cap-touch-7inch-parallel.dtbo \ + imx7d-colibri-emmc-vga.dtbo \ imx7d-colibri-eval-v3.dtb \ imx7d-colibri-iris.dtb \ imx7d-colibri-iris-v2.dtb \ @@ -444,6 +489,12 @@ imx7d-sdb-reva.dtb \ imx7d-sdb-sht11.dtb \ imx7d-smegw01.dtb \ + imx7d-var-som-emmc-mx7customboard.dtb \ + imx7d-var-som-emmc-wm8731-mx7customboard.dtb \ + imx7d-var-som-nand-mx7customboard.dtb \ + imx7d-var-som-nand-wm8731-mx7customboard.dtb \ + imx7d-var-som-v2-emmc-mx7customboard.dtb \ + imx7d-var-som-v2-nand-mx7customboard.dtb \ imx7d-zii-rmu2.dtb \ imx7d-zii-rpu2.dtb \ imx7s-colibri-aster.dtb \
diff --git a/arch/arm/boot/dts/nxp/imx/e60k02.dtsi b/arch/arm/boot/dts/nxp/imx/e60k02.dtsi index aac7b9e..ed59b27 100644 --- a/arch/arm/boot/dts/nxp/imx/e60k02.dtsi +++ b/arch/arm/boot/dts/nxp/imx/e60k02.dtsi
@@ -240,13 +240,13 @@ regulator-state-mem { }; /* IR_3V3 */ - ldo1_reg: LDO1 { + ldo1_reg: LDO1 { regulator-name = "LDO1"; regulator-boot-on; }; /* Core1_3V3 */ - ldo2_reg: LDO2 { + ldo2_reg: LDO2 { regulator-name = "LDO2"; regulator-always-on; regulator-boot-on; @@ -259,7 +259,7 @@ regulator-state-mem { }; /* Core5_1V2 */ - ldo3_reg: LDO3 { + ldo3_reg: LDO3 { regulator-name = "LDO3"; regulator-always-on; regulator-boot-on; @@ -310,7 +310,7 @@ ldo10_reg: LDO10 { regulator-boot-on; }; - ldortc1_reg: LDORTC1 { + ldortc1_reg: LDORTC1 { regulator-name = "LDORTC1"; regulator-boot-on; };
diff --git a/arch/arm/boot/dts/nxp/imx/e70k02.dtsi b/arch/arm/boot/dts/nxp/imx/e70k02.dtsi index 3bb11c5..dc7ff108 100644 --- a/arch/arm/boot/dts/nxp/imx/e70k02.dtsi +++ b/arch/arm/boot/dts/nxp/imx/e70k02.dtsi
@@ -243,13 +243,13 @@ regulator-state-mem { }; }; - ldo1_reg: LDO1 { + ldo1_reg: LDO1 { regulator-name = "LDO1"; regulator-boot-on; }; /* Core1_3V3 */ - ldo2_reg: LDO2 { + ldo2_reg: LDO2 { regulator-name = "LDO2"; regulator-always-on; regulator-boot-on; @@ -262,7 +262,7 @@ regulator-state-mem { }; /* Core5_1V2 */ - ldo3_reg: LDO3 { + ldo3_reg: LDO3 { regulator-name = "LDO3"; regulator-always-on; regulator-boot-on; @@ -311,7 +311,7 @@ ldo10_reg: LDO10 { regulator-boot-on; }; - ldortc1_reg: LDORTC1 { + ldortc1_reg: LDORTC1 { regulator-name = "LDORTC1"; regulator-boot-on; };
diff --git a/arch/arm/boot/dts/nxp/imx/imx50-amazon-yoshi.dts b/arch/arm/boot/dts/nxp/imx/imx50-amazon-yoshi.dts new file mode 100644 index 0000000..417972a --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx50-amazon-yoshi.dts
@@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0+ +/dts-v1/; +#include "imx50.dtsi" + +/ { + model = "Amazon Kindle 4 (Yoshi)"; + compatible = "amazon,yoshi", "fsl,imx50"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@70000000 { + device_type = "memory"; + reg = <0x70000000 0x10000000>; + }; +}; + +&esdhc3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sd3>; + bus-width = <8>; + non-removable; + min-frequency = <400000>; + max-frequency = <40000000>; + disable-wp; + status = "okay"; + + /* Internal eMMC */ +}; + +&iomuxc { + pinctrl_sd3: sd3grp { + fsl,pins = < + MX50_PAD_SD3_CMD__ESDHC3_CMD 0x1e4 + MX50_PAD_SD3_CLK__ESDHC3_CLK 0xd4 + MX50_PAD_SD3_D0__ESDHC3_DAT0 0x1d4 + MX50_PAD_SD3_D1__ESDHC3_DAT1 0x1d4 + MX50_PAD_SD3_D2__ESDHC3_DAT2 0x1d4 + MX50_PAD_SD3_D3__ESDHC3_DAT3 0x1d4 + MX50_PAD_SD3_D4__ESDHC3_DAT4 0x1d4 + MX50_PAD_SD3_D5__ESDHC3_DAT5 0x1d4 + MX50_PAD_SD3_D6__ESDHC3_DAT6 0x1d4 + MX50_PAD_SD3_D7__ESDHC3_DAT7 0x1d4 + >; + }; + pinctrl_uart1: uart1grp { + fsl,pins = < + MX50_PAD_UART1_TXD__UART1_TXD_MUX 0x1e4 + MX50_PAD_UART1_RXD__UART1_RXD_MUX 0x1e4 + >; + }; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx50-kobo-aura.dts b/arch/arm/boot/dts/nxp/imx/imx50-kobo-aura.dts index 4725ee2..4d8672ab 100644 --- a/arch/arm/boot/dts/nxp/imx/imx50-kobo-aura.dts +++ b/arch/arm/boot/dts/nxp/imx/imx50-kobo-aura.dts
@@ -75,15 +75,14 @@ sd2_pwrseq: pwrseq { reset-gpios = <&gpio4 17 GPIO_ACTIVE_LOW>; }; - sd2_vmmc: gpio-regulator { - compatible = "regulator-gpio"; + sd2_vmmc: regulator-sd2-vmmc { + compatible = "regulator-fixed"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sd2_vmmc>; regulator-name = "vmmc"; - states = <3300000 0>; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; - enable-gpios = <&gpio4 12 GPIO_ACTIVE_LOW>; + gpio = <&gpio4 12 GPIO_ACTIVE_LOW>; startup-delay-us = <100000>; }; };
diff --git a/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts b/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts index 91c63d1..c17ab36 100644 --- a/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts +++ b/arch/arm/boot/dts/nxp/imx/imx51-zii-rdu1.dts
@@ -115,7 +115,7 @@ panel_in: endpoint { }; }; - i2c_gpio: i2c-gpio { + i2c_gpio: i2c-0 { compatible = "i2c-gpio"; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_swi2c>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-m53.dtsi b/arch/arm/boot/dts/nxp/imx/imx53-m53.dtsi index 89b1750..9f7548e 100644 --- a/arch/arm/boot/dts/nxp/imx/imx53-m53.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx53-m53.dtsi
@@ -41,11 +41,8 @@ &i2c2 { touchscreen@41 { compatible = "st,stmpe610"; reg = <0x41>; - id = <0>; - blocks = <0x5>; interrupts = <6 0x0>; interrupt-parent = <&gpio7>; - irq-trigger = <0x1>; touchscreen { compatible = "st,stmpe-ts";
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-qsb.dts b/arch/arm/boot/dts/nxp/imx/imx53-qsb.dts index 6831836..e7e15d2 100644 --- a/arch/arm/boot/dts/nxp/imx/imx53-qsb.dts +++ b/arch/arm/boot/dts/nxp/imx/imx53-qsb.dts
@@ -13,7 +13,7 @@ / { &i2c1 { pmic: dialog@48 { - compatible = "dlg,da9053-aa", "dlg,da9052"; + compatible = "dlg,da9053-aa"; reg = <0x48>; interrupt-parent = <&gpio7>; interrupts = <11 IRQ_TYPE_LEVEL_LOW>; /* low-level active IRQ at GPIO7_11 */
diff --git a/arch/arm/boot/dts/nxp/imx/imx53-voipac-dmm-668.dtsi b/arch/arm/boot/dts/nxp/imx/imx53-voipac-dmm-668.dtsi index 6dc70a9..6eed683 100644 --- a/arch/arm/boot/dts/nxp/imx/imx53-voipac-dmm-668.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx53-voipac-dmm-668.dtsi
@@ -128,7 +128,7 @@ &i2c1 { status = "okay"; pmic: dialog@48 { - compatible = "dlg,da9053-aa", "dlg,da9052"; + compatible = "dlg,da9053-aa"; reg = <0x48>; interrupt-parent = <&gpio7>; interrupts = <11 IRQ_TYPE_LEVEL_LOW>; /* low-level active IRQ at GPIO7_11 */
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-b125pv2.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-b125pv2.dts index 94625d5..c6ee5f9 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-b125pv2.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-b125pv2.dts
@@ -26,5 +26,7 @@ touchscreen@2a { interrupt-parent = <&gpio5>; interrupts = <2 IRQ_TYPE_LEVEL_LOW>; reset-gpios = <&tca6424a 21 GPIO_ACTIVE_HIGH>; + touchscreen-size-x = <1280>; + touchscreen-size-y = <800>; }; };
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-b125v2.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-b125v2.dts index b3cfa81..bd4ef09 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-b125v2.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-b125v2.dts
@@ -26,5 +26,7 @@ touchscreen@2a { interrupt-parent = <&gpio5>; interrupts = <2 IRQ_TYPE_LEVEL_LOW>; reset-gpios = <&tca6424a 21 GPIO_ACTIVE_HIGH>; + touchscreen-size-x = <1280>; + touchscreen-size-y = <800>; }; };
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-mamoj.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-mamoj.dts index ec5a9bf..3027531 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-mamoj.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-mamoj.dts
@@ -151,7 +151,7 @@ reg_usb_host: regulator-usb-vbus { enable-active-high; }; - reg_wl18xx_vmmc: regulator-wl18xx-vmcc { + reg_wl18xx_vmmc: regulator-wl18xx-vmcc { compatible = "regulator-fixed"; regulator-name = "vwl1807"; pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-phytec-mira-rdk-emmc.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-phytec-mira-rdk-emmc.dts new file mode 100644 index 0000000..aa32396 --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-phytec-mira-rdk-emmc.dts
@@ -0,0 +1,75 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2018 PHYTEC Messtechnik GmbH + * Author: Christian Hemp <c.hemp@phytec.de> + */ + +/dts-v1/; +#include "imx6dl.dtsi" +#include "imx6dl-phytec-phycore-som.dtsi" +#include "imx6qdl-phytec-mira.dtsi" +#include "imx6qdl-phytec-mira-peb-eval-01.dtsi" +#include "imx6qdl-phytec-mira-peb-av-02.dtsi" +#include "imx6qdl-phytec-mira-peb-wlbt-05.dtsi" + +/ { + model = "PHYTEC phyBOARD-Mira DualLite/Solo Carrier-Board with eMMC"; + compatible = "phytec,imx6dl-pbac06-emmc", "phytec,imx6dl-pbac06", + "phytec,imx6qdl-pcm058", "fsl,imx6dl"; + + chosen { + stdout-path = &uart2; + }; +}; + +&can1 { + status = "okay"; +}; + +&fec { + status = "okay"; +}; + +&hdmi { + status = "okay"; +}; + +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c_rtc { + status = "okay"; +}; + +&m25p80 { + status = "okay"; +}; + +&pcie { + status = "okay"; +}; + +&uart3 { + status = "okay"; +}; + +&usbh1 { + status = "okay"; +}; + +&usbotg { + status = "okay"; +}; + +&usdhc1 { + status = "okay"; +}; + +&usdhc4 { + status = "okay"; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-phytec-mira-rdk-nand.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-phytec-mira-rdk-nand.dts index d906a7f..8ec2708 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-phytec-mira-rdk-nand.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-phytec-mira-rdk-nand.dts
@@ -6,7 +6,7 @@ /dts-v1/; #include "imx6dl.dtsi" -#include "imx6qdl-phytec-phycore-som.dtsi" +#include "imx6dl-phytec-phycore-som.dtsi" #include "imx6qdl-phytec-mira.dtsi" #include "imx6qdl-phytec-mira-peb-eval-01.dtsi" #include "imx6qdl-phytec-mira-peb-av-02.dtsi"
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-phytec-phycore-som.dtsi b/arch/arm/boot/dts/nxp/imx/imx6dl-phytec-phycore-som.dtsi new file mode 100644 index 0000000..de85c08 --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-phytec-phycore-som.dtsi
@@ -0,0 +1,23 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2021 PHYTEC Messtechnik GmbH + * Author: Yunus Bas <y.bas@phytec.de> + */ + +#include "imx6qdl-phytec-phycore-som.dtsi" + +&cpu0 { + operating-points = + /* kHz uV */ + <996000 1275000>, + <792000 1175000>, + <396000 1150000>; +}; + +&cpu1 { + operating-points = + /* kHz uV */ + <996000 1275000>, + <792000 1175000>, + <396000 1150000>; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-plym2m.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-plym2m.dts index 635c5a1..e3496ea 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-plym2m.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-plym2m.dts
@@ -155,7 +155,7 @@ alert { touchscreen { compatible = "resistive-adc-touch"; io-channels = <&adc_ts 1>, <&adc_ts 3>, <&adc_ts 4>, - <&adc_ts 5>; + <&adc_ts 5>; io-channel-names = "y", "z1", "z2", "x"; touchscreen-min-pressure = <64687>; touchscreen-inverted-x;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-prtvt7.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-prtvt7.dts index 353f709..09381dc 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-prtvt7.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-prtvt7.dts
@@ -288,7 +288,7 @@ alert { touchscreen { compatible = "resistive-adc-touch"; io-channels = <&adc_ts 1>, <&adc_ts 3>, <&adc_ts 4>, - <&adc_ts 5>; + <&adc_ts 5>; io-channel-names = "y", "z1", "z2", "x"; touchscreen-min-pressure = <64687>; touchscreen-x-plate-ohms = <300>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl-victgo.dts b/arch/arm/boot/dts/nxp/imx/imx6dl-victgo.dts index 18019a6b..f874b2b 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl-victgo.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6dl-victgo.dts
@@ -116,7 +116,7 @@ alert { touchscreen { compatible = "resistive-adc-touch"; io-channels = <&adc_ts 1>, <&adc_ts 3>, <&adc_ts 4>, - <&adc_ts 5>; + <&adc_ts 5>; io-channel-names = "y", "z1", "z2", "x"; touchscreen-min-pressure = <64687>; touchscreen-inverted-y;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6dl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6dl.dtsi index dc919e0..78092d9 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6dl.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6dl.dtsi
@@ -48,7 +48,7 @@ cpu0: cpu@0 { nvmem-cell-names = "speed_grade"; }; - cpu@1 { + cpu1: cpu@1 { compatible = "arm,cortex-a9"; device_type = "cpu"; reg = <1>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-bosch-acc.dts b/arch/arm/boot/dts/nxp/imx/imx6q-bosch-acc.dts index 929def2..20b6cc7 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-bosch-acc.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6q-bosch-acc.dts
@@ -177,7 +177,7 @@ reg_usb_h2_vbus: regulator-usb-h2-vbus { regulator-name = "usb_h2_vbus"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - vin-supply = <®_5p0> ; + vin-supply = <®_5p0>; regulator-always-on; }; @@ -207,7 +207,7 @@ reg_dac: regulator-dac { regulator-name = "vref_dac"; regulator-min-microvolt = <20000>; regulator-max-microvolt = <20000>; - vin-supply = <®_5p0> ; + vin-supply = <®_5p0>; regulator-boot-on; };
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-novena.dts b/arch/arm/boot/dts/nxp/imx/imx6q-novena.dts index cd9a050..9938a63 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-novena.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6q-novena.dts
@@ -281,9 +281,6 @@ touch: stmpe811@44 { compatible = "st,stmpe811"; reg = <0x44>; irq-gpio = <&gpio5 13 GPIO_ACTIVE_HIGH>; - id = <0>; - blocks = <0x5>; - irq-trigger = <0x1>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_stmpe_novena>; vio-supply = <®_3p3v>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-phytec-mira-rdk-emmc.dts b/arch/arm/boot/dts/nxp/imx/imx6q-phytec-mira-rdk-emmc.dts index 322f071d..7d947762 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-phytec-mira-rdk-emmc.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6q-phytec-mira-rdk-emmc.dts
@@ -6,7 +6,7 @@ /dts-v1/; #include "imx6q.dtsi" -#include "imx6qdl-phytec-phycore-som.dtsi" +#include "imx6q-phytec-phycore-som.dtsi" #include "imx6qdl-phytec-mira.dtsi" #include "imx6qdl-phytec-mira-peb-eval-01.dtsi" #include "imx6qdl-phytec-mira-peb-av-02.dtsi"
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-phytec-mira-rdk-nand.dts b/arch/arm/boot/dts/nxp/imx/imx6q-phytec-mira-rdk-nand.dts index 3f13726..afbb668 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6q-phytec-mira-rdk-nand.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6q-phytec-mira-rdk-nand.dts
@@ -6,7 +6,7 @@ /dts-v1/; #include "imx6q.dtsi" -#include "imx6qdl-phytec-phycore-som.dtsi" +#include "imx6q-phytec-phycore-som.dtsi" #include "imx6qdl-phytec-mira.dtsi" #include "imx6qdl-phytec-mira-peb-eval-01.dtsi" #include "imx6qdl-phytec-mira-peb-av-02.dtsi"
diff --git a/arch/arm/boot/dts/nxp/imx/imx6q-phytec-phycore-som.dtsi b/arch/arm/boot/dts/nxp/imx/imx6q-phytec-phycore-som.dtsi new file mode 100644 index 0000000..ebe05d76 --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx6q-phytec-phycore-som.dtsi
@@ -0,0 +1,75 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2021 PHYTEC Messtechnik GmbH + * Author: Yunus Bas <y.bas@phytec.de> + */ + +#include "imx6qdl-phytec-phycore-som.dtsi" + +&cpu0 { + operating-points = + /* kHz uV */ + <1200000 1300000>, + <996000 1250000>, + <852000 1250000>, + <792000 1175000>, + <396000 1075000>; + fsl,soc-operating-points = + /* ARM kHz SOC-PU uV */ + <1200000 1275000>, + <996000 1250000>, + <852000 1250000>, + <792000 1250000>, + <396000 1250000>; +}; + +&cpu1 { + operating-points = + /* kHz uV */ + <1200000 1300000>, + <996000 1250000>, + <852000 1250000>, + <792000 1175000>, + <396000 1075000>; + fsl,soc-operating-points = + /* ARM kHz SOC-PU uV */ + <1200000 1275000>, + <996000 1250000>, + <852000 1250000>, + <792000 1250000>, + <396000 1250000>; +}; + +&cpu2 { + operating-points = + /* kHz uV */ + <1200000 1300000>, + <996000 1250000>, + <852000 1250000>, + <792000 1175000>, + <396000 1075000>; + fsl,soc-operating-points = + /* ARM kHz SOC-PU uV */ + <1200000 1275000>, + <996000 1250000>, + <852000 1250000>, + <792000 1250000>, + <396000 1250000>; +}; + +&cpu3 { + operating-points = + /* kHz uV */ + <1200000 1300000>, + <996000 1250000>, + <852000 1250000>, + <792000 1175000>, + <396000 1075000>; + fsl,soc-operating-points = + /* ARM kHz SOC-PU uV */ + <1200000 1275000>, + <996000 1250000>, + <852000 1250000>, + <792000 1250000>, + <396000 1250000>; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi index 5fcd7cd..af038ac 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-apalis.dtsi
@@ -631,11 +631,8 @@ codec: sgtl5000@a { /* STMPE811 touch screen controller */ stmpe811@41 { compatible = "st,stmpe811"; - blocks = <0x5>; - id = <0>; interrupts = <10 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&gpio4>; - irq-trigger = <0x1>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_touch_int>; reg = <0x41>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-colibri.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-colibri.dtsi index 8a0ce25..c9e539f 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-colibri.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-colibri.dtsi
@@ -555,11 +555,8 @@ codec: sgtl5000@a { /* STMPE811 touch screen controller */ stmpe811@41 { compatible = "st,stmpe811"; - blocks = <0x5>; interrupts = <20 IRQ_TYPE_LEVEL_LOW>; interrupt-parent = <&gpio6>; - id = <0>; - irq-trigger = <0x1>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_touch_int>; reg = <0x41>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-emcon.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-emcon.dtsi index 9f4e746..34ad7fc 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-emcon.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-emcon.dtsi
@@ -733,7 +733,6 @@ &pcie { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pcie_ctrl>; reset-gpio = <&gpio7 12 GPIO_ACTIVE_LOW>; - disable-gpio = <&gpio2 22 GPIO_ACTIVE_LOW>; }; &pwm1 {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw560x.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw560x.dtsi index e9d5bbb..57f1583 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-gw560x.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-gw560x.dtsi
@@ -418,16 +418,16 @@ tca8418: keypad@34 { reg = <0x34>; interrupt-parent = <&gpio5>; interrupts = <11 IRQ_TYPE_EDGE_FALLING>; - linux,keymap = < MATRIX_KEY(0x00, 0x01, BTN_0) - MATRIX_KEY(0x00, 0x00, BTN_1) - MATRIX_KEY(0x01, 0x01, BTN_2) - MATRIX_KEY(0x01, 0x00, BTN_3) - MATRIX_KEY(0x02, 0x00, BTN_4) - MATRIX_KEY(0x00, 0x03, BTN_5) - MATRIX_KEY(0x00, 0x02, BTN_6) - MATRIX_KEY(0x01, 0x03, BTN_7) - MATRIX_KEY(0x01, 0x02, BTN_8) - MATRIX_KEY(0x02, 0x02, BTN_9) + linux,keymap = <MATRIX_KEY(0x00, 0x01, BTN_0) + MATRIX_KEY(0x00, 0x00, BTN_1) + MATRIX_KEY(0x01, 0x01, BTN_2) + MATRIX_KEY(0x01, 0x00, BTN_3) + MATRIX_KEY(0x02, 0x00, BTN_4) + MATRIX_KEY(0x00, 0x03, BTN_5) + MATRIX_KEY(0x00, 0x02, BTN_6) + MATRIX_KEY(0x01, 0x03, BTN_7) + MATRIX_KEY(0x01, 0x02, BTN_8) + MATRIX_KEY(0x02, 0x02, BTN_9) >; keypad,num-rows = <4>; keypad,num-columns = <4>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-pico.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-pico.dtsi index ca4cb98..0cc05d0 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-pico.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-pico.dtsi
@@ -233,7 +233,9 @@ camera@3c { pinctrl-0 = <&pinctrl_ov5645>; reg = <0x3c>; clocks = <&clks IMX6QDL_CLK_CKO2>; - clock-frequency = <24000000>; + assigned-clocks = <&clks IMX6QDL_CLK_CKO2>; + assigned-clock-rates = <24000000>; + vdddo-supply = <®_1p8v>; vdda-supply = <®_2p8v>; vddd-supply = <®_1p5v>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi index e2631db..27a73a3 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-skov-cpu.dtsi
@@ -28,7 +28,7 @@ aliases { iio-hwmon { compatible = "iio-hwmon"; io-channels = <&adc 0>, /* 24V */ - <&adc 1>; /* temperature */ + <&adc 1>; /* temperature */ }; leds {
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-wandboard.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-wandboard.dtsi index 26489ec..f3aaca03 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-wandboard.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-wandboard.dtsi
@@ -137,7 +137,9 @@ camera@3c { pinctrl-0 = <&pinctrl_ov5645>; reg = <0x3c>; clocks = <&clks IMX6QDL_CLK_CKO2>; - clock-frequency = <24000000>; + assigned-clocks = <&clks IMX6QDL_CLK_CKO2>; + assigned-clock-rates = <24000000>; + vdddo-supply = <®_1p8v>; vdda-supply = <®_2p8v>; vddd-supply = <®_1p5v>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl-zii-rdu2.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl-zii-rdu2.dtsi index 9ff183e..601733c 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl-zii-rdu2.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl-zii-rdu2.dtsi
@@ -22,8 +22,8 @@ mdio1: mdio { #size-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&pinctrl_mdio1>; - gpios = <&gpio6 5 GPIO_ACTIVE_HIGH - &gpio6 4 GPIO_ACTIVE_HIGH>; + gpios = <&gpio6 5 GPIO_ACTIVE_HIGH>, + <&gpio6 4 GPIO_ACTIVE_HIGH>; phy: ethernet-phy@0 { pinctrl-0 = <&pinctrl_rmii_phy_irq>; @@ -218,9 +218,9 @@ edp_refclk: edp-refclk { &clks { assigned-clocks = <&clks IMX6QDL_CLK_LDB_DI0_SEL>, - <&clks IMX6QDL_CLK_LDB_DI1_SEL>; + <&clks IMX6QDL_CLK_LDB_DI1_SEL>; assigned-clock-parents = <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>, - <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>; + <&clks IMX6QDL_CLK_PLL5_VIDEO_DIV>; }; &cpu0 { @@ -629,7 +629,7 @@ reg_5p0v_user_usb: charger@32 { pinctrl-0 = <&pinctrl_ucs1002_pins>; reg = <0x32>; interrupts-extended = <&gpio5 2 IRQ_TYPE_EDGE_BOTH>, - <&gpio3 21 IRQ_TYPE_EDGE_FALLING>; + <&gpio3 21 IRQ_TYPE_EDGE_FALLING>; interrupt-names = "a_det", "alert"; };
diff --git a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi index 9438862..86c4f7e 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6qdl.dtsi
@@ -924,11 +924,11 @@ pd_pu: power-domain@1 { #power-domain-cells = <0>; power-supply = <®_pu>; clocks = <&clks IMX6QDL_CLK_GPU3D_CORE>, - <&clks IMX6QDL_CLK_GPU3D_SHADER>, - <&clks IMX6QDL_CLK_GPU2D_CORE>, - <&clks IMX6QDL_CLK_GPU2D_AXI>, - <&clks IMX6QDL_CLK_OPENVG_AXI>, - <&clks IMX6QDL_CLK_VPU_AXI>; + <&clks IMX6QDL_CLK_GPU3D_SHADER>, + <&clks IMX6QDL_CLK_GPU2D_CORE>, + <&clks IMX6QDL_CLK_GPU2D_AXI>, + <&clks IMX6QDL_CLK_OPENVG_AXI>, + <&clks IMX6QDL_CLK_VPU_AXI>; }; }; };
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sl-kobo-aura2.dts b/arch/arm/boot/dts/nxp/imx/imx6sl-kobo-aura2.dts index 657d0f1..47b0520 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6sl-kobo-aura2.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6sl-kobo-aura2.dts
@@ -211,14 +211,14 @@ regulator-state-mem { }; /* IR_3V3 */ - ldo1_reg: LDO1 { + ldo1_reg: LDO1 { regulator-name = "LDO1"; regulator-always-on; regulator-boot-on; }; /* Core1_3V3 */ - ldo2_reg: LDO2 { + ldo2_reg: LDO2 { regulator-name = "LDO2"; regulator-always-on; regulator-boot-on; @@ -231,7 +231,7 @@ regulator-state-mem { }; /* Core5_1V2 */ - ldo3_reg: LDO3 { + ldo3_reg: LDO3 { regulator-name = "LDO3"; regulator-always-on; regulator-boot-on; @@ -282,7 +282,7 @@ ldo10_reg: LDO10 { regulator-boot-on; }; - ldortc1_reg: LDORTC1 { + ldortc1_reg: LDORTC1 { regulator-name = "LDORTC1"; regulator-always-on; regulator-boot-on;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts b/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts index 4c65557..64a7471 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6sl-tolino-shine2hd.dts
@@ -276,13 +276,13 @@ regulator-state-mem { }; /* IR_3V3 */ - ldo1_reg: LDO1 { + ldo1_reg: LDO1 { regulator-name = "LDO1"; regulator-boot-on; }; /* Core1_3V3 */ - ldo2_reg: LDO2 { + ldo2_reg: LDO2 { regulator-name = "LDO2"; regulator-always-on; regulator-boot-on; @@ -295,7 +295,7 @@ regulator-state-mem { }; /* Core5_1V2 */ - ldo3_reg: LDO3 { + ldo3_reg: LDO3 { regulator-name = "LDO3"; regulator-always-on; regulator-boot-on; @@ -346,7 +346,7 @@ ldo10_reg: LDO10 { regulator-boot-on; }; - ldortc1_reg: LDORTC1 { + ldortc1_reg: LDORTC1 { regulator-name = "LDORTC1"; regulator-always-on; regulator-boot-on;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sll-evk.dts b/arch/arm/boot/dts/nxp/imx/imx6sll-evk.dts index 8144014..d20d273 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6sll-evk.dts +++ b/arch/arm/boot/dts/nxp/imx/imx6sll-evk.dts
@@ -633,7 +633,7 @@ MX6SLL_PAD_PWM1__PWM1_OUT 0x110b0 >; }; - pinctrl_wdog1: wdog1grp { + pinctrl_wdog1: wdog1grp { fsl,pins = < MX6SLL_PAD_WDOG_B__WDOG1_B 0x170b0 >;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6sll.dtsi b/arch/arm/boot/dts/nxp/imx/imx6sll.dtsi index c966696..929f781 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6sll.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6sll.dtsi
@@ -624,17 +624,6 @@ gpr: iomuxc-gpr@20e4000 { reg = <0x020e4000 0x4000>; }; - csi: csi@20e8000 { - compatible = "fsl,imx6sll-csi", "fsl,imx6s-csi"; - reg = <0x020e8000 0x4000>; - interrupts = <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clks IMX6SLL_CLK_DUMMY>, - <&clks IMX6SLL_CLK_CSI>, - <&clks IMX6SLL_CLK_DUMMY>; - clock-names = "disp-axi", "csi_mclk", "disp_dcic"; - status = "disabled"; - }; - sdma: dma-controller@20ec000 { compatible = "fsl,imx6sll-sdma", "fsl,imx6ul-sdma"; reg = <0x020ec000 0x4000>;
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi index 32afe41..181676c 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6ul-14x14-evk.dtsi
@@ -236,7 +236,6 @@ &csi { port { parallel_from_ov5640: endpoint { remote-endpoint = <&ov5640_to_parallel>; - bus-type = <MEDIA_BUS_TYPE_PARALLEL>; }; }; };
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-kontron-bl-common.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-kontron-bl-common.dtsi index f4c45e9..0658584 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6ul-kontron-bl-common.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6ul-kontron-bl-common.dtsi
@@ -132,6 +132,22 @@ ethphy2: ethernet-phy@2 { }; }; +&gpio1 { + gpio-line-names = "", "", "ADC_REF", "AIN1", + "", "", "ENET2_MDIO", "ENET2_MDC", + "AIN2", "", "", "", + "", "", "", "", + "", "", "", "SD1_CD", + "", "", "", "", + "CAN_ADR0", "CAN_ADR1", "CAN_ADR2", "CAN_ADR3", + "", "", "LED_H14"; +}; + +&gpio5 { + gpio-line-names = "DIN2", "DOUT2", "LED_H16", + "LED_H15", "DIN1", "DOUT1"; +}; + &i2c1 { clock-frequency = <100000>; pinctrl-names = "default"; @@ -172,13 +188,6 @@ &uart2 { status = "okay"; }; -&uart3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_uart3>; - uart-has-rtscts; - status = "okay"; -}; - &uart4 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart4>; @@ -283,6 +292,11 @@ MX6UL_PAD_SNVS_TAMPER5__GPIO5_IO05 0x1b0b0 /* DOUT1 */ MX6UL_PAD_SNVS_TAMPER4__GPIO5_IO04 0x1b0b0 /* DIN1 */ MX6UL_PAD_SNVS_TAMPER1__GPIO5_IO01 0x1b0b0 /* DOUT2 */ MX6UL_PAD_SNVS_TAMPER0__GPIO5_IO00 0x1b0b0 /* DIN2 */ + + MX6UL_PAD_UART3_TX_DATA__GPIO1_IO24 0x1b0b0 /* CAN_ADR0 (DIP sw 1) */ + MX6UL_PAD_UART3_RX_DATA__GPIO1_IO25 0x1b0b0 /* CAN_ADR1 (DIP sw 2) */ + MX6UL_PAD_UART3_CTS_B__GPIO1_IO26 0x1b0b0 /* CAN_ADR2 (DIP sw 3) */ + MX6UL_PAD_UART3_RTS_B__GPIO1_IO27 0x1b0b0 /* CAN_ADR3 (DIP sw 4) */ >; }; @@ -334,15 +348,6 @@ MX6UL_PAD_NAND_DATA07__UART2_DCE_RTS 0x1b0b1 >; }; - pinctrl_uart3: uart3grp { - fsl,pins = < - MX6UL_PAD_UART3_TX_DATA__UART3_DCE_TX 0x1b0b1 - MX6UL_PAD_UART3_RX_DATA__UART3_DCE_RX 0x1b0b1 - MX6UL_PAD_UART3_CTS_B__UART3_DCE_CTS 0x1b0b1 - MX6UL_PAD_UART3_RTS_B__UART3_DCE_RTS 0x1b0b1 - >; - }; - pinctrl_uart4: uart4grp { fsl,pins = < MX6UL_PAD_UART4_TX_DATA__UART4_DCE_TX 0x1b0b1 @@ -352,6 +357,7 @@ MX6UL_PAD_UART4_RX_DATA__UART4_DCE_RX 0x1b0b1 pinctrl_usbotg1: usbotg1grp { fsl,pins = < + MX6UL_PAD_GPIO1_IO00__ANATOP_OTG1_ID 0x17059 MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0x1b0b0 >; };
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ul-tx6ul.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ul-tx6ul.dtsi index 192c6a9..2f6916c 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6ul-tx6ul.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6ul-tx6ul.dtsi
@@ -369,7 +369,7 @@ &lcdif { display = <&display>; status = "okay"; - display: disp0 { + display: display0 { bits-per-pixel = <32>; bus-width = <24>; status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri.dtsi b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri.dtsi index ec3c1e7..1eb1cf2 100644 --- a/arch/arm/boot/dts/nxp/imx/imx6ull-colibri.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx6ull-colibri.dtsi
@@ -229,6 +229,7 @@ &lcdif { port { lcdif_out: endpoint { + bus-width = <18>; remote-endpoint = <&lcd_panel_in>; }; };
diff --git a/arch/arm/boot/dts/nxp/imx/imx7-colibri-iris-v2.dtsi b/arch/arm/boot/dts/nxp/imx/imx7-colibri-iris-v2.dtsi index b687727..216dac7 100644 --- a/arch/arm/boot/dts/nxp/imx/imx7-colibri-iris-v2.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx7-colibri-iris-v2.dtsi
@@ -106,7 +106,6 @@ &usbotg1 { /* Colibri MMC/SD, UHS-I capable uSD slot */ &usdhc1 { cap-power-off-card; - /delete-property/ keep-power-in-suspend; /delete-property/ no-1-8-v; vmmc-supply = <®_3v3_vmmc>; status = "okay";
diff --git a/arch/arm/boot/dts/nxp/imx/imx7-colibri.dtsi b/arch/arm/boot/dts/nxp/imx/imx7-colibri.dtsi index 8666dcd..c4088d3 100644 --- a/arch/arm/boot/dts/nxp/imx/imx7-colibri.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx7-colibri.dtsi
@@ -537,6 +537,7 @@ &lcdif { port { lcdif_out: endpoint { + bus-width = <18>; remote-endpoint = <&lcd_panel_in>; }; };
diff --git a/arch/arm/boot/dts/nxp/imx/imx7-tqma7.dtsi b/arch/arm/boot/dts/nxp/imx/imx7-tqma7.dtsi index e1f740e..353af6b 100644 --- a/arch/arm/boot/dts/nxp/imx/imx7-tqma7.dtsi +++ b/arch/arm/boot/dts/nxp/imx/imx7-tqma7.dtsi
@@ -46,8 +46,8 @@ pfuze3000: pmic@8 { regulators { sw1a_reg: sw1a { - regulator-min-microvolt = <700000>; - regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1225000>; regulator-boot-on; regulator-always-on; regulator-ramp-delay = <6250>; @@ -55,34 +55,33 @@ sw1a_reg: sw1a { /* use sw1c_reg to align with pfuze100/pfuze200 */ sw1c_reg: sw1b { - regulator-min-microvolt = <700000>; - regulator-max-microvolt = <1475000>; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; regulator-boot-on; regulator-always-on; regulator-ramp-delay = <6250>; }; sw2_reg: sw2 { - regulator-min-microvolt = <1500000>; - regulator-max-microvolt = <1850000>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; regulator-boot-on; regulator-always-on; }; sw3a_reg: sw3 { - regulator-min-microvolt = <900000>; - regulator-max-microvolt = <1650000>; + regulator-min-microvolt = <1350000>; + regulator-max-microvolt = <1350000>; regulator-boot-on; regulator-always-on; }; swbst_reg: swbst { - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5150000>; + /* Not connected and left unconfigured */ }; snvs_reg: vsnvs { - regulator-min-microvolt = <1000000>; + regulator-min-microvolt = <3000000>; regulator-max-microvolt = <3000000>; regulator-boot-on; regulator-always-on; @@ -95,18 +94,25 @@ vref_reg: vrefddr { vgen1_reg: vldo1 { regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; + regulator-max-microvolt = <1800000>; regulator-always-on; }; vgen2_reg: vldo2 { - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <1550000>; + regulator-min-microvolt = <1500000>; + regulator-max-microvolt = <1500000>; regulator-always-on; }; vgen3_reg: vccsd { - regulator-min-microvolt = <2850000>; + /* + * Specified values refer to 3.3V operation; voltage for 1.8V + * operation is derived from this. + * + * The base board should usually mux GPIO1_IO08 to SD1_VSELECT for + * automatic switching of SD card IO voltage. + */ + regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; regulator-always-on; }; @@ -118,19 +124,25 @@ vgen4_reg: v33 { }; vgen5_reg: vldo3 { - regulator-min-microvolt = <1800000>; + regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; regulator-always-on; }; vgen6_reg: vldo4 { - regulator-min-microvolt = <1800000>; + regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; regulator-always-on; }; }; }; + /* NXP SE97BTP with temperature sensor + eeprom, TQMa7x 02xx */ + se97b: temperature-sensor@1e { + compatible = "nxp,se97b", "jedec,jc-42.4-temp"; + reg = <0x1e>; + }; + /* LM75A temperature sensor, TQMa7x 01xx */ lm75a: temperature-sensor@48 { compatible = "national,lm75a"; @@ -138,12 +150,6 @@ lm75a: temperature-sensor@48 { vs-supply = <&vgen4_reg>; }; - /* NXP SE97BTP with temperature sensor + eeprom, TQMa7x 02xx */ - se97b: temperature-sensor@1e { - compatible = "nxp,se97b", "jedec,jc-42.4-temp"; - reg = <0x1e>; - }; - /* ST M24C64 */ m24c64: eeprom@50 { compatible = "atmel,24c64";
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-panel-cap-touch-7inch-parallel-touch-adapter.dtso b/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-panel-cap-touch-7inch-parallel-touch-adapter.dtso new file mode 100644 index 0000000..890461f --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-panel-cap-touch-7inch-parallel-touch-adapter.dtso
@@ -0,0 +1,58 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (c) Toradex + * + * Toradex Capacitive Touch Display 7" Parallel connected through the 40-way + * Unified Interface Display connector and Toradex Capacitive Touch Adapter. + * + * Toradex Capacitive Touch Adapter connection with the various carrier boards + * is documented in the datasheet [1]. + * + * https://developer.toradex.com/hardware/accessories/displays/capacitive-touch-display-7inch-parallel/ + * https://www.toradex.com/accessories/capacitive-touch-display-7-inch-parallel + * https://docs.toradex.com/104497-7-inch-parallel-capacitive-touch-display-800x480-datasheet.pdf + * https://developer.toradex.com/hardware/accessories/add-ons/capacitive-touch-adapter/ + * https://www.toradex.com/accessories/capacitive-touch-adapter + * https://docs.toradex.com/104615-capacitive-touch-adapter-datasheet.pdf [1] + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> + +&atmel_mxt_ts { + pinctrl-0 = <&pinctrl_atmel_adapter>; + /* SODIMM 28 / TOUCH_INT# */ + interrupt-parent = <&gpio1>; + interrupts = <9 IRQ_TYPE_EDGE_FALLING>; + /* SODIMM 30 / TOUCH_RST# */ + reset-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>; + + status = "okay"; +}; + +&backlight { + status = "okay"; +}; + +&lcdif { + status = "okay"; +}; + +&panel_dpi { + compatible = "logictechno,lt161010-2nhc"; + + status = "okay"; +}; + +/* Conflict with SODIMM 28 / TOUCH_INT# */ +&pwm2 { + status = "disabled"; +}; + +/* Conflict with SODIMM 30 / TOUCH_RST# */ +&pwm3 { + status = "disabled"; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-panel-cap-touch-7inch-parallel.dtso b/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-panel-cap-touch-7inch-parallel.dtso new file mode 100644 index 0000000..f336f7b --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-panel-cap-touch-7inch-parallel.dtso
@@ -0,0 +1,43 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (c) Toradex + * + * Toradex Capacitive Touch Display 7" Parallel connected through the 40-way + * Unified Interface Display and 10-way Capacitive Touch Interface connectors + * (as featured on Iris v2 and Aster v1.1 carrier boards). + * + * https://docs.toradex.com/104497-7-inch-parallel-capacitive-touch-display-800x480-datasheet.pdf + * https://developer.toradex.com/hardware/accessories/displays/capacitive-touch-display-7inch-parallel/ + * https://www.toradex.com/accessories/capacitive-touch-display-7-inch-parallel + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> + +&atmel_mxt_ts { + pinctrl-0 = <&pinctrl_atmel_connector>; + /* SODIMM 107 / TOUCH_INT# */ + interrupt-parent = <&gpio2>; + interrupts = <15 IRQ_TYPE_EDGE_FALLING>; + /* SODIMM 106 / TOUCH_RST# */ + reset-gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; + + status = "okay"; +}; + +&backlight { + status = "okay"; +}; + +&lcdif { + status = "okay"; +}; + +&panel_dpi { + compatible = "logictechno,lt161010-2nhc"; + + status = "okay"; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-panel-res-touch-7inch-parallel.dtso b/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-panel-res-touch-7inch-parallel.dtso new file mode 100644 index 0000000..b926cc0 --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-panel-res-touch-7inch-parallel.dtso
@@ -0,0 +1,32 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (c) Toradex + * + * Toradex Resistive Touch Display 7" Parallel connected through the 40-way + * Unified Interface Display connector. + * + * https://docs.toradex.com/104498-7-inch-parallel-resistive-touch-display-800x480.pdf + * https://developer.toradex.com/hardware/accessories/displays/resistive-touch-display-7inch-parallel/ + * https://www.toradex.com/accessories/resistive-touch-display + */ + +/dts-v1/; +/plugin/; + +&ad7879_ts { + status = "okay"; +}; + +&backlight { + status = "okay"; +}; + +&lcdif { + status = "okay"; +}; + +&panel_dpi { + compatible = "logictechno,lt161010-2nhr"; + + status = "okay"; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-vga.dtso b/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-vga.dtso new file mode 100644 index 0000000..cda214c --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-colibri-emmc-vga.dtso
@@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * VGA output connected to the Colibri parallel RGB LCD interface through a + * non-programmable video DAC with a DVI connector. + * + * The VGA output is available on multiple carrier boards (including Iris, + * Eval, Aster) without VESA DDC I2C signals. + */ + +/dts-v1/; +/plugin/; + +&{/} { + vga-encoder { + compatible = "dumb-vga-dac"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + vga_enc_in: endpoint { + remote-endpoint = <&lcdif_out>; + }; + }; + + port@1 { + reg = <1>; + + vga_enc_out: endpoint { + remote-endpoint = <&dvi_connector_in>; + }; + }; + }; + }; + + dvi-connector { + compatible = "dvi-connector"; + analog; + + port { + dvi_connector_in: endpoint { + remote-endpoint = <&vga_enc_out>; + }; + }; + }; +}; + +&lcdif { + status = "okay"; +}; + +&lcdif_out { + remote-endpoint = <&vga_enc_in>; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-meerkat96.dts b/arch/arm/boot/dts/nxp/imx/imx7d-meerkat96.dts index f0fda15..38f886c 100644 --- a/arch/arm/boot/dts/nxp/imx/imx7d-meerkat96.dts +++ b/arch/arm/boot/dts/nxp/imx/imx7d-meerkat96.dts
@@ -134,7 +134,7 @@ &i2c4 { &lcdif { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lcdif>; - status = "okay"; + status = "disabled"; }; &uart1 {
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-nitrogen7.dts b/arch/arm/boot/dts/nxp/imx/imx7d-nitrogen7.dts index 2192f105..c72859a 100644 --- a/arch/arm/boot/dts/nxp/imx/imx7d-nitrogen7.dts +++ b/arch/arm/boot/dts/nxp/imx/imx7d-nitrogen7.dts
@@ -284,7 +284,6 @@ touchscreen@48 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_i2c3_tsc2004>; interrupts-extended = <&gpio3 4 IRQ_TYPE_EDGE_FALLING>; - wakeup-gpios = <&gpio3 4 GPIO_ACTIVE_LOW>; }; };
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-var-som-emmc-mx7customboard.dts b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-emmc-mx7customboard.dts new file mode 100644 index 0000000..594ee2d --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-emmc-mx7customboard.dts
@@ -0,0 +1,23 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * VAR-MX7CustomBoard for VAR-SOM-MX7 with eMMC + * + * Link: https://variscite.com/carrier-boards/var-mx7customboard/ + * + * Copyright (C) 2026 Variscite Ltd. - https://www.variscite.com/ + * + */ + +/dts-v1/; + +#include "imx7d-var-som.dtsi" +#include "imx7d-var-som-emmc.dtsi" +#include "imx7d-var-som-wm8904.dtsi" +#include "imx7d-var-som-mx7customboard.dtsi" + +/ { + model = "Variscite VAR-SOM-MX7 with eMMC & WM8904 on VAR-MX7CustomBoard"; + compatible = "variscite,var-som-imx7d-emmc-mx7customboard", + "variscite,var-som-imx7d", + "fsl,imx7d"; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-var-som-emmc-wm8731-mx7customboard.dts b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-emmc-wm8731-mx7customboard.dts new file mode 100644 index 0000000..94c4b1fa --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-emmc-wm8731-mx7customboard.dts
@@ -0,0 +1,23 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * VAR-MX7CustomBoard for VAR-SOM-MX7 with eMMC and WM8731 + * + * Link: https://variscite.com/carrier-boards/var-mx7customboard/ + * + * Copyright (C) 2026 Variscite Ltd. - https://www.variscite.com/ + * + */ + +/dts-v1/; + +#include "imx7d-var-som.dtsi" +#include "imx7d-var-som-emmc.dtsi" +#include "imx7d-var-som-wm8731.dtsi" +#include "imx7d-var-som-mx7customboard.dtsi" + +/ { + model = "Variscite VAR-SOM-MX7 with eMMC & WM8731 on VAR-MX7CustomBoard"; + compatible = "variscite,var-som-imx7d-emmc-wm8731-mx7customboard", + "variscite,var-som-imx7d", + "fsl,imx7d"; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-var-som-emmc.dtsi b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-emmc.dtsi new file mode 100644 index 0000000..62f60ec --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-emmc.dtsi
@@ -0,0 +1,56 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Common dtsi for eMMC support on Variscite VAR-SOM-MX7 + * + * Link: https://variscite.com/system-on-module-som/i-mx-7/var-som-mx7/ + * + * Copyright (C) 2026 Variscite Ltd. - https://www.variscite.com/ + * + */ + +&usdhc3 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_sleep>; + vmmc-supply = <&vgen3_reg>; + assigned-clocks = <&clks IMX7D_USDHC3_ROOT_CLK>; + assigned-clock-rates = <400000000>; + no-1-8-v; + bus-width = <8>; + non-removable; + status = "okay"; +}; + +&iomuxc { + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + MX7D_PAD_SD3_RESET_B__SD3_RESET_B 0x59 + MX7D_PAD_SD3_CMD__SD3_CMD 0x59 + MX7D_PAD_SD3_CLK__SD3_CLK 0x19 + MX7D_PAD_SD3_DATA0__SD3_DATA0 0x59 + MX7D_PAD_SD3_DATA1__SD3_DATA1 0x59 + MX7D_PAD_SD3_DATA2__SD3_DATA2 0x59 + MX7D_PAD_SD3_DATA3__SD3_DATA3 0x59 + MX7D_PAD_SD3_DATA4__SD3_DATA4 0x59 + MX7D_PAD_SD3_DATA5__SD3_DATA5 0x59 + MX7D_PAD_SD3_DATA6__SD3_DATA6 0x59 + MX7D_PAD_SD3_DATA7__SD3_DATA7 0x59 + >; + }; + + pinctrl_usdhc3_sleep: usdhc3-sleepgrp { + fsl,pins = < + MX7D_PAD_SD3_RESET_B__GPIO6_IO11 0x10 + MX7D_PAD_SD3_CMD__GPIO6_IO1 0x10 + MX7D_PAD_SD3_CLK__GPIO6_IO0 0x10 + MX7D_PAD_SD3_DATA0__GPIO6_IO2 0x10 + MX7D_PAD_SD3_DATA1__GPIO6_IO3 0x10 + MX7D_PAD_SD3_DATA2__GPIO6_IO4 0x10 + MX7D_PAD_SD3_DATA3__GPIO6_IO5 0x10 + MX7D_PAD_SD3_DATA4__GPIO6_IO6 0x10 + MX7D_PAD_SD3_DATA5__GPIO6_IO7 0x10 + MX7D_PAD_SD3_DATA6__GPIO6_IO8 0x10 + MX7D_PAD_SD3_DATA7__GPIO6_IO9 0x10 + >; + }; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-var-som-mx7customboard.dtsi b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-mx7customboard.dtsi new file mode 100644 index 0000000..d798b02 --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-mx7customboard.dtsi
@@ -0,0 +1,358 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Variscite VAR-MX7CustomBoard carrier board for VAR-SOM-MX7 + * + * Link: https://variscite.com/carrier-boards/var-mx7customboard/ + * + * Copyright (C) 2026 Variscite Ltd. - https://www.variscite.com/ + * + */ + +/ { + chosen { + stdout-path = &uart1; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_keys>; + + key-back { + label = "Back"; + gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; + linux,code = <KEY_BACK>; + }; + + key-menu { + label = "Menu"; + gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; + linux,code = <KEY_MENU>; + }; + + key-home { + label = "Home"; + gpios = <&gpio2 29 GPIO_ACTIVE_LOW>; + linux,code = <KEY_HOME>; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_leds>; + + led-d10 { + function = LED_FUNCTION_STATUS; + color = <LED_COLOR_ID_GREEN>; + gpios = <&gpio1 13 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; + + reg_hsic_hub_connect: regulator-hsic-hub-connect { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hsic_hub_connect>; + regulator-name = "reg_hsic_hub_connect"; + gpio = <&gpio1 12 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + }; + + reg_hsic_hub_pwr_on: regulator-hsic-hub-pwr-on { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hsic_hub_pwr>; + regulator-name = "hsic_hub_pwr_on"; + gpio = <&gpio1 10 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_usb_otg1_vbus: regulator-otg1-vbus { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg1_pwr>; + regulator-name = "usb_otg1_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio1 5 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_usb_otg2_vbus: regulator-otg2-vbus { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbotg2_pwr>; + regulator-name = "usb_otg2_vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio1 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&clks { + assigned-clocks = <&clks IMX7D_PLL_AUDIO_POST_DIV>; + assigned-clock-rates = <884736000>; +}; + +&ecspi2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ecspi2>; + cs-gpios = <&gpio4 23 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&flexcan2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan2>; + status = "okay"; +}; + +&i2c2 { + /* DS1337 RTC module */ + rtc@68 { + compatible = "dallas,ds1337"; + reg = <0x68>; + }; +}; + +&i2c4 { + clock-frequency = <100000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c4>; + pinctrl-1 = <&pinctrl_i2c4_gpio>; + scl-gpios = <&gpio4 14 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio4 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + status = "okay"; + + ft5x06_ts: touchscreen@38 { + compatible = "edt,edt-ft5206"; + reg = <0x38>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_touch>; + interrupt-parent = <&gpio2>; + interrupts = <30 IRQ_TYPE_EDGE_FALLING>; + touchscreen-size-x = <800>; + touchscreen-size-y = <480>; + touchscreen-inverted-x; + touchscreen-inverted-y; + }; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie>; + reset-gpios = <&gpio2 31 GPIO_ACTIVE_LOW>; + status = "okay"; +}; + +&pwm2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm2>; + status = "okay"; +}; + +&snvs_poweroff { + status = "okay"; +}; + +&snvs_pwrkey { + status = "okay"; +}; + +&snvs_rtc { + status = "disabled"; +}; + +/* DEBUG */ +&uart1 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pinctrl_uart1>; + pinctrl-1 = <&pinctrl_uart1_sleep>; + assigned-clocks = <&clks IMX7D_UART1_ROOT_SRC>; + assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + assigned-clocks = <&clks IMX7D_UART2_ROOT_SRC>; + assigned-clock-parents = <&clks IMX7D_OSC_24M_CLK>; + uart-has-rtscts; + status = "okay"; +}; + +&usbh { + disable-over-current; + vbus-supply = <®_hsic_hub_pwr_on>; + status = "okay"; +}; + +&usbotg1 { + dr_mode = "host"; + disable-over-current; + vbus-supply = <®_usb_otg1_vbus>; + status = "okay"; +}; + +&usbotg2 { + dr_mode = "host"; + disable-over-current; + vbus-supply = <®_usb_otg2_vbus>; + status = "okay"; +}; + +&usdhc1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_usdhc1_gpio>; + cd-gpios = <&gpio5 0 GPIO_ACTIVE_LOW>; + no-1-8-v; + keep-power-in-suspend; + status = "okay"; +}; + +&wdog1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; +}; + +&iomuxc { + pinctrl_gpio_keys: gpio-keysgrp { + fsl,pins = < + MX7D_PAD_EPDC_BDR0__GPIO2_IO28 0x32 + MX7D_PAD_EPDC_BDR1__GPIO2_IO29 0x32 + MX7D_PAD_GPIO1_IO11__GPIO1_IO11 0x32 + >; + }; + + pinctrl_gpio_leds: gpio-ledsgrp { + fsl,pins = < + MX7D_PAD_GPIO1_IO13__GPIO1_IO13 0x59 + >; + }; + + pinctrl_ecspi2: ecspi2grp { + fsl,pins = < + MX7D_PAD_ECSPI2_MISO__ECSPI2_MISO 0x2 + MX7D_PAD_ECSPI2_MOSI__ECSPI2_MOSI 0x2 + MX7D_PAD_ECSPI2_SCLK__ECSPI2_SCLK 0x2 + MX7D_PAD_ECSPI2_SS0__GPIO4_IO23 0x2 + >; + }; + + pinctrl_flexcan2: flexcan2grp { + fsl,pins = < + MX7D_PAD_I2C3_SCL__FLEXCAN2_RX 0x59 + MX7D_PAD_I2C3_SDA__FLEXCAN2_TX 0x59 + >; + }; + + pinctrl_hsic_hub_connect: hsichubconnectgrp { + fsl,pins = < + MX7D_PAD_GPIO1_IO12__GPIO1_IO12 0x59 + >; + }; + + pinctrl_hsic_hub_pwr: hsichubpwrgrp { + fsl,pins = < + MX7D_PAD_GPIO1_IO10__GPIO1_IO10 0x59 + >; + }; + + pinctrl_i2c4: i2c4grp { + fsl,pins = < + MX7D_PAD_I2C4_SDA__I2C4_SDA 0x4000007f + MX7D_PAD_I2C4_SCL__I2C4_SCL 0x4000007f + >; + }; + + pinctrl_i2c4_gpio: i2c4gpiogrp { + fsl,pins = < + MX7D_PAD_I2C4_SDA__GPIO4_IO15 0x4000007f + MX7D_PAD_I2C4_SCL__GPIO4_IO14 0x4000007f + >; + }; + + pinctrl_pcie: pciegrp { + fsl,pins = < + MX7D_PAD_EPDC_PWR_STAT__GPIO2_IO31 0x79 + >; + }; + + pinctrl_touch: touchgrp { + fsl,pins = < + MX7D_PAD_EPDC_PWR_COM__GPIO2_IO30 0x80000000 + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX7D_PAD_UART1_TX_DATA__UART1_DCE_TX 0x79 + MX7D_PAD_UART1_RX_DATA__UART1_DCE_RX 0x79 + >; + }; + + pinctrl_uart1_sleep: uart1sleep-grp { + fsl,pins = < + MX7D_PAD_UART1_TX_DATA__GPIO4_IO1 0x10 + MX7D_PAD_UART1_RX_DATA__GPIO4_IO0 0x10 + >; + }; + + pinctrl_uart2: uart2grp { + fsl,pins = < + MX7D_PAD_LCD_ENABLE__UART2_DCE_TX 0x79 + MX7D_PAD_LCD_CLK__UART2_DCE_RX 0x79 + MX7D_PAD_LCD_VSYNC__UART2_DCE_CTS 0x79 + MX7D_PAD_LCD_HSYNC__UART2_DCE_RTS 0x79 + >; + }; + + pinctrl_usdhc1_gpio: usdhc1-gpiogrp { + fsl,pins = < + MX7D_PAD_SD1_CD_B__GPIO5_IO0 0x59 + MX7D_PAD_GPIO1_IO08__SD1_VSELECT 0x59 + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX7D_PAD_SD1_CMD__SD1_CMD 0x59 + MX7D_PAD_SD1_CLK__SD1_CLK 0x19 + MX7D_PAD_SD1_DATA0__SD1_DATA0 0x59 + MX7D_PAD_SD1_DATA1__SD1_DATA1 0x59 + MX7D_PAD_SD1_DATA2__SD1_DATA2 0x59 + MX7D_PAD_SD1_DATA3__SD1_DATA3 0x59 + >; + }; +}; + +&iomuxc_lpsr { + pinctrl_pwm2: pwm2grp { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO02__PWM2_OUT 0x110b0 + >; + }; + + pinctrl_usbotg1_pwr: usbotg1pwrgrp { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO05__GPIO1_IO5 0x14 + >; + }; + + pinctrl_usbotg2_pwr: usbotg2pwrgrp { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO07__GPIO1_IO7 0x14 + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO00__WDOG1_WDOG_B 0x74 + >; + }; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-var-som-nand-mx7customboard.dts b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-nand-mx7customboard.dts new file mode 100644 index 0000000..d3fbf3b --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-nand-mx7customboard.dts
@@ -0,0 +1,23 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * VAR-MX7CustomBoard for VAR-SOM-MX7 with NAND + * + * Link: https://variscite.com/carrier-boards/var-mx7customboard/ + * + * Copyright (C) 2026 Variscite Ltd. - https://www.variscite.com/ + * + */ + +/dts-v1/; + +#include "imx7d-var-som.dtsi" +#include "imx7d-var-som-nand.dtsi" +#include "imx7d-var-som-wm8904.dtsi" +#include "imx7d-var-som-mx7customboard.dtsi" + +/ { + model = "Variscite VAR-SOM-MX7 with NAND flash & WM8904 on VAR-MX7CustomBoard"; + compatible = "variscite,var-som-imx7d-nand-mx7customboard", + "variscite,var-som-imx7d", + "fsl,imx7d"; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-var-som-nand-wm8731-mx7customboard.dts b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-nand-wm8731-mx7customboard.dts new file mode 100644 index 0000000..603b2dbf --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-nand-wm8731-mx7customboard.dts
@@ -0,0 +1,23 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * VAR-MX7CustomBoard for VAR-SOM-MX7 with NAND and WM8731 + * + * Link: https://variscite.com/carrier-boards/var-mx7customboard/ + * + * Copyright (C) 2026 Variscite Ltd. - https://www.variscite.com/ + * + */ + +/dts-v1/; + +#include "imx7d-var-som.dtsi" +#include "imx7d-var-som-nand.dtsi" +#include "imx7d-var-som-wm8731.dtsi" +#include "imx7d-var-som-mx7customboard.dtsi" + +/ { + model = "Variscite VAR-SOM-MX7 with NAND flash & WM8731 on VAR-MX7CustomBoard"; + compatible = "variscite,var-som-imx7d-nand-wm8731-mx7customboard", + "variscite,var-som-imx7d", + "fsl,imx7d"; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-var-som-nand.dtsi b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-nand.dtsi new file mode 100644 index 0000000..d2c3b9e --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-nand.dtsi
@@ -0,0 +1,73 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Common dtsi for NAND support on Variscite VAR-SOM-MX7 + * + * Link: https://variscite.com/system-on-module-som/i-mx-7/var-som-mx7/ + * + * Copyright (C) 2026 Variscite Ltd. - https://www.variscite.com/ + * + */ + +&gpmi { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpmi_nand>; + status = "okay"; + + nand@0 { + reg = <0>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "spl"; + reg = <0x00000000 0x00200000>; + }; + + partition@200000 { + label = "u-boot"; + reg = <0x00200000 0x00200000>; + }; + + partition@400000 { + label = "u-boot_env"; + reg = <0x00400000 0x00200000>; + }; + + partition@600000 { + label = "kernel"; + reg = <0x00600000 0x00c00000>; + }; + + partition@1200000 { + label = "rootfs"; + reg = <0x01200000 0x3ee00000>; + }; + }; + }; +}; + +&iomuxc { + pinctrl_gpmi_nand: gpminandgrp { + fsl,pins = < + MX7D_PAD_SD3_CLK__NAND_CLE 0x71 + MX7D_PAD_SD3_CMD__NAND_ALE 0x71 + MX7D_PAD_SAI1_MCLK__NAND_WP_B 0x71 + MX7D_PAD_SAI1_TX_BCLK__NAND_CE0_B 0x71 + MX7D_PAD_SAI1_RX_DATA__NAND_CE1_B 0x71 + MX7D_PAD_SAI1_TX_DATA__NAND_READY_B 0x74 + MX7D_PAD_SD3_STROBE__NAND_RE_B 0x71 + MX7D_PAD_SD3_RESET_B__NAND_WE_B 0x71 + MX7D_PAD_SD3_DATA0__NAND_DATA00 0x71 + MX7D_PAD_SD3_DATA1__NAND_DATA01 0x71 + MX7D_PAD_SD3_DATA2__NAND_DATA02 0x71 + MX7D_PAD_SD3_DATA3__NAND_DATA03 0x71 + MX7D_PAD_SD3_DATA4__NAND_DATA04 0x71 + MX7D_PAD_SD3_DATA5__NAND_DATA05 0x71 + MX7D_PAD_SD3_DATA6__NAND_DATA06 0x71 + MX7D_PAD_SD3_DATA7__NAND_DATA07 0x71 + >; + }; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-var-som-v2-emmc-mx7customboard.dts b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-v2-emmc-mx7customboard.dts new file mode 100644 index 0000000..1c41925 --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-v2-emmc-mx7customboard.dts
@@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * VAR-MX7CustomBoard for VAR-SOM-MX7 V2 with eMMC + * + * Link: https://variscite.com/carrier-boards/var-mx7customboard/ + * + * Copyright (C) 2026 Variscite Ltd. - https://www.variscite.com/ + * + */ + +/dts-v1/; + +#include "imx7d-var-som.dtsi" +#include "imx7d-var-som-v2.dtsi" +#include "imx7d-var-som-emmc.dtsi" +#include "imx7d-var-som-wm8904.dtsi" +#include "imx7d-var-som-mx7customboard.dtsi" + +/ { + model = "Variscite VAR-SOM-MX7-5G_V2 with eMMC & WM8904 on VAR-MX7CustomBoard"; + compatible = "variscite,var-som-imx7d-v2-emmc-mx7customboard", + "variscite,var-som-imx7d-v2", + "fsl,imx7d"; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-var-som-v2-nand-mx7customboard.dts b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-v2-nand-mx7customboard.dts new file mode 100644 index 0000000..6856911 --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-v2-nand-mx7customboard.dts
@@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * VAR-MX7CustomBoard for VAR-SOM-MX7 V2 with NAND + * + * Link: https://variscite.com/carrier-boards/var-mx7customboard/ + * + * Copyright (C) 2026 Variscite Ltd. - https://www.variscite.com/ + * + */ + +/dts-v1/; + +#include "imx7d-var-som.dtsi" +#include "imx7d-var-som-v2.dtsi" +#include "imx7d-var-som-nand.dtsi" +#include "imx7d-var-som-wm8904.dtsi" +#include "imx7d-var-som-mx7customboard.dtsi" + +/ { + model = "Variscite VAR-SOM-MX7-5G_V2 with NAND flash & WM8904 on VAR-MX7CustomBoard"; + compatible = "variscite,var-som-imx7d-v2-nand-mx7customboard", + "variscite,var-som-imx7d-v2", + "fsl,imx7d"; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-var-som-v2.dtsi b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-v2.dtsi new file mode 100644 index 0000000..8aa9d09 --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-v2.dtsi
@@ -0,0 +1,66 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * dtsi for Variscite VAR-SOM-MX7 V2 + * + * Changelog link: https://dev.variscite.com/var-som-mx7/changelog/#var-som-mx7_v2-v20 + * + * Copyright (C) 2026 Variscite Ltd. - https://www.variscite.com/ + * + */ + +/ { + model = "Variscite i.MX7 Dual VAR-SOM-MX7 V2"; + compatible = "variscite,var-som-imx7d-v2", "fsl,imx7d"; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + post-power-on-delay-ms = <100>; + power-off-delay-us = <10000>; + reset-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>; + }; +}; + +&fec1 { + /* + * The required RGMII TX and RX 2ns delays are implemented directly + * in hardware via passive delay elements on the SOM PCB. + * No delay configuration is needed in software via PHY driver. + */ + phy-mode = "rgmii"; +}; + +&fec2 { + /* + * The required RGMII TX and RX 2ns delays are implemented directly + * in hardware via passive delay elements on the SOM PCB. + * No delay configuration is needed in software via PHY driver. + */ + phy-mode = "rgmii"; +}; + +&pinctrl_wlan { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO04__GPIO1_IO4 0x09 + >; +}; + +&pinctrl_wlan_sleep { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO04__GPIO1_IO4 0x10 + >; +}; + +/* BT */ +&uart3 { + bluetooth_iw61x: bluetooth { + compatible = "nxp,88w8987-bt"; + }; +}; + +/* WiFi */ +&usdhc2 { + /delete-property/ #address-cells; + /delete-property/ #size-cells; + mmc-pwrseq = <&wifi_pwrseq>; + /delete-node/ wifi@1; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-var-som-wm8731.dtsi b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-wm8731.dtsi new file mode 100644 index 0000000..ab05de43 --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-wm8731.dtsi
@@ -0,0 +1,102 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Common dtsi for WM8731 support on Variscite VAR-SOM-MX7 + * + * Link: https://variscite.com/system-on-module-som/i-mx-7/var-som-mx7/ + * + * Copyright (C) 2026 Variscite Ltd. - https://www.variscite.com/ + * + */ + +/ { + codec_wm8731: sound { + compatible = "simple-audio-card"; + simple-audio-card,bitclock-master = <&sound_master>; + simple-audio-card,format = "i2s"; + simple-audio-card,frame-master = <&sound_master>; + simple-audio-card,name = "wm8731audio"; + simple-audio-card,routing = + "Headphone Jack", "RHPOUT", + "Headphone Jack", "LHPOUT", + "LLINEIN", "Line Jack", + "RLINEIN", "Line Jack", + "MICIN", "Mic Bias", + "Mic Bias", "Mic Jack"; + simple-audio-card,widgets = + "Headphone", "Headphone Jack", + "Line", "Line Jack", + "Microphone", "Mic Jack"; + + sound_master: simple-audio-card,cpu { + sound-dai = <&sai1>; + }; + + simple-audio-card,codec { + sound-dai = <&wm8731>; + system-clock-frequency = <12288000>; + }; + }; +}; + +&i2c2 { + wm8731: audio-codec@1a { + compatible = "wlf,wm8731"; + reg = <0x1a>; + #sound-dai-cells = <0>; + AVDD-supply = <&vgen6_reg>; + DBVDD-supply = <&vgen6_reg>; + DCVDD-supply = <&vgen6_reg>; + HPVDD-supply = <&vgen6_reg>; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>; + clock-names = "mclk"; + assigned-clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_SRC>, + <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>; + assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>; + assigned-clock-rates = <0>, <12288000>; + }; +}; + +&sai1 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pinctrl_sai1>, <&pinctrl_sai1_mclk>; + pinctrl-1 = <&pinctrl_sai1_sleep>, <&pinctrl_sai1_mclk_sleep>; + assigned-clocks = <&clks IMX7D_SAI1_ROOT_SRC>, + <&clks IMX7D_SAI1_ROOT_CLK>; + assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>; + assigned-clock-rates = <0>, <36864000>; + status = "okay"; +}; + +&iomuxc { + pinctrl_sai1: sai1grp { + fsl,pins = < + MX7D_PAD_ENET1_RX_CLK__SAI1_TX_BCLK 0x1f + MX7D_PAD_ENET1_CRS__SAI1_TX_SYNC 0x1f + MX7D_PAD_ENET1_COL__SAI1_TX_DATA0 0x30 + MX7D_PAD_ENET1_TX_CLK__SAI1_RX_DATA0 0x1f + >; + }; + + pinctrl_sai1_sleep: sai1-sleepgrp { + fsl,pins = < + MX7D_PAD_ENET1_RX_CLK__GPIO7_IO13 0x10 + MX7D_PAD_ENET1_CRS__GPIO7_IO14 0x10 + MX7D_PAD_ENET1_COL__GPIO7_IO15 0x10 + MX7D_PAD_ENET1_TX_CLK__GPIO7_IO12 0x10 + >; + }; +}; + +&iomuxc_lpsr { + pinctrl_sai1_mclk: sai1-mclkgrp { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO01__SAI1_MCLK 0x1f + >; + }; + + pinctrl_sai1_mclk_sleep: sai1-mclksleepgrp { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO01__GPIO1_IO1 0x10 + >; + }; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-var-som-wm8904.dtsi b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-wm8904.dtsi new file mode 100644 index 0000000..b56f368 --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-var-som-wm8904.dtsi
@@ -0,0 +1,118 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Common dtsi for WM8904 support on Variscite VAR-SOM-MX7 + * + * Link: https://variscite.com/system-on-module-som/i-mx-7/var-som-mx7/ + * + * Copyright (C) 2026 Variscite Ltd. - https://www.variscite.com/ + * + */ + +/ { + codec_wm8904: sound { + compatible = "simple-audio-card"; + simple-audio-card,bitclock-master = <&dailink_master>; + simple-audio-card,format = "i2s"; + simple-audio-card,frame-master = <&dailink_master>; + simple-audio-card,name = "wm8904-audio"; + simple-audio-card,routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "IN2L", "Line In Jack", + "IN2R", "Line In Jack", + "IN1L", "Microphone Jack", + "IN1R", "Microphone Jack", + "Microphone Jack", "MICBIAS"; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Headphone", "Headphone Jack", + "Line", "Line In Jack"; + simple-audio-card,mclk-fs = <256>; + + dailink_master: simple-audio-card,codec { + sound-dai = <&wm8904>; + }; + + simple-audio-card,cpu { + sound-dai = <&sai1>; + }; + }; +}; + +&i2c2 { + wm8904: audio-codec@1a { + compatible = "wlf,wm8904"; + reg = <0x1a>; + #sound-dai-cells = <0>; + clocks = <&clks IMX7D_AUDIO_MCLK_ROOT_DIV>; + clock-names = "mclk"; + AVDD-supply = <&vgen6_reg>; + CPVDD-supply = <&vgen6_reg>; + DCVDD-supply = <&vgen6_reg>; + DBVDD-supply = <&vgen6_reg>; + MICVDD-supply = <&vgen6_reg>; + wlf,drc-cfg-names = "default", "peaklimiter", "tradition", + "soft", "music"; + /* + * Config registers per name, respectively: + * KNEE_IP = 0, KNEE_OP = 0, HI_COMP = 1, LO_COMP = 1 + * KNEE_IP = -24, KNEE_OP = -6, HI_COMP = 1/4, LO_COMP = 1 + * KNEE_IP = -42, KNEE_OP = -3, HI_COMP = 0, LO_COMP = 1 + * KNEE_IP = -45, KNEE_OP = -9, HI_COMP = 1/8, LO_COMP = 1 + * KNEE_IP = -30, KNEE_OP = -10.5, HI_COMP = 1/4, LO_COMP = 1 + */ + wlf,drc-cfg-regs = /bits/ 16 <0x01af 0x3248 0x0000 0x0000>, + /bits/ 16 <0x04af 0x324b 0x0010 0x0408>, + /bits/ 16 <0x04af 0x324b 0x0028 0x0704>, + /bits/ 16 <0x04af 0x324b 0x0018 0x078c>, + /bits/ 16 <0x04af 0x324b 0x0010 0x050e>; + /* GPIO1 = DMIC_CLK, don't touch others */ + wlf,gpio-cfg = <0x0018>, <0xffff>, <0xffff>, <0xffff>; + }; +}; + +&sai1 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pinctrl_sai1>, <&pinctrl_sai1_mclk>; + pinctrl-1 = <&pinctrl_sai1_sleep>, <&pinctrl_sai1_mclk_sleep>; + assigned-clocks = <&clks IMX7D_SAI1_ROOT_SRC>, + <&clks IMX7D_SAI1_ROOT_CLK>; + assigned-clock-parents = <&clks IMX7D_PLL_AUDIO_POST_DIV>; + assigned-clock-rates = <0>, <12288000>; + fsl,sai-mclk-direction-output; + status = "okay"; +}; + +&iomuxc { + pinctrl_sai1: sai1grp { + fsl,pins = < + MX7D_PAD_ENET1_RX_CLK__SAI1_TX_BCLK 0x1f + MX7D_PAD_ENET1_CRS__SAI1_TX_SYNC 0x1f + MX7D_PAD_ENET1_COL__SAI1_TX_DATA0 0x30 + MX7D_PAD_ENET1_TX_CLK__SAI1_RX_DATA0 0x1f + >; + }; + + pinctrl_sai1_sleep: sai1-sleepgrp { + fsl,pins = < + MX7D_PAD_ENET1_RX_CLK__GPIO7_IO13 0x10 + MX7D_PAD_ENET1_CRS__GPIO7_IO14 0x10 + MX7D_PAD_ENET1_COL__GPIO7_IO15 0x10 + MX7D_PAD_ENET1_TX_CLK__GPIO7_IO12 0x10 + >; + }; +}; + +&iomuxc_lpsr { + pinctrl_sai1_mclk: sai1-mclkgrp { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO01__SAI1_MCLK 0x1f + >; + }; + + pinctrl_sai1_mclk_sleep: sai1-mclksleepgrp { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO01__GPIO1_IO1 0x10 + >; + }; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7d-var-som.dtsi b/arch/arm/boot/dts/nxp/imx/imx7d-var-som.dtsi new file mode 100644 index 0000000..255cf44 --- /dev/null +++ b/arch/arm/boot/dts/nxp/imx/imx7d-var-som.dtsi
@@ -0,0 +1,533 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Common dtsi for Variscite VAR-SOM-MX7 + * + * Link: https://variscite.com/system-on-module-som/i-mx-7/var-som-mx7/ + * + * Copyright (C) 2026 Variscite Ltd. - https://www.variscite.com/ + * + */ + +#include <dt-bindings/leds/common.h> +#include "imx7d.dtsi" + +/ { + model = "Variscite i.MX7 Dual VAR-SOM-MX7"; + compatible = "variscite,var-som-imx7d", "fsl,imx7d"; + + memory@80000000 { + device_type = "memory"; + reg = <0x80000000 0x80000000>; + }; + + reg_phy_vddio: regulator-phy-vddio { + compatible = "regulator-fixed"; + regulator-name = "vddio-1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + reg_vmmc_wl: regulator-vmmc-wl { + compatible = "regulator-fixed"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "wlreg_on"; + }; + + reg_vref_1v8: regulator-vref-1v8 { + compatible = "regulator-fixed"; + regulator-name = "vref-1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + +}; + +&adc1 { + vref-supply = <®_vref_1v8>; + status = "okay"; +}; + +&adc2 { + vref-supply = <®_vref_1v8>; + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&sw1a_reg>; +}; + +&cpu1 { + cpu-supply = <&sw1a_reg>; +}; + +&ecspi1 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pinctrl_ecspi1>; + pinctrl-1 = <&pinctrl_ecspi1_sleep>; + cs-gpios = <&gpio4 19 GPIO_ACTIVE_LOW>; + status = "okay"; + + /* Resistive touch controller */ + ads7846_ts: touchscreen@0 { + reg = <0>; + compatible = "ti,ads7846"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_restouch>; + interrupt-parent = <&gpio1>; + interrupts = <9 IRQ_TYPE_EDGE_FALLING>; + spi-max-frequency = <1500000>; + pendown-gpio = <&gpio1 9 GPIO_ACTIVE_LOW>; + ti,x-min = /bits/ 16 <125>; + ti,x-max = /bits/ 16 <4008>; + ti,y-min = /bits/ 16 <282>; + ti,y-max = /bits/ 16 <3864>; + ti,x-plate-ohms = /bits/ 16 <180>; + ti,pressure-max = /bits/ 16 <255>; + ti,debounce-max = /bits/ 16 <10>; + ti,debounce-tol = /bits/ 16 <3>; + ti,debounce-rep = /bits/ 16 <1>; + ti,settle-delay-usec = /bits/ 16 <150>; + ti,keep-vref-on; + }; +}; + +&fec1 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pinctrl_enet1>, + <&pinctrl_enet1_rst>, + <&pinctrl_enet2_rst>; + pinctrl-1 = <&pinctrl_enet1_sleep>, + <&pinctrl_enet1_rst_sleep>, + <&pinctrl_enet2_rst_sleep>; + phy-supply = <&vgen3_reg>; + assigned-clocks = <&clks IMX7D_ENET_PHY_REF_ROOT_SRC>, + <&clks IMX7D_ENET_AXI_ROOT_SRC>, + <&clks IMX7D_ENET1_TIME_ROOT_SRC>, + <&clks IMX7D_ENET1_TIME_ROOT_CLK>, + <&clks IMX7D_ENET_AXI_ROOT_CLK>; + assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_25M_CLK>, + <&clks IMX7D_PLL_ENET_MAIN_250M_CLK>, + <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>; + assigned-clock-rates = <0>, <0>, <0>, <100000000>, <250000000>; + phy-mode = "rgmii-id"; + phy-handle = <ðphy0>; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + ethphy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0>; + reset-gpios = <&gpio5 11 GPIO_ACTIVE_LOW>; + reset-assert-us = <20000>; + reset-deassert-us = <80000>; + vddio-supply = <®_phy_vddio>; + }; + + ethphy1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + reset-gpios = <&gpio4 3 GPIO_ACTIVE_LOW>; + reset-assert-us = <20000>; + reset-deassert-us = <80000>; + vddio-supply = <®_phy_vddio>; + }; + }; +}; + +&fec2 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pinctrl_enet2>; + pinctrl-1 = <&pinctrl_enet2_sleep>; + phy-supply = <&vgen3_reg>; + assigned-clocks = <&clks IMX7D_ENET_PHY_REF_ROOT_SRC>, + <&clks IMX7D_ENET_AXI_ROOT_SRC>, + <&clks IMX7D_ENET2_TIME_ROOT_SRC>, + <&clks IMX7D_ENET2_TIME_ROOT_CLK>, + <&clks IMX7D_ENET_AXI_ROOT_CLK>; + assigned-clock-parents = <&clks IMX7D_PLL_ENET_MAIN_25M_CLK>, + <&clks IMX7D_PLL_ENET_MAIN_250M_CLK>, + <&clks IMX7D_PLL_ENET_MAIN_100M_CLK>; + assigned-clock-rates = <0>, <0>, <0>, <100000000>, <250000000>; + phy-mode = "rgmii-id"; + phy-handle = <ðphy1>; + status = "okay"; +}; + +&i2c1 { + clock-frequency = <100000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + scl-gpios = <&gpio4 8 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio4 9 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + status = "okay"; + + pfuze300: pmic@8 { + compatible = "fsl,pfuze3000"; + reg = <0x08>; + + regulators { + sw1a_reg: sw1a { + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + + /* use sw1c_reg to align with pfuze100/pfuze200 */ + sw1c_reg: sw1b { + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <1475000>; + regulator-boot-on; + regulator-always-on; + regulator-ramp-delay = <6250>; + }; + + sw2_reg: sw2 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + sw3a_reg: sw3 { + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1650000>; + regulator-boot-on; + regulator-always-on; + }; + + swbst_reg: swbst { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5150000>; + }; + + snvs_reg: vsnvs { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <3000000>; + regulator-boot-on; + regulator-always-on; + }; + + vref_reg: vrefddr { + regulator-boot-on; + regulator-always-on; + }; + + vgen1_reg: vldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen2_reg: vldo2 { + status = "disabled"; + }; + + vgen3_reg: vccsd { + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vgen4_reg: v33 { + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <2850000>; + regulator-always-on; + }; + + vgen5_reg: vldo3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + vgen6_reg: vldo4 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + }; + }; +}; + +&i2c2 { + clock-frequency = <100000>; + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c2>; + pinctrl-1 = <&pinctrl_i2c2_gpio>; + scl-gpios = <&gpio4 10 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio4 11 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + status = "okay"; +}; + +®_1p0d { + vin-supply = <&sw2_reg>; +}; + +®_1p2 { + vin-supply = <&sw2_reg>; +}; + +/* BT */ +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>, <&pinctrl_bt>; + assigned-clocks = <&clks IMX7D_UART3_ROOT_SRC>; + assigned-clock-parents = <&clks IMX7D_PLL_SYS_MAIN_240M_CLK>; + uart-has-rtscts; + status = "okay"; +}; + +/* WiFi */ +&usdhc2 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_wlan>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_wlan>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_wlan>; + pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_wlan_sleep>; + keep-power-in-suspend; + non-removable; + vmmc-supply = <®_vmmc_wl>; + status = "okay"; + + brcmf: wifi@1 { + compatible = "brcm,bcm4329-fmac"; + reg = <1>; + }; +}; + +&iomuxc { + /* GPIO Used in User Space init script */ + pinctrl_bt: btgrp { + fsl,pins = < + MX7D_PAD_GPIO1_IO14__GPIO1_IO14 0x80000000 + >; + }; + + pinctrl_ecspi1: ecspi1grp { + fsl,pins = < + MX7D_PAD_ECSPI1_MISO__ECSPI1_MISO 0x2 + MX7D_PAD_ECSPI1_MOSI__ECSPI1_MOSI 0x2 + MX7D_PAD_ECSPI1_SCLK__ECSPI1_SCLK 0x2 + MX7D_PAD_ECSPI1_SS0__GPIO4_IO19 0x2 + >; + }; + + pinctrl_ecspi1_sleep: ecspi1-sleepgrp { + fsl,pins = < + MX7D_PAD_ECSPI1_MISO__GPIO4_IO18 0x10 + MX7D_PAD_ECSPI1_MOSI__GPIO4_IO17 0x10 + MX7D_PAD_ECSPI1_SCLK__GPIO4_IO16 0x10 + >; + }; + + pinctrl_enet1: enet1grp { + fsl,pins = < + MX7D_PAD_SD2_CD_B__ENET1_MDIO 0x3 + MX7D_PAD_SD2_WP__ENET1_MDC 0x3 + MX7D_PAD_ENET1_RGMII_TXC__ENET1_RGMII_TXC 0x1 + MX7D_PAD_ENET1_RGMII_TD0__ENET1_RGMII_TD0 0x1 + MX7D_PAD_ENET1_RGMII_TD1__ENET1_RGMII_TD1 0x1 + MX7D_PAD_ENET1_RGMII_TD2__ENET1_RGMII_TD2 0x1 + MX7D_PAD_ENET1_RGMII_TD3__ENET1_RGMII_TD3 0x1 + MX7D_PAD_ENET1_RGMII_TX_CTL__ENET1_RGMII_TX_CTL 0x1 + MX7D_PAD_ENET1_RGMII_RXC__ENET1_RGMII_RXC 0x1 + MX7D_PAD_ENET1_RGMII_RD0__ENET1_RGMII_RD0 0x1 + MX7D_PAD_ENET1_RGMII_RD1__ENET1_RGMII_RD1 0x1 + MX7D_PAD_ENET1_RGMII_RD2__ENET1_RGMII_RD2 0x1 + MX7D_PAD_ENET1_RGMII_RD3__ENET1_RGMII_RD3 0x1 + MX7D_PAD_ENET1_RGMII_RX_CTL__ENET1_RGMII_RX_CTL 0x1 + >; + }; + + pinctrl_enet1_rst: enet1rstgrp { + fsl,pins = < + MX7D_PAD_SD2_RESET_B__GPIO5_IO11 0x59 + >; + }; + + pinctrl_enet1_sleep: enet1-sleepgrp { + fsl,pins = < + MX7D_PAD_SD2_CD_B__GPIO5_IO9 0x10 + MX7D_PAD_SD2_WP__GPIO5_IO10 0x10 + MX7D_PAD_ENET1_RGMII_TXC__GPIO7_IO11 0x10 + MX7D_PAD_ENET1_RGMII_TD0__GPIO7_IO6 0x10 + MX7D_PAD_ENET1_RGMII_TD1__GPIO7_IO7 0x10 + MX7D_PAD_ENET1_RGMII_TD2__GPIO7_IO8 0x10 + MX7D_PAD_ENET1_RGMII_TD3__GPIO7_IO9 0x10 + MX7D_PAD_ENET1_RGMII_TX_CTL__GPIO7_IO10 0x10 + MX7D_PAD_ENET1_RGMII_RXC__GPIO7_IO5 0x10 + MX7D_PAD_ENET1_RGMII_RD0__GPIO7_IO0 0x10 + MX7D_PAD_ENET1_RGMII_RD1__GPIO7_IO1 0x10 + MX7D_PAD_ENET1_RGMII_RD2__GPIO7_IO2 0x10 + MX7D_PAD_ENET1_RGMII_RD3__GPIO7_IO3 0x10 + MX7D_PAD_ENET1_RGMII_RX_CTL__GPIO7_IO4 0x10 + >; + }; + + pinctrl_enet1_rst_sleep: enet1-rstsleepgrp { + fsl,pins = < + MX7D_PAD_SD2_RESET_B__GPIO5_IO11 0x10 + >; + }; + + pinctrl_enet2: enet2grp { + fsl,pins = < + MX7D_PAD_EPDC_GDSP__ENET2_RGMII_TXC 0x1 + MX7D_PAD_EPDC_SDCE2__ENET2_RGMII_TD0 0x1 + MX7D_PAD_EPDC_SDCE3__ENET2_RGMII_TD1 0x1 + MX7D_PAD_EPDC_GDCLK__ENET2_RGMII_TD2 0x1 + MX7D_PAD_EPDC_GDOE__ENET2_RGMII_TD3 0x1 + MX7D_PAD_EPDC_GDRL__ENET2_RGMII_TX_CTL 0x1 + MX7D_PAD_EPDC_SDCE1__ENET2_RGMII_RXC 0x1 + MX7D_PAD_EPDC_SDCLK__ENET2_RGMII_RD0 0x1 + MX7D_PAD_EPDC_SDLE__ENET2_RGMII_RD1 0x1 + MX7D_PAD_EPDC_SDOE__ENET2_RGMII_RD2 0x1 + MX7D_PAD_EPDC_SDSHR__ENET2_RGMII_RD3 0x1 + MX7D_PAD_EPDC_SDCE0__ENET2_RGMII_RX_CTL 0x1 + >; + }; + + pinctrl_enet2_rst: enet2rstgrp { + fsl,pins = < + MX7D_PAD_UART2_TX_DATA__GPIO4_IO3 0x59 + >; + }; + + pinctrl_enet2_sleep: enet2-sleepgrp { + fsl,pins = < + MX7D_PAD_EPDC_GDSP__GPIO2_IO27 0x10 + MX7D_PAD_EPDC_SDCE2__GPIO2_IO22 0x10 + MX7D_PAD_EPDC_SDCE3__GPIO2_IO23 0x10 + MX7D_PAD_EPDC_GDCLK__GPIO2_IO24 0x10 + MX7D_PAD_EPDC_GDOE__GPIO2_IO25 0x10 + MX7D_PAD_EPDC_GDRL__GPIO2_IO26 0x10 + MX7D_PAD_EPDC_SDCE1__GPIO2_IO21 0x10 + MX7D_PAD_EPDC_SDCLK__GPIO2_IO16 0x10 + MX7D_PAD_EPDC_SDLE__GPIO2_IO17 0x10 + MX7D_PAD_EPDC_SDOE__GPIO2_IO18 0x10 + MX7D_PAD_EPDC_SDSHR__GPIO2_IO19 0x10 + MX7D_PAD_EPDC_SDCE0__GPIO2_IO20 0x10 + >; + }; + + pinctrl_enet2_rst_sleep: enet2-rstsleepgrp { + fsl,pins = < + MX7D_PAD_UART2_TX_DATA__GPIO4_IO3 0x10 + >; + }; + + pinctrl_i2c1: i2c1grp { + fsl,pins = < + MX7D_PAD_I2C1_SDA__I2C1_SDA 0x4000007f + MX7D_PAD_I2C1_SCL__I2C1_SCL 0x4000007f + >; + }; + + pinctrl_i2c1_gpio: i2c1gpiogrp { + fsl,pins = < + MX7D_PAD_I2C1_SDA__GPIO4_IO9 0x4000007f + MX7D_PAD_I2C1_SCL__GPIO4_IO8 0x4000007f + >; + }; + + pinctrl_i2c2: i2c2grp { + fsl,pins = < + MX7D_PAD_I2C2_SDA__I2C2_SDA 0x4000007f + MX7D_PAD_I2C2_SCL__I2C2_SCL 0x4000007f + >; + }; + + pinctrl_i2c2_gpio: i2c2gpiogrp { + fsl,pins = < + MX7D_PAD_I2C2_SDA__GPIO4_IO11 0x4000007f + MX7D_PAD_I2C2_SCL__GPIO4_IO10 0x4000007f + >; + }; + + pinctrl_restouch: restouchgrp { + fsl,pins = < + MX7D_PAD_GPIO1_IO09__GPIO1_IO9 0x59 + >; + }; + + pinctrl_uart3: uart3grp { + fsl,pins = < + MX7D_PAD_UART3_TX_DATA__UART3_DCE_TX 0x79 + MX7D_PAD_UART3_RX_DATA__UART3_DCE_RX 0x79 + MX7D_PAD_UART3_CTS_B__UART3_DCE_CTS 0x79 + MX7D_PAD_UART3_RTS_B__UART3_DCE_RTS 0x79 + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX7D_PAD_SD2_CMD__SD2_CMD 0x59 + MX7D_PAD_SD2_CLK__SD2_CLK 0x19 + MX7D_PAD_SD2_DATA0__SD2_DATA0 0x59 + MX7D_PAD_SD2_DATA1__SD2_DATA1 0x59 + MX7D_PAD_SD2_DATA2__SD2_DATA2 0x59 + MX7D_PAD_SD2_DATA3__SD2_DATA3 0x59 + >; + }; + + pinctrl_usdhc2_sleep: usdhc2-sleepgrp { + fsl,pins = < + MX7D_PAD_SD2_CMD__GPIO5_IO13 0x10 + MX7D_PAD_SD2_CLK__GPIO5_IO12 0x10 + MX7D_PAD_SD2_DATA0__GPIO5_IO14 0x10 + MX7D_PAD_SD2_DATA1__GPIO5_IO15 0x10 + MX7D_PAD_SD2_DATA2__GPIO5_IO16 0x10 + MX7D_PAD_SD2_DATA3__GPIO5_IO17 0x10 + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { + fsl,pins = < + MX7D_PAD_SD2_CMD__SD2_CMD 0x5a + MX7D_PAD_SD2_CLK__SD2_CLK 0x1a + MX7D_PAD_SD2_DATA0__SD2_DATA0 0x5a + MX7D_PAD_SD2_DATA1__SD2_DATA1 0x5a + MX7D_PAD_SD2_DATA2__SD2_DATA2 0x5a + MX7D_PAD_SD2_DATA3__SD2_DATA3 0x5a + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { + fsl,pins = < + MX7D_PAD_SD2_CMD__SD2_CMD 0x5b + MX7D_PAD_SD2_CLK__SD2_CLK 0x1b + MX7D_PAD_SD2_DATA0__SD2_DATA0 0x5b + MX7D_PAD_SD2_DATA1__SD2_DATA1 0x5b + MX7D_PAD_SD2_DATA2__SD2_DATA2 0x5b + MX7D_PAD_SD2_DATA3__SD2_DATA3 0x5b + >; + }; +}; + +&iomuxc_lpsr { + /* GPIO Used in User Space init script */ + pinctrl_wlan: wlangrp { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO04__GPIO1_IO4 0x09 + >; + }; + + pinctrl_wlan_sleep: wlan-sleepgrp { + fsl,pins = < + MX7D_PAD_LPSR_GPIO1_IO04__GPIO1_IO4 0x10 + >; + }; +};
diff --git a/arch/arm/boot/dts/nxp/imx/imx7s-warp.dts b/arch/arm/boot/dts/nxp/imx/imx7s-warp.dts index 25f38ac..b198901 100644 --- a/arch/arm/boot/dts/nxp/imx/imx7s-warp.dts +++ b/arch/arm/boot/dts/nxp/imx/imx7s-warp.dts
@@ -272,7 +272,7 @@ &uart1 { status = "okay"; }; -&uart3 { +&uart3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart3>; assigned-clocks = <&clks IMX7D_UART3_ROOT_SRC>;
diff --git a/arch/arm/boot/dts/nxp/imx/mba6ulx.dtsi b/arch/arm/boot/dts/nxp/imx/mba6ulx.dtsi index 1fda60d..fd05479 100644 --- a/arch/arm/boot/dts/nxp/imx/mba6ulx.dtsi +++ b/arch/arm/boot/dts/nxp/imx/mba6ulx.dtsi
@@ -118,16 +118,6 @@ reg_mpcie: regulator-mpcie-3v3 { vin-supply = <®_mba6ul_3v3>; }; - reg_otg2vbus_5v0: regulator-otg2-vbus-5v0 { - compatible = "regulator-fixed"; - gpio = <&expander_out1 0 GPIO_ACTIVE_HIGH>; - enable-active-high; - regulator-name = "otg2-vbus-supply-5v0"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <®_mpcie>; - }; - reserved-memory { #address-cells = <1>; #size-cells = <1>; @@ -215,6 +205,8 @@ ethphy0: ethernet-phy@0 { clocks = <&clks IMX6UL_CLK_ENET_REF>; reg = <0>; max-speed = <100>; + interrupt-parent = <&expander_in0>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; }; ethphy1: ethernet-phy@1 { @@ -222,6 +214,8 @@ ethphy1: ethernet-phy@1 { clocks = <&clks IMX6UL_CLK_ENET2_REF_125M>; reg = <1>; max-speed = <100>; + interrupt-parent = <&expander_in0>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; }; }; }; @@ -261,18 +255,6 @@ expander_in0: gpio-expander@21 { gpio-controller; #gpio-cells = <2>; vcc-supply = <®_mba6ul_3v3>; - - enet1_int-hog { - gpio-hog; - gpios = <6 0>; - input; - }; - - enet2_int-hog { - gpio-hog; - gpios = <7 0>; - input; - }; }; expander_out1: gpio-expander@22 { @@ -377,10 +359,18 @@ &usbotg1 { /* 7-port usb hub */ /* id, pwr, oc pins not connected */ &usbotg2 { + #address-cells = <1>; + #size-cells = <0>; disable-over-current; - vbus-supply = <®_otg2vbus_5v0>; dr_mode = "host"; status = "okay"; + + hub_2_0: hub@1 { + compatible = "usb424,2517"; + reg = <1>; + reset-gpios = <&expander_out1 0 GPIO_ACTIVE_LOW>; + vdd-supply = <®_mba6ul_3v3>; + }; }; &usdhc1 {
diff --git a/arch/arm/boot/dts/nxp/ls/ls1021a.dtsi b/arch/arm/boot/dts/nxp/ls/ls1021a.dtsi index e0b9ea6..af518fc 100644 --- a/arch/arm/boot/dts/nxp/ls/ls1021a.dtsi +++ b/arch/arm/boot/dts/nxp/ls/ls1021a.dtsi
@@ -721,7 +721,7 @@ queue-group@2d10000 { <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>; }; - queue-group@2d14000 { + queue-group@2d14000 { reg = <0x0 0x2d14000 0x0 0x1000>; interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>, @@ -740,14 +740,14 @@ enet1: ethernet@2d50000 { ranges; dma-coherent; - queue-group@2d50000 { + queue-group@2d50000 { reg = <0x0 0x2d50000 0x0 0x1000>; interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>; }; - queue-group@2d54000 { + queue-group@2d54000 { reg = <0x0 0x2d54000 0x0 0x1000>; interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>, @@ -766,14 +766,14 @@ enet2: ethernet@2d90000 { ranges; dma-coherent; - queue-group@2d90000 { + queue-group@2d90000 { reg = <0x0 0x2d90000 0x0 0x1000>; interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>; }; - queue-group@2d94000 { + queue-group@2d94000 { reg = <0x0 0x2d94000 0x0 0x1000>; interrupts = <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 161 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm/boot/dts/nxp/vf/Makefile b/arch/arm/boot/dts/nxp/vf/Makefile index 0a4a7f9..47be8bc 100644 --- a/arch/arm/boot/dts/nxp/vf/Makefile +++ b/arch/arm/boot/dts/nxp/vf/Makefile
@@ -1,8 +1,10 @@ # SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_SOC_VF610) += \ vf500-colibri-eval-v3.dtb \ + vf500-colibri-iris.dtb \ vf610-bk4.dtb \ vf610-colibri-eval-v3.dtb \ + vf610-colibri-iris.dtb \ vf610m4-colibri.dtb \ vf610-cosmic.dtb \ vf610m4-cosmic.dtb \
diff --git a/arch/arm/boot/dts/nxp/vf/vf-colibri-iris.dtsi b/arch/arm/boot/dts/nxp/vf/vf-colibri-iris.dtsi new file mode 100644 index 0000000..36e34dd --- /dev/null +++ b/arch/arm/boot/dts/nxp/vf/vf-colibri-iris.dtsi
@@ -0,0 +1,126 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright 2026 Mehmet Fide + * + * Toradex Iris carrier board V1.1, common part for Colibri VF50 and VF61. + * + * The Colibri modules are pin compatible, so the carrier signals sit on the + * same SODIMM pins as they do for the i.MX modules, whose Iris device trees + * are already upstream. The two SODIMM pins below are taken from the Colibri + * VFxx datasheet (102 -> PTA12 -> PORT0[5], 104 -> PTD28 -> PORT2[2]). + * + * An Iris V2.0 carries the same signals on the same pins, so everything here + * works on it as well. What it adds is a regulator on SODIMM 100 that can cut + * power to the uSD slot, which this file does not describe. + */ + +/ { + chosen { + stdout-path = "serial0:115200n8"; + }; + + reg_usbh_vbus: regulator-usbh-vbus { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usbh1_reg>; + regulator-name = "VCC_USB[1-4]"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpio2 19 GPIO_ACTIVE_LOW>; /* SODIMM 129, USBH_PEN */ + }; +}; + +&gpio0 { + /* + * The RS232 transceivers on the carrier are switched on by these two + * lines. Delete the hog to turn a transceiver off from userspace. + * The pin group belongs to the gpio controller rather than to iomuxc, + * which would depend on its own child and log a dependency cycle. + */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_iris_uart1_tx_on>; + + uart1-tx-on-hog { + gpio-hog; + gpios = <5 GPIO_ACTIVE_HIGH>; /* SODIMM 102 */ + output-high; + }; +}; + +&gpio2 { + pinctrl-names = "default"; + /* keep the EXT_IO group from vf-colibri.dtsi alongside ours */ + pinctrl-0 = <&pinctrl_gpio_ext>, <&pinctrl_iris_uart25_tx_on>; + + uart25-tx-on-hog { + gpio-hog; + gpios = <2 GPIO_ACTIVE_HIGH>; /* SODIMM 104 */ + output-high; + }; +}; + +&iomuxc { + pinctrl_iris_uart1_tx_on: irisuart1txongrp { + fsl,pins = < + VF610_PAD_PTA12__GPIO_5 0x22ef + >; + }; + + pinctrl_iris_uart25_tx_on: irisuart25txongrp { + fsl,pins = < + VF610_PAD_PTD28__GPIO_66 0x22ef + >; + }; +}; + +/* Colibri SSP, on the extension connector */ +&dspi1 { + status = "okay"; +}; + +&esdhc1 { + status = "okay"; +}; + +&fec1 { + status = "okay"; +}; + +&pwm0 { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + + /* M41T0M6 real time clock on the carrier */ + rtc@68 { + compatible = "st,m41t0"; + reg = <0x68>; + }; +}; + +&uart0 { + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; + +&uart2 { + status = "okay"; +}; + +&usbdev0 { + status = "okay"; +}; + +&usbh1 { + vbus-supply = <®_usbh_vbus>; + status = "okay"; +};
diff --git a/arch/arm/boot/dts/nxp/vf/vf-colibri.dtsi b/arch/arm/boot/dts/nxp/vf/vf-colibri.dtsi index 98f9ee1..a926985 100644 --- a/arch/arm/boot/dts/nxp/vf/vf-colibri.dtsi +++ b/arch/arm/boot/dts/nxp/vf/vf-colibri.dtsi
@@ -170,6 +170,62 @@ &usbphy1 { status = "okay"; }; +&gpio0 { + gpio-line-names = "", "", "SODIMM_89", "", + "", "SODIMM_102", "SODIMM_18", "SODIMM_134", + "SODIMM_16", "SODIMM_14", "SODIMM_23", "", + "", "", "SODIMM_47", "SODIMM_190", + "SODIMM_192", "SODIMM_49", "SODIMM_51", "SODIMM_53", + "SODIMM_37", "SODIMM_29", "", "SODIMM_30", + "SODIMM_20", "SODIMM_24", "SODIMM_21", "SODIMM_19", + "SODIMM_94", "SODIMM_81", "SODIMM_28"; +}; + +&gpio1 { + gpio-line-names = "SODIMM_35", "SODIMM_33", "SODIMM_27", "SODIMM_25", + "SODIMM_196", "SODIMM_194", "SODIMM_63", "SODIMM_55", + "SODIMM_65", "SODIMM_45", "SODIMM_43", "SODIMM_73", + "SODIMM_77", "SODIMM_71", "SODIMM_98", "SODIMM_101", + "SODIMM_103", "SODIMM_79", "SODIMM_97", "", + "", "SODIMM_85", "", "", + "", "", "", "", + "", "", "", "SODIMM_106"; +}; + +&gpio3 { + gpio-line-names = "SODIMM_105", "", "SODIMM_93", "", + "", "", "", "SODIMM_95", + "SODIMM_22", "SODIMM_68", "SODIMM_82", "SODIMM_56", + "SODIMM_131", "SODIMM_44", "SODIMM_144", "SODIMM_146", + "SODIMM_52", "SODIMM_54", "SODIMM_66", "SODIMM_64", + "SODIMM_57", "SODIMM_61", "SODIMM_140", "SODIMM_142", + "SODIMM_80", "SODIMM_46", "SODIMM_62", "SODIMM_48", + "SODIMM_74", "SODIMM_50", "SODIMM_136", "SODIMM_138"; +}; + +&gpio4 { + gpio-line-names = "SODIMM_76", "SODIMM_70", "SODIMM_60", "SODIMM_58", + "SODIMM_78", "SODIMM_72", "SODIMM_96"; +}; + +&gpio2 { + /* + * EXT_IO_0..2 belong to no device, so hog the pin group here rather + * than on the pin controller, which would depend on its own child. + */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_ext>; + + gpio-line-names = "SODIMM_69", "SODIMM_99", "SODIMM_104", "SODIMM_107", + "SODIMM_127", "SODIMM_184", "SODIMM_186", "", + "", "", "", "", + "", "", "", "SODIMM_38", + "SODIMM_36", "SODIMM_34", "SODIMM_32", "SODIMM_129", + "SODIMM_86", "SODIMM_90", "SODIMM_92", "SODIMM_88", + "SODIMM_133", "SODIMM_135", "SODIMM_188", "SODIMM_75", + "SODIMM_100"; +}; + &iomuxc { pinctrl_flexcan0: can0grp { fsl,pins = <
diff --git a/arch/arm/boot/dts/nxp/vf/vf500-colibri-iris.dts b/arch/arm/boot/dts/nxp/vf/vf500-colibri-iris.dts new file mode 100644 index 0000000..aa91537 --- /dev/null +++ b/arch/arm/boot/dts/nxp/vf/vf500-colibri-iris.dts
@@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright 2026 Mehmet Fide + */ + +/dts-v1/; +#include "vf500-colibri.dtsi" +#include "vf-colibri-iris.dtsi" + +/ { + model = "Toradex Colibri VF50 on Iris Carrier Board"; + compatible = "toradex,vf500-colibri-vf50-on-iris", "toradex,vf500-colibri_vf50", + "fsl,vf500"; +};
diff --git a/arch/arm/boot/dts/nxp/vf/vf500.dtsi b/arch/arm/boot/dts/nxp/vf/vf500.dtsi index 71ccdaa..a73e9a8 100644 --- a/arch/arm/boot/dts/nxp/vf/vf500.dtsi +++ b/arch/arm/boot/dts/nxp/vf/vf500.dtsi
@@ -18,6 +18,12 @@ cpus { a5_cpu: cpu@0 { compatible = "arm,cortex-a5"; device_type = "cpu"; + d-cache-line-size = <32>; + d-cache-sets = <256>; + d-cache-size = <0x8000>; + i-cache-line-size = <32>; + i-cache-sets = <512>; + i-cache-size = <0x8000>; reg = <0x0>; }; };
diff --git a/arch/arm/boot/dts/nxp/vf/vf610-colibri-iris.dts b/arch/arm/boot/dts/nxp/vf/vf610-colibri-iris.dts new file mode 100644 index 0000000..7db5aa4 --- /dev/null +++ b/arch/arm/boot/dts/nxp/vf/vf610-colibri-iris.dts
@@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright 2026 Mehmet Fide + */ + +/dts-v1/; +#include "vf610-colibri.dtsi" +#include "vf-colibri-iris.dtsi" + +/ { + model = "Toradex Colibri VF61 on Iris Carrier Board"; + compatible = "toradex,vf610-colibri-vf61-on-iris", "toradex,vf610-colibri_vf61", + "fsl,vf610"; +};
diff --git a/arch/arm/boot/dts/nxp/vf/vf610.dtsi b/arch/arm/boot/dts/nxp/vf/vf610.dtsi index 2fba923..ea59e3d 100644 --- a/arch/arm/boot/dts/nxp/vf/vf610.dtsi +++ b/arch/arm/boot/dts/nxp/vf/vf610.dtsi
@@ -14,6 +14,9 @@ L2: cache-controller@40006000 { reg = <0x40006000 0x1000>; cache-unified; cache-level = <2>; + cache-line-size = <32>; + cache-sets = <2048>; + cache-size = <0x80000>; arm,data-latency = <3 3 3>; arm,tag-latency = <2 2 2>; };
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8960-sony-huashan.dts b/arch/arm/boot/dts/qcom/qcom-msm8960-sony-huashan.dts index 591dc83..7d54ced 100644 --- a/arch/arm/boot/dts/qcom/qcom-msm8960-sony-huashan.dts +++ b/arch/arm/boot/dts/qcom/qcom-msm8960-sony-huashan.dts
@@ -95,6 +95,21 @@ MATRIX_KEY(1, 1, KEY_CAMERA) status = "okay"; }; +&riva { + vddcx-supply = <&pm8921_s3>; + vddmx-supply = <&pm8921_l24>; + vddpx-supply = <&pm8921_s4>; + + status = "okay"; + + iris { + vdddig-supply = <&pm8921_lvs2>; + vddpa-supply = <&pm8921_l10>; + vddrfa-supply = <&pm8921_s2>; + vddxo-supply = <&pm8921_l4>; + }; +}; + &rpm { regulators { compatible = "qcom,rpm-pm8921-regulators";
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi index fd28401..b9c28e4 100644 --- a/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi +++ b/arch/arm/boot/dts/qcom/qcom-msm8960.dtsi
@@ -5,6 +5,7 @@ #include <dt-bindings/clock/qcom,gcc-msm8960.h> #include <dt-bindings/reset/qcom,gcc-msm8960.h> #include <dt-bindings/clock/qcom,lcc-msm8960.h> +#include <dt-bindings/clock/qcom,rpmcc.h> #include <dt-bindings/mfd/qcom-rpm.h> #include <dt-bindings/soc/qcom,gsbi.h> @@ -76,11 +77,68 @@ l2: l2-cache { }; }; + firmware { + scm { + compatible = "qcom,scm-msm8960", "qcom,scm"; + + clocks = <&rpmcc RPM_DAYTONA_FABRIC_CLK>; + clock-names = "core"; + }; + }; + memory@80000000 { device_type = "memory"; reg = <0x80000000 0>; }; + reserved-memory { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + smem_region: smem@80000000 { + reg = <0x80000000 0x200000>; + no-map; + }; + + wcnss_mem: wcnss@8f000000 { + reg = <0x8f000000 0x700000>; + no-map; + }; + }; + + smem { + compatible = "qcom,smem"; + memory-region = <&smem_region>; + + hwlocks = <&sfpb_mutex 3>; + }; + + smsm { + compatible = "qcom,smsm"; + + #address-cells = <1>; + #size-cells = <0>; + + qcom,ipc-1 = <&l2cc 8 4>; + qcom,ipc-2 = <&l2cc 8 14>; + qcom,ipc-3 = <&l2cc 8 23>; + qcom,ipc-4 = <&sps_sic_non_secure 0x4094 0>; + + apps_smsm: apps@0 { + reg = <0>; + #qcom,smem-state-cells = <1>; + }; + + wcnss_smsm: wcnss@3 { + reg = <3>; + interrupts = <GIC_SPI 204 IRQ_TYPE_EDGE_RISING>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + soc: soc { compatible = "simple-bus"; ranges; @@ -98,6 +156,16 @@ rpm: rpm@108000 { interrupt-names = "ack", "err", "wakeup"; + + rpmcc: clock-controller { + compatible = "qcom,rpmcc-apq8064", + "qcom,rpmcc"; + #clock-cells = <1>; + clocks = <&pxo_board>, + <&cxo_board>; + clock-names = "pxo", + "cxo"; + }; }; ssbi: ssbi@500000 { @@ -257,6 +325,34 @@ i2c12-pins { }; }; + riva_bt_default_state: riva-bt-active-state { + pins = "gpio28", "gpio29"; + function = "bt"; + drive-strength = <2>; + bias-disable; + }; + + riva_bt_sleep_state: riva-bt-sleep-state { + pins = "gpio28", "gpio29"; + function = "bt"; + drive-strength = <2>; + bias-pull-down; + }; + + riva_wlan_default_state: riva-wlan-active-state { + pins = "gpio84", "gpio85", "gpio86", "gpio87", "gpio88"; + function = "wlan"; + drive-strength = <6>; + bias-pull-down; + }; + + riva_wlan_sleep_state: riva-wlan-sleep-state { + pins = "gpio84", "gpio85", "gpio86", "gpio87", "gpio88"; + function = "wlan"; + drive-strength = <2>; + bias-pull-up; + }; + sdcc3_default_state: sdcc3-default-state { clk-pins { pins = "sdc3_clk"; @@ -323,6 +419,12 @@ tsens: thermal-sensor { }; }; + sfpb_mutex: hwlock@1200600 { + compatible = "qcom,sfpb-mutex"; + reg = <0x01200600 0x100>; + #hwlock-cells = <1>; + }; + intc: interrupt-controller@2000000 { compatible = "qcom,msm-qgic2"; reg = <0x02000000 0x1000>, @@ -390,6 +492,60 @@ saw1_vreg: regulator { }; }; + riva: riva-pil@3200800 { + compatible = "qcom,riva-pil"; + reg = <0x03200800 0x1000>, + <0x03202000 0x2000>, + <0x03204000 0x100>; + reg-names = "ccu", + "dxe", + "pmu"; + pinctrl-0 = <&riva_wlan_default_state>, <&riva_bt_default_state>; + pinctrl-1 = <&riva_wlan_sleep_state>, <&riva_bt_sleep_state>; + pinctrl-names = "default", "sleep"; + interrupts-extended = <&intc GIC_SPI 199 IRQ_TYPE_EDGE_RISING>, + <&wcnss_smsm 6 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", "fatal"; + memory-region = <&wcnss_mem>; + + status = "disabled"; + + iris { + compatible = "qcom,wcn3660"; + clocks = <&cxo_board>; + clock-names = "xo"; + }; + + smd-edge { + interrupts = <GIC_SPI 198 IRQ_TYPE_EDGE_RISING>; + label = "riva"; + qcom,ipc = <&l2cc 8 25>; + qcom,smd-edge = <6>; + + wcnss { + compatible = "qcom,wcnss"; + qcom,smd-channels = "WCNSS_CTRL"; + qcom,mmio = <&riva>; + + bluetooth { + compatible = "qcom,wcnss-bt"; + }; + + wifi { + compatible = "qcom,wcnss-wlan"; + interrupts = <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "tx", + "rx"; + qcom,smem-states = <&apps_smsm 10>, + <&apps_smsm 9>; + qcom,smem-state-names = "tx-enable", + "tx-rings-empty"; + }; + }; + }; + }; + clock-controller@4000000 { compatible = "qcom,mmcc-msm8960"; reg = <0x4000000 0x1000>; @@ -414,6 +570,11 @@ clock-controller@4000000 { "hdmipll"; }; + sps_sic_non_secure: interrupt-controller@12100000 { + compatible = "qcom,msm8960-sps-sic", "syscon"; + reg = <0x12100000 0x10000>; + }; + sdcc3: mmc@12180000 { compatible = "arm,pl18x", "arm,primecell"; reg = <0x12180000 0x2000>; @@ -507,8 +668,12 @@ usb1: usb@12500000 { reg = <0x12500000 0x200>, <0x12500200 0x200>; interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&gcc USB_HS1_XCVR_CLK>, <&gcc USB_HS1_H_CLK>; - clock-names = "core", "iface"; + clocks = <&rpmcc RPM_DAYTONA_FABRIC_CLK>, + <&gcc USB_HS1_H_CLK>, + <&gcc USB_HS1_XCVR_CLK>; + clock-names = "iface", + "core", + "fs"; assigned-clocks = <&gcc USB_HS1_XCVR_CLK>; assigned-clock-rates = <60000000>; resets = <&gcc USB_HS1_RESET>;
diff --git a/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi b/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi index 06c0af0..f300de7 100644 --- a/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi +++ b/arch/arm/boot/dts/qcom/qcom-msm8974.dtsi
@@ -10,6 +10,7 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/reset/qcom,gcc-msm8974.h> +#include <dt-bindings/reset/qcom,mmcc-msm8974.h> / { #address-cells = <1>; @@ -1935,6 +1936,8 @@ mdss: display-subsystem@fd900000 { interrupt-controller; #interrupt-cells = <1>; + resets = <&mmcc MDSS_RESET>; + status = "disabled"; #address-cells = <1>;
diff --git a/arch/arm/boot/dts/qcom/qcom-sdx55-t55.dts b/arch/arm/boot/dts/qcom/qcom-sdx55-t55.dts index d23b8ec..0443a86 100644 --- a/arch/arm/boot/dts/qcom/qcom-sdx55-t55.dts +++ b/arch/arm/boot/dts/qcom/qcom-sdx55-t55.dts
@@ -249,7 +249,7 @@ &pcie_phy { &pcie_rc { perst-gpios = <&tlmm 57 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 53 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 53 GPIO_ACTIVE_LOW>; pinctrl-0 = <&pcie_default>; pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/renesas/r7s72100-gr-peach.dts b/arch/arm/boot/dts/renesas/r7s72100-gr-peach.dts index 23ddec2..2477db9 100644 --- a/arch/arm/boot/dts/renesas/r7s72100-gr-peach.dts +++ b/arch/arm/boot/dts/renesas/r7s72100-gr-peach.dts
@@ -131,5 +131,7 @@ phy0: ethernet-phy@0 { reset-gpios = <&port4 2 GPIO_ACTIVE_LOW>; reset-delay-us = <5>; + reset-assert-us = <25000>; + reset-deassert-us = <300>; }; };
diff --git a/arch/arm/boot/dts/renesas/r8a7740-armadillo800eva.dts b/arch/arm/boot/dts/renesas/r8a7740-armadillo800eva.dts index 1d56bde..eb65a54 100644 --- a/arch/arm/boot/dts/renesas/r8a7740-armadillo800eva.dts +++ b/arch/arm/boot/dts/renesas/r8a7740-armadillo800eva.dts
@@ -197,6 +197,8 @@ phy0: ethernet-phy@0 { "ethernet-phy-ieee802.3-c22"; reg = <0>; reset-gpios = <&pfc 18 GPIO_ACTIVE_LOW>; + reset-assert-us = <25000>; + reset-deassert-us = <300>; }; };
diff --git a/arch/arm/boot/dts/renesas/r8a7743-sk-rzg1m.dts b/arch/arm/boot/dts/renesas/r8a7743-sk-rzg1m.dts index 6021779..dc1b4ca 100644 --- a/arch/arm/boot/dts/renesas/r8a7743-sk-rzg1m.dts +++ b/arch/arm/boot/dts/renesas/r8a7743-sk-rzg1m.dts
@@ -75,5 +75,7 @@ phy1: ethernet-phy@1 { interrupts-extended = <&irqc 0 IRQ_TYPE_LEVEL_LOW>; micrel,led-mode = <1>; reset-gpios = <&gpio5 22 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <300>; }; };
diff --git a/arch/arm/boot/dts/renesas/r8a7743.dtsi b/arch/arm/boot/dts/renesas/r8a7743.dtsi index c697942..4db849b 100644 --- a/arch/arm/boot/dts/renesas/r8a7743.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7743.dtsi
@@ -456,7 +456,7 @@ ipmmu_gp: iommu@e62a0000 { status = "disabled"; }; - icram0: sram@e63a0000 { + icram0: sram@e63a0000 { compatible = "mmio-sram"; reg = <0 0xe63a0000 0 0x12000>; #address-cells = <1>; @@ -464,7 +464,7 @@ icram0: sram@e63a0000 { ranges = <0 0 0xe63a0000 0x12000>; }; - icram1: sram@e63c0000 { + icram1: sram@e63c0000 { compatible = "mmio-sram"; reg = <0 0xe63c0000 0 0x1000>; #address-cells = <1>; @@ -477,7 +477,7 @@ smp-sram@0 { }; }; - icram2: sram@e6300000 { + icram2: sram@e6300000 { compatible = "mmio-sram"; reg = <0 0xe6300000 0 0x40000>; #address-cells = <1>;
diff --git a/arch/arm/boot/dts/renesas/r8a7744.dtsi b/arch/arm/boot/dts/renesas/r8a7744.dtsi index fed4634..1a85bc0 100644 --- a/arch/arm/boot/dts/renesas/r8a7744.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7744.dtsi
@@ -456,7 +456,7 @@ ipmmu_gp: iommu@e62a0000 { status = "disabled"; }; - icram0: sram@e63a0000 { + icram0: sram@e63a0000 { compatible = "mmio-sram"; reg = <0 0xe63a0000 0 0x12000>; #address-cells = <1>; @@ -464,7 +464,7 @@ icram0: sram@e63a0000 { ranges = <0 0 0xe63a0000 0x12000>; }; - icram1: sram@e63c0000 { + icram1: sram@e63c0000 { compatible = "mmio-sram"; reg = <0 0xe63c0000 0 0x1000>; #address-cells = <1>; @@ -477,7 +477,7 @@ smp-sram@0 { }; }; - icram2: sram@e6300000 { + icram2: sram@e6300000 { compatible = "mmio-sram"; reg = <0 0xe6300000 0 0x40000>; #address-cells = <1>;
diff --git a/arch/arm/boot/dts/renesas/r8a7745-sk-rzg1e.dts b/arch/arm/boot/dts/renesas/r8a7745-sk-rzg1e.dts index 42e82f0..26ee1ee 100644 --- a/arch/arm/boot/dts/renesas/r8a7745-sk-rzg1e.dts +++ b/arch/arm/boot/dts/renesas/r8a7745-sk-rzg1e.dts
@@ -70,5 +70,7 @@ phy1: ethernet-phy@1 { interrupts-extended = <&irqc 8 IRQ_TYPE_LEVEL_LOW>; micrel,led-mode = <1>; reset-gpios = <&gpio1 24 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <300>; }; };
diff --git a/arch/arm/boot/dts/renesas/r8a7745.dtsi b/arch/arm/boot/dts/renesas/r8a7745.dtsi index 5424a73..78ff5a9 100644 --- a/arch/arm/boot/dts/renesas/r8a7745.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7745.dtsi
@@ -420,7 +420,7 @@ ipmmu_gp: iommu@e62a0000 { status = "disabled"; }; - icram0: sram@e63a0000 { + icram0: sram@e63a0000 { compatible = "mmio-sram"; reg = <0 0xe63a0000 0 0x12000>; #address-cells = <1>; @@ -428,7 +428,7 @@ icram0: sram@e63a0000 { ranges = <0 0 0xe63a0000 0x12000>; }; - icram1: sram@e63c0000 { + icram1: sram@e63c0000 { compatible = "mmio-sram"; reg = <0 0xe63c0000 0 0x1000>; #address-cells = <1>; @@ -441,7 +441,7 @@ smp-sram@0 { }; }; - icram2: sram@e6300000 { + icram2: sram@e6300000 { compatible = "mmio-sram"; reg = <0 0xe6300000 0 0x40000>; #address-cells = <1>;
diff --git a/arch/arm/boot/dts/renesas/r8a77470.dtsi b/arch/arm/boot/dts/renesas/r8a77470.dtsi index c61790e..02df768 100644 --- a/arch/arm/boot/dts/renesas/r8a77470.dtsi +++ b/arch/arm/boot/dts/renesas/r8a77470.dtsi
@@ -285,7 +285,7 @@ tmu3: timer@fff80000 { status = "disabled"; }; - icram0: sram@e63a0000 { + icram0: sram@e63a0000 { compatible = "mmio-sram"; reg = <0 0xe63a0000 0 0x12000>; #address-cells = <1>; @@ -293,7 +293,7 @@ icram0: sram@e63a0000 { ranges = <0 0 0xe63a0000 0x12000>; }; - icram1: sram@e63c0000 { + icram1: sram@e63c0000 { compatible = "mmio-sram"; reg = <0 0xe63c0000 0 0x1000>; #address-cells = <1>; @@ -306,7 +306,7 @@ smp-sram@0 { }; }; - icram2: sram@e6300000 { + icram2: sram@e6300000 { compatible = "mmio-sram"; reg = <0 0xe6300000 0 0x20000>; #address-cells = <1>;
diff --git a/arch/arm/boot/dts/renesas/r8a7790-lager.dts b/arch/arm/boot/dts/renesas/r8a7790-lager.dts index 8e76655..f7345d1 100644 --- a/arch/arm/boot/dts/renesas/r8a7790-lager.dts +++ b/arch/arm/boot/dts/renesas/r8a7790-lager.dts
@@ -302,13 +302,13 @@ gpioi2c2: i2c-9 { }; /* - * IIC0/I2C0 is routed to EXIO connector A, pins 114 (SCL) + 116 (SDA) only. + * IIC0/I2C0 is routed to EXIO connector C, pins 114 (SCL) + 116 (SDA) only. * We use the I2C demuxer, so the desired IP core can be selected at runtime - * depending on the use case (e.g. DMA with IIC0 or slave support with I2C0). - * Note: For testing the I2C slave feature, it is convenient to connect this + * depending on the use case (e.g. DMA with IIC0 or target support with I2C0). + * Note: For testing the I2C target feature, it is convenient to connect this * bus with IIC3 on pins 110 (SCL) + 112 (SDA), select I2C0 at runtime, and - * instantiate the slave device at runtime according to the documentation. - * You can then communicate with the slave via IIC3. + * instantiate the target device at runtime according to the documentation. + * You can then communicate with the target via IIC3. * * IIC0/I2C0 does not appear to support fallback to GPIO. */ @@ -690,6 +690,8 @@ phy1: ethernet-phy@1 { interrupts-extended = <&irqc0 0 IRQ_TYPE_LEVEL_LOW>; micrel,led-mode = <1>; reset-gpios = <&gpio5 31 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <300>; }; }; @@ -813,46 +815,46 @@ &cpu0 { cpu0-supply = <&vdd_dvfs>; }; -&i2c0 { +&i2c0 { pinctrl-0 = <&i2c0_pins>; pinctrl-names = "i2c-exio0"; }; -&iic0 { +&iic0 { pinctrl-0 = <&iic0_pins>; pinctrl-names = "i2c-exio0"; }; -&i2c1 { +&i2c1 { pinctrl-0 = <&i2c1_pins>; pinctrl-names = "i2c-exio1"; }; -&iic1 { +&iic1 { pinctrl-0 = <&iic1_pins>; pinctrl-names = "i2c-exio1"; }; -&i2c2 { +&i2c2 { pinctrl-0 = <&i2c2_pins>; pinctrl-names = "i2c-hdmi"; clock-frequency = <100000>; }; -&iic2 { +&iic2 { pinctrl-0 = <&iic2_pins>; pinctrl-names = "i2c-hdmi"; clock-frequency = <100000>; }; -&i2c3 { +&i2c3 { pinctrl-0 = <&i2c3_pins>; pinctrl-names = "i2c-pwr"; }; -&iic3 { +&iic3 { pinctrl-0 = <&iic3_pins>; pinctrl-names = "i2c-pwr"; };
diff --git a/arch/arm/boot/dts/renesas/r8a7790-stout.dts b/arch/arm/boot/dts/renesas/r8a7790-stout.dts index 8ba9d85..95adece 100644 --- a/arch/arm/boot/dts/renesas/r8a7790-stout.dts +++ b/arch/arm/boot/dts/renesas/r8a7790-stout.dts
@@ -213,6 +213,8 @@ phy1: ethernet-phy@1 { interrupts-extended = <&irqc0 1 IRQ_TYPE_LEVEL_LOW>; micrel,led-mode = <1>; reset-gpios = <&gpio3 31 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <300>; }; }; @@ -289,7 +291,7 @@ &cpu0 { cpu0-supply = <&vdd_dvfs>; }; -&iic2 { +&iic2 { status = "okay"; pinctrl-0 = <&iic2_pins>; pinctrl-names = "default";
diff --git a/arch/arm/boot/dts/renesas/r8a7790.dtsi b/arch/arm/boot/dts/renesas/r8a7790.dtsi index 12cce9b..358c806 100644 --- a/arch/arm/boot/dts/renesas/r8a7790.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7790.dtsi
@@ -566,7 +566,7 @@ ipmmu_rt: iommu@ffc80000 { status = "disabled"; }; - icram0: sram@e63a0000 { + icram0: sram@e63a0000 { compatible = "mmio-sram"; reg = <0 0xe63a0000 0 0x12000>; #address-cells = <1>; @@ -574,7 +574,7 @@ icram0: sram@e63a0000 { ranges = <0 0 0xe63a0000 0x12000>; }; - icram1: sram@e63c0000 { + icram1: sram@e63c0000 { compatible = "mmio-sram"; reg = <0 0xe63c0000 0 0x1000>; #address-cells = <1>;
diff --git a/arch/arm/boot/dts/renesas/r8a7791-koelsch.dts b/arch/arm/boot/dts/renesas/r8a7791-koelsch.dts index 48db62e..54148a5 100644 --- a/arch/arm/boot/dts/renesas/r8a7791-koelsch.dts +++ b/arch/arm/boot/dts/renesas/r8a7791-koelsch.dts
@@ -681,6 +681,8 @@ phy1: ethernet-phy@1 { interrupts-extended = <&irqc0 0 IRQ_TYPE_LEVEL_LOW>; micrel,led-mode = <1>; reset-gpios = <&gpio5 22 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <300>; }; };
diff --git a/arch/arm/boot/dts/renesas/r8a7791-porter.dts b/arch/arm/boot/dts/renesas/r8a7791-porter.dts index 811e263..05989da 100644 --- a/arch/arm/boot/dts/renesas/r8a7791-porter.dts +++ b/arch/arm/boot/dts/renesas/r8a7791-porter.dts
@@ -331,6 +331,8 @@ phy1: ethernet-phy@1 { interrupts-extended = <&irqc0 0 IRQ_TYPE_LEVEL_LOW>; micrel,led-mode = <1>; reset-gpios = <&gpio5 22 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <300>; }; };
diff --git a/arch/arm/boot/dts/renesas/r8a7791.dtsi b/arch/arm/boot/dts/renesas/r8a7791.dtsi index 35313e8..3a447a1 100644 --- a/arch/arm/boot/dts/renesas/r8a7791.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7791.dtsi
@@ -493,7 +493,7 @@ ipmmu_gp: iommu@e62a0000 { status = "disabled"; }; - icram0: sram@e63a0000 { + icram0: sram@e63a0000 { compatible = "mmio-sram"; reg = <0 0xe63a0000 0 0x12000>; #address-cells = <1>; @@ -501,7 +501,7 @@ icram0: sram@e63a0000 { ranges = <0 0 0xe63a0000 0x12000>; }; - icram1: sram@e63c0000 { + icram1: sram@e63c0000 { compatible = "mmio-sram"; reg = <0 0xe63c0000 0 0x1000>; #address-cells = <1>;
diff --git a/arch/arm/boot/dts/renesas/r8a7792.dtsi b/arch/arm/boot/dts/renesas/r8a7792.dtsi index fbdbcff..a63a28d 100644 --- a/arch/arm/boot/dts/renesas/r8a7792.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7792.dtsi
@@ -415,7 +415,7 @@ tmu3: timer@fff80000 { status = "disabled"; }; - icram0: sram@e63a0000 { + icram0: sram@e63a0000 { compatible = "mmio-sram"; reg = <0 0xe63a0000 0 0x12000>; #address-cells = <1>; @@ -423,7 +423,7 @@ icram0: sram@e63a0000 { ranges = <0 0 0xe63a0000 0x12000>; }; - icram1: sram@e63c0000 { + icram1: sram@e63c0000 { compatible = "mmio-sram"; reg = <0 0xe63c0000 0 0x1000>; #address-cells = <1>;
diff --git a/arch/arm/boot/dts/renesas/r8a7793-gose.dts b/arch/arm/boot/dts/renesas/r8a7793-gose.dts index 69d9c67..9687c1e 100644 --- a/arch/arm/boot/dts/renesas/r8a7793-gose.dts +++ b/arch/arm/boot/dts/renesas/r8a7793-gose.dts
@@ -621,6 +621,8 @@ phy1: ethernet-phy@1 { interrupts-extended = <&irqc0 0 IRQ_TYPE_LEVEL_LOW>; micrel,led-mode = <1>; reset-gpios = <&gpio5 22 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <300>; }; };
diff --git a/arch/arm/boot/dts/renesas/r8a7793.dtsi b/arch/arm/boot/dts/renesas/r8a7793.dtsi index 1ad50070..4cb3bf3 100644 --- a/arch/arm/boot/dts/renesas/r8a7793.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7793.dtsi
@@ -468,7 +468,7 @@ ipmmu_gp: iommu@e62a0000 { status = "disabled"; }; - icram0: sram@e63a0000 { + icram0: sram@e63a0000 { compatible = "mmio-sram"; reg = <0 0xe63a0000 0 0x12000>; #address-cells = <1>; @@ -476,7 +476,7 @@ icram0: sram@e63a0000 { ranges = <0 0 0xe63a0000 0x12000>; }; - icram1: sram@e63c0000 { + icram1: sram@e63c0000 { compatible = "mmio-sram"; reg = <0 0xe63c0000 0 0x1000>; #address-cells = <1>;
diff --git a/arch/arm/boot/dts/renesas/r8a7794-alt.dts b/arch/arm/boot/dts/renesas/r8a7794-alt.dts index 5d6d0d8..92bc4ec 100644 --- a/arch/arm/boot/dts/renesas/r8a7794-alt.dts +++ b/arch/arm/boot/dts/renesas/r8a7794-alt.dts
@@ -383,6 +383,8 @@ phy1: ethernet-phy@1 { interrupts-extended = <&irqc0 8 IRQ_TYPE_LEVEL_LOW>; micrel,led-mode = <1>; reset-gpios = <&gpio1 24 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <300>; }; };
diff --git a/arch/arm/boot/dts/renesas/r8a7794-silk.dts b/arch/arm/boot/dts/renesas/r8a7794-silk.dts index af474b1..72829ce 100644 --- a/arch/arm/boot/dts/renesas/r8a7794-silk.dts +++ b/arch/arm/boot/dts/renesas/r8a7794-silk.dts
@@ -417,6 +417,8 @@ phy1: ethernet-phy@1 { interrupts-extended = <&irqc0 8 IRQ_TYPE_LEVEL_LOW>; micrel,led-mode = <1>; reset-gpios = <&gpio1 24 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <300>; }; };
diff --git a/arch/arm/boot/dts/renesas/r8a7794.dtsi b/arch/arm/boot/dts/renesas/r8a7794.dtsi index 7669a67..732e99f 100644 --- a/arch/arm/boot/dts/renesas/r8a7794.dtsi +++ b/arch/arm/boot/dts/renesas/r8a7794.dtsi
@@ -413,7 +413,7 @@ ipmmu_gp: iommu@e62a0000 { status = "disabled"; }; - icram0: sram@e63a0000 { + icram0: sram@e63a0000 { compatible = "mmio-sram"; reg = <0 0xe63a0000 0 0x12000>; #address-cells = <1>; @@ -421,7 +421,7 @@ icram0: sram@e63a0000 { ranges = <0 0 0xe63a0000 0x12000>; }; - icram1: sram@e63c0000 { + icram1: sram@e63c0000 { compatible = "mmio-sram"; reg = <0 0xe63c0000 0 0x1000>; #address-cells = <1>;
diff --git a/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts b/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts index 5626d7f..49f2def 100644 --- a/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts +++ b/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-db.dts
@@ -194,7 +194,6 @@ &gpioirqmux { &gpio2 { pinctrl-0 = <&pins_gpio2>; pinctrl-names = "default"; - status = "okay"; }; &i2c2 {
diff --git a/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-eb.dts b/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-eb.dts index ead3799..eb729550 100644 --- a/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-eb.dts +++ b/arch/arm/boot/dts/renesas/r9a06g032-rzn1d400-eb.dts
@@ -53,8 +53,9 @@ led@1 { }; }; -&gpio2 { - status = "okay"; +&gpio2b { + pinctrl-0 = <&pins_cn12>; + pinctrl-names = "default"; }; &i2c2 { @@ -85,6 +86,15 @@ &pci_usb { }; &pinctrl { + pins_cn12: pins-cn12 { + pinmux = <RZN1_PINMUX(164, RZN1_FUNC_GPIO)>, + <RZN1_PINMUX(165, RZN1_FUNC_GPIO)>, + <RZN1_PINMUX(166, RZN1_FUNC_GPIO)>, + <RZN1_PINMUX(167, RZN1_FUNC_GPIO)>, + <RZN1_PINMUX(168, RZN1_FUNC_GPIO)>, + <RZN1_PINMUX(169, RZN1_FUNC_GPIO)>; + }; + pins_eth0: pins-eth0 { pinmux = <RZN1_PINMUX(0, RZN1_FUNC_CLK_ETH_MII_RGMII_RMII)>, <RZN1_PINMUX(1, RZN1_FUNC_CLK_ETH_MII_RGMII_RMII)>,
diff --git a/arch/arm/boot/dts/renesas/r9a06g032.dtsi b/arch/arm/boot/dts/renesas/r9a06g032.dtsi index 19c9bce..8645bab 100644 --- a/arch/arm/boot/dts/renesas/r9a06g032.dtsi +++ b/arch/arm/boot/dts/renesas/r9a06g032.dtsi
@@ -145,7 +145,6 @@ wdt1: watchdog@40009000 { sysctrl: system-controller@4000c000 { compatible = "renesas,r9a06g032-sysctrl"; reg = <0x4000c000 0x1000>; - status = "okay"; #clock-cells = <1>; #power-domain-cells = <0>; @@ -352,7 +351,6 @@ pinctrl: pinctrl@40067000 { reg = <0x40067000 0x1000>, <0x51000000 0x480>; clocks = <&sysctrl R9A06G032_HCLK_PINCONFIG>; clock-names = "bus"; - status = "okay"; }; sdio1: mmc@40100000 {
diff --git a/arch/arm/boot/dts/samsung/exynos4210-i9100.dts b/arch/arm/boot/dts/samsung/exynos4210-i9100.dts index 8a635be..b9a3171 100644 --- a/arch/arm/boot/dts/samsung/exynos4210-i9100.dts +++ b/arch/arm/boot/dts/samsung/exynos4210-i9100.dts
@@ -169,11 +169,14 @@ image-sensor@2d { vdda-supply = <&cam_io_en_reg>; vddreg-supply = <&vt_core_15v_reg>; vddio-supply = <&vtcam_reg>; + clocks = <&camera 0>; clock-names = "mclk"; + assigned-clocks = <&camera 0>; + assigned-clock-rates = <24000000>; + stbyn-gpios = <&gpl2 0 GPIO_ACTIVE_LOW>; rstn-gpios = <&gpl2 1 GPIO_ACTIVE_LOW>; - clock-frequency = <24000000>; port { s5k5bafx_ep: endpoint { @@ -877,9 +880,13 @@ &serial_0 { pinctrl-names = "default"; pinctrl-0 = <&bt_en>, <&bt_res>, <&uart0_data>, <&uart0_fctl>; + uart-has-rtscts; + bluetooth { compatible = "brcm,bcm4330-bt"; + max-speed = <3000000>; + shutdown-gpios = <&gpl0 4 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpl1 0 GPIO_ACTIVE_LOW>; device-wakeup-gpios = <&gpx3 1 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/boot/dts/samsung/exynos4210-trats.dts b/arch/arm/boot/dts/samsung/exynos4210-trats.dts index 6bd902c..20fe148 100644 --- a/arch/arm/boot/dts/samsung/exynos4210-trats.dts +++ b/arch/arm/boot/dts/samsung/exynos4210-trats.dts
@@ -541,8 +541,13 @@ &serial_0 { pinctrl-0 = <&uart0_data &uart0_fctl>; pinctrl-names = "default"; + uart-has-rtscts; + bluetooth { compatible = "brcm,bcm4330-bt"; + + max-speed = <3000000>; + pinctrl-0 = <&bt_shutdown &bt_device_wakeup &bt_host_wakeup>; pinctrl-names = "default"; shutdown-gpios = <&gpl1 0 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts b/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts index 9149069..7440390 100644 --- a/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts +++ b/arch/arm/boot/dts/samsung/exynos4210-universal_c210.dts
@@ -634,8 +634,13 @@ &serial_0 { pinctrl-0 = <&uart0_data &uart0_fctl>; pinctrl-names = "default"; + uart-has-rtscts; + bluetooth { compatible = "brcm,bcm4330-bt"; + + max-speed = <3000000>; + pinctrl-0 = <&bt_shutdown &bt_device_wakeup &bt_host_wakeup>; pinctrl-names = "default"; shutdown-gpios = <&gpe1 4 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi b/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi index 48245b1..8b6c2e2 100644 --- a/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi +++ b/arch/arm/boot/dts/samsung/exynos4412-midas.dtsi
@@ -638,10 +638,13 @@ image-sensor@10 { svdda-supply = <&cam_io_reg>; svddio-supply = <&ldo19_reg>; afvdd-supply = <&ldo19_reg>; - clock-frequency = <24000000>; + /* CAM_B_CLKOUT */ clocks = <&camera 1>; clock-names = "extclk"; + assigned-clocks = <&camera 1>; + assigned-clock-rates = <24000000>; + gpios = <&gpm1 6 GPIO_ACTIVE_LOW>; port {
diff --git a/arch/arm/boot/dts/st/ste-ab8500.dtsi b/arch/arm/boot/dts/st/ste-ab8500.dtsi index dd30d08..03cee37 100644 --- a/arch/arm/boot/dts/st/ste-ab8500.dtsi +++ b/arch/arm/boot/dts/st/ste-ab8500.dtsi
@@ -228,8 +228,8 @@ ab8500_usb: phy { "USB_ADP_PROBE_PLUG", "USB_ADP_PROBE_UNPLUG"; vddulpivio18-supply = <&ab8500_ldo_intcore_reg>; - v-ape-supply = <&db8500_vape_reg>; - musb_1v8-supply = <&db8500_vsmps2_reg>; + v-ape-supply = <&ab8500_buck_vape>; + musb_1v8-supply = <&ab8500_buck_vsmps2>; clocks = <&prcmu_clk PRCMU_SYSCLK>; clock-names = "sysclk"; #phy-cells = <0>; @@ -272,6 +272,7 @@ pwm@3 { codec: codec { compatible = "stericsson,ab8500-codec"; + #sound-dai-cells = <1>; V-AUD-supply = <&ab8500_ldo_audio_reg>; V-AMIC1-supply = <&ab8500_ldo_anamic1_reg>; @@ -360,16 +361,34 @@ ab8500_ldo_dmic_reg: ab8500_ldo_dmic { // supply for U8500 CSI/DSI; VANA LDO ab8500_ldo_ana_reg: ab8500_ldo_ana { }; + + // 1.2 V I/O and memory supply for DB8500 and peripherals + ab8500_buck_vsmps1: ab8500_buck_smps1 { + }; + + // 1.8 V I/O and memory supply for DB8500 and peripherals + buck_vio18: ab8500_buck_vsmps2: ab8500_buck_smps2 { + }; + + // DB8500 VSAFE supply for permanent logic and DDR PHY + ab8500_buck_vsmps3: ab8500_buck_smps3 { + }; + + // DB8500 Cortex-A9 supply + ab8500_buck_varm: ab8500_buck_arm { + }; + + // DB8500 APE logic and multimedia accelerator supply + ab8500_buck_vape: ab8500_buck_ape { + }; + + // DB8500 modem subsystem supply + ab8500_buck_vmod: ab8500_buck_mod { + }; }; }; }; - sound { - stericsson,audio-codec = <&codec>; - clocks = <&prcmu_clk PRCMU_SYSCLK>, <&ab8500_clock AB8500_SYSCLK_ULP>, <&ab8500_clock AB8500_SYSCLK_INT>; - clock-names = "sysclk", "ulpclk", "intclk"; - }; - mcde@a0350000 { vana-supply = <&ab8500_ldo_ana_reg>;
diff --git a/arch/arm/boot/dts/st/ste-ab8505.dtsi b/arch/arm/boot/dts/st/ste-ab8505.dtsi index 131c825..38a58d07 100644 --- a/arch/arm/boot/dts/st/ste-ab8505.dtsi +++ b/arch/arm/boot/dts/st/ste-ab8505.dtsi
@@ -137,13 +137,9 @@ ab8500_btemp { }; ab8500_charger { - compatible = "stericsson,ab8500-charger"; - interrupts = <10 IRQ_TYPE_LEVEL_HIGH>, - <11 IRQ_TYPE_LEVEL_HIGH>, - <0 IRQ_TYPE_LEVEL_HIGH>, - <107 IRQ_TYPE_LEVEL_HIGH>, - <106 IRQ_TYPE_LEVEL_HIGH>, - <14 IRQ_TYPE_LEVEL_HIGH>, + compatible = "stericsson,ab8505-charger", + "stericsson,ab8500-charger"; + interrupts = <14 IRQ_TYPE_LEVEL_HIGH>, <15 IRQ_TYPE_LEVEL_HIGH>, <79 IRQ_TYPE_LEVEL_HIGH>, <105 IRQ_TYPE_LEVEL_HIGH>, @@ -152,12 +148,7 @@ ab8500_charger { <22 IRQ_TYPE_LEVEL_HIGH>, <21 IRQ_TYPE_LEVEL_HIGH>, <16 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "MAIN_CH_UNPLUG_DET", - "MAIN_CHARGE_PLUG_DET", - "MAIN_EXT_CH_NOT_OK", - "MAIN_CH_TH_PROT_R", - "MAIN_CH_TH_PROT_F", - "VBUS_DET_F", + interrupt-names = "VBUS_DET_F", "VBUS_DET_R", "USB_LINK_STATUS", "USB_CH_TH_PROT_R", @@ -196,8 +187,8 @@ ab8500_usb: phy { "USB_ADP_PROBE_PLUG", "USB_ADP_PROBE_UNPLUG"; vddulpivio18-supply = <&ab8500_ldo_intcore_reg>; - v-ape-supply = <&db8500_vape_reg>; - musb_1v8-supply = <&db8500_vsmps2_reg>; + v-ape-supply = <&ab8505_buck_vsmpsc>; + musb_1v8-supply = <&ab8505_buck_vsmpsb>; clocks = <&prcmu_clk PRCMU_SYSCLK>; clock-names = "sysclk"; #phy-cells = <0>; @@ -224,6 +215,7 @@ pwm@1 { codec: codec { compatible = "stericsson,ab8500-codec"; + #sound-dai-cells = <1>; V-AUD-supply = <&ab8500_ldo_audio_reg>; V-AMIC1-supply = <&ab8500_ldo_anamic1_reg>; @@ -297,16 +289,34 @@ ab8500_ldo_aux8_reg: ab8500_ldo_aux8 { // supply for U8500 CSI/DSI; VANA LDO ab8500_ldo_ana_reg: ab8500_ldo_ana { }; + + // 1.2 V I/O and memory supply for DB8500 and peripherals + ab8505_buck_vsmpsa: ab8505_buck_smpsa { + }; + + // 1.8 V I/O and memory supply for DB8500 and peripherals + buck_vio18: ab8505_buck_vsmpsb: ab8505_buck_smpsb { + }; + + // DB8500 VSAFE supply for permanent logic and DDR PHY + ab8505_buck_vsafe: ab8505_buck_safe { + }; + + // DB8500 Cortex-A9 supply + ab8505_buck_varm: ab8505_buck_arm { + }; + + // DB8500 APE logic and multimedia accelerator supply + ab8505_buck_vsmpsc: ab8505_buck_smpsc { + }; + + // DB8500 modem subsystem supply + ab8505_buck_vsmpsm: ab8505_buck_smpsm { + }; }; }; }; - sound { - stericsson,audio-codec = <&codec>; - clocks = <&prcmu_clk PRCMU_SYSCLK>, <&ab8500_clock AB8500_SYSCLK_ULP>, <&ab8500_clock AB8500_SYSCLK_INT>; - clock-names = "sysclk", "ulpclk", "intclk"; - }; - mcde@a0350000 { vana-supply = <&ab8500_ldo_ana_reg>;
diff --git a/arch/arm/boot/dts/st/ste-dbx5x0.dtsi b/arch/arm/boot/dts/st/ste-dbx5x0.dtsi index 25a20fa..912d250 100644 --- a/arch/arm/boot/dts/st/ste-dbx5x0.dtsi +++ b/arch/arm/boot/dts/st/ste-dbx5x0.dtsi
@@ -1071,13 +1071,9 @@ mmc@80008000 { status = "disabled"; }; - sound { - compatible = "stericsson,snd-soc-mop500"; - stericsson,cpu-dai = <&msp1 &msp3>; - }; - msp0: msp@80123000 { compatible = "stericsson,ux500-msp-i2s"; + #sound-dai-cells = <0>; reg = <0x80123000 0x1000>; interrupts = <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; v-ape-supply = <&db8500_vape_reg>; @@ -1095,6 +1091,7 @@ msp0: msp@80123000 { msp1: msp@80124000 { compatible = "stericsson,ux500-msp-i2s"; + #sound-dai-cells = <0>; reg = <0x80124000 0x1000>; interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; v-ape-supply = <&db8500_vape_reg>; @@ -1113,6 +1110,7 @@ msp1: msp@80124000 { // HDMI sound msp2: msp@80117000 { compatible = "stericsson,ux500-msp-i2s"; + #sound-dai-cells = <0>; reg = <0x80117000 0x1000>; interrupts = <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; v-ape-supply = <&db8500_vape_reg>; @@ -1131,6 +1129,7 @@ HighPrio - Fixed */ msp3: msp@80125000 { compatible = "stericsson,ux500-msp-i2s"; + #sound-dai-cells = <0>; reg = <0x80125000 0x1000>; interrupts = <GIC_SPI 62 IRQ_TYPE_LEVEL_HIGH>; v-ape-supply = <&db8500_vape_reg>;
diff --git a/arch/arm/boot/dts/st/ste-href-ab8500.dtsi b/arch/arm/boot/dts/st/ste-href-ab8500.dtsi index 5eeb44c..ff72f5f 100644 --- a/arch/arm/boot/dts/st/ste-href-ab8500.dtsi +++ b/arch/arm/boot/dts/st/ste-href-ab8500.dtsi
@@ -6,6 +6,48 @@ #include "ste-ab8500.dtsi" / { + href_sound: sound { + compatible = "audio-graph-card2"; + label = "HREF-500"; + widgets = + "Headphone", "Headset", + "Speaker", "Earpiece Speaker", + "Speaker", "Loudspeaker", + "Line", "Line Out", + "Speaker", "Vibra 1 Motor", + "Speaker", "Vibra 2 Motor", + "Microphone", "Mic 1 Jack", + "Microphone", "Mic 2 Jack", + "Line", "Line In", + "Microphone", "Digital Mic 1", + "Microphone", "Digital Mic 2", + "Microphone", "Digital Mic 3", + "Microphone", "Digital Mic 4", + "Microphone", "Digital Mic 5", + "Microphone", "Digital Mic 6"; + routing = + "Headset", "Headset Left", + "Headset", "Headset Right", + "Earpiece Speaker", "Earpiece", + "Loudspeaker", "Speaker Left", + "Loudspeaker", "Speaker Right", + "Line Out", "LineOut Left", + "Line Out", "LineOut Right", + "Vibra 1 Motor", "Vibra 1", + "Vibra 2 Motor", "Vibra 2", + "Mic 1", "Mic 1 Jack", + "Mic 2", "Mic 2 Jack", + "LineIn Left", "Line In", + "LineIn Right", "Line In", + "DMic 1", "Digital Mic 1", + "DMic 2", "Digital Mic 2", + "DMic 3", "Digital Mic 3", + "DMic 4", "Digital Mic 4", + "DMic 5", "Digital Mic 5", + "DMic 6", "Digital Mic 6"; + links = <&href_msp1_port &href_msp3_port>; + }; + soc { prcmu@80157000 { ab8500 { @@ -488,3 +530,65 @@ ab8500_chargalg { }; }; }; + +&codec { + assigned-clocks = <&ab8500_clock AB8500_SYSCLK_INT>; + assigned-clock-parents = <&ab8500_clock AB8500_SYSCLK_ULP>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + href_codec_playback: endpoint { + remote-endpoint = <&href_msp1_endpoint>; + bitclock-master; + frame-master; + dai-tdm-slot-num = <16>; + dai-tdm-slot-width = <16>; + dai-tdm-slot-tx-mask = <0 1 0 1>; + }; + }; + + port@1 { + reg = <1>; + + href_codec_capture: endpoint { + remote-endpoint = <&href_msp3_endpoint>; + bitclock-master; + frame-master; + dai-tdm-slot-num = <16>; + dai-tdm-slot-width = <16>; + dai-tdm-slot-rx-mask = <1>; + }; + }; + }; +}; + +&msp1 { + href_msp1_port: port { + href_msp1_endpoint: endpoint { + continuous-clock; + remote-endpoint = <&href_codec_playback>; + dai-format = "dsp_a"; + dai-tdm-slot-num = <16>; + dai-tdm-slot-width = <16>; + dai-tdm-slot-tx-mask = <0 1 0 1>; + }; + }; +}; + +&msp3 { + href_msp3_port: port { + href_msp3_endpoint: endpoint { + continuous-clock; + remote-endpoint = <&href_codec_capture>; + dai-format = "dsp_a"; + dai-tdm-slot-num = <16>; + dai-tdm-slot-width = <16>; + dai-tdm-slot-rx-mask = <1>; + }; + }; +};
diff --git a/arch/arm/boot/dts/st/ste-href-ab8505.dtsi b/arch/arm/boot/dts/st/ste-href-ab8505.dtsi index 268db68..eba6f67 100644 --- a/arch/arm/boot/dts/st/ste-href-ab8505.dtsi +++ b/arch/arm/boot/dts/st/ste-href-ab8505.dtsi
@@ -6,6 +6,36 @@ #include "ste-ab8505.dtsi" / { + href_sound: sound { + compatible = "audio-graph-card2"; + label = "HREF-500"; + widgets = + "Headphone", "Headset", + "Speaker", "Earpiece Speaker", + "Speaker", "Loudspeaker", + "Line", "Line Out", + "Speaker", "Vibra 1 Motor", + "Speaker", "Vibra 2 Motor", + "Microphone", "Mic 1 Jack", + "Microphone", "Mic 2 Jack", + "Line", "Line In"; + routing = + "Headset", "Headset Left", + "Headset", "Headset Right", + "Earpiece Speaker", "Earpiece", + "Loudspeaker", "Speaker Left", + "Loudspeaker", "Speaker Right", + "Line Out", "LineOut Left", + "Line Out", "LineOut Right", + "Vibra 1 Motor", "Vibra 1", + "Vibra 2 Motor", "Vibra 2", + "Mic 1", "Mic 1 Jack", + "Mic 2", "Mic 2 Jack", + "LineIn Left", "Line In", + "LineIn Right", "Line In"; + links = <&href_msp1_port &href_msp3_port>; + }; + soc { prcmu@80157000 { ab8505 { @@ -48,10 +78,6 @@ ab8500_ldo_anamic2_reg: ab8500_ldo_anamic2 { regulator-name = "V-AMIC2"; }; - ab8500_ldo_dmic_reg: ab8500_ldo_dmic { - regulator-name = "V-DMIC"; - }; - ab8500_ldo_ana_reg: ab8500_ldo_ana { regulator-name = "V-CSI/DSI"; }; @@ -80,7 +106,6 @@ gpio { <&pwm_default_mode>, <&adi1_default_mode>, <&usbuicc_default_mode>, - <&dmic_default_mode>, <&extcpena_default_mode>, <&modsclsda_default_mode>; @@ -365,27 +390,6 @@ default_cfg { }; }; }; - /* This sets up the microphone pins */ - dmic { - dmic_default_mode: dmic_default { - default_mux { - function = "dmic"; - groups = "dmic12_d_1", - "dmic34_d_1", - "dmic56_d_1"; - }; - default_cfg { - pins = "GPIO27_J6", - "GPIO28_K6", - "GPIO29_G6", - "GPIO30_H6", - "GPIO31_F5", - "GPIO32_G5"; - input-enable; - bias-pull-down; - }; - }; - }; extcpena { extcpena_default_mode: extcpena_default { default_mux { @@ -488,3 +492,65 @@ ab8500_chargalg { }; }; }; + +&codec { + assigned-clocks = <&ab8500_clock AB8500_SYSCLK_INT>; + assigned-clock-parents = <&ab8500_clock AB8500_SYSCLK_ULP>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + href_codec_playback: endpoint { + remote-endpoint = <&href_msp1_endpoint>; + bitclock-master; + frame-master; + dai-tdm-slot-num = <16>; + dai-tdm-slot-width = <16>; + dai-tdm-slot-tx-mask = <0 1 0 1>; + }; + }; + + port@1 { + reg = <1>; + + href_codec_capture: endpoint { + remote-endpoint = <&href_msp3_endpoint>; + bitclock-master; + frame-master; + dai-tdm-slot-num = <16>; + dai-tdm-slot-width = <16>; + dai-tdm-slot-rx-mask = <1>; + }; + }; + }; +}; + +&msp1 { + href_msp1_port: port { + href_msp1_endpoint: endpoint { + continuous-clock; + remote-endpoint = <&href_codec_playback>; + dai-format = "dsp_a"; + dai-tdm-slot-num = <16>; + dai-tdm-slot-width = <16>; + dai-tdm-slot-tx-mask = <0 1 0 1>; + }; + }; +}; + +&msp3 { + href_msp3_port: port { + href_msp3_endpoint: endpoint { + continuous-clock; + remote-endpoint = <&href_codec_capture>; + dai-format = "dsp_a"; + dai-tdm-slot-num = <16>; + dai-tdm-slot-width = <16>; + dai-tdm-slot-rx-mask = <1>; + }; + }; +};
diff --git a/arch/arm/boot/dts/st/ste-href-stuib.dtsi b/arch/arm/boot/dts/st/ste-href-stuib.dtsi index 79c2be3..729e7e1 100644 --- a/arch/arm/boot/dts/st/ste-href-stuib.dtsi +++ b/arch/arm/boot/dts/st/ste-href-stuib.dtsi
@@ -35,8 +35,8 @@ stmpe1601: port-expander@40 { reg = <0x40>; interrupts = <26 IRQ_TYPE_EDGE_FALLING>; interrupt-parent = <&gpio6>; - vcc-supply = <&db8500_vsmps2_reg>; - vio-supply = <&db8500_vsmps2_reg>; + vcc-supply = <&buck_vio18>; + vio-supply = <&buck_vio18>; pinctrl-names = "default"; pinctrl-0 = <&stmpe_stuib_mode>; @@ -80,7 +80,7 @@ lis331dl@1c { st,drdy-int-pin = <1>; reg = <0x1c>; vdd-supply = <&ab8500_ldo_aux1_reg>; - vddio-supply = <&db8500_vsmps2_reg>; + vddio-supply = <&buck_vio18>; pinctrl-names = "default"; pinctrl-0 = <&accel_stuib_mode>; interrupt-parent = <&gpio2>; @@ -92,7 +92,7 @@ ak8974@f { compatible = "asahi-kasei,ak8974"; reg = <0x0f>; vdd-supply = <&ab8500_ldo_aux1_reg>; - vddio-supply = <&db8500_vsmps2_reg>; + vddio-supply = <&buck_vio18>; pinctrl-names = "default"; pinctrl-0 = <&magneto_stuib_mode>; interrupt-parent = <&gpio1>;
diff --git a/arch/arm/boot/dts/st/ste-href-tvk1281618-r2.dtsi b/arch/arm/boot/dts/st/ste-href-tvk1281618-r2.dtsi index 7448135..391e697 100644 --- a/arch/arm/boot/dts/st/ste-href-tvk1281618-r2.dtsi +++ b/arch/arm/boot/dts/st/ste-href-tvk1281618-r2.dtsi
@@ -90,7 +90,7 @@ accelerometer@18 { drive-open-drain; reg = <0x18>; vdd-supply = <&ab8500_ldo_aux1_reg>; - vddio-supply = <&db8500_vsmps2_reg>; + vddio-supply = <&buck_vio18>; pinctrl-names = "default"; pinctrl-0 = <&accel_tvk_mode>; /* @@ -113,7 +113,7 @@ magnetometer@1e { compatible = "st,lsm303dlh-magn"; reg = <0x1e>; vdd-supply = <&ab8500_ldo_aux1_reg>; - vddio-supply = <&db8500_vsmps2_reg>; + vddio-supply = <&buck_vio18>; /* * These interrupts cannot be used: the other component * ST-Micro L3D4200D gyro that is connected to the same lines @@ -132,7 +132,7 @@ accelerometer@1c { st,drdy-int-pin = <1>; reg = <0x1c>; vdd-supply = <&ab8500_ldo_aux1_reg>; - vddio-supply = <&db8500_vsmps2_reg>; + vddio-supply = <&buck_vio18>; pinctrl-names = "default"; pinctrl-0 = <&accel_tvk_mode>; interrupt-parent = <&gpio2>; @@ -148,7 +148,7 @@ magnetometer@f { compatible = "asahi-kasei,ak8974"; reg = <0x0f>; avdd-supply = <&ab8500_ldo_aux1_reg>; - dvdd-supply = <&db8500_vsmps2_reg>; + dvdd-supply = <&buck_vio18>; pinctrl-names = "default"; pinctrl-0 = <&gyro_magn_tvk_mode>; /* @@ -169,7 +169,7 @@ gyroscope@68 { st,drdy-int-pin = <2>; reg = <0x68>; vdd-supply = <&ab8500_ldo_aux1_reg>; - vddio-supply = <&db8500_vsmps2_reg>; + vddio-supply = <&buck_vio18>; pinctrl-names = "default"; pinctrl-0 = <&gyro_magn_tvk_mode>; interrupts-extended = @@ -181,7 +181,7 @@ pressure@5c { compatible = "st,lps001wp-press"; reg = <0x5c>; vdd-supply = <&ab8500_ldo_aux1_reg>; - vddio-supply = <&db8500_vsmps2_reg>; + vddio-supply = <&buck_vio18>; }; }; i2c@80110000 { @@ -192,7 +192,7 @@ synaptics@4b { #size-cells = <0>; reg = <0x4b>; vdd-supply = <&ab8500_ldo_aux1_reg>; - vio-supply = <&db8500_vsmps2_reg>; + vio-supply = <&buck_vio18>; pinctrl-names = "default"; pinctrl-0 = <&synaptics_tvk_mode>; interrupt-parent = <&gpio2>;
diff --git a/arch/arm/boot/dts/st/ste-href-tvk1281618-r3.dtsi b/arch/arm/boot/dts/st/ste-href-tvk1281618-r3.dtsi index 00ce9d7..c5acb60 100644 --- a/arch/arm/boot/dts/st/ste-href-tvk1281618-r3.dtsi +++ b/arch/arm/boot/dts/st/ste-href-tvk1281618-r3.dtsi
@@ -83,7 +83,7 @@ accelerometer@19 { st,drdy-int-pin = <1>; reg = <0x19>; vdd-supply = <&ab8500_ldo_aux1_reg>; - vddio-supply = <&db8500_vsmps2_reg>; + vddio-supply = <&buck_vio18>; interrupt-parent = <&gpio2>; interrupts = <18 IRQ_TYPE_EDGE_RISING>, <19 IRQ_TYPE_EDGE_RISING>; @@ -97,7 +97,7 @@ magnetometer@1e { compatible = "st,lsm303dlm-magn"; reg = <0x1e>; vdd-supply = <&ab8500_ldo_aux1_reg>; - vddio-supply = <&db8500_vsmps2_reg>; + vddio-supply = <&buck_vio18>; // This interrupt is not properly working with the driver // interrupt-parent = <&gpio1>; // interrupts = <0 IRQ_TYPE_EDGE_RISING>; @@ -109,14 +109,14 @@ gyroscope@68 { compatible = "st,l3g4200d-gyro"; reg = <0x68>; vdd-supply = <&ab8500_ldo_aux1_reg>; - vddio-supply = <&db8500_vsmps2_reg>; + vddio-supply = <&buck_vio18>; }; pressure@5c { /* Barometer/pressure sensor */ compatible = "st,lps001wp-press"; reg = <0x5c>; vdd-supply = <&ab8500_ldo_aux1_reg>; - vddio-supply = <&db8500_vsmps2_reg>; + vddio-supply = <&buck_vio18>; }; }; @@ -139,7 +139,7 @@ touchscreen@0 { interrupt-parent = <&gpio2>; interrupts = <20 IRQ_TYPE_EDGE_FALLING>; vcpin-supply = <&ab8500_ldo_aux1_reg>; - vdd-supply = <&db8500_vsmps2_reg>; + vdd-supply = <&buck_vio18>; reset-gpios = <&gpio4 15 GPIO_ACTIVE_LOW>; touchscreen-size-x = <480>; touchscreen-size-y = <854>;
diff --git a/arch/arm/boot/dts/st/ste-href.dtsi b/arch/arm/boot/dts/st/ste-href.dtsi index a85d876..3150e1d 100644 --- a/arch/arm/boot/dts/st/ste-href.dtsi +++ b/arch/arm/boot/dts/st/ste-href.dtsi
@@ -196,7 +196,7 @@ mmc@80005000 { non-removable; no-sdio; no-sd; - vmmc-supply = <&db8500_vsmps2_reg>; + vmmc-supply = <&buck_vio18>; pinctrl-names = "default", "sleep"; pinctrl-0 = <&mc2_a_1_default>; pinctrl-1 = <&mc2_a_1_sleep>;
diff --git a/arch/arm/boot/dts/st/ste-snowball.dts b/arch/arm/boot/dts/st/ste-snowball.dts index 14ed107..1607bfb 100644 --- a/arch/arm/boot/dts/st/ste-snowball.dts +++ b/arch/arm/boot/dts/st/ste-snowball.dts
@@ -208,7 +208,7 @@ ethernet@0 { interrupts = <12 IRQ_TYPE_EDGE_RISING>; interrupt-parent = <&gpio4>; vdd33a-supply = <&en_3v3_reg>; - vddvario-supply = <&db8500_vape_reg>; + vddvario-supply = <&ab8500_buck_vsmps2>; pinctrl-names = "default"; pinctrl-0 = <ð_snowball_mode>; @@ -354,7 +354,7 @@ lsm303dlh@18 { st,drdy-int-pin = <1>; reg = <0x18>; vdd-supply = <&ab8500_ldo_aux1_reg>; - vddio-supply = <&db8500_vsmps2_reg>; + vddio-supply = <&ab8500_buck_vsmps2>; pinctrl-names = "default"; pinctrl-0 = <&accel_snowball_mode>; interrupt-parent = <&gpio5>; @@ -366,7 +366,7 @@ lsm303dlh@1e { compatible = "st,lsm303dlh-magn"; reg = <0x1e>; vdd-supply = <&ab8500_ldo_aux1_reg>; - vddio-supply = <&db8500_vsmps2_reg>; + vddio-supply = <&ab8500_buck_vsmps2>; pinctrl-names = "default"; pinctrl-0 = <&magneto_snowball_mode>; interrupt-parent = <&gpio5>; @@ -378,7 +378,7 @@ l3g4200d@68 { st,drdy-int-pin = <2>; reg = <0x68>; vdd-supply = <&ab8500_ldo_aux1_reg>; - vddio-supply = <&db8500_vsmps2_reg>; + vddio-supply = <&ab8500_buck_vsmps2>; pinctrl-names = "default"; pinctrl-0 = <&gyro_snowball_mode>; interrupt-parent = <&gpio5>; @@ -390,7 +390,7 @@ lsp001wm@5c { compatible = "st,lps001wp-press"; reg = <0x5c>; vdd-supply = <&ab8500_ldo_aux1_reg>; - vddio-supply = <&db8500_vsmps2_reg>; + vddio-supply = <&ab8500_buck_vsmps2>; }; };
diff --git a/arch/arm/boot/dts/st/ste-ux500-samsung-codina-tmo.dts b/arch/arm/boot/dts/st/ste-ux500-samsung-codina-tmo.dts index 8f1780d..3350fc7 100644 --- a/arch/arm/boot/dts/st/ste-ux500-samsung-codina-tmo.dts +++ b/arch/arm/boot/dts/st/ste-ux500-samsung-codina-tmo.dts
@@ -21,6 +21,7 @@ #include "ste-db8500.dtsi" #include "ste-ab8505.dtsi" #include "ste-dbx5x0-pinctrl.dtsi" +#include "ste-ux500-samsung.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/leds/common.h> #include <dt-bindings/input/input.h>
diff --git a/arch/arm/boot/dts/st/ste-ux500-samsung-codina.dts b/arch/arm/boot/dts/st/ste-ux500-samsung-codina.dts index 9f58a3c..8df2e4b 100644 --- a/arch/arm/boot/dts/st/ste-ux500-samsung-codina.dts +++ b/arch/arm/boot/dts/st/ste-ux500-samsung-codina.dts
@@ -22,6 +22,7 @@ #include "ste-db8500.dtsi" #include "ste-ab8500.dtsi" #include "ste-dbx5x0-pinctrl.dtsi" +#include "ste-ux500-samsung.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/leds/common.h> #include <dt-bindings/input/input.h> @@ -451,7 +452,7 @@ mmc@80005000 { no-sdio; no-sd; vmmc-supply = <&ldo_3v3_reg>; - vqmmc-supply = <&db8500_vsmps2_reg>; + vqmmc-supply = <&ab8500_buck_vsmps2>; pinctrl-names = "default", "sleep"; /* * This muxing excludes the feedback clock on GPIO130 @@ -503,7 +504,7 @@ gnss { /* GPS_ON_OFF on GPIO86 */ enable-gpios = <&gpio2 22 GPIO_ACTIVE_HIGH>; /* GPS_1V8 (VSMPS2) */ - vddio-supply = <&db8500_vsmps2_reg>; + vddio-supply = <&ab8500_buck_vsmps2>; pinctrl-names = "default"; pinctrl-0 = <&bcm4751_codina_default>; }; @@ -667,6 +668,26 @@ display_out: endpoint { }; }; +&samsung_playback_cpu { + dai-format = "dsp_b"; + dai-tdm-slot-num = <16>; + dai-tdm-slot-tx-mask = <0 1 0 1>; +}; + +&samsung_codec_playback { + dai-tdm-slot-num = <16>; + dai-tdm-slot-tx-mask = <0 1 0 1>; +}; + +&samsung_capture_cpu { + dai-format = "dsp_b"; + dai-tdm-slot-num = <16>; +}; + +&samsung_codec_capture { + dai-tdm-slot-num = <16>; +}; + &pinctrl { /* * This extends the MC0_A_2 default config to include
diff --git a/arch/arm/boot/dts/st/ste-ux500-samsung-gavini.dts b/arch/arm/boot/dts/st/ste-ux500-samsung-gavini.dts index 0c3eef7..277060c 100644 --- a/arch/arm/boot/dts/st/ste-ux500-samsung-gavini.dts +++ b/arch/arm/boot/dts/st/ste-ux500-samsung-gavini.dts
@@ -7,6 +7,7 @@ #include "ste-db8500.dtsi" #include "ste-ab8500.dtsi" #include "ste-dbx5x0-pinctrl.dtsi" +#include "ste-ux500-samsung.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/leds/common.h> #include <dt-bindings/input/input.h> @@ -329,7 +330,38 @@ i2c-gpio-2 { pinctrl-0 = <&i2c_gpio_2_default>; #address-cells = <1>; #size-cells = <0>; - /* TODO: add the Immersion ISA1200 I2C device here */ + + /* Haptic feedback unit Imagis ISA1200 */ + haptic-engine@49 { + compatible = "imagis,isa1200"; + reg = <0x49>; + + /* + * GPIO194 pin HEN (motor hardware enable) + * GPIO195 pin LEN (motor LDO enable) + */ + control-gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>, <&gpio6 3 GPIO_ACTIVE_HIGH>; + + /* clkout1 from ACLK divided by 8 */ + clocks = <&clkout_clk DB8500_CLKOUT_1 DB8500_CLKOUT_SRC_ACLK 8>; + + imagis,clk-div = <256>; + imagis,pll-div = <2>; + + imagis,mode = <0>; /* LRA_MODE */ + + imagis,period-ns = <13400>; + imagis,duty-cycle-ns = <100>; + + pinctrl-names = "default"; + pinctrl-0 = <&isa1200_gavini_default>; + + ldo { + regulator-name = "vdd_vib"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + }; }; /* Bit-banged I2C on GPIO196 and GPIO197 also called "MPR_I2C" */ @@ -604,6 +636,10 @@ display_out: endpoint { }; }; +&codec { + stericsson,amic1a-bias-vamic2; +}; + &pinctrl { /* * This extends the MC0_A_2 default config to include @@ -884,4 +920,27 @@ gavini_cfg1 { }; }; }; + isa1200 { + isa1200_gavini_default: isa1200_gavini { + /* Bring out clkout1 on pin GPIO227 pin AH7 */ + gavini_mux { + function = "clkout"; + groups = "clkout1_a_1"; + }; + gavini_cfg1 { + pins = "GPIO227_AH7"; + ste,config = <&out_lo>; + }; + /* HEN GPIO */ + gavini_cfg2 { + pins = "GPIO194_AF27"; + ste,config = <&gpio_out_lo>; + }; + /* LEN GPIO */ + gavini_cfg3 { + pins = "GPIO195_AG28"; + ste,config = <&gpio_out_lo>; + }; + }; + }; };
diff --git a/arch/arm/boot/dts/st/ste-ux500-samsung-golden.dts b/arch/arm/boot/dts/st/ste-ux500-samsung-golden.dts index f736888..3f5499a 100644 --- a/arch/arm/boot/dts/st/ste-ux500-samsung-golden.dts +++ b/arch/arm/boot/dts/st/ste-ux500-samsung-golden.dts
@@ -4,6 +4,7 @@ #include "ste-db8500.dtsi" #include "ste-ab8505.dtsi" #include "ste-dbx5x0-pinctrl.dtsi" +#include "ste-ux500-samsung.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/leds/common.h> #include <dt-bindings/input/input.h> @@ -391,21 +392,21 @@ gpio-keys { label = "GPIO Buttons"; volume-up { - label = "Volume Up"; + label = "VOL+"; /* GPIO67 (VOL_UP) */ gpios = <&gpio2 3 GPIO_ACTIVE_LOW>; linux,code = <KEY_VOLUMEUP>; }; volume-down { - label = "Volume Down"; + label = "VOL-"; /* GPIO92 (VOL_DOWN) */ gpios = <&gpio2 28 GPIO_ACTIVE_LOW>; linux,code = <KEY_VOLUMEDOWN>; }; home { - label = "Home"; + label = "HOME"; /* GPIO91 (HOME_KEY) */ gpios = <&gpio2 27 GPIO_ACTIVE_LOW>; linux,code = <KEY_HOMEPAGE>; @@ -510,7 +511,7 @@ wl_reg_on: regulator-wl-reg-on { panel_reg_1v8: regulator-panel-1v8 { compatible = "regulator-fixed"; - regulator-name = "panel-fixed-supply"; + regulator-name = "panel-fixed-supply-1v8"; regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; /* GPIO219 */ @@ -527,7 +528,7 @@ panel_reg_1v8: regulator-panel-1v8 { panel_reg_3v0: regulator-panel-3v0 { compatible = "regulator-fixed"; - regulator-name = "panel-fixed-supply"; + regulator-name = "panel-fixed-supply-3v0"; regulator-min-microvolt = <3000000>; regulator-max-microvolt = <3000000>; /* GPIO219 */
diff --git a/arch/arm/boot/dts/st/ste-ux500-samsung-janice.dts b/arch/arm/boot/dts/st/ste-ux500-samsung-janice.dts index 18fb726..e821527 100644 --- a/arch/arm/boot/dts/st/ste-ux500-samsung-janice.dts +++ b/arch/arm/boot/dts/st/ste-ux500-samsung-janice.dts
@@ -7,6 +7,7 @@ #include "ste-db8500.dtsi" #include "ste-ab8500.dtsi" #include "ste-dbx5x0-pinctrl.dtsi" +#include "ste-ux500-samsung.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/leds/common.h> #include <dt-bindings/input/input.h> @@ -360,7 +361,38 @@ i2c-gpio-2 { pinctrl-0 = <&i2c_gpio_2_default>; #address-cells = <1>; #size-cells = <0>; - /* TODO: add the Immersion ISA1200 I2C device here */ + + /* Haptic feedback unit Imagis ISA1200 */ + haptic-engine@49 { + compatible = "imagis,isa1200"; + reg = <0x49>; + + /* + * GPIO194 pin HEN (motor hardware enable) + * GPIO195 pin LEN (motor LDO enable) + */ + control-gpios = <&gpio6 2 GPIO_ACTIVE_HIGH>, <&gpio6 3 GPIO_ACTIVE_HIGH>; + + /* clkout1 from ACLK divided by 8 */ + clocks = <&clkout_clk DB8500_CLKOUT_1 DB8500_CLKOUT_SRC_ACLK 8>; + + imagis,clk-div = <256>; + imagis,pll-div = <2>; + + imagis,mode = <0>; /* LRA_MODE */ + + imagis,period-ns = <13400>; + imagis,duty-cycle-ns = <100>; + + pinctrl-names = "default"; + pinctrl-0 = <&isa1200_janice_default>; + + ldo { + regulator-name = "vdd_vib"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + }; + }; }; /* Bit-banged I2C on GPIO151 and GPIO152 also called "NFC_I2C" */ @@ -512,7 +544,7 @@ gnss { /* GPS_ON_OFF on GPIO96 */ sirf,onoff-gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>; /* GPS_1V8 (VSMPS2) */ - vcc-supply = <&db8500_vsmps2_reg>; + vcc-supply = <&ab8500_buck_vsmps2>; pinctrl-names = "default"; pinctrl-0 = <&gsd4t_janice_default>; /* According to /etc/sirfgps.conf */ @@ -996,4 +1028,27 @@ janice_cfg3 { }; }; }; + isa1200 { + isa1200_janice_default: isa1200_janice { + /* Bring out clkout1 on pin GPIO227 pin AH7 */ + janice_mux { + function = "clkout"; + groups = "clkout1_a_1"; + }; + janice_cfg1 { + pins = "GPIO227_AH7"; + ste,config = <&out_lo>; + }; + /* HEN GPIO */ + janice_cfg2 { + pins = "GPIO194_AF27"; + ste,config = <&gpio_out_lo>; + }; + /* LEN GPIO */ + janice_cfg3 { + pins = "GPIO195_AG28"; + ste,config = <&gpio_out_lo>; + }; + }; + }; };
diff --git a/arch/arm/boot/dts/st/ste-ux500-samsung-kyle.dts b/arch/arm/boot/dts/st/ste-ux500-samsung-kyle.dts index c34d43a..30f9bdf 100644 --- a/arch/arm/boot/dts/st/ste-ux500-samsung-kyle.dts +++ b/arch/arm/boot/dts/st/ste-ux500-samsung-kyle.dts
@@ -11,6 +11,7 @@ #include "ste-db8500.dtsi" #include "ste-ab8505.dtsi" #include "ste-dbx5x0-pinctrl.dtsi" +#include "ste-ux500-samsung.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/leds/common.h> #include <dt-bindings/input/input.h> @@ -323,8 +324,8 @@ gnss { reset-gpios = <&gpio0 21 GPIO_ACTIVE_LOW>; /* GPS_ON_OFF on GPIO86 */ sirf,onoff-gpios = <&gpio2 22 GPIO_ACTIVE_HIGH>; - /* GPS_1V8 (VSMPS2) */ - vcc-supply = <&db8500_vsmps2_reg>; + /* GPS_1V8 (VSMPSB) */ + vcc-supply = <&ab8505_buck_vsmpsb>; pinctrl-names = "default"; pinctrl-0 = <&g05ta03_kyle_default>; /* According to /etc/sirfgps.conf */
diff --git a/arch/arm/boot/dts/st/ste-ux500-samsung-skomer.dts b/arch/arm/boot/dts/st/ste-ux500-samsung-skomer.dts index 7bf4287..c3eb07f 100644 --- a/arch/arm/boot/dts/st/ste-ux500-samsung-skomer.dts +++ b/arch/arm/boot/dts/st/ste-ux500-samsung-skomer.dts
@@ -7,6 +7,7 @@ #include "ste-db8500.dtsi" #include "ste-ab8505.dtsi" #include "ste-dbx5x0-pinctrl.dtsi" +#include "ste-ux500-samsung.dtsi" #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/leds/common.h> #include <dt-bindings/input/input.h> @@ -303,8 +304,8 @@ gnss { reset-gpios = <&gpio6 17 GPIO_ACTIVE_LOW>; /* GPS_ON_OFF on GPIO86 */ sirf,onoff-gpios = <&gpio2 22 GPIO_ACTIVE_HIGH>; - /* GPS_1V8 (VSMPS2) */ - vcc-supply = <&db8500_vsmps2_reg>; + /* GPS_1V8 (VSMPSB) */ + vcc-supply = <&ab8505_buck_vsmpsb>; pinctrl-names = "default"; pinctrl-0 = <&g05ta03_skomer_default>; /* According to /etc/sirfgps.conf */
diff --git a/arch/arm/boot/dts/st/ste-ux500-samsung.dtsi b/arch/arm/boot/dts/st/ste-ux500-samsung.dtsi new file mode 100644 index 0000000..2b46145 --- /dev/null +++ b/arch/arm/boot/dts/st/ste-ux500-samsung.dtsi
@@ -0,0 +1,77 @@ +// SPDX-License-Identifier: GPL-2.0-only + +/ { + samsung_sound: sound { + compatible = "audio-graph-card2"; + label = "Samsung"; + links = <&samsung_msp1_port &samsung_msp3_port>; + }; +}; + +&codec { + assigned-clocks = <&ab8500_clock AB8500_SYSCLK_INT>; + assigned-clock-parents = <&ab8500_clock AB8500_SYSCLK_ULP>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + samsung_codec_playback: endpoint { + remote-endpoint = <&samsung_playback_cpu>; + bitclock-master; + frame-master; + dai-tdm-slot-num = <8>; + dai-tdm-slot-width = <16>; + dai-tdm-slot-tx-mask = <1 1>; + }; + }; + + port@1 { + reg = <1>; + + samsung_codec_capture: endpoint { + remote-endpoint = <&samsung_capture_cpu>; + bitclock-master; + frame-master; + dai-tdm-slot-num = <8>; + dai-tdm-slot-width = <16>; + dai-tdm-slot-rx-mask = <1>; + }; + }; + }; +}; + +&msp1 { + pinctrl-names = "default"; + pinctrl-0 = <&msp1txrx_a_1_default>; + status = "okay"; + + samsung_msp1_port: port { + samsung_playback_cpu: endpoint { + continuous-clock; + remote-endpoint = <&samsung_codec_playback>; + dai-format = "dsp_a"; + dai-tdm-slot-num = <8>; + dai-tdm-slot-width = <16>; + dai-tdm-slot-tx-mask = <1 1>; + }; + }; +}; + +&msp3 { + status = "okay"; + + samsung_msp3_port: port { + samsung_capture_cpu: endpoint { + continuous-clock; + remote-endpoint = <&samsung_codec_capture>; + dai-format = "dsp_a"; + dai-tdm-slot-num = <8>; + dai-tdm-slot-width = <16>; + dai-tdm-slot-rx-mask = <1>; + }; + }; +};
diff --git a/arch/arm/boot/dts/st/stm32mp131.dtsi b/arch/arm/boot/dts/st/stm32mp131.dtsi index 83ae59b..5ae33b2 100644 --- a/arch/arm/boot/dts/st/stm32mp131.dtsi +++ b/arch/arm/boot/dts/st/stm32mp131.dtsi
@@ -139,6 +139,30 @@ soc { interrupt-parent = <&intc>; ranges; + sram1: sram@30000000 { + compatible = "mmio-sram"; + reg = <0x30000000 0x4000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x30000000 0x4000>; + }; + + sram2: sram@30004000 { + compatible = "mmio-sram"; + reg = <0x30004000 0x2000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x30004000 0x2000>; + }; + + sram3: sram@30006000 { + compatible = "mmio-sram"; + reg = <0x30006000 0x2000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0 0x30006000 0x2000>; + }; + timers2: timer@40000000 { #address-cells = <1>; #size-cells = <0>;
diff --git a/arch/arm/boot/dts/st/stm32mp135.dtsi b/arch/arm/boot/dts/st/stm32mp135.dtsi index 834a4d5..f573335 100644 --- a/arch/arm/boot/dts/st/stm32mp135.dtsi +++ b/arch/arm/boot/dts/st/stm32mp135.dtsi
@@ -6,29 +6,29 @@ #include "stm32mp133.dtsi" -/ { - soc { - dcmipp: dcmipp@5a000000 { - compatible = "st,stm32mp13-dcmipp"; - reg = <0x5a000000 0x400>; - interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; - resets = <&rcc DCMIPP_R>; - clocks = <&rcc DCMIPP_K>; - status = "disabled"; +&etzpc { + dcmipp: dcmipp@5a000000 { + compatible = "st,stm32mp13-dcmipp"; + reg = <0x5a000000 0x400>; + interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; + resets = <&rcc DCMIPP_R>; + clocks = <&rcc DCMIPP_K>; + access-controllers = <&etzpc 4>; + status = "disabled"; - port { - }; + port { }; + }; - ltdc: display-controller@5a001000 { - compatible = "st,stm32-ltdc"; - reg = <0x5a001000 0x400>; - interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&rcc LTDC_PX>; - clock-names = "lcd"; - resets = <&scmi_reset RST_SCMI_LTDC>; - status = "disabled"; - }; + ltdc: display-controller@5a001000 { + compatible = "st,stm32-ltdc"; + reg = <0x5a001000 0x400>; + interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc LTDC_PX>; + clock-names = "lcd"; + resets = <&scmi_reset RST_SCMI_LTDC>; + access-controllers = <&etzpc 3>; + status = "disabled"; }; };
diff --git a/arch/arm/boot/dts/st/stm32mp135f-dk.dts b/arch/arm/boot/dts/st/stm32mp135f-dk.dts index 1d6435c..2d6c5af 100644 --- a/arch/arm/boot/dts/st/stm32mp135f-dk.dts +++ b/arch/arm/boot/dts/st/stm32mp135f-dk.dts
@@ -60,17 +60,6 @@ optee@dd000000 { }; }; - gpio-keys { - compatible = "gpio-keys"; - - button-user { - /* GPIO on PA13 "User button 2 (B2)" */ - label = "User-PA13"; - linux,code = <BTN_1>; - gpios = <&gpioa 13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; - }; - }; - leds { compatible = "gpio-leds"; @@ -190,11 +179,11 @@ &cryp { status = "okay"; }; -&cs_cti_trace { +&cs_cti_cpu0 { status = "okay"; }; -&cs_cti_cpu0 { +&cs_cti_trace { status = "okay"; }; @@ -479,9 +468,21 @@ &spi5 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&spi5_pins_a>; pinctrl-1 = <&spi5_sleep_pins_a>; + dmas = <&dmamux1 85 0x400 0x01>, + <&dmamux1 86 0x400 0x01>, + <&mdma 0 0x3 0x1200000a 0 0>; + dma-names = "rx", "tx", "rxm2m"; + sram = <&spi5_dma_pool>; status = "disabled"; }; +&sram2 { + spi5_dma_pool: dma-sram@1000 { + reg = <0x1000 0x1000>; + pool; + }; +}; + &timers3 { /delete-property/dmas; /delete-property/dma-names; @@ -628,6 +629,7 @@ hub@1 { compatible = "usb424,2514"; reg = <1>; vdd-supply = <&scmi_v3v3_sw>; + vdda-supply = <&scmi_v3v3_sw>; }; };
diff --git a/arch/arm/boot/dts/st/stm32mp15-pinctrl.dtsi b/arch/arm/boot/dts/st/stm32mp15-pinctrl.dtsi index aaa91b6..4480bc5 100644 --- a/arch/arm/boot/dts/st/stm32mp15-pinctrl.dtsi +++ b/arch/arm/boot/dts/st/stm32mp15-pinctrl.dtsi
@@ -2874,6 +2874,31 @@ pins2 { }; /omit-if-no-ref/ + spi4_pins_b: spi4-1 { + pins1 { + pinmux = <STM32_PINMUX('E', 12, AF5)>, /* SPI4_SCK */ + <STM32_PINMUX('E', 14, AF5)>; /* SPI4_MOSI */ + bias-disable; + drive-push-pull; + slew-rate = <1>; + }; + + pins2 { + pinmux = <STM32_PINMUX('E', 13, AF5)>; /* SPI4_MISO */ + bias-disable; + }; + }; + + /omit-if-no-ref/ + spi4_sleep_pins_b: spi4-sleep-1 { + pins { + pinmux = <STM32_PINMUX('E', 12, ANALOG)>, /* SPI4_SCK */ + <STM32_PINMUX('E', 13, ANALOG)>, /* SPI4_MISO */ + <STM32_PINMUX('E', 14, ANALOG)>; /* SPI4_MOSI */ + }; + }; + + /omit-if-no-ref/ spi5_pins_a: spi5-0 { pins1 { pinmux = <STM32_PINMUX('F', 7, AF5)>, /* SPI5_SCK */ @@ -2890,6 +2915,15 @@ pins2 { }; /omit-if-no-ref/ + spi5_sleep_pins_a: spi5-sleep-0 { + pins { + pinmux = <STM32_PINMUX('F', 7, ANALOG)>, /* SPI5_SCK */ + <STM32_PINMUX('F', 8, ANALOG)>, /* SPI5_MISO */ + <STM32_PINMUX('F', 9, ANALOG)>; /* SPI5_MOSI */ + }; + }; + + /omit-if-no-ref/ stusb1600_pins_a: stusb1600-0 { pins { pinmux = <STM32_PINMUX('I', 11, GPIO)>;
diff --git a/arch/arm/boot/dts/st/stm32mp151.dtsi b/arch/arm/boot/dts/st/stm32mp151.dtsi index 84f68e8..e7fec8b 100644 --- a/arch/arm/boot/dts/st/stm32mp151.dtsi +++ b/arch/arm/boot/dts/st/stm32mp151.dtsi
@@ -943,8 +943,8 @@ spi2: spi@4000b000 { interrupts = <GIC_SPI 36 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc SPI2_K>; resets = <&rcc SPI2_R>; - dmas = <&dmamux1 39 0x400 0x05>, - <&dmamux1 40 0x400 0x05>; + dmas = <&dmamux1 39 0x400 0x01>, + <&dmamux1 40 0x400 0x01>; dma-names = "rx", "tx"; access-controllers = <&etzpc 27>; status = "disabled"; @@ -970,8 +970,8 @@ spi3: spi@4000c000 { interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc SPI3_K>; resets = <&rcc SPI3_R>; - dmas = <&dmamux1 61 0x400 0x05>, - <&dmamux1 62 0x400 0x05>; + dmas = <&dmamux1 61 0x400 0x01>, + <&dmamux1 62 0x400 0x01>; dma-names = "rx", "tx"; access-controllers = <&etzpc 28>; status = "disabled"; @@ -1301,8 +1301,8 @@ spi1: spi@44004000 { interrupts = <GIC_SPI 35 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc SPI1_K>; resets = <&rcc SPI1_R>; - dmas = <&dmamux1 37 0x400 0x05>, - <&dmamux1 38 0x400 0x05>; + dmas = <&dmamux1 37 0x400 0x01>, + <&dmamux1 38 0x400 0x01>; dma-names = "rx", "tx"; access-controllers = <&etzpc 52>; status = "disabled"; @@ -1316,8 +1316,8 @@ spi4: spi@44005000 { interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc SPI4_K>; resets = <&rcc SPI4_R>; - dmas = <&dmamux1 83 0x400 0x05>, - <&dmamux1 84 0x400 0x05>; + dmas = <&dmamux1 83 0x400 0x01>, + <&dmamux1 84 0x400 0x01>; dma-names = "rx", "tx"; access-controllers = <&etzpc 53>; status = "disabled"; @@ -1432,8 +1432,8 @@ spi5: spi@44009000 { interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; clocks = <&rcc SPI5_K>; resets = <&rcc SPI5_R>; - dmas = <&dmamux1 85 0x400 0x05>, - <&dmamux1 86 0x400 0x05>; + dmas = <&dmamux1 85 0x400 0x01>, + <&dmamux1 86 0x400 0x01>; dma-names = "rx", "tx"; access-controllers = <&etzpc 57>; status = "disabled";
diff --git a/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi b/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi index 7d3a6a3..d30b626 100644 --- a/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi +++ b/arch/arm/boot/dts/st/stm32mp153c-lxa-fairytux2.dtsi
@@ -28,7 +28,7 @@ aliases { }; chosen { - stdout-path = &uart4; + stdout-path = "serial0:115200n8"; }; backlight: backlight {
diff --git a/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts b/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts index 847b360..53e40e2 100644 --- a/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts +++ b/arch/arm/boot/dts/st/stm32mp157a-dk1-scmi.dts
@@ -51,10 +51,6 @@ &iwdg2 { clocks = <&rcc IWDG2>, <&scmi_clk CK_SCMI_LSI>; }; -&mdma1 { - resets = <&scmi_reset RST_SCMI_MDMA>; -}; - &m4_rproc { /delete-property/ st,syscfg-holdboot; resets = <&scmi_reset RST_SCMI_MCU>, @@ -62,6 +58,10 @@ &m4_rproc { reset-names = "mcu_rst", "hold_boot"; }; +&mdma1 { + resets = <&scmi_reset RST_SCMI_MDMA>; +}; + &optee { interrupt-parent = <&intc>; interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
diff --git a/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts b/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts index 4328028..0790ed4 100644 --- a/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts +++ b/arch/arm/boot/dts/st/stm32mp157c-dk2-scmi.dts
@@ -57,10 +57,6 @@ &iwdg2 { clocks = <&rcc IWDG2>, <&scmi_clk CK_SCMI_LSI>; }; -&mdma1 { - resets = <&scmi_reset RST_SCMI_MDMA>; -}; - &m4_rproc { /delete-property/ st,syscfg-holdboot; resets = <&scmi_reset RST_SCMI_MCU>, @@ -68,6 +64,10 @@ &m4_rproc { reset-names = "mcu_rst", "hold_boot"; }; +&mdma1 { + resets = <&scmi_reset RST_SCMI_MDMA>; +}; + &optee { interrupt-parent = <&intc>; interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
diff --git a/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts b/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts index 6f27d79..0a3894a 100644 --- a/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts +++ b/arch/arm/boot/dts/st/stm32mp157c-ed1-scmi.dts
@@ -56,10 +56,6 @@ &iwdg2 { clocks = <&rcc IWDG2>, <&scmi_clk CK_SCMI_LSI>; }; -&mdma1 { - resets = <&scmi_reset RST_SCMI_MDMA>; -}; - &m4_rproc { /delete-property/ st,syscfg-holdboot; resets = <&scmi_reset RST_SCMI_MCU>, @@ -67,6 +63,10 @@ &m4_rproc { reset-names = "mcu_rst", "hold_boot"; }; +&mdma1 { + resets = <&scmi_reset RST_SCMI_MDMA>; +}; + &optee { interrupt-parent = <&intc>; interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
diff --git a/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts b/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts index 6ae391b..c2b6efb 100644 --- a/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts +++ b/arch/arm/boot/dts/st/stm32mp157c-ev1-scmi.dts
@@ -61,10 +61,6 @@ &m_can1 { clocks = <&scmi_clk CK_SCMI_HSE>, <&rcc FDCAN_K>; }; -&mdma1 { - resets = <&scmi_reset RST_SCMI_MDMA>; -}; - &m4_rproc { /delete-property/ st,syscfg-holdboot; resets = <&scmi_reset RST_SCMI_MCU>, @@ -72,6 +68,10 @@ &m4_rproc { reset-names = "mcu_rst", "hold_boot"; }; +&mdma1 { + resets = <&scmi_reset RST_SCMI_MDMA>; +}; + &optee { interrupt-parent = <&intc>; interrupts = <GIC_PPI 15 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
diff --git a/arch/arm/boot/dts/st/stm32mp157c-ev1.dts b/arch/arm/boot/dts/st/stm32mp157c-ev1.dts index 0e65a18..c0e274e 100644 --- a/arch/arm/boot/dts/st/stm32mp157c-ev1.dts +++ b/arch/arm/boot/dts/st/stm32mp157c-ev1.dts
@@ -81,10 +81,6 @@ &cec { status = "okay"; }; -&cs_cti_trace { - status = "okay"; -}; - &cs_cti_cpu0 { status = "okay"; }; @@ -93,6 +89,10 @@ &cs_cti_cpu1 { status = "okay"; }; +&cs_cti_trace { + status = "okay"; +}; + &cs_etf { status = "okay"; }; @@ -439,6 +439,7 @@ hub@1 { compatible = "usb424,2514"; reg = <1>; vdd-supply = <&v3v3>; + vdda-supply = <&v3v3>; }; };
diff --git a/arch/arm/boot/dts/st/stm32mp157c-lxa-mc1.dts b/arch/arm/boot/dts/st/stm32mp157c-lxa-mc1.dts index eada9cf..b3d8eb5 100644 --- a/arch/arm/boot/dts/st/stm32mp157c-lxa-mc1.dts +++ b/arch/arm/boot/dts/st/stm32mp157c-lxa-mc1.dts
@@ -33,7 +33,7 @@ backlight: backlight { }; chosen { - stdout-path = &uart4; + stdout-path = "serial0:115200n8"; }; led-controller-0 {
diff --git a/arch/arm/boot/dts/st/stm32mp157f-dk2-scmi.dtsi b/arch/arm/boot/dts/st/stm32mp157f-dk2-scmi.dtsi index 89de85a..1723477 100644 --- a/arch/arm/boot/dts/st/stm32mp157f-dk2-scmi.dtsi +++ b/arch/arm/boot/dts/st/stm32mp157f-dk2-scmi.dtsi
@@ -180,6 +180,7 @@ &sdmmc3 { &usbh_ehci { hub@1 { vdd-supply = <&scmi_v3v3>; + vdda-supply = <&scmi_v3v3>; }; };
diff --git a/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi b/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi index ab13f0c..ddb1657 100644 --- a/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi +++ b/arch/arm/boot/dts/st/stm32mp15xc-lxa-tac.dtsi
@@ -33,7 +33,7 @@ aliases { }; chosen { - stdout-path = &uart4; + stdout-path = "serial0:115200n8"; }; led-controller-0 {
diff --git a/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi b/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi index 4cc6336..0a4263e 100644 --- a/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi +++ b/arch/arm/boot/dts/st/stm32mp15xx-dhcom-som.dtsi
@@ -505,9 +505,11 @@ &sdmmc1_b4_pins_a { * - mandatory on SoMs without SD voltage translator */ pins1 { + /delete-property/ bias-disable; bias-pull-up; }; pins2 { + /delete-property/ bias-disable; bias-pull-up; }; };
diff --git a/arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi b/arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi index 599ea07..1a07ae0 100644 --- a/arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi +++ b/arch/arm/boot/dts/st/stm32mp15xx-dkx.dtsi
@@ -155,10 +155,6 @@ &crc1 { status = "okay"; }; -&cs_cti_trace { - status = "okay"; -}; - &cs_cti_cpu0 { status = "okay"; }; @@ -167,6 +163,10 @@ &cs_cti_cpu1 { status = "okay"; }; +&cs_cti_trace { + status = "okay"; +}; + &cs_etf { status = "okay"; }; @@ -623,6 +623,32 @@ &sdmmc3 { status = "disabled"; }; +&spi4 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&spi4_pins_b>; + pinctrl-1 = <&spi4_sleep_pins_b>; + dmas = <&dmamux1 83 0x400 0x01>, + <&dmamux1 84 0x400 0x01>, + <&mdma1 0 0x3 0x1200000a 0 0>; + dma-names = "rx", "tx", "rxm2m"; + sram = <&spi4_dma_pool>; + status = "disabled"; +}; + +&spi5 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&spi5_pins_a>; + pinctrl-1 = <&spi5_sleep_pins_a>; + status = "disabled"; +}; + +&sram4 { + spi4_dma_pool: dma-sram@9000 { + reg = <0x9000 0x1000>; + pool; + }; +}; + &timers1 { /* spare dmas for other usage */ /delete-property/dmas; @@ -764,6 +790,7 @@ hub@1 { compatible = "usb424,2514"; reg = <1>; vdd-supply = <&v3v3>; + vdda-supply = <&v3v3>; }; };
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2e.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-k2e.dtsi index 662aa33..083c94b 100644 --- a/arch/arm/boot/dts/ti/keystone/keystone-k2e.dtsi +++ b/arch/arm/boot/dts/ti/keystone/keystone-k2e.dtsi
@@ -110,7 +110,7 @@ pscrst: reset-controller { }; devctrl: device-state-control@2620000 { - dspgpio0: keystone_dsp_gpio@240 { + dspgpio0: gpio@240 { compatible = "ti,keystone-dsp-gpio"; reg = <0x240 0x4>; gpio-controller;
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2g.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-k2g.dtsi index dafe485..ee03a85 100644 --- a/arch/arm/boot/dts/ti/keystone/keystone-k2g.dtsi +++ b/arch/arm/boot/dts/ti/keystone/keystone-k2g.dtsi
@@ -69,22 +69,16 @@ pmu { interrupts = <GIC_SPI 4 IRQ_TYPE_EDGE_RISING>; }; - usbphy { - #address-cells = <1>; - #size-cells = <0>; - compatible = "simple-bus"; + usb0_phy: usb0-phy { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; + status = "disabled"; + }; - usb0_phy: usb-phy@0 { - compatible = "usb-nop-xceiv"; - reg = <0>; - status = "disabled"; - }; - - usb1_phy: usb-phy@1 { - compatible = "usb-nop-xceiv"; - reg = <1>; - status = "disabled"; - }; + usb1_phy: usb1-phy { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; + status = "disabled"; }; soc0: soc@0 { @@ -121,7 +115,7 @@ devctrl: device-state-control@2620000 { #size-cells = <1>; ranges = <0x0 0x02620000 0x1000>; - kirq0: keystone_irq@2a0 { + kirq0: interrupt-controller@2a0 { compatible = "ti,keystone-irq"; reg = <0x2a0 0x10>; interrupts = <GIC_SPI 1 IRQ_TYPE_EDGE_RISING>; @@ -130,7 +124,7 @@ kirq0: keystone_irq@2a0 { ti,syscon-dev = <&devctrl 0x2a0>; }; - dspgpio0: keystone_dsp_gpio@240 { + dspgpio0: gpio@240 { compatible = "ti,keystone-dsp-gpio"; reg = <0x240 0x4>; gpio-controller;
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2hk.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-k2hk.dtsi index 4fdf4b3..b7a9fbd 100644 --- a/arch/arm/boot/dts/ti/keystone/keystone-k2hk.dtsi +++ b/arch/arm/boot/dts/ti/keystone/keystone-k2hk.dtsi
@@ -88,7 +88,7 @@ pscrst: reset-controller { }; devctrl: device-state-control@2620000 { - dspgpio0: keystone_dsp_gpio@240 { + dspgpio0: gpio@240 { compatible = "ti,keystone-dsp-gpio"; reg = <0x240 0x4>; gpio-controller; @@ -96,7 +96,7 @@ dspgpio0: keystone_dsp_gpio@240 { gpio,syscon-dev = <&devctrl 0x240>; }; - dspgpio1: keystone_dsp_gpio@244 { + dspgpio1: gpio@244 { compatible = "ti,keystone-dsp-gpio"; reg = <0x244 0x4>; gpio-controller; @@ -104,7 +104,7 @@ dspgpio1: keystone_dsp_gpio@244 { gpio,syscon-dev = <&devctrl 0x244>; }; - dspgpio2: keystone_dsp_gpio@248 { + dspgpio2: gpio@248 { compatible = "ti,keystone-dsp-gpio"; reg = <0x248 0x4>; gpio-controller; @@ -112,7 +112,7 @@ dspgpio2: keystone_dsp_gpio@248 { gpio,syscon-dev = <&devctrl 0x248>; }; - dspgpio3: keystone_dsp_gpio@24c { + dspgpio3: gpio@24c { compatible = "ti,keystone-dsp-gpio"; reg = <0x24c 0x4>; gpio-controller; @@ -120,7 +120,7 @@ dspgpio3: keystone_dsp_gpio@24c { gpio,syscon-dev = <&devctrl 0x24c>; }; - dspgpio4: keystone_dsp_gpio@250 { + dspgpio4: gpio@250 { compatible = "ti,keystone-dsp-gpio"; reg = <0x250 0x4>; gpio-controller; @@ -128,7 +128,7 @@ dspgpio4: keystone_dsp_gpio@250 { gpio,syscon-dev = <&devctrl 0x250>; }; - dspgpio5: keystone_dsp_gpio@254 { + dspgpio5: gpio@254 { compatible = "ti,keystone-dsp-gpio"; reg = <0x254 0x4>; gpio-controller; @@ -136,7 +136,7 @@ dspgpio5: keystone_dsp_gpio@254 { gpio,syscon-dev = <&devctrl 0x254>; }; - dspgpio6: keystone_dsp_gpio@258 { + dspgpio6: gpio@258 { compatible = "ti,keystone-dsp-gpio"; reg = <0x258 0x4>; gpio-controller; @@ -144,7 +144,7 @@ dspgpio6: keystone_dsp_gpio@258 { gpio,syscon-dev = <&devctrl 0x258>; }; - dspgpio7: keystone_dsp_gpio@25c { + dspgpio7: gpio@25c { compatible = "ti,keystone-dsp-gpio"; reg = <0x25c 0x4>; gpio-controller;
diff --git a/arch/arm/boot/dts/ti/keystone/keystone-k2l.dtsi b/arch/arm/boot/dts/ti/keystone/keystone-k2l.dtsi index 330b437..9830cff 100644 --- a/arch/arm/boot/dts/ti/keystone/keystone-k2l.dtsi +++ b/arch/arm/boot/dts/ti/keystone/keystone-k2l.dtsi
@@ -51,7 +51,7 @@ uart2: serial@2348400 { interrupts = <GIC_SPI 432 IRQ_TYPE_EDGE_RISING>; }; - uart3: serial@2348800 { + uart3: serial@2348800 { compatible = "ti,da830-uart", "ns16550a"; current-speed = <115200>; reg-shift = <2>; @@ -290,7 +290,7 @@ osr: sram@70000000 { }; devctrl: device-state-control@2620000 { - dspgpio0: keystone_dsp_gpio@240 { + dspgpio0: gpio@240 { compatible = "ti,keystone-dsp-gpio"; reg = <0x240 0x4>; gpio-controller; @@ -298,7 +298,7 @@ dspgpio0: keystone_dsp_gpio@240 { gpio,syscon-dev = <&devctrl 0x240>; }; - dspgpio1: keystone_dsp_gpio@244 { + dspgpio1: gpio@244 { compatible = "ti,keystone-dsp-gpio"; reg = <0x244 0x4>; gpio-controller; @@ -306,7 +306,7 @@ dspgpio1: keystone_dsp_gpio@244 { gpio,syscon-dev = <&devctrl 0x244>; }; - dspgpio2: keystone_dsp_gpio@248 { + dspgpio2: gpio@248 { compatible = "ti,keystone-dsp-gpio"; reg = <0x248 0x4>; gpio-controller; @@ -314,7 +314,7 @@ dspgpio2: keystone_dsp_gpio@248 { gpio,syscon-dev = <&devctrl 0x248>; }; - dspgpio3: keystone_dsp_gpio@24c { + dspgpio3: gpio@24c { compatible = "ti,keystone-dsp-gpio"; reg = <0x24c 0x4>; gpio-controller; @@ -401,15 +401,15 @@ mdio: mdio@26200f00 { }; &spi0 { - ti,davinci-spi-num-cs = <5>; + num-cs = <5>; }; &spi1 { - ti,davinci-spi-num-cs = <3>; + num-cs = <3>; }; &spi2 { - ti,davinci-spi-num-cs = <5>; + num-cs = <5>; /* Pin muxed. Enabled and configured by Bootloader */ status = "disabled"; };
diff --git a/arch/arm/boot/dts/ti/keystone/keystone.dtsi b/arch/arm/boot/dts/ti/keystone/keystone.dtsi index ff16428..f803b9e 100644 --- a/arch/arm/boot/dts/ti/keystone/keystone.dtsi +++ b/arch/arm/boot/dts/ti/keystone/keystone.dtsi
@@ -93,7 +93,7 @@ devctrl: device-state-control@2620000 { #size-cells = <1>; ranges = <0x0 0x02620000 0x1000>; - kirq0: keystone_irq@2a0 { + kirq0: interrupt-controller@2a0 { compatible = "ti,keystone-irq"; reg = <0x2a0 0x4>; interrupts = <GIC_SPI 4 IRQ_TYPE_EDGE_RISING>; @@ -123,7 +123,7 @@ uart0: serial@2530c00 { interrupts = <GIC_SPI 277 IRQ_TYPE_EDGE_RISING>; }; - uart1: serial@2531000 { + uart1: serial@2531000 { compatible = "ti,da830-uart", "ns16550a"; current-speed = <115200>; reg-shift = <2>;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-boneblack-hdmi.dtsi b/arch/arm/boot/dts/ti/omap/am335x-boneblack-hdmi.dtsi index 109f08f..c52bc33 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-boneblack-hdmi.dtsi +++ b/arch/arm/boot/dts/ti/omap/am335x-boneblack-hdmi.dtsi
@@ -99,7 +99,7 @@ hdmi_0: endpoint { }; }; -&mcasp0 { +&mcasp0 { #sound-dai-cells = <0>; pinctrl-names = "default"; pinctrl-0 = <&mcasp0_pins>;
diff --git a/arch/arm/boot/dts/ti/omap/am335x-bonegreen-eco.dts b/arch/arm/boot/dts/ti/omap/am335x-bonegreen-eco.dts index d21118c..f00abfdd 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-bonegreen-eco.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-bonegreen-eco.dts
@@ -63,7 +63,7 @@ regulators { buck1: buck1 { regulator-name = "vdd_mpu"; regulator-min-microvolt = <925000>; - regulator-max-microvolt = <1298500>; + regulator-max-microvolt = <1351500>; regulator-boot-on; regulator-always-on; };
diff --git a/arch/arm/boot/dts/ti/omap/am335x-shc.dts b/arch/arm/boot/dts/ti/omap/am335x-shc.dts index 5974828..2b94682 100644 --- a/arch/arm/boot/dts/ti/omap/am335x-shc.dts +++ b/arch/arm/boot/dts/ti/omap/am335x-shc.dts
@@ -241,10 +241,6 @@ &mmc3 { status = "okay"; }; -&rtc { - ti,no-init; -}; - &sham { status = "okay"; };
diff --git a/arch/arm/boot/dts/ti/omap/am437x-l4.dtsi b/arch/arm/boot/dts/ti/omap/am437x-l4.dtsi index 30fcce3..9745e0d 100644 --- a/arch/arm/boot/dts/ti/omap/am437x-l4.dtsi +++ b/arch/arm/boot/dts/ti/omap/am437x-l4.dtsi
@@ -902,7 +902,7 @@ timer2_target: target-module@40000 { /* 0x48040000, ap 18 1e.0 */ #size-cells = <1>; ranges = <0x0 0x40000 0x1000>; - timer2: timer@0 { + timer2: timer@0 { compatible = "ti,am4372-timer","ti,am335x-timer"; reg = <0x0 0x400>; interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/ti/omap/am57-pruss.dtsi b/arch/arm/boot/dts/ti/omap/am57-pruss.dtsi index f733166..1579f28 100644 --- a/arch/arm/boot/dts/ti/omap/am57-pruss.dtsi +++ b/arch/arm/boot/dts/ti/omap/am57-pruss.dtsi
@@ -61,6 +61,17 @@ pruss1_iepclk_mux: iepclk-mux@30 { }; }; + pruss1_iep: iep@2e000 { + compatible = "ti,am5728-icss-iep"; + reg = <0x2e000 0x31c>; + clocks = <&pruss1_iepclk_mux>; + }; + + pruss1_ecap: ecap@30000 { + compatible = "ti,pruss-ecap"; + reg = <0x30000 0x60>; + }; + pruss1_mii_rt: mii-rt@32000 { compatible = "ti,pruss-mii", "syscon"; reg = <0x32000 0x58>;
diff --git a/arch/arm/boot/dts/ti/omap/am571x-idk.dts b/arch/arm/boot/dts/ti/omap/am571x-idk.dts index 02653b4..e74c154 100644 --- a/arch/arm/boot/dts/ti/omap/am571x-idk.dts +++ b/arch/arm/boot/dts/ti/omap/am571x-idk.dts
@@ -165,6 +165,53 @@ blue3-led { default-state = "off"; }; }; + + /* Dual mac ethernet application node on icss1 */ + pruss1-eth { + compatible = "ti,am57-prueth"; + ti,prus = <&pru1_0>, <&pru1_1>; + ti,pruss-gp-mux-sel = <0>, /* GP, default */ + <4>; /* MII2, for PRUSS1_MII1 */ + sram = <&ocmcram1>; + ti,mii-rt = <&pruss1_mii_rt>; + ti,iep = <&pruss1_iep>; + ti,ecap = <&pruss1_ecap>; + interrupts = <20 2 2>, <21 3 3>; + interrupt-names = "rx_hp", "rx_lp"; + interrupt-parent = <&pruss1_intc>; + + ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + pruss1_emac0: ethernet-port@0 { + reg = <0>; + phy-handle = <&pruss1_eth0_phy>; + phy-mode = "mii"; + interrupts = <20 2 2>, <26 6 6>, <23 6 6>; + interrupt-names = "rx", "emac_ptp_tx", + "hsr_ptp_tx"; + /* Filled in by bootloader */ + local-mac-address = [00 00 00 00 00 00]; + }; + + pruss1_emac1: ethernet-port@1 { + reg = <1>; + phy-handle = <&pruss1_eth1_phy>; + phy-mode = "mii"; + interrupts = <21 3 3>, <27 9 7>, <24 9 7>; + interrupt-names = "rx", "emac_ptp_tx", + "hsr_ptp_tx"; + /* Filled in by bootloader */ + local-mac-address = [00 00 00 00 00 00]; + }; + }; + }; +}; + +&pruss1_iep { + interrupt-parent = <&pruss1_intc>; + interrupts = <7 7 8>; + interrupt-names = "iep_cap_cmp"; }; &extcon_usb2 { @@ -210,7 +257,23 @@ &mmc2 { }; &pruss1_mdio { - status = "disabled"; + status = "okay"; + reset-gpios = <&gpio5 8 GPIO_ACTIVE_LOW>; + reset-delay-us = <2>; /* PHY datasheet states 1uS min */ + #address-cells = <1>; + #size-cells = <0>; + + pruss1_eth0_phy: ethernet-phy@0 { + reg = <0>; + interrupt-parent = <&gpio3>; + interrupts = <28 IRQ_TYPE_LEVEL_LOW>; + }; + + pruss1_eth1_phy: ethernet-phy@1 { + reg = <1>; + interrupt-parent = <&gpio3>; + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + }; }; &pruss2_mdio {
diff --git a/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts b/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts index 76bfb36..46270ed 100644 --- a/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts +++ b/arch/arm/boot/dts/ti/omap/am5729-beagleboneai.dts
@@ -386,7 +386,7 @@ regen2: regen2 { }; }; - tps659038_rtc: tps659038_rtc { + tps659038_rtc: rtc { compatible = "ti,palmas-rtc"; interrupt-parent = <&tps659038>; interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
diff --git a/arch/arm/boot/dts/ti/omap/am57xx-beagle-x15-common.dtsi b/arch/arm/boot/dts/ti/omap/am57xx-beagle-x15-common.dtsi index 87b61a9..e7c1869 100644 --- a/arch/arm/boot/dts/ti/omap/am57xx-beagle-x15-common.dtsi +++ b/arch/arm/boot/dts/ti/omap/am57xx-beagle-x15-common.dtsi
@@ -360,7 +360,7 @@ regen1: regen1 { }; }; - tps659038_rtc: tps659038_rtc { + tps659038_rtc: rtc { compatible = "ti,palmas-rtc"; interrupt-parent = <&tps659038>; interrupts = <8 IRQ_TYPE_EDGE_FALLING>;
diff --git a/arch/arm/boot/dts/ti/omap/am57xx-idk-common.dtsi b/arch/arm/boot/dts/ti/omap/am57xx-idk-common.dtsi index 5eccff3..699141b 100644 --- a/arch/arm/boot/dts/ti/omap/am57xx-idk-common.dtsi +++ b/arch/arm/boot/dts/ti/omap/am57xx-idk-common.dtsi
@@ -405,7 +405,7 @@ regen2: regen2 { }; }; - tps659038_rtc: tps659038_rtc { + tps659038_rtc: rtc { compatible = "ti,palmas-rtc"; interrupt-parent = <&tps659038>; interrupts = <8 IRQ_TYPE_EDGE_FALLING>; @@ -491,7 +491,6 @@ &uart3 { &rtc { status = "okay"; - ext-clk-src; }; &mac_sw {
diff --git a/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi b/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi index a595745..51dda16 100644 --- a/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi +++ b/arch/arm/boot/dts/ti/omap/dra7-l4.dtsi
@@ -3556,7 +3556,7 @@ rtctarget: target-module@38000 { /* 0x48838000, ap 29 12.0 */ ranges = <0x0 0x38000 0x1000>; rtc: rtc@0 { - compatible = "ti,am3352-rtc"; + compatible = "ti,am3352-rtc", "ti,da830-rtc"; reg = <0x0 0x100>; interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 217 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm/boot/dts/ti/omap/motorola-mapphone-common.dtsi b/arch/arm/boot/dts/ti/omap/motorola-mapphone-common.dtsi index 28b4f12..edc8492 100644 --- a/arch/arm/boot/dts/ti/omap/motorola-mapphone-common.dtsi +++ b/arch/arm/boot/dts/ti/omap/motorola-mapphone-common.dtsi
@@ -101,10 +101,10 @@ &cpu0 { */ operating-points = < /* kHz uV */ - 300000 1025000 - 600000 1200000 - 800000 1313000 - 1008000 1375000 + 300000 1025000 + 600000 1200000 + 800000 1313000 + 1008000 1375000 1200000 1375000 >; };
diff --git a/arch/arm/boot/dts/ti/omap/motorola-mapphone-mz607-mz617.dtsi b/arch/arm/boot/dts/ti/omap/motorola-mapphone-mz607-mz617.dtsi index a356b3a..b97ab29 100644 --- a/arch/arm/boot/dts/ti/omap/motorola-mapphone-mz607-mz617.dtsi +++ b/arch/arm/boot/dts/ti/omap/motorola-mapphone-mz607-mz617.dtsi
@@ -4,6 +4,8 @@ #include "motorola-mapphone-common.dtsi" &keypad { + status = "okay"; + keypad,num-rows = <8>; keypad,num-columns = <8>; linux,keymap = <MATRIX_KEY(5, 0, KEY_VOLUMEUP)>,
diff --git a/arch/arm/boot/dts/ti/omap/omap3-igep.dtsi b/arch/arm/boot/dts/ti/omap/omap3-igep.dtsi index 7346cad..a071746 100644 --- a/arch/arm/boot/dts/ti/omap/omap3-igep.dtsi +++ b/arch/arm/boot/dts/ti/omap/omap3-igep.dtsi
@@ -37,7 +37,7 @@ &omap3_pmx_core { gpmc_pins: gpmc-pins { pinctrl-single,pins = < /* OneNAND seems to require PIN_INPUT on clock. */ - OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0) /* gpmc_clk.gpmc_clk */ + OMAP3_CORE1_IOPAD(0x20be, PIN_INPUT | MUX_MODE0) /* gpmc_clk.gpmc_clk */ >; };
diff --git a/arch/arm/boot/dts/ti/omap/omap3-n9.dts b/arch/arm/boot/dts/ti/omap/omap3-n9.dts index a3cf3f4..2edc193 100644 --- a/arch/arm/boot/dts/ti/omap/omap3-n9.dts +++ b/arch/arm/boot/dts/ti/omap/omap3-n9.dts
@@ -21,8 +21,11 @@ smia_1: camera@10 { reg = <0x10>; /* No reset gpio */ vana-supply = <&vaux3>; + clocks = <&isp 0>; - clock-frequency = <9600000>; + assigned-clocks = <&isp 0>; + assigned-clock-rates = <9600000>; + flash-leds = <&as3645a_flash &as3645a_indicator>; port { smia_1_1: endpoint {
diff --git a/arch/arm/boot/dts/ti/omap/omap3-n900.dts b/arch/arm/boot/dts/ti/omap/omap3-n900.dts index 7db73d9..97e9eae 100644 --- a/arch/arm/boot/dts/ti/omap/omap3-n900.dts +++ b/arch/arm/boot/dts/ti/omap/omap3-n900.dts
@@ -792,7 +792,8 @@ cam1: camera@3e { clocks = <&isp 0>; clock-names = "extclk"; - clock-frequency = <9600000>; + assigned-clocks = <&isp 0>; + assigned-clock-rates = <9600000>; reset-gpio = <&gpio4 6 GPIO_ACTIVE_HIGH>; /* 102 */
diff --git a/arch/arm/boot/dts/ti/omap/omap3-n950.dts b/arch/arm/boot/dts/ti/omap/omap3-n950.dts index b99f978..2864ed8 100644 --- a/arch/arm/boot/dts/ti/omap/omap3-n950.dts +++ b/arch/arm/boot/dts/ti/omap/omap3-n950.dts
@@ -74,8 +74,11 @@ smia_1: camera@10 { reg = <0x10>; /* No reset gpio */ vana-supply = <&vaux3>; + clocks = <&isp 0>; - clock-frequency = <9600000>; + assigned-clocks = <&isp 0>; + assigned-clock-rates = <9600000>; + flash-leds = <&as3645a_flash &as3645a_indicator>; port { smia_1_1: endpoint {
diff --git a/arch/arm/boot/dts/ti/omap/omap3-tao3530.dtsi b/arch/arm/boot/dts/ti/omap/omap3-tao3530.dtsi index 92a5846..f5bfa01 100644 --- a/arch/arm/boot/dts/ti/omap/omap3-tao3530.dtsi +++ b/arch/arm/boot/dts/ti/omap/omap3-tao3530.dtsi
@@ -145,10 +145,10 @@ OMAP3_CORE1_IOPAD(0x21ce, PIN_OUTPUT | MUX_MODE0) /* mcspi1_cs0.mcspi1_cs0 */ mcspi3_pins: mcspi3-pins { pinctrl-single,pins = < - OMAP3_CORE1_IOPAD(0x25dc, PIN_OUTPUT | MUX_MODE1) /* etk_d0.mcspi3_simo gpio14 INPUT | MODE1 */ - OMAP3_CORE1_IOPAD(0x25de, PIN_INPUT_PULLUP | MUX_MODE1) /* etk_d1.mcspi3_somi gpio15 INPUT | MODE1 */ - OMAP3_CORE1_IOPAD(0x25e0, PIN_OUTPUT | MUX_MODE1) /* etk_d2.mcspi3_cs0 gpio16 INPUT | MODE1 */ - OMAP3_CORE1_IOPAD(0x25e2, PIN_INPUT | MUX_MODE1) /* etk_d3.mcspi3_clk gpio17 INPUT | MODE1 */ + OMAP3_CORE1_IOPAD(0x25dc, PIN_OUTPUT | MUX_MODE1) /* etk_d0.mcspi3_simo gpio14 INPUT | MODE1 */ + OMAP3_CORE1_IOPAD(0x25de, PIN_INPUT_PULLUP | MUX_MODE1) /* etk_d1.mcspi3_somi gpio15 INPUT | MODE1 */ + OMAP3_CORE1_IOPAD(0x25e0, PIN_OUTPUT | MUX_MODE1) /* etk_d2.mcspi3_cs0 gpio16 INPUT | MODE1 */ + OMAP3_CORE1_IOPAD(0x25e2, PIN_INPUT | MUX_MODE1) /* etk_d3.mcspi3_clk gpio17 INPUT | MODE1 */ >; };
diff --git a/arch/arm/boot/dts/ti/omap/omap4-droid-bionic-xt875.dts b/arch/arm/boot/dts/ti/omap/omap4-droid-bionic-xt875.dts index 1d9000f..e72ac17 100644 --- a/arch/arm/boot/dts/ti/omap/omap4-droid-bionic-xt875.dts +++ b/arch/arm/boot/dts/ti/omap/omap4-droid-bionic-xt875.dts
@@ -18,6 +18,8 @@ aliases { }; &keypad { + status = "okay"; + keypad,num-rows = <8>; keypad,num-columns = <8>; linux,keymap = <
diff --git a/arch/arm/boot/dts/ti/omap/omap4-droid4-xt894.dts b/arch/arm/boot/dts/ti/omap/omap4-droid4-xt894.dts index cc3f3e1..62f87cf 100644 --- a/arch/arm/boot/dts/ti/omap/omap4-droid4-xt894.dts +++ b/arch/arm/boot/dts/ti/omap/omap4-droid4-xt894.dts
@@ -46,6 +46,8 @@ slider { }; &keypad { + status = "okay"; + keypad,num-rows = <8>; keypad,num-columns = <8>; linux,keymap = <
diff --git a/arch/arm/boot/dts/ti/omap/omap4-epson-embt2ws.dts b/arch/arm/boot/dts/ti/omap/omap4-epson-embt2ws.dts index e11d193..d519136 100644 --- a/arch/arm/boot/dts/ti/omap/omap4-epson-embt2ws.dts +++ b/arch/arm/boot/dts/ti/omap/omap4-epson-embt2ws.dts
@@ -428,6 +428,8 @@ mpu9150: imu@68 { }; &keypad { + status = "okay"; + pinctrl-names = "default"; pinctrl-0 = <&keypad_pins>; keypad,num-rows = <2>;
diff --git a/arch/arm/boot/dts/ti/omap/omap4-l4.dtsi b/arch/arm/boot/dts/ti/omap/omap4-l4.dtsi index c1afc49..00f9899 100644 --- a/arch/arm/boot/dts/ti/omap/omap4-l4.dtsi +++ b/arch/arm/boot/dts/ti/omap/omap4-l4.dtsi
@@ -1200,6 +1200,7 @@ keypad: keypad@0 { reg = <0x0 0x80>; interrupts = <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>; reg-names = "mpu"; + status = "disabled"; }; };
diff --git a/arch/arm/boot/dts/ti/omap/omap4-samsung-espresso-common.dtsi b/arch/arm/boot/dts/ti/omap/omap4-samsung-espresso-common.dtsi index 0665107..07c76a8 100644 --- a/arch/arm/boot/dts/ti/omap/omap4-samsung-espresso-common.dtsi +++ b/arch/arm/boot/dts/ti/omap/omap4-samsung-espresso-common.dtsi
@@ -16,7 +16,7 @@ reserved-memory { #size-cells = <1>; ranges; - continuous_splash: framebuffer@bef00000{ + continuous_splash: framebuffer@bef00000 { reg = <0xbef00000 (1024 * 600 * 4)>; no-map; }; @@ -117,7 +117,7 @@ reg_espresso_external: regulator-espresso-external { enable-active-high; }; - reg_touch_ldo_en: regulator-touch-ldo-en { + reg_touch_ldo_en: regulator-touch-ldo-en { compatible = "regulator-fixed"; regulator-name = "touch_ldo_en"; regulator-max-microvolt = <2800000>; @@ -153,7 +153,7 @@ button-voldown { }; }; - reg_lcd: regulator-lcd { + reg_lcd: regulator-lcd { compatible = "regulator-fixed"; regulator-name = "lcd_en"; gpios = <&gpio5 7 GPIO_ACTIVE_HIGH>; /* GPIO_135 */
diff --git a/arch/arm/boot/dts/ti/omap/omap4-sdp.dts b/arch/arm/boot/dts/ti/omap/omap4-sdp.dts index b550105..a04234b3 100644 --- a/arch/arm/boot/dts/ti/omap/omap4-sdp.dts +++ b/arch/arm/boot/dts/ti/omap/omap4-sdp.dts
@@ -531,6 +531,8 @@ &emif2 { }; &keypad { + status = "okay"; + keypad,num-rows = <8>; keypad,num-columns = <8>; linux,keymap = <0x00000012 /* KEY_E */
diff --git a/arch/arm/boot/dts/ti/omap/omap4.dtsi b/arch/arm/boot/dts/ti/omap/omap4.dtsi index 559b2bf..6ebe5f6 100644 --- a/arch/arm/boot/dts/ti/omap/omap4.dtsi +++ b/arch/arm/boot/dts/ti/omap/omap4.dtsi
@@ -590,7 +590,7 @@ target-module@2000 { #size-cells = <1>; ranges = <0 0x2000 0x1000>; - rfbi: encoder@0 { + rfbi: encoder@0 { reg = <0 0x1000>; status = "disabled"; clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>, <&l3_div_ck>; @@ -679,7 +679,7 @@ dsi2: encoder@0 { interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 8>, - <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>; + <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>; clock-names = "fck", "sys_clk"; #address-cells = <1>; @@ -716,7 +716,7 @@ hdmi: encoder@0 { interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; status = "disabled"; clocks = <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 9>, - <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>; + <&l3_dss_clkctrl OMAP4_DSS_CORE_CLKCTRL 10>; clock-names = "fck", "sys_clk"; dmas = <&sdma 76>; dma-names = "audio_tx";
diff --git a/arch/arm/boot/dts/ti/omap/omap5-l4.dtsi b/arch/arm/boot/dts/ti/omap/omap5-l4.dtsi index 72849e1..af32ca3 100644 --- a/arch/arm/boot/dts/ti/omap/omap5-l4.dtsi +++ b/arch/arm/boot/dts/ti/omap/omap5-l4.dtsi
@@ -2449,6 +2449,7 @@ target-module@c000 { /* 0x4ae1c000, ap 11 1c.0 */ keypad: keypad@0 { compatible = "ti,omap4-keypad"; reg = <0x0 0x400>; + status = "disabled"; }; }; };
diff --git a/arch/arm/boot/dts/ti/omap/omap5.dtsi b/arch/arm/boot/dts/ti/omap/omap5.dtsi index 6a66214..07159b9 100644 --- a/arch/arm/boot/dts/ti/omap/omap5.dtsi +++ b/arch/arm/boot/dts/ti/omap/omap5.dtsi
@@ -536,7 +536,7 @@ target-module@2000 { #size-cells = <1>; ranges = <0 0x2000 0x1000>; - rfbi: encoder@0 { + rfbi: encoder@0 { compatible = "ti,omap5-rfbi"; reg = <0 0x100>; status = "disabled";
diff --git a/arch/arm/boot/dts/xilinx/zynq-7000.dtsi b/arch/arm/boot/dts/xilinx/zynq-7000.dtsi index 153b8d9..715299f 100644 --- a/arch/arm/boot/dts/xilinx/zynq-7000.dtsi +++ b/arch/arm/boot/dts/xilinx/zynq-7000.dtsi
@@ -380,10 +380,10 @@ dmac_s: dma-controller@f8003000 { * "dma4", "dma5", "dma6", "dma7"; */ interrupts = <0 13 4>, - <0 14 4>, <0 15 4>, - <0 16 4>, <0 17 4>, - <0 40 4>, <0 41 4>, - <0 42 4>, <0 43 4>; + <0 14 4>, <0 15 4>, + <0 16 4>, <0 17 4>, + <0 40 4>, <0 41 4>, + <0 42 4>, <0 43 4>; #dma-cells = <1>; clocks = <&clkc 27>; clock-names = "apb_pclk";
diff --git a/arch/arm/boot/dts/xilinx/zynq-parallella.dts b/arch/arm/boot/dts/xilinx/zynq-parallella.dts index 366af4f..b465154 100644 --- a/arch/arm/boot/dts/xilinx/zynq-parallella.dts +++ b/arch/arm/boot/dts/xilinx/zynq-parallella.dts
@@ -44,10 +44,10 @@ &gem0 { ethernet_phy: ethernet-phy@0 { /* Marvell 88E1318 */ compatible = "ethernet-phy-id0141.0e90", - "ethernet-phy-ieee802.3-c22"; + "ethernet-phy-ieee802.3-c22"; reg = <0>; marvell,reg-init = <0x3 0x10 0xff00 0x1e>, - <0x3 0x11 0xfff0 0xa>; + <0x3 0x11 0xfff0 0xa>; }; };
diff --git a/arch/arm/configs/multi_v7_defconfig b/arch/arm/configs/multi_v7_defconfig index f9b8dbf..069d5a49 100644 --- a/arch/arm/configs/multi_v7_defconfig +++ b/arch/arm/configs/multi_v7_defconfig
@@ -800,6 +800,7 @@ CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y CONFIG_SOUND=m CONFIG_SND=m +CONFIG_SND_ALOOP=m CONFIG_SND_HDA_INPUT_BEEP=y CONFIG_SND_HDA_PATCH_LOADER=y CONFIG_SND_HDA_TEGRA=m @@ -1101,15 +1102,6 @@ CONFIG_CLK_TWL=m CONFIG_CLK_RASPBERRYPI=y CONFIG_COMMON_CLK_QCOM=y -CONFIG_QCOM_A53PLL=y -CONFIG_QCOM_CLK_APCS_MSM8916=y -CONFIG_QCOM_CLK_RPM=y -CONFIG_QCOM_CLK_SMD_RPM=y -CONFIG_APQ_MMCC_8084=y -CONFIG_MSM_GCC_8660=y -CONFIG_MSM_GCC_8916=y -CONFIG_MSM_MMCC_8960=y -CONFIG_MSM_MMCC_8974=y CONFIG_HWSPINLOCK=y CONFIG_HWSPINLOCK_OMAP=y CONFIG_HWSPINLOCK_QCOM=y
diff --git a/arch/arm/configs/omap2plus_defconfig b/arch/arm/configs/omap2plus_defconfig index f827f89..5791953b 100644 --- a/arch/arm/configs/omap2plus_defconfig +++ b/arch/arm/configs/omap2plus_defconfig
@@ -268,6 +268,8 @@ CONFIG_PCI_EPF_TEST=m CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y +CONFIG_FW_LOADER_COMPRESS=y +CONFIG_FW_LOADER_COMPRESS_ZSTD=y CONFIG_OMAP_OCP2SCP=y CONFIG_CONNECTOR=m CONFIG_MTD=y @@ -523,6 +525,7 @@ CONFIG_LOGO=y CONFIG_SOUND=m CONFIG_SND=m +CONFIG_SND_ALOOP=m CONFIG_SND_OSSEMUL=y CONFIG_SND_MIXER_OSS=m CONFIG_SND_PCM_OSS=m
diff --git a/arch/arm/configs/qcom_defconfig b/arch/arm/configs/qcom_defconfig index df0a0ce..cc93a32 100644 --- a/arch/arm/configs/qcom_defconfig +++ b/arch/arm/configs/qcom_defconfig
@@ -206,20 +206,6 @@ CONFIG_QCOM_BAM_DMA=y CONFIG_STAGING=y CONFIG_COMMON_CLK_QCOM=y -CONFIG_QCOM_A7PLL=y -CONFIG_QCOM_CLK_APCS_SDX55=y -CONFIG_QCOM_CLK_RPM=y -CONFIG_QCOM_CLK_SMD_RPM=y -CONFIG_QCOM_CLK_RPMH=y -CONFIG_APQ_MMCC_8084=y -CONFIG_IPQ_GCC_4019=y -CONFIG_IPQ_LCC_806X=y -CONFIG_MSM_GCC_8660=y -CONFIG_MSM_LCC_8960=y -CONFIG_MDM_LCC_9615=y -CONFIG_MSM_MMCC_8960=y -CONFIG_MSM_MMCC_8974=y -CONFIG_SDX_GCC_55=y CONFIG_HWSPINLOCK=y CONFIG_HWSPINLOCK_QCOM=y CONFIG_MAILBOX=y
diff --git a/arch/arm/configs/shmobile_defconfig b/arch/arm/configs/shmobile_defconfig index 6f9696e..cb7eddd 100644 --- a/arch/arm/configs/shmobile_defconfig +++ b/arch/arm/configs/shmobile_defconfig
@@ -48,7 +48,6 @@ CONFIG_MTD_PHYSMAP=y CONFIG_MTD_PHYSMAP_OF=y CONFIG_MTD_SPI_NOR=y -CONFIG_EEPROM_AT24=y CONFIG_BLK_DEV_SD=y CONFIG_ATA=y CONFIG_SATA_RCAR=y @@ -79,6 +78,7 @@ CONFIG_SERIAL_8250_CONSOLE=y # CONFIG_SERIAL_8250_PCI is not set # CONFIG_SERIAL_8250_EXAR is not set +# CONFIG_SERIAL_8250_MOXA_PCIE is not set CONFIG_SERIAL_8250_DW=y CONFIG_SERIAL_8250_EM=y # CONFIG_SERIAL_8250_PERICOM is not set @@ -209,6 +209,7 @@ CONFIG_PWM_RENESAS_TPU=y CONFIG_PHY_RCAR_GEN2=y CONFIG_PHY_RCAR_GEN3_USB2=y +CONFIG_EEPROM_AT24=y # CONFIG_DNOTIFY is not set CONFIG_MSDOS_FS=y CONFIG_VFAT_FS=y
diff --git a/arch/arm/crypto/aes-neonbs-glue.c b/arch/arm/crypto/aes-neonbs-glue.c index c49ddafc..f0c8bfd 100644 --- a/arch/arm/crypto/aes-neonbs-glue.c +++ b/arch/arm/crypto/aes-neonbs-glue.c
@@ -60,7 +60,7 @@ static int aesbs_setkey(struct crypto_skcipher *tfm, const u8 *in_key, unsigned int key_len) { struct aesbs_ctx *ctx = crypto_skcipher_ctx(tfm); - struct crypto_aes_ctx rk; + struct crypto_aes_ctx rk __cleanup(aes_zeroize_ctx); int err; err = aes_expandkey(&rk, in_key, key_len);
diff --git a/arch/arm/include/asm/domain.h b/arch/arm/include/asm/domain.h index d48859f..f91c2a7 100644 --- a/arch/arm/include/asm/domain.h +++ b/arch/arm/include/asm/domain.h
@@ -18,27 +18,10 @@ * DOMAIN_IO - domain 2 includes all IO only * DOMAIN_USER - domain 1 includes all user memory only * DOMAIN_KERNEL - domain 0 includes all kernel memory only - * - * The domain numbering depends on whether we support 36 physical - * address for I/O or not. Addresses above the 32 bit boundary can - * only be mapped using supersections and supersections can only - * be set for domain 0. We could just default to DOMAIN_IO as zero, - * but there may be systems with supersection support and no 36-bit - * addressing. In such cases, we want to map system memory with - * supersections to reduce TLB misses and footprint. - * - * 36-bit addressing and supersections are only available on - * CPUs based on ARMv6+ or the Intel XSC3 core. */ -#ifndef CONFIG_IO_36 #define DOMAIN_KERNEL 0 #define DOMAIN_USER 1 #define DOMAIN_IO 2 -#else -#define DOMAIN_KERNEL 2 -#define DOMAIN_USER 1 -#define DOMAIN_IO 0 -#endif #define DOMAIN_VECTORS 3 /*
diff --git a/arch/arm/include/asm/linkage.h b/arch/arm/include/asm/linkage.h index c467069..bba992f 100644 --- a/arch/arm/include/asm/linkage.h +++ b/arch/arm/include/asm/linkage.h
@@ -9,4 +9,33 @@ .type name, %function; \ END(name) +#ifdef __ASSEMBLY__ + +/* + * Variants of SYM_TYPED_START/SYM_TYPED_FUNC_START that align the + * function entry itself instead of the kCFI type hash preceding it, + * for functions whose entry point must meet an alignment requirement, + * such as the 8-byte alignment fncpy() demands of its source. + */ +#ifdef CONFIG_CFI + +#define SYM_TYPED_START_ALIGNED(name, linkage, align) \ + linkage(name) ASM_NL \ + .balign align ASM_NL \ + .fill (align) - 4, 1, 0 ASM_NL \ + __CFI_TYPE(name) ASM_NL \ + name: + +#else /* CONFIG_CFI */ + +#define SYM_TYPED_START_ALIGNED(name, linkage, align) \ + SYM_START(name, linkage, .balign align) + +#endif /* CONFIG_CFI */ + +#define SYM_TYPED_FUNC_START_ALIGNED(name, align) \ + SYM_TYPED_START_ALIGNED(name, SYM_L_GLOBAL, align) + +#endif /* __ASSEMBLY__ */ + #endif
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h index 7c2fa7d..e25749b 100644 --- a/arch/arm/include/asm/memory.h +++ b/arch/arm/include/asm/memory.h
@@ -89,9 +89,9 @@ #if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE) /* - * Allow 16MB-aligned ioremap pages + * Allow 2MB-aligned ioremap pages */ -#define IOREMAP_MAX_ORDER 24 +#define IOREMAP_MAX_ORDER 21 #endif #define VECTORS_BASE UL(0xffff0000)
diff --git a/arch/arm/include/asm/pgtable-2level-hwdef.h b/arch/arm/include/asm/pgtable-2level-hwdef.h index 556937e..3fa254a 100644 --- a/arch/arm/include/asm/pgtable-2level-hwdef.h +++ b/arch/arm/include/asm/pgtable-2level-hwdef.h
@@ -35,7 +35,6 @@ #define PMD_SECT_APX (_AT(pmdval_t, 1) << 15) /* v6 */ #define PMD_SECT_S (_AT(pmdval_t, 1) << 16) /* v6 */ #define PMD_SECT_nG (_AT(pmdval_t, 1) << 17) /* v6 */ -#define PMD_SECT_SUPER (_AT(pmdval_t, 1) << 18) /* v6 */ #define PMD_SECT_AF (_AT(pmdval_t, 0)) #define PMD_SECT_UNCACHED (_AT(pmdval_t, 0))
diff --git a/arch/arm/include/asm/pgtable-2level.h b/arch/arm/include/asm/pgtable-2level.h index 6b5392e..7e1c08f 100644 --- a/arch/arm/include/asm/pgtable-2level.h +++ b/arch/arm/include/asm/pgtable-2level.h
@@ -96,13 +96,6 @@ #define SECTION_SIZE (1UL << SECTION_SHIFT) #define SECTION_MASK (~(SECTION_SIZE-1)) -/* - * ARMv6 supersection address mask and size definitions. - */ -#define SUPERSECTION_SHIFT 24 -#define SUPERSECTION_SIZE (1UL << SUPERSECTION_SHIFT) -#define SUPERSECTION_MASK (~(SUPERSECTION_SIZE-1)) - #define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) /*
diff --git a/arch/arm/include/asm/smp.h b/arch/arm/include/asm/smp.h index 8c05a7f..84aa6a6 100644 --- a/arch/arm/include/asm/smp.h +++ b/arch/arm/include/asm/smp.h
@@ -43,7 +43,7 @@ extern void set_smp_ipi_range(int ipi_base, int nr_ipi); * Called from platform specific assembly code, this is the * secondary CPU entry point. */ -asmlinkage void secondary_start_kernel(struct task_struct *task); +asmlinkage void secondary_start_kernel(void); /*
diff --git a/arch/arm/include/asm/sparsemem.h b/arch/arm/include/asm/sparsemem.h index 421e341..6b512be 100644 --- a/arch/arm/include/asm/sparsemem.h +++ b/arch/arm/include/asm/sparsemem.h
@@ -19,7 +19,11 @@ * These can be overridden in your mach/memory.h. */ #if !defined(MAX_PHYSMEM_BITS) || !defined(SECTION_SIZE_BITS) +#ifdef CONFIG_ARM_LPAE #define MAX_PHYSMEM_BITS 36 +#else +#define MAX_PHYSMEM_BITS 32 +#endif #define SECTION_SIZE_BITS 28 #endif
diff --git a/arch/arm/kernel/cacheinfo.c b/arch/arm/kernel/cacheinfo.c index e1469b6..993c8a1 100644 --- a/arch/arm/kernel/cacheinfo.c +++ b/arch/arm/kernel/cacheinfo.c
@@ -80,19 +80,21 @@ static void ci_leaf_init(struct cacheinfo *this_leaf, this_leaf->type = type; } +static bool clidr_present(void) +{ + /* CLIDR is not present before ARMv7/v7m */ + if (cpu_architecture() < CPU_ARCH_ARMv7) + return false; + + /* Don't try reading CLIDR if CTR declares old format */ + return FIELD_GET(CTR_FORMAT_MASK, read_cpuid_cachetype()) == CTR_FORMAT_ARMV7; +} + static int detect_cache_level(unsigned int *level_p, unsigned int *leaves_p) { unsigned int ctype, level, leaves; - u32 ctr, format; - /* CLIDR is not present before ARMv7/v7m */ - if (cpu_architecture() < CPU_ARCH_ARMv7) - return -EOPNOTSUPP; - - /* Don't try reading CLIDR if CTR declares old format */ - ctr = read_cpuid_cachetype(); - format = FIELD_GET(CTR_FORMAT_MASK, ctr); - if (format != CTR_FORMAT_ARMV7) + if (!clidr_present()) return -EOPNOTSUPP; for (level = 1, leaves = 0; level <= MAX_CACHE_LEVEL; level++) { @@ -111,13 +113,6 @@ static int detect_cache_level(unsigned int *level_p, unsigned int *leaves_p) return 0; } -int early_cache_level(unsigned int cpu) -{ - struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); - - return detect_cache_level(&this_cpu_ci->num_levels, &this_cpu_ci->num_leaves); -} - int init_cache_level(unsigned int cpu) { unsigned int level, leaves; @@ -146,26 +141,32 @@ int init_cache_level(unsigned int cpu) return 0; } +int early_cache_level(unsigned int cpu) +{ + return init_cache_level(cpu); +} + int populate_cache_leaves(unsigned int cpu) { unsigned int level, idx; enum cache_type type; struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); - struct cacheinfo *this_leaf = this_cpu_ci->info_list; - unsigned int arch = cpu_architecture(); + struct cacheinfo *infos = this_cpu_ci->info_list; - /* CLIDR is not present before ARMv7/v7m */ - if (arch < CPU_ARCH_ARMv7) - return -EOPNOTSUPP; + /* The device tree can describe caches CLIDR cannot fill in. */ + if (!clidr_present()) + return -ENOENT; for (idx = 0, level = 1; level <= this_cpu_ci->num_levels && - idx < this_cpu_ci->num_leaves; idx++, level++) { + idx < this_cpu_ci->num_leaves; level++) { type = get_cache_type(level); if (type == CACHE_TYPE_SEPARATE) { - ci_leaf_init(this_leaf++, CACHE_TYPE_DATA, level); - ci_leaf_init(this_leaf++, CACHE_TYPE_INST, level); + if (idx + 1 >= this_cpu_ci->num_leaves) + break; + ci_leaf_init(&infos[idx++], CACHE_TYPE_DATA, level); + ci_leaf_init(&infos[idx++], CACHE_TYPE_INST, level); } else { - ci_leaf_init(this_leaf++, type, level); + ci_leaf_init(&infos[idx++], type, level); } }
diff --git a/arch/arm/kernel/efi.c b/arch/arm/kernel/efi.c index 6f9ec7d..c142752 100644 --- a/arch/arm/kernel/efi.c +++ b/arch/arm/kernel/efi.c
@@ -6,6 +6,7 @@ #include <linux/efi.h> #include <linux/memblock.h> #include <linux/screen_info.h> +#include <linux/sizes.h> #include <asm/efi.h> #include <asm/mach/map.h> @@ -55,6 +56,18 @@ int __init efi_create_mapping(struct mm_struct *mm, efi_memory_desc_t *md) }; /* + * Non-LPAE page tables cannot map EFI runtime regions extending + * beyond the 32-bit physical address space. + */ + if (!IS_ENABLED(CONFIG_ARM_LPAE) && + (md->phys_addr >= SZ_4G || + md->num_pages > (SZ_4G - md->phys_addr) / EFI_PAGE_SIZE)) { + pr_warn("EFI runtime region at 0x%llx exceeds 32-bit physical address space\n", + md->phys_addr); + return -ERANGE; + } + + /* * Order is important here: memory regions may have all of the * bits below set (and usually do), so we check them in order of * preference.
diff --git a/arch/arm/kernel/head-nommu.S b/arch/arm/kernel/head-nommu.S index b9d6818..f80bbfb 100644 --- a/arch/arm/kernel/head-nommu.S +++ b/arch/arm/kernel/head-nommu.S
@@ -116,6 +116,7 @@ ldr r7, __secondary_data @ reload r7 ldr sp, [r7, #12] @ set up the stack pointer ldr r0, [r7, #16] @ set up task pointer + set_current r0, r1 mov fp, #0 b secondary_start_kernel ENDPROC(secondary_startup)
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S index f22c50d..a22403a 100644 --- a/arch/arm/kernel/head.S +++ b/arch/arm/kernel/head.S
@@ -442,6 +442,7 @@ adr_l r7, secondary_data + 12 @ get secondary_data.stack ldr sp, [r7] ldr r0, [r7, #4] @ get secondary_data.task + set_current r0, r1 mov fp, #0 b secondary_start_kernel ENDPROC(__secondary_switched)
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index b5fb469..a9f4600 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c
@@ -371,12 +371,9 @@ void __noreturn arch_cpu_idle_dead(void) */ __asm__("mov sp, %0\n" " mov fp, #0\n" - " mov r0, %1\n" " b secondary_start_kernel" : - : "r" (task_stack_page(current) + THREAD_SIZE - 8), - "r" (current) - : "r0"); + : "r" (task_stack_page(current) + THREAD_SIZE - 8)); unreachable(); } @@ -397,23 +394,15 @@ static void smp_store_cpu_info(unsigned int cpuid) check_cpu_icache_size(cpuid); } -static void set_current(struct task_struct *cur) -{ - /* Set TPIDRURO */ - asm("mcr p15, 0, %0, c13, c0, 3" :: "r"(cur) : "memory"); -} - /* * This is the secondary CPU boot entry. We're using this CPUs * idle thread stack, but a set of temporary page tables. */ -asmlinkage void secondary_start_kernel(struct task_struct *task) +asmlinkage void secondary_start_kernel(void) { struct mm_struct *mm = &init_mm; unsigned int cpu; - set_current(task); - secondary_biglittle_init(); /*
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 2336ee2..e6b50cd4 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c
@@ -12,6 +12,7 @@ */ #include <linux/arch_topology.h> +#include <linux/cacheinfo.h> #include <linux/cpu.h> #include <linux/cpufreq.h> #include <linux/cpumask.h> @@ -238,8 +239,20 @@ void store_cpu_topology(unsigned int cpuid) */ void __init init_cpu_topology(void) { + int cpu, ret; + reset_cpu_topology(); smp_wmb(); parse_dt_topology(); + + for_each_possible_cpu(cpu) { + ret = fetch_cache_info(cpu); + if (!ret) + continue; + /* CPUs without a usable CLIDR return -EOPNOTSUPP. */ + if (ret != -ENOENT && ret != -EOPNOTSUPP) + pr_err("Early cacheinfo failed, ret = %d\n", ret); + return; + } }
diff --git a/arch/arm/lib/backtrace-clang.S b/arch/arm/lib/backtrace-clang.S index 290c52a..9a10828 100644 --- a/arch/arm/lib/backtrace-clang.S +++ b/arch/arm/lib/backtrace-clang.S
@@ -107,8 +107,10 @@ /* * Switches the current frame to be the frame for dump_stack. + * (Only in case of current task using current registers) */ - add frame, sp, #24 @ switch to false frame + cmp frame, fp + addeq frame, sp, #24 @ switch to false frame for_each_frame: tst frame, mask @ Check for address exceptions bne no_frame
diff --git a/arch/arm/mach-at91/pm.h b/arch/arm/mach-at91/pm.h index 50c3a42..2193e1a 100644 --- a/arch/arm/mach-at91/pm.h +++ b/arch/arm/mach-at91/pm.h
@@ -25,7 +25,7 @@ #define AT91_PM_ULP1 0x03 #define AT91_PM_BACKUP 0x04 -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ struct at91_pm_data { void __iomem *pmc; void __iomem *ramc[2];
diff --git a/arch/arm/mach-exynos/smc.h b/arch/arm/mach-exynos/smc.h index 5c30feb..5c7730f 100644 --- a/arch/arm/mach-exynos/smc.h +++ b/arch/arm/mach-exynos/smc.h
@@ -32,11 +32,11 @@ #define SMC_REG_CLASS_SFR_W (0x1 << 30) #define SMC_REG_ID_SFR_W(addr) (SMC_REG_CLASS_SFR_W | ((addr) >> 2)) -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ extern void exynos_smc(u32 cmd, u32 arg1, u32 arg2, u32 arg3); -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ /* op type for SMC_CMD_SAVE and SMC_CMD_SHUTDOWN */ #define OP_TYPE_CORE 0x0
diff --git a/arch/arm/mach-imx/hardware.h b/arch/arm/mach-imx/hardware.h index 0760fff..71f0964 100644 --- a/arch/arm/mach-imx/hardware.h +++ b/arch/arm/mach-imx/hardware.h
@@ -7,7 +7,7 @@ #ifndef __ASM_ARCH_MXC_HARDWARE_H__ #define __ASM_ARCH_MXC_HARDWARE_H__ -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include <asm/io.h> #include <soc/imx/revision.h> #endif
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c index 7f62009..58f53fb 100644 --- a/arch/arm/mach-imx/mach-imx6q.c +++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -20,26 +20,6 @@ #include "cpuidle.h" #include "hardware.h" -/* For imx6q sabrelite board: set KSZ9021RN RGMII pad skew */ -static int ksz9021rn_phy_fixup(struct phy_device *phydev) -{ - if (IS_BUILTIN(CONFIG_PHYLIB)) { - /* min rx data delay */ - phy_write(phydev, MICREL_KSZ9021_EXTREG_CTRL, - 0x8000 | MICREL_KSZ9021_RGMII_RX_DATA_PAD_SCEW); - phy_write(phydev, MICREL_KSZ9021_EXTREG_DATA_WRITE, 0x0000); - - /* max rx/tx clock delay, min rx/tx control delay */ - phy_write(phydev, MICREL_KSZ9021_EXTREG_CTRL, - 0x8000 | MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW); - phy_write(phydev, MICREL_KSZ9021_EXTREG_DATA_WRITE, 0xf0f0); - phy_write(phydev, MICREL_KSZ9021_EXTREG_CTRL, - MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW); - } - - return 0; -} - /* * fixup for PLX PEX8909 bridge to configure GPIO1-7 as output High * as they are used for slots1-7 PERST# @@ -68,14 +48,6 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8609, ventana_pciesw_early_fixup); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8606, ventana_pciesw_early_fixup); DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_PLX, 0x8604, ventana_pciesw_early_fixup); -static void __init imx6q_enet_phy_init(void) -{ - if (IS_BUILTIN(CONFIG_PHYLIB)) { - phy_register_fixup_for_uid(PHY_ID_KSZ9021, MICREL_PHY_ID_MASK, - ksz9021rn_phy_fixup); - } -} - static void __init imx6q_1588_init(void) { struct device_node *np; @@ -179,8 +151,6 @@ static void __init imx6q_init_machine(void) imx_print_silicon_rev(cpu_is_imx6dl() ? "i.MX6DL" : "i.MX6Q", imx_get_soc_revision()); - imx6q_enet_phy_init(); - of_platform_default_populate(NULL, NULL, NULL); imx_anatop_init();
diff --git a/arch/arm/mach-imx/mxc.h b/arch/arm/mach-imx/mxc.h index fe2d0f5..1d13e39 100644 --- a/arch/arm/mach-imx/mxc.h +++ b/arch/arm/mach-imx/mxc.h
@@ -16,7 +16,7 @@ #define IMX_DDR_TYPE_LPDDR2 1 -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #ifdef CONFIG_SOC_IMX6SL static inline bool cpu_is_imx6sl(void)
diff --git a/arch/arm/mach-imx/pm-imx6.c b/arch/arm/mach-imx/pm-imx6.c index a671ca4..3c73e2c 100644 --- a/arch/arm/mach-imx/pm-imx6.c +++ b/arch/arm/mach-imx/pm-imx6.c
@@ -4,6 +4,8 @@ * Copyright 2011 Linaro Ltd. */ +#include <linux/build_bug.h> +#include <linux/cfi.h> #include <linux/clk/imx.h> #include <linux/delay.h> #include <linux/init.h> @@ -18,6 +20,7 @@ #include <linux/of_platform.h> #include <linux/platform_device.h> #include <linux/regmap.h> +#include <linux/stddef.h> #include <linux/suspend.h> #include <asm/cacheflush.h> #include <asm/fncpy.h> @@ -61,9 +64,9 @@ #define MX6Q_SUSPEND_OCRAM_SIZE 0x1000 #define MX6_MAX_MMDC_IO_NUM 33 -static void __iomem *ccm_base; -static void __iomem *suspend_ocram_base; -static void (*imx6_suspend_in_ocram_fn)(void __iomem *ocram_vbase); +static void __iomem *ccm_base __ro_after_init; +static void __iomem *suspend_ocram_base __ro_after_init; +static void (*imx6_suspend_in_ocram_fn)(void __iomem *ocram_vbase) __ro_after_init; /* * suspend ocram space layout: @@ -229,8 +232,18 @@ struct imx6_cpu_pm_info { struct imx6_pm_base l2_base; u32 mmdc_io_num; /* Number of MMDC IOs which need saved/restored. */ u32 mmdc_io_val[MX6_MAX_MMDC_IO_NUM][2]; /* To save offset and value */ + u32 cfi_type; /* kCFI type hash of imx6_suspend() */ } __aligned(8); +/* + * The ocram copy of imx6_suspend() starts right after struct imx6_cpu_pm_info, + * and the CFI check on the indirect call reads the kCFI type hash from the + * four bytes preceding the function entry, so cfi_type must occupy the last + * four bytes of the struct, i.e. fit into its tail padding. + */ +static_assert(offsetofend(struct imx6_cpu_pm_info, cfi_type) == + sizeof(struct imx6_cpu_pm_info)); + void imx6_set_int_mem_clk_lpm(bool enable) { u32 val = readl_relaxed(ccm_base + CGPR); @@ -568,6 +581,13 @@ static int __init imx6q_suspend_init(const struct imx6_pm_socdata *socdata) mmdc_offset_array[i]); } + /* + * Mask out the Thumb bit, as cfi_get_func_hash() expects the + * function's actual start address. Returns 0 if CONFIG_CFI=n. + */ + pm_info->cfi_type = + cfi_get_func_hash((void *)((uintptr_t)&imx6_suspend & ~1UL)); + imx6_suspend_in_ocram_fn = fncpy( suspend_ocram_base + sizeof(*pm_info), &imx6_suspend,
diff --git a/arch/arm/mach-imx/suspend-imx6.S b/arch/arm/mach-imx/suspend-imx6.S index 63ccc2d..95d5f72 100644 --- a/arch/arm/mach-imx/suspend-imx6.S +++ b/arch/arm/mach-imx/suspend-imx6.S
@@ -3,6 +3,7 @@ * Copyright 2014 Freescale Semiconductor, Inc. */ +#include <linux/cfi_types.h> #include <linux/linkage.h> #include <asm/assembler.h> #include <asm/asm-offsets.h> @@ -148,7 +149,8 @@ .endm -ENTRY(imx6_suspend) +/* fncpy() requires an 8-byte-aligned entry; see arch/arm/include/asm/fncpy.h */ +SYM_TYPED_FUNC_START_ALIGNED(imx6_suspend, 8) ldr r1, [r0, #PM_INFO_PBASE_OFFSET] ldr r2, [r0, #PM_INFO_RESUME_ADDR_OFFSET] ldr r3, [r0, #PM_INFO_DDR_TYPE_OFFSET] @@ -329,4 +331,4 @@ resume_mmdc ret lr -ENDPROC(imx6_suspend) +SYM_FUNC_END(imx6_suspend)
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 9f60a6f..5203b5c 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig
@@ -55,7 +55,9 @@ config MACH_ARMADA_38X bool "Marvell Armada 380/385 boards" depends on ARCH_MULTI_V7 - select ARM_ERRATA_720789 + select ARM_ERRATA_754322 + select ARM_ERRATA_764319 + select ARM_ERRATA_764369 if SMP select PL310_ERRATA_753970 select ARM_GIC select ARM_GLOBAL_TIMER
diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index 7e74405..e4f4b16 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h
@@ -18,7 +18,7 @@ #include "am33xx.h" -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #define OMAP242X_CTRL_REGADDR(reg) \ OMAP2_L4_IO_ADDRESS(OMAP242X_CTRL_BASE + (reg)) #define OMAP243X_CTRL_REGADDR(reg) \ @@ -36,7 +36,7 @@ OMAP2_L4_IO_ADDRESS(OMAP343X_CTRL_BASE + (reg)) #define AM33XX_CTRL_REGADDR(reg) \ AM33XX_L4_WK_IO_ADDRESS(AM33XX_SCM_BASE + (reg)) -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ /* * As elsewhere, the "OMAP2_" prefix indicates that the macro is valid for @@ -503,7 +503,7 @@ #define FEAT_NEON_NONE 1 -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #ifdef CONFIG_ARCH_OMAP2PLUS extern u8 omap_ctrl_readb(u16 offset); extern u16 omap_ctrl_readw(u16 offset); @@ -534,7 +534,7 @@ int omap_control_init(void); #define omap_ctrl_writel(x, y) WARN_ON(1) #define omap4_ctrl_pad_writel(x, y) WARN_ON(1) #endif -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* __ARCH_ARM_MACH_OMAP2_CONTROL_H */
diff --git a/arch/arm/mach-omap2/ctrl_module_wkup_44xx.h b/arch/arm/mach-omap2/ctrl_module_wkup_44xx.h deleted file mode 100644 index 414f14d..0000000 --- a/arch/arm/mach-omap2/ctrl_module_wkup_44xx.h +++ /dev/null
@@ -1,89 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * OMAP44xx CTRL_MODULE_WKUP registers and bitfields - * - * Copyright (C) 2009-2010 Texas Instruments, Inc. - * - * Benoit Cousson (b-cousson@ti.com) - * Santosh Shilimkar (santosh.shilimkar@ti.com) - * - * This file is automatically generated from the OMAP hardware databases. - * We respectfully ask that any modifications to this file be coordinated - * with the public linux-omap@vger.kernel.org mailing list and the - * authors above to ensure that the autogeneration scripts are kept - * up-to-date with the file contents. - */ - -#ifndef __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_WKUP_44XX_H -#define __ARCH_ARM_MACH_OMAP2_CTRL_MODULE_WKUP_44XX_H - - -/* Base address */ -#define OMAP4_CTRL_MODULE_WKUP 0x4a30c000 - -/* Registers offset */ -#define OMAP4_CTRL_MODULE_WKUP_IP_REVISION 0x0000 -#define OMAP4_CTRL_MODULE_WKUP_IP_HWINFO 0x0004 -#define OMAP4_CTRL_MODULE_WKUP_IP_SYSCONFIG 0x0010 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_0 0x0460 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_1 0x0464 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_2 0x0468 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_3 0x046c -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_4 0x0470 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_5 0x0474 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_6 0x0478 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_7 0x047c -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_8 0x0480 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_9 0x0484 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_10 0x0488 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_11 0x048c -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_12 0x0490 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_13 0x0494 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_14 0x0498 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_15 0x049c -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_16 0x04a0 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_17 0x04a4 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_18 0x04a8 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_19 0x04ac -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_20 0x04b0 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_21 0x04b4 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_22 0x04b8 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_23 0x04bc -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_24 0x04c0 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_25 0x04c4 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_26 0x04c8 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_27 0x04cc -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_28 0x04d0 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_29 0x04d4 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_30 0x04d8 -#define OMAP4_CTRL_MODULE_WKUP_CONF_DEBUG_SEL_TST_31 0x04dc - -/* Registers shifts and masks */ - -/* IP_REVISION */ -#define OMAP4_IP_REV_SCHEME_SHIFT 30 -#define OMAP4_IP_REV_SCHEME_MASK (0x3 << 30) -#define OMAP4_IP_REV_FUNC_SHIFT 16 -#define OMAP4_IP_REV_FUNC_MASK (0xfff << 16) -#define OMAP4_IP_REV_RTL_SHIFT 11 -#define OMAP4_IP_REV_RTL_MASK (0x1f << 11) -#define OMAP4_IP_REV_MAJOR_SHIFT 8 -#define OMAP4_IP_REV_MAJOR_MASK (0x7 << 8) -#define OMAP4_IP_REV_CUSTOM_SHIFT 6 -#define OMAP4_IP_REV_CUSTOM_MASK (0x3 << 6) -#define OMAP4_IP_REV_MINOR_SHIFT 0 -#define OMAP4_IP_REV_MINOR_MASK (0x3f << 0) - -/* IP_HWINFO */ -#define OMAP4_IP_HWINFO_SHIFT 0 -#define OMAP4_IP_HWINFO_MASK (0xffffffff << 0) - -/* IP_SYSCONFIG */ -#define OMAP4_IP_SYSCONFIG_IDLEMODE_SHIFT 2 -#define OMAP4_IP_SYSCONFIG_IDLEMODE_MASK (0x3 << 2) - -/* CONF_DEBUG_SEL_TST_0 */ -#define OMAP4_WKUP_MODE_SHIFT 0 -#define OMAP4_WKUP_MODE_MASK (1 << 0) - -#endif
diff --git a/arch/arm/mach-omap2/soc.h b/arch/arm/mach-omap2/soc.h index 9e3dbb7..b394955 100644 --- a/arch/arm/mach-omap2/soc.h +++ b/arch/arm/mach-omap2/soc.h
@@ -19,7 +19,7 @@ #include "am33xx.h" #include "omap54xx.h" -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ #include <linux/bitops.h> #include <linux/of.h> @@ -501,4 +501,4 @@ level(__##fn); #define cpu_is_ti816x() soc_is_ti816x() #define cpu_is_ti81xx() soc_is_ti81xx() -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */
diff --git a/arch/arm/mach-omap2/sram.h b/arch/arm/mach-omap2/sram.h index 030cabc..a1d72e0 100644 --- a/arch/arm/mach-omap2/sram.h +++ b/arch/arm/mach-omap2/sram.h
@@ -3,7 +3,7 @@ * Interface for functions that need to be run in internal SRAM */ -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ extern void omap2_sram_ddr_init(u32 *slow_dll_ctrl, u32 fast_dll_ctrl, u32 base_cs, u32 force_unlock); @@ -48,7 +48,7 @@ extern void omap_push_sram_idle(void); static inline void omap_push_sram_idle(void) {} #endif /* CONFIG_PM */ -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ /* * OMAP2+: define the SRAM PA addresses.
diff --git a/arch/arm/mach-s3c/Kconfig b/arch/arm/mach-s3c/Kconfig index b365610..2e77bb4 100644 --- a/arch/arm/mach-s3c/Kconfig +++ b/arch/arm/mach-s3c/Kconfig
@@ -111,11 +111,6 @@ Compile in platform device definitions for S3C64XX's type SPI controller 0 -config SAMSUNG_DEV_KEYPAD - bool - help - Compile in platform device definitions for keypad - config SAMSUNG_DEV_PWM bool help
diff --git a/arch/arm/mach-s3c/Kconfig.s3c64xx b/arch/arm/mach-s3c/Kconfig.s3c64xx index cf59147..145d04e 100644 --- a/arch/arm/mach-s3c/Kconfig.s3c64xx +++ b/arch/arm/mach-s3c/Kconfig.s3c64xx
@@ -81,11 +81,6 @@ help Common setup code for S3C64XX with an 24bpp RGB display helper. -config S3C64XX_SETUP_KEYPAD - bool - help - Common setup code for S3C64XX KEYPAD GPIO configurations - config S3C64XX_SETUP_SDHCI_GPIO bool help @@ -113,7 +108,6 @@ select S3C64XX_DEV_SPI0 select S3C64XX_SETUP_FB_24BPP select S3C64XX_SETUP_I2C1 - select S3C64XX_SETUP_KEYPAD select S3C64XX_SETUP_SDHCI select S3C64XX_SETUP_SPI select S3C64XX_SETUP_USB_PHY @@ -124,7 +118,6 @@ select S3C_DEV_I2C1 select S3C_DEV_USB_HOST select S3C_DEV_USB_HSOTG - select SAMSUNG_DEV_KEYPAD select SAMSUNG_DEV_PWM help Machine support for the Wolfson Cragganmore S3C6410 variant.
diff --git a/arch/arm/mach-s3c/Makefile.s3c64xx b/arch/arm/mach-s3c/Makefile.s3c64xx index 61287ad..1686b1f 100644 --- a/arch/arm/mach-s3c/Makefile.s3c64xx +++ b/arch/arm/mach-s3c/Makefile.s3c64xx
@@ -32,7 +32,6 @@ obj-$(CONFIG_S3C64XX_SETUP_FB_24BPP) += setup-fb-24bpp-s3c64xx.o obj-$(CONFIG_S3C64XX_SETUP_I2C0) += setup-i2c0-s3c64xx.o obj-$(CONFIG_S3C64XX_SETUP_I2C1) += setup-i2c1-s3c64xx.o -obj-$(CONFIG_S3C64XX_SETUP_KEYPAD) += setup-keypad-s3c64xx.o obj-$(CONFIG_S3C64XX_SETUP_SDHCI_GPIO) += setup-sdhci-gpio-s3c64xx.o obj-$(CONFIG_S3C64XX_SETUP_SPI) += setup-spi-s3c64xx.o obj-$(CONFIG_S3C64XX_SETUP_USB_PHY) += setup-usb-phy-s3c64xx.o
diff --git a/arch/arm/mach-s3c/devs.c b/arch/arm/mach-s3c/devs.c index 572b156..35b98a9 100644 --- a/arch/arm/mach-s3c/devs.c +++ b/arch/arm/mach-s3c/devs.c
@@ -39,7 +39,6 @@ #include "devs.h" #include "fb.h" #include <linux/platform_data/i2c-s3c2410.h> -#include "keypad.h" #include "pwm-core.h" #include "sdhci.h" #include "usb-phy.h" @@ -265,32 +264,6 @@ void __init s3c_i2c1_set_platdata(struct s3c2410_platform_i2c *pd) } #endif /* CONFIG_S3C_DEV_I2C1 */ -/* KEYPAD */ - -#ifdef CONFIG_SAMSUNG_DEV_KEYPAD -static struct resource samsung_keypad_resources[] = { - [0] = DEFINE_RES_MEM(SAMSUNG_PA_KEYPAD, SZ_32), - [1] = DEFINE_RES_IRQ(IRQ_KEYPAD), -}; - -struct platform_device samsung_device_keypad = { - .name = "samsung-keypad", - .id = -1, - .num_resources = ARRAY_SIZE(samsung_keypad_resources), - .resource = samsung_keypad_resources, -}; - -void __init samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd) -{ - struct samsung_keypad_platdata *npd; - - npd = s3c_set_platdata(pd, sizeof(*npd), &samsung_device_keypad); - - if (!npd->cfg_gpio) - npd->cfg_gpio = samsung_keypad_cfg_gpio; -} -#endif /* CONFIG_SAMSUNG_DEV_KEYPAD */ - /* PWM Timer */ #ifdef CONFIG_SAMSUNG_DEV_PWM
diff --git a/arch/arm/mach-s3c/devs.h b/arch/arm/mach-s3c/devs.h index 21c0078..2737990 100644 --- a/arch/arm/mach-s3c/devs.h +++ b/arch/arm/mach-s3c/devs.h
@@ -39,7 +39,6 @@ extern struct platform_device s3c_device_i2c1; extern struct platform_device s3c_device_ohci; extern struct platform_device s3c_device_usb_hsotg; -extern struct platform_device samsung_device_keypad; extern struct platform_device samsung_device_pwm; /**
diff --git a/arch/arm/mach-s3c/gpio-core.h b/arch/arm/mach-s3c/gpio-core.h index 6801c85..464b0d0 100644 --- a/arch/arm/mach-s3c/gpio-core.h +++ b/arch/arm/mach-s3c/gpio-core.h
@@ -14,6 +14,8 @@ #include "gpio-samsung.h" #include <linux/gpio/driver.h> +struct software_node; + #define GPIOCON_OFF (0x00) #define GPIODAT_OFF (0x04) @@ -66,6 +68,7 @@ struct samsung_gpio_cfg; */ struct samsung_gpio_chip { struct gpio_chip chip; + const struct software_node *swnode; struct samsung_gpio_cfg *config; struct samsung_gpio_pm *pm; void __iomem *base;
diff --git a/arch/arm/mach-s3c/gpio-samsung-s3c64xx.h b/arch/arm/mach-s3c/gpio-samsung-s3c64xx.h index 8ed144a..fc21d3f 100644 --- a/arch/arm/mach-s3c/gpio-samsung-s3c64xx.h +++ b/arch/arm/mach-s3c/gpio-samsung-s3c64xx.h
@@ -13,6 +13,8 @@ #ifdef CONFIG_GPIO_SAMSUNG +#include <linux/property.h> + /* GPIO bank sizes */ #define S3C64XX_GPIO_A_NR (8) #define S3C64XX_GPIO_B_NR (7) @@ -89,6 +91,9 @@ enum s3c_gpio_number { /* define the number of gpios we need to the one after the GPQ() range */ #define GPIO_BOARD_START (S3C64XX_GPQ(S3C64XX_GPIO_Q_NR) + 1) +extern const struct software_node samsung_gpiochip_nodes[]; +#define SAMSUNG_GPIO_NODE(node) (&samsung_gpiochip_nodes[(node) - 'A']) + #endif /* GPIO_SAMSUNG */ #endif /* GPIO_SAMSUNG_S3C64XX_H */
diff --git a/arch/arm/mach-s3c/gpio-samsung.c b/arch/arm/mach-s3c/gpio-samsung.c index 81e198e..b35cf62 100644 --- a/arch/arm/mach-s3c/gpio-samsung.c +++ b/arch/arm/mach-s3c/gpio-samsung.c
@@ -37,6 +37,28 @@ #include "gpio-cfg-helpers.h" #include "pm.h" +const struct software_node samsung_gpiochip_nodes[] = { + SOFTWARE_NODE("GPA", NULL, NULL), + SOFTWARE_NODE("GPB", NULL, NULL), + SOFTWARE_NODE("GPC", NULL, NULL), + SOFTWARE_NODE("GPD", NULL, NULL), + SOFTWARE_NODE("GPE", NULL, NULL), + SOFTWARE_NODE("GPF", NULL, NULL), + SOFTWARE_NODE("GPG", NULL, NULL), + SOFTWARE_NODE("GPH", NULL, NULL), + SOFTWARE_NODE("GPI", NULL, NULL), + SOFTWARE_NODE("GPJ", NULL, NULL), + SOFTWARE_NODE("GPK", NULL, NULL), + SOFTWARE_NODE("GPL", NULL, NULL), + SOFTWARE_NODE("GPM", NULL, NULL), + SOFTWARE_NODE("GPN", NULL, NULL), + SOFTWARE_NODE("GPO", NULL, NULL), + SOFTWARE_NODE("GPP", NULL, NULL), + SOFTWARE_NODE("GPQ", NULL, NULL), +}; + +#define NUM_SAMSUNG_GPIOCHIPS ARRAY_SIZE(samsung_gpiochip_nodes) + static int samsung_gpio_setpull_updown(struct samsung_gpio_chip *chip, unsigned int off, samsung_gpio_pull_t pull) { @@ -491,6 +513,16 @@ static __init void s3c_gpiolib_track(struct samsung_gpio_chip *chip) } #endif /* CONFIG_S3C_GPIO_TRACK */ +static void __init samsung_setup_gpiochip_nodes(void) +{ + const struct software_node *group[NUM_SAMSUNG_GPIOCHIPS + 1] = { 0 }; + + for (unsigned int i = 0; i < NUM_SAMSUNG_GPIOCHIPS; i++) + group[i] = &samsung_gpiochip_nodes[i]; + + software_node_register_node_group(group); +} + /* * samsung_gpiolib_add() - add the Samsung gpio_chip. * @chip: The chip to register @@ -506,12 +538,16 @@ static void __init samsung_gpiolib_add(struct samsung_gpio_chip *chip) struct gpio_chip *gc = &chip->chip; int ret; + gc->label = chip->swnode->name; + BUG_ON(!chip->base); BUG_ON(!gc->label); BUG_ON(!gc->ngpio); spin_lock_init(&chip->lock); + gc->fwnode = software_node_fwnode(chip->swnode); + if (!gc->direction_input) gc->direction_input = samsung_gpiolib_2bit_input; if (!gc->direction_output) @@ -659,49 +695,49 @@ static struct samsung_gpio_chip s3c64xx_gpios_4bit[] = { .chip = { .base = S3C64XX_GPA(0), .ngpio = S3C64XX_GPIO_A_NR, - .label = "GPA", }, + .swnode = SAMSUNG_GPIO_NODE('A'), }, { .chip = { .base = S3C64XX_GPB(0), .ngpio = S3C64XX_GPIO_B_NR, - .label = "GPB", }, + .swnode = SAMSUNG_GPIO_NODE('B'), }, { .chip = { .base = S3C64XX_GPC(0), .ngpio = S3C64XX_GPIO_C_NR, - .label = "GPC", }, + .swnode = SAMSUNG_GPIO_NODE('C'), }, { .chip = { .base = S3C64XX_GPD(0), .ngpio = S3C64XX_GPIO_D_NR, - .label = "GPD", }, + .swnode = SAMSUNG_GPIO_NODE('D'), }, { .config = &samsung_gpio_cfgs[0], .chip = { .base = S3C64XX_GPE(0), .ngpio = S3C64XX_GPIO_E_NR, - .label = "GPE", }, + .swnode = SAMSUNG_GPIO_NODE('E'), }, { .base = S3C64XX_GPG_BASE, .chip = { .base = S3C64XX_GPG(0), .ngpio = S3C64XX_GPIO_G_NR, - .label = "GPG", }, + .swnode = SAMSUNG_GPIO_NODE('G'), }, { .base = S3C64XX_GPM_BASE, .config = &samsung_gpio_cfgs[1], .chip = { .base = S3C64XX_GPM(0), .ngpio = S3C64XX_GPIO_M_NR, - .label = "GPM", .to_irq = s3c64xx_gpiolib_mbank_to_irq, }, + .swnode = SAMSUNG_GPIO_NODE('M'), }, }; @@ -711,25 +747,25 @@ static struct samsung_gpio_chip s3c64xx_gpios_4bit2[] = { .chip = { .base = S3C64XX_GPH(0), .ngpio = S3C64XX_GPIO_H_NR, - .label = "GPH", }, + .swnode = SAMSUNG_GPIO_NODE('H'), }, { .base = S3C64XX_GPK_BASE + 0x4, .config = &samsung_gpio_cfgs[0], .chip = { .base = S3C64XX_GPK(0), .ngpio = S3C64XX_GPIO_K_NR, - .label = "GPK", }, + .swnode = SAMSUNG_GPIO_NODE('K'), }, { .base = S3C64XX_GPL_BASE + 0x4, .config = &samsung_gpio_cfgs[1], .chip = { .base = S3C64XX_GPL(0), .ngpio = S3C64XX_GPIO_L_NR, - .label = "GPL", .to_irq = s3c64xx_gpiolib_lbank_to_irq, }, + .swnode = SAMSUNG_GPIO_NODE('L'), }, }; @@ -740,43 +776,43 @@ static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = { .chip = { .base = S3C64XX_GPF(0), .ngpio = S3C64XX_GPIO_F_NR, - .label = "GPF", }, + .swnode = SAMSUNG_GPIO_NODE('F'), }, { .config = &samsung_gpio_cfgs[7], .chip = { .base = S3C64XX_GPI(0), .ngpio = S3C64XX_GPIO_I_NR, - .label = "GPI", }, + .swnode = SAMSUNG_GPIO_NODE('I'), }, { .config = &samsung_gpio_cfgs[7], .chip = { .base = S3C64XX_GPJ(0), .ngpio = S3C64XX_GPIO_J_NR, - .label = "GPJ", }, + .swnode = SAMSUNG_GPIO_NODE('J'), }, { .config = &samsung_gpio_cfgs[6], .chip = { .base = S3C64XX_GPO(0), .ngpio = S3C64XX_GPIO_O_NR, - .label = "GPO", }, + .swnode = SAMSUNG_GPIO_NODE('O'), }, { .config = &samsung_gpio_cfgs[6], .chip = { .base = S3C64XX_GPP(0), .ngpio = S3C64XX_GPIO_P_NR, - .label = "GPP", }, + .swnode = SAMSUNG_GPIO_NODE('P'), }, { .config = &samsung_gpio_cfgs[6], .chip = { .base = S3C64XX_GPQ(0), .ngpio = S3C64XX_GPIO_Q_NR, - .label = "GPQ", }, + .swnode = SAMSUNG_GPIO_NODE('Q'), }, { .base = S3C64XX_GPN_BASE, .irq_base = IRQ_EINT(0), @@ -784,9 +820,9 @@ static struct samsung_gpio_chip s3c64xx_gpios_2bit[] = { .chip = { .base = S3C64XX_GPN(0), .ngpio = S3C64XX_GPIO_N_NR, - .label = "GPN", .to_irq = samsung_gpiolib_to_irq, }, + .swnode = SAMSUNG_GPIO_NODE('N'), }, }; @@ -803,6 +839,8 @@ static __init int samsung_gpiolib_init(void) return 0; if (soc_is_s3c64xx()) { + samsung_setup_gpiochip_nodes(); + samsung_gpiolib_set_cfg(samsung_gpio_cfgs, ARRAY_SIZE(samsung_gpio_cfgs)); samsung_gpiolib_add_2bit_chips(s3c64xx_gpios_2bit,
diff --git a/arch/arm/mach-s3c/keypad.h b/arch/arm/mach-s3c/keypad.h deleted file mode 100644 index 9754b9a..0000000 --- a/arch/arm/mach-s3c/keypad.h +++ /dev/null
@@ -1,27 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Samsung Platform - Keypad platform data definitions - * - * Copyright (C) 2010 Samsung Electronics Co.Ltd - * Author: Joonyoung Shim <jy0922.shim@samsung.com> - */ - -#ifndef __PLAT_SAMSUNG_KEYPAD_H -#define __PLAT_SAMSUNG_KEYPAD_H - -#include <linux/input/samsung-keypad.h> - -/** - * samsung_keypad_set_platdata - Set platform data for Samsung Keypad device. - * @pd: Platform data to register to device. - * - * Register the given platform data for use with Samsung Keypad device. - * The call will copy the platform data, so the board definitions can - * make the structure itself __initdata. - */ -extern void samsung_keypad_set_platdata(struct samsung_keypad_platdata *pd); - -/* defined by architecture to configure gpio. */ -extern void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols); - -#endif /* __PLAT_SAMSUNG_KEYPAD_H */
diff --git a/arch/arm/mach-s3c/mach-crag6410.c b/arch/arm/mach-s3c/mach-crag6410.c index 5717671..2264bee 100644 --- a/arch/arm/mach-s3c/mach-crag6410.c +++ b/arch/arm/mach-s3c/mach-crag6410.c
@@ -15,13 +15,16 @@ #include <linux/io.h> #include <linux/init.h> #include <linux/input-event-codes.h> +#include <linux/input/matrix_keypad.h> #include <linux/gpio/legacy.h> #include <linux/gpio/machine.h> +#include <linux/gpio/property.h> #include <linux/leds.h> #include <linux/delay.h> #include <linux/mmc/host.h> #include <linux/regulator/machine.h> #include <linux/regulator/fixed.h> +#include <linux/property.h> #include <linux/pwm.h> #include <linux/pwm_backlight.h> #include <linux/dm9000.h> @@ -53,7 +56,6 @@ #include "gpio-cfg.h" #include <linux/platform_data/spi-s3c64xx.h> -#include "keypad.h" #include "devs.h" #include "cpu.h" #include <linux/platform_data/i2c-s3c2410.h> @@ -176,7 +178,7 @@ static struct s3c_fb_platdata crag6410_lcd_pdata = { /* 2x6 keypad */ -static uint32_t crag6410_keymap[] = { +static const u32 crag6410_keymap[] __initconst = { /* KEY(row, col, keycode) */ KEY(0, 0, KEY_VOLUMEUP), KEY(0, 1, KEY_HOME), @@ -192,43 +194,103 @@ static uint32_t crag6410_keymap[] = { KEY(1, 5, KEY_CAMERA), }; -static struct matrix_keymap_data crag6410_keymap_data = { - .keymap = crag6410_keymap, - .keymap_size = ARRAY_SIZE(crag6410_keymap), +static const struct property_entry crag6410_keypad_props[] __initconst = { + PROPERTY_ENTRY_U32("keypad,num-columns", 6), + PROPERTY_ENTRY_U32("keypad,num-rows", 2), + PROPERTY_ENTRY_U32_ARRAY("linux,keymap", crag6410_keymap), + { } }; -static struct samsung_keypad_platdata crag6410_keypad_data = { - .keymap_data = &crag6410_keymap_data, - .rows = 2, - .cols = 6, +static const struct resource crag6410_keypad_resources[] __initconst = { + [0] = DEFINE_RES_MEM(SAMSUNG_PA_KEYPAD, SZ_32), + [1] = DEFINE_RES_IRQ(IRQ_KEYPAD), }; -static struct gpio_keys_button crag6410_gpio_keys[] = { - [0] = { - .code = KEY_SUSPEND, - .gpio = S3C64XX_GPL(10), /* EINT 18 */ - .type = EV_KEY, - .wakeup = 1, - .active_low = 1, - }, - [1] = { - .code = SW_FRONT_PROXIMITY, - .gpio = S3C64XX_GPN(11), /* EINT 11 */ - .type = EV_SW, - }, +static const struct platform_device_info crag6410_keypad_info __initconst = { + .name = "samsung-keypad", + .id = PLATFORM_DEVID_NONE, + .res = crag6410_keypad_resources, + .num_res = ARRAY_SIZE(crag6410_keypad_resources), + .properties = crag6410_keypad_props, }; -static struct gpio_keys_platform_data crag6410_gpio_keydata = { - .buttons = crag6410_gpio_keys, - .nbuttons = ARRAY_SIZE(crag6410_gpio_keys), +static void __init crag6410_setup_keypad(void) +{ + struct platform_device *pd; + + /* Set all the necessary GPK pins to special-function 3: KP_ROW[x] */ + s3c_gpio_cfgrange_nopull(S3C64XX_GPK(8), 2, S3C_GPIO_SFN(3)); + + /* Set all the necessary GPL pins to special-function 3: KP_COL[x] */ + s3c_gpio_cfgrange_nopull(S3C64XX_GPL(0), 6, S3C_GPIO_SFN(3)); + + pd = platform_device_register_full(&crag6410_keypad_info); + if (IS_ERR(pd)) + pr_err("failed to instantiate keypad device\n"); +} + +static const struct software_node crag6410_gpio_keys_node = { + .name = "crag6410-gpio-keys", }; -static struct platform_device crag6410_gpio_keydev = { - .name = "gpio-keys", - .id = 0, - .dev.platform_data = &crag6410_gpio_keydata, +static const struct property_entry crag6410_suspend_key_props[] = { + PROPERTY_ENTRY_U32("linux,code", KEY_SUSPEND), + PROPERTY_ENTRY_GPIO("gpios", + SAMSUNG_GPIO_NODE('L'), 10, /* EINT 18 */ + GPIO_ACTIVE_LOW), + PROPERTY_ENTRY_BOOL("wakeup-source"), + { } }; +static const struct software_node crag6410_suspend_key_node = { + .parent = &crag6410_gpio_keys_node, + .properties = crag6410_suspend_key_props, +}; + +static const struct property_entry crag6410_prox_sw_props[] = { + PROPERTY_ENTRY_U32("linux,input-type", EV_SW), + PROPERTY_ENTRY_U32("linux,code", SW_FRONT_PROXIMITY), + PROPERTY_ENTRY_GPIO("gpios", + SAMSUNG_GPIO_NODE('N'), 11, /* EINT 11 */ + GPIO_ACTIVE_HIGH), + { } +}; + +static const struct software_node crag6410_prox_sw_node = { + .parent = &crag6410_gpio_keys_node, + .properties = crag6410_prox_sw_props, +}; + +static const struct software_node *crag6410_gpio_keys_swnodes[] = { + &crag6410_gpio_keys_node, + &crag6410_suspend_key_node, + &crag6410_prox_sw_node, + NULL +}; + +static void __init crag6410_setup_gpio_keys(void) +{ + struct platform_device_info keys_info = { + .name = "gpio-keys", + .id = 0, + }; + struct platform_device *pd; + int err; + + err = software_node_register_node_group(crag6410_gpio_keys_swnodes); + if (err) { + pr_err("failed to register gpio-keys software nodes: %d\n", err); + return; + } + + keys_info.fwnode = software_node_fwnode(&crag6410_gpio_keys_node); + + pd = platform_device_register_full(&keys_info); + err = PTR_ERR_OR_ZERO(pd); + if (err) + pr_err("failed to create gpio-keys device: %d\n", err); +} + static struct resource crag6410_dm9k_resource[] = { [0] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN5, 2), [1] = DEFINE_RES_MEM(S3C64XX_PA_XM0CSN5 + (1 << 8), 2), @@ -361,7 +423,7 @@ static struct platform_device wallvdd_device = { }, }; -static struct platform_device *crag6410_devices[] __initdata = { +static struct platform_device *crag6410_devs0[] __initdata = { &s3c_device_hsmmc0, &s3c_device_hsmmc2, &s3c_device_i2c0, @@ -372,8 +434,9 @@ static struct platform_device *crag6410_devices[] __initdata = { &samsung_device_pwm, &s3c64xx_device_iis0, &s3c64xx_device_iis1, - &samsung_device_keypad, - &crag6410_gpio_keydev, +}; + +static struct platform_device *crag6410_devs1[] __initdata = { &crag6410_dm9k_device, &s3c64xx_device_spi0, &crag6410_lcd_powerdev, @@ -873,16 +936,18 @@ static void __init crag6410_machine_init(void) gpiod_add_lookup_table(&crag_wm1250_ev1_gpiod_table); i2c_register_board_info(1, i2c_devs1, ARRAY_SIZE(i2c_devs1)); - samsung_keypad_set_platdata(&crag6410_keypad_data); - gpiod_add_lookup_table(&crag_spi0_gpiod_table); s3c64xx_spi0_set_platdata(0, 2); pwm_add_table(crag6410_pwm_lookup, ARRAY_SIZE(crag6410_pwm_lookup)); - platform_add_devices(crag6410_devices, ARRAY_SIZE(crag6410_devices)); + platform_add_devices(crag6410_devs0, ARRAY_SIZE(crag6410_devs0)); platform_device_register_full(&crag6410_mmgpio_devinfo); gpiod_add_lookup_table(&crag_leds_table); + crag6410_setup_keypad(); + crag6410_setup_gpio_keys(); + + platform_add_devices(crag6410_devs1, ARRAY_SIZE(crag6410_devs1)); gpio_led_register_device(-1, &gpio_leds_pdata); regulator_has_full_constraints();
diff --git a/arch/arm/mach-s3c/setup-keypad-s3c64xx.c b/arch/arm/mach-s3c/setup-keypad-s3c64xx.c deleted file mode 100644 index 2e13678..0000000 --- a/arch/arm/mach-s3c/setup-keypad-s3c64xx.c +++ /dev/null
@@ -1,20 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// Copyright (c) 2010 Samsung Electronics Co., Ltd. -// http://www.samsung.com/ -// -// GPIO configuration for S3C64XX KeyPad device - -#include <linux/gpio/consumer.h> -#include "gpio-cfg.h" -#include "keypad.h" -#include "gpio-samsung.h" - -void samsung_keypad_cfg_gpio(unsigned int rows, unsigned int cols) -{ - /* Set all the necessary GPK pins to special-function 3: KP_ROW[x] */ - s3c_gpio_cfgrange_nopull(S3C64XX_GPK(8), rows, S3C_GPIO_SFN(3)); - - /* Set all the necessary GPL pins to special-function 3: KP_COL[x] */ - s3c_gpio_cfgrange_nopull(S3C64XX_GPL(0), cols, S3C_GPIO_SFN(3)); -}
diff --git a/arch/arm/mach-tegra/sleep.S b/arch/arm/mach-tegra/sleep.S index 945f2c1..751cc71 100644 --- a/arch/arm/mach-tegra/sleep.S +++ b/arch/arm/mach-tegra/sleep.S
@@ -48,7 +48,7 @@ blne v7_flush_dcache_louis bleq v7_flush_dcache_all - /* Trun off coherency */ + /* Turn off coherency */ exit_smp r4, r5 ldmfd sp!, {r0, r4-r5, r7, r9-r11, pc}
diff --git a/arch/arm/mach-versatile/platsmp-vexpress.c b/arch/arm/mach-versatile/platsmp-vexpress.c index 1ee3c45..b810ad5 100644 --- a/arch/arm/mach-versatile/platsmp-vexpress.c +++ b/arch/arm/mach-versatile/platsmp-vexpress.c
@@ -61,8 +61,8 @@ static const struct of_device_id vexpress_smp_dt_scu_match[] __initconst = { static void __init vexpress_smp_dt_prepare_cpus(unsigned int max_cpus) { - struct device_node *scu = of_find_matching_node(NULL, - vexpress_smp_dt_scu_match); + struct device_node *scu __free(device_node) = + of_find_matching_node(NULL, vexpress_smp_dt_scu_match); if (scu) scu_enable(of_iomap(scu, 0));
diff --git a/arch/arm/mach-versatile/v2m.c b/arch/arm/mach-versatile/v2m.c index 79afdf2..c86b383 100644 --- a/arch/arm/mach-versatile/v2m.c +++ b/arch/arm/mach-versatile/v2m.c
@@ -13,8 +13,8 @@ void vexpress_flags_set(u32 data) static void __iomem *base; if (!base) { - struct device_node *node = of_find_compatible_node(NULL, NULL, - "arm,vexpress-sysreg"); + struct device_node *node __free(device_node) = + of_find_compatible_node(NULL, NULL, "arm,vexpress-sysreg"); base = of_iomap(node, 0); }
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig index 6574659..41d7b49 100644 --- a/arch/arm/mm/Kconfig +++ b/arch/arm/mm/Kconfig
@@ -328,7 +328,6 @@ select CPU_PABRT_LEGACY select CPU_THUMB_CAPABLE select CPU_TLB_V4WBI if MMU - select IO_36 # Marvell PJ1 (Mohawk) config CPU_MOHAWK @@ -676,12 +675,6 @@ If unsure, keep default value. -# -# CPU supports 36-bit I/O -# -config IO_36 - bool - comment "Processor Features" config ARM_LPAE
diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c index 812380f..f6c1e6b 100644 --- a/arch/arm/mm/alignment.c +++ b/arch/arm/mm/alignment.c
@@ -341,6 +341,8 @@ static int do_alignment_ldrhstrh(unsigned long addr, u32 instr, struct pt_regs *regs) { unsigned int rd = RD_BITS(instr); + unsigned int ua_flags; + bool ua_saved = false; ai_half += 1; @@ -364,10 +366,11 @@ do_alignment_ldrhstrh(unsigned long addr, u32 instr, struct pt_regs *regs) user: if (LDST_L_BIT(instr)) { unsigned long val; - unsigned int __ua_flags = uaccess_save_and_enable(); + ua_flags = uaccess_save_and_enable(); + ua_saved = true; get16t_unaligned_check(val, addr); - uaccess_restore(__ua_flags); + uaccess_restore(ua_flags); /* signed half-word? */ if (instr & 0x40) @@ -375,14 +378,17 @@ do_alignment_ldrhstrh(unsigned long addr, u32 instr, struct pt_regs *regs) regs->uregs[rd] = val; } else { - unsigned int __ua_flags = uaccess_save_and_enable(); + ua_flags = uaccess_save_and_enable(); + ua_saved = true; put16t_unaligned_check(regs->uregs[rd], addr); - uaccess_restore(__ua_flags); + uaccess_restore(ua_flags); } return TYPE_LDST; fault: + if (ua_saved) + uaccess_restore(ua_flags); return TYPE_FAULT; } @@ -391,6 +397,8 @@ do_alignment_ldrdstrd(unsigned long addr, u32 instr, struct pt_regs *regs) { unsigned int rd = RD_BITS(instr); unsigned int rd2; + unsigned int ua_flags; + bool ua_saved = false; int load; if ((instr & 0xfe000000) == 0xe8000000) { @@ -425,26 +433,30 @@ do_alignment_ldrdstrd(unsigned long addr, u32 instr, struct pt_regs *regs) user: if (load) { unsigned long val, val2; - unsigned int __ua_flags = uaccess_save_and_enable(); + ua_flags = uaccess_save_and_enable(); + ua_saved = true; get32t_unaligned_check(val, addr); get32t_unaligned_check(val2, addr + 4); - uaccess_restore(__ua_flags); + uaccess_restore(ua_flags); regs->uregs[rd] = val; regs->uregs[rd2] = val2; } else { - unsigned int __ua_flags = uaccess_save_and_enable(); + ua_flags = uaccess_save_and_enable(); + ua_saved = true; put32t_unaligned_check(regs->uregs[rd], addr); put32t_unaligned_check(regs->uregs[rd2], addr + 4); - uaccess_restore(__ua_flags); + uaccess_restore(ua_flags); } return TYPE_LDST; bad: return TYPE_ERROR; fault: + if (ua_saved) + uaccess_restore(ua_flags); return TYPE_FAULT; } @@ -452,6 +464,8 @@ static int do_alignment_ldrstr(unsigned long addr, u32 instr, struct pt_regs *regs) { unsigned int rd = RD_BITS(instr); + unsigned int ua_flags; + bool ua_saved = false; ai_word += 1; @@ -469,18 +483,22 @@ do_alignment_ldrstr(unsigned long addr, u32 instr, struct pt_regs *regs) trans: if (LDST_L_BIT(instr)) { unsigned int val; - unsigned int __ua_flags = uaccess_save_and_enable(); + ua_flags = uaccess_save_and_enable(); + ua_saved = true; get32t_unaligned_check(val, addr); - uaccess_restore(__ua_flags); + uaccess_restore(ua_flags); regs->uregs[rd] = val; } else { - unsigned int __ua_flags = uaccess_save_and_enable(); + ua_flags = uaccess_save_and_enable(); + ua_saved = true; put32t_unaligned_check(regs->uregs[rd], addr); - uaccess_restore(__ua_flags); + uaccess_restore(ua_flags); } return TYPE_LDST; fault: + if (ua_saved) + uaccess_restore(ua_flags); return TYPE_FAULT; } @@ -502,6 +520,8 @@ do_alignment_ldmstm(unsigned long addr, u32 instr, struct pt_regs *regs) { unsigned int rd, rn, correction, nr_regs, regbits; unsigned long eaddr, newaddr; + unsigned int ua_flags; + bool ua_saved = false; if (LDM_S_BIT(instr)) goto bad; @@ -547,7 +567,8 @@ do_alignment_ldmstm(unsigned long addr, u32 instr, struct pt_regs *regs) #endif if (user_mode(regs)) { - unsigned int __ua_flags = uaccess_save_and_enable(); + ua_flags = uaccess_save_and_enable(); + ua_saved = true; for (regbits = REGMASK_BITS(instr), rd = 0; regbits; regbits >>= 1, rd += 1) if (regbits & 1) { @@ -559,7 +580,7 @@ do_alignment_ldmstm(unsigned long addr, u32 instr, struct pt_regs *regs) put32t_unaligned_check(regs->uregs[rd], eaddr); eaddr += 4; } - uaccess_restore(__ua_flags); + uaccess_restore(ua_flags); } else { for (regbits = REGMASK_BITS(instr), rd = 0; regbits; regbits >>= 1, rd += 1) @@ -581,6 +602,8 @@ do_alignment_ldmstm(unsigned long addr, u32 instr, struct pt_regs *regs) return TYPE_DONE; fault: + if (ua_saved) + uaccess_restore(ua_flags); regs->ARM_pc -= correction; return TYPE_FAULT; @@ -892,11 +915,17 @@ do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs) break; case SHIFT_LSR: - offset.un >>= shiftval; + if (shiftval == 0) + offset.un = 0; + else + offset.un >>= shiftval; break; case SHIFT_ASR: - offset.sn >>= shiftval; + if (shiftval == 0) + offset.sn >>= 31; + else + offset.sn >>= shiftval; break; case SHIFT_RORRRX:
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c index 4204ffa..7c4e1e4 100644 --- a/arch/arm/mm/context.c +++ b/arch/arm/mm/context.c
@@ -238,7 +238,7 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk) { unsigned long flags; unsigned int cpu = smp_processor_id(); - u64 asid; + u64 asid, old_active_asid; check_vmalloc_seq(mm); @@ -250,8 +250,17 @@ void check_and_switch_context(struct mm_struct *mm, struct task_struct *tsk) cpu_set_reserved_ttbr0(); asid = atomic64_read(&mm->context.id); - if (!((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS) - && atomic64_xchg(&per_cpu(active_asids, cpu), asid)) + + /* + * If our active_asids is zero, we are racing with an ASID roll-over + * on a different CPU, so skip the update (using cmpxchg if non-zero) + * and take the slow path. + */ + old_active_asid = atomic64_read(&per_cpu(active_asids, cpu)); + if (old_active_asid && + !((asid ^ atomic64_read(&asid_generation)) >> ASID_BITS) && + atomic64_cmpxchg(&per_cpu(active_asids, cpu), + old_active_asid, asid)) goto switch_mm_fastpath; raw_spin_lock_irqsave(&cpu_asid_lock, flags);
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index 7761099..fb2eb0e 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c
@@ -1056,7 +1056,10 @@ static void *__iommu_alloc_simple(struct device *dev, size_t size, gfp_t gfp, return addr; err_mapping: - __free_from_pool(addr, size); + if (coherent_flag == COHERENT) + __dma_free_buffer(virt_to_page(addr), size); + else + __free_from_pool(addr, size); return NULL; }
diff --git a/arch/arm/mm/ioremap.c b/arch/arm/mm/ioremap.c index 27e64f7..539b6c2 100644 --- a/arch/arm/mm/ioremap.c +++ b/arch/arm/mm/ioremap.c
@@ -30,8 +30,6 @@ #include <linux/sizes.h> #include <linux/memblock.h> -#include <asm/cp15.h> -#include <asm/cputype.h> #include <asm/cacheflush.h> #include <asm/early_ioremap.h> #include <asm/mmu_context.h> @@ -236,39 +234,6 @@ remap_area_sections(unsigned long virt, unsigned long pfn, return 0; } -static int -remap_area_supersections(unsigned long virt, unsigned long pfn, - size_t size, const struct mem_type *type) -{ - unsigned long addr = virt, end = virt + size; - pmd_t *pmd = pmd_off_k(addr); - - /* - * Remove and free any PTE-based mapping, and - * sync the current kernel mapping. - */ - unmap_area_sections(virt, size); - do { - unsigned long super_pmd_val, i; - - super_pmd_val = __pfn_to_phys(pfn) | type->prot_sect | - PMD_SECT_SUPER; - super_pmd_val |= ((pfn >> (32 - PAGE_SHIFT)) & 0xf) << 20; - - for (i = 0; i < 8; i++) { - pmd[0] = __pmd(super_pmd_val); - pmd[1] = __pmd(super_pmd_val); - flush_pmd_entry(pmd); - - addr += PMD_SIZE; - pmd += 2; - } - - pfn += SUPERSECTION_SIZE >> PAGE_SHIFT; - } while (addr < end); - - return 0; -} #endif static void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn, @@ -278,15 +243,17 @@ static void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn, int err; unsigned long addr; struct vm_struct *area; - phys_addr_t paddr = __pfn_to_phys(pfn); + phys_addr_t paddr; #ifndef CONFIG_ARM_LPAE /* - * High mappings must be supersection aligned + * The physical range must not extend beyond the 32-bit + * phys_addr_t */ - if (pfn >= 0x100000 && (paddr & ~SUPERSECTION_MASK)) + if (((u64)pfn << PAGE_SHIFT) + offset + size > SZ_4G) return NULL; #endif + paddr = __pfn_to_phys(pfn); type = get_mem_type(mtype); if (!type) @@ -300,7 +267,7 @@ static void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn, /* * Try to reuse one of the static mapping whenever possible. */ - if (size && !(sizeof(phys_addr_t) == 4 && pfn >= 0x100000)) { + if (size) { struct static_vm *svm; svm = find_static_vm_paddr(paddr, size, mtype); @@ -326,13 +293,7 @@ static void __iomem * __arm_ioremap_pfn_caller(unsigned long pfn, area->phys_addr = paddr; #if !defined(CONFIG_SMP) && !defined(CONFIG_ARM_LPAE) - if (DOMAIN_IO == 0 && - (((cpu_architecture() >= CPU_ARCH_ARMv6) && (get_cr() & CR_XP)) || - cpu_is_xsc3()) && pfn >= 0x100000 && - !((paddr | size | addr) & ~SUPERSECTION_MASK)) { - area->flags |= VM_ARM_SECTION_MAPPING; - err = remap_area_supersections(addr, pfn, size, type); - } else if (!((paddr | size | addr) & ~PMD_MASK)) { + if (!((paddr | size | addr) & ~PMD_MASK)) { area->flags |= VM_ARM_SECTION_MAPPING; err = remap_area_sections(addr, pfn, size, type); } else
diff --git a/arch/arm/mm/mmap.c b/arch/arm/mm/mmap.c index 3dbb383..dbb3f07 100644 --- a/arch/arm/mm/mmap.c +++ b/arch/arm/mm/mmap.c
@@ -11,6 +11,7 @@ #include <linux/io.h> #include <linux/personality.h> #include <linux/random.h> +#include <linux/hugetlb.h> #include <asm/cachetype.h> #define COLOUR_ALIGN(addr,pgoff) \ @@ -72,7 +73,10 @@ arch_get_unmapped_area(struct file *filp, unsigned long addr, info.length = len; info.low_limit = mm->mmap_base; info.high_limit = TASK_SIZE; - info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0; + if (filp && is_file_hugepages(filp)) + info.align_mask = huge_page_mask_align(filp); + else + info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0; info.align_offset = pgoff << PAGE_SHIFT; return vm_unmapped_area(&info); } @@ -123,7 +127,10 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0, info.length = len; info.low_limit = FIRST_USER_ADDRESS; info.high_limit = mm->mmap_base; - info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0; + if (filp && is_file_hugepages(filp)) + info.align_mask = huge_page_mask_align(filp); + else + info.align_mask = do_align ? (PAGE_MASK & (SHMLBA - 1)) : 0; info.align_offset = pgoff << PAGE_SHIFT; addr = vm_unmapped_area(&info);
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c index 23b87b5..5d0ae25 100644 --- a/arch/arm/mm/mmu.c +++ b/arch/arm/mm/mmu.c
@@ -854,69 +854,6 @@ static void __init alloc_init_p4d(pgd_t *pgd, unsigned long addr, } while (p4d++, addr = next, addr != end); } -#ifndef CONFIG_ARM_LPAE -static void __init create_36bit_mapping(struct mm_struct *mm, - struct map_desc *md, - const struct mem_type *type, - bool ng) -{ - unsigned long addr, length, end; - phys_addr_t phys; - pgd_t *pgd; - - addr = md->virtual; - phys = __pfn_to_phys(md->pfn); - length = PAGE_ALIGN(md->length); - - if (!(cpu_architecture() >= CPU_ARCH_ARMv6 || cpu_is_xsc3())) { - pr_err("MM: CPU does not support supersection mapping for 0x%08llx at 0x%08lx\n", - (long long)__pfn_to_phys((u64)md->pfn), addr); - return; - } - - /* N.B. ARMv6 supersections are only defined to work with domain 0. - * Since domain assignments can in fact be arbitrary, the - * 'domain == 0' check below is required to insure that ARMv6 - * supersections are only allocated for domain 0 regardless - * of the actual domain assignments in use. - */ - if (type->domain) { - pr_err("MM: invalid domain in supersection mapping for 0x%08llx at 0x%08lx\n", - (long long)__pfn_to_phys((u64)md->pfn), addr); - return; - } - - if ((addr | length | __pfn_to_phys(md->pfn)) & ~SUPERSECTION_MASK) { - pr_err("MM: cannot create mapping for 0x%08llx at 0x%08lx invalid alignment\n", - (long long)__pfn_to_phys((u64)md->pfn), addr); - return; - } - - /* - * Shift bits [35:32] of address into bits [23:20] of PMD - * (See ARMv6 spec). - */ - phys |= (((md->pfn >> (32 - PAGE_SHIFT)) & 0xF) << 20); - - pgd = pgd_offset(mm, addr); - end = addr + length; - do { - p4d_t *p4d = p4d_offset(pgd, addr); - pud_t *pud = pud_offset(p4d, addr); - pmd_t *pmd = pmd_offset(pud, addr); - int i; - - for (i = 0; i < 16; i++) - *pmd++ = __pmd(phys | type->prot_sect | PMD_SECT_SUPER | - (ng ? PMD_SECT_nG : 0)); - - addr += SUPERSECTION_SIZE; - phys += SUPERSECTION_SIZE; - pgd += SUPERSECTION_SIZE >> PGDIR_SHIFT; - } while (addr != end); -} -#endif /* !CONFIG_ARM_LPAE */ - static void __init __create_mapping(struct mm_struct *mm, struct map_desc *md, void *(*alloc)(unsigned long sz), bool ng) @@ -928,16 +865,6 @@ static void __init __create_mapping(struct mm_struct *mm, struct map_desc *md, type = &mem_types[md->type]; -#ifndef CONFIG_ARM_LPAE - /* - * Catch 36-bit addresses - */ - if (md->pfn >= 0x100000) { - create_36bit_mapping(mm, md, type, ng); - return; - } -#endif - addr = md->virtual & PAGE_MASK; phys = __pfn_to_phys(md->pfn); length = PAGE_ALIGN(md->length + (md->virtual & ~PAGE_MASK)); @@ -964,8 +891,7 @@ static void __init __create_mapping(struct mm_struct *mm, struct map_desc *md, * Create the page directory entries and any necessary * page tables for the mapping specified by `md'. We * are able to cope here with varying sizes and address - * offsets, and we take full advantage of sections and - * supersections. + * offsets, and we take full advantage of sections. */ static void __init create_mapping(struct map_desc *md) {
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index a8507da..d5ccf1d 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig
@@ -197,6 +197,7 @@ if DYNAMIC_FTRACE_WITH_ARGS select HAVE_SAMPLE_FTRACE_DIRECT select HAVE_SAMPLE_FTRACE_DIRECT_MULTI + select HAVE_SHARED_GPIOS select HAVE_BUILDTIME_MCOUNT_SORT select HAVE_EFFICIENT_UNALIGNED_ACCESS select HAVE_GUP_FAST
diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 07127f7..49dcd7b 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms
@@ -153,6 +153,14 @@ help This enables support for ARMv8 based Samsung Exynos SoC family. +config ARCH_GOOGLE + bool "Google-Designed SoC family" + help + This enables support for Google Tensor SoCs starting at the + Google Tensor G5 (Laguna) found in Pixel 10 and later phones. + Tensor G1 to G4 are offshoots of the Exynos family and are + enabled via ARCH_EXYNOS. + config ARCH_K3 bool "Texas Instruments Inc. K3 multicore SoC architecture" select SOC_TI @@ -328,7 +336,6 @@ select GPIOLIB select PINCTRL select HAVE_PWRCTRL if PCI - select HAVE_SHARED_GPIOS help This enables support for the ARMv8 based Qualcomm chipsets.
diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile index fc726b2..f2d7cd6 100644 --- a/arch/arm64/boot/dts/Makefile +++ b/arch/arm64/boot/dts/Makefile
@@ -19,6 +19,7 @@ subdir-y += cix subdir-y += exynos subdir-y += freescale +subdir-y += google subdir-y += hisilicon subdir-y += intel subdir-y += lg
diff --git a/arch/arm64/boot/dts/actions/s700.dtsi b/arch/arm64/boot/dts/actions/s700.dtsi index 2c78cae..3d11467 100644 --- a/arch/arm64/boot/dts/actions/s700.dtsi +++ b/arch/arm64/boot/dts/actions/s700.dtsi
@@ -66,9 +66,9 @@ psci { arm-pmu { compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; };
diff --git a/arch/arm64/boot/dts/actions/s900.dtsi b/arch/arm64/boot/dts/actions/s900.dtsi index eb35cf7..267ac2d 100644 --- a/arch/arm64/boot/dts/actions/s900.dtsi +++ b/arch/arm64/boot/dts/actions/s900.dtsi
@@ -66,9 +66,9 @@ psci { arm-pmu { compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 7 IRQ_TYPE_LEVEL_HIGH>; interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; };
diff --git a/arch/arm64/boot/dts/allwinner/Makefile b/arch/arm64/boot/dts/allwinner/Makefile index aa21f58..d1f768d 100644 --- a/arch/arm64/boot/dts/allwinner/Makefile +++ b/arch/arm64/boot/dts/allwinner/Makefile
@@ -26,6 +26,7 @@ dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a100-allwinner-perf1.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a133-helperboard.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a133-liontron-h-a133l.dtb +dtb-$(CONFIG_ARCH_SUNXI) += sun50i-a133-teclast-p80.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-bananapi-m2-plus-v1.2.dtb dtb-$(CONFIG_ARCH_SUNXI) += sun50i-h5-emlid-neutis-n5-devboard.dtb
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-a133-teclast-p80.dts b/arch/arm64/boot/dts/allwinner/sun50i-a133-teclast-p80.dts new file mode 100644 index 0000000..47b5f2a --- /dev/null +++ b/arch/arm64/boot/dts/allwinner/sun50i-a133-teclast-p80.dts
@@ -0,0 +1,205 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2026 Arm Ltd. + */ + +/dts-v1/; + +#include "sun50i-a100.dtsi" +#include "sun50i-a100-cpu-opp.dtsi" + +#include <dt-bindings/gpio/gpio.h> + +/{ + model = "Teclast P80"; + compatible = "teclast,p80", "allwinner,sun50i-a133"; + chassis-type = "tablet"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + reg_vcc5v: vcc5v { + /* external power input from the USB-C port*/ + compatible = "regulator-fixed"; + regulator-always-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-name = "vcc-5v"; + }; + + speaker_amp: audio-amplifier { + compatible = "simple-audio-amplifier"; + enable-gpios = <&pio 7 6 GPIO_ACTIVE_HIGH>; /* PH6 */ + sound-name-prefix = "Speaker Amp"; + }; +}; + +&cpu0 { + cpu-supply = <®_dcdc2>; +}; + +&ehci0 { + status = "okay"; +}; + +&mmc0 { + bus-width = <4>; + cd-gpios = <&pio 5 6 GPIO_ACTIVE_LOW>; /* PF6 */ + disable-wp; + vmmc-supply = <®_dcdc1>; + status = "okay"; +}; + +&mmc2 { + bus-width = <8>; + cap-mmc-hw-reset; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + non-removable; + vmmc-supply = <®_dcdc1>; + vqmmc-supply = <®_eldo1>; + status = "okay"; +}; + +&ohci0 { + status = "okay"; +}; + +&r_i2c0 { + status = "okay"; + + axp803: pmic@34 { + compatible = "x-powers,axp803"; + reg = <0x34>; + interrupt-parent = <&r_intc>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + x-powers,drive-vbus-en; + }; +}; + +#include "axp803.dtsi" + +&ac_power_supply { + status = "okay"; +}; + +&battery_power_supply { + status = "okay"; +}; + +®_aldo1 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-codec-avcc"; +}; + +®_aldo2 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-dram-1"; +}; + +®_aldo3 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-usb-pl"; +}; + +®_dcdc1 { + regulator-always-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc-io-usb-pd-mmc"; +}; + +®_dcdc2 { + regulator-always-on; + regulator-min-microvolt = <810000>; + regulator-max-microvolt = <1200000>; + regulator-name = "vdd-cpux"; +}; + +®_dcdc3 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-name = "vdd-usb-cpus"; +}; + +®_dcdc4 { + regulator-always-on; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <950000>; + regulator-name = "vdd-sys"; +}; + +®_dcdc5 { + regulator-always-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "vcc-dram"; +}; + +®_dc1sw { + regulator-name = "vcc-dc1sw"; +}; + +®_drivevbus { + regulator-name = "usb0-vbus"; + status = "okay"; +}; + +®_dldo1 { + regulator-always-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-dldo1"; +}; + +®_eldo1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-eldo1"; +}; + +®_eldo3 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc-eldo3"; +}; + +®_fldo1 { + regulator-always-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-name = "vdd-cpus-usb"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pb_pins>; + status = "okay"; +}; + +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + +&usb_power_supply { + status = "okay"; +}; + +&usbphy { + usb0_vbus-supply = <®_drivevbus>; + usb0_id_det-gpios = <&pio 7 8 GPIO_ACTIVE_HIGH>; /* PH8 */ + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts index 6e57ee1..c233159 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts +++ b/arch/arm64/boot/dts/allwinner/sun50i-h5-orangepi-pc2.dts
@@ -7,6 +7,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> #include <dt-bindings/pinctrl/sun4i-a10.h> / { @@ -132,6 +133,27 @@ &external_mdio { ext_rgmii_phy: ethernet-phy@1 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <1>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = <LED_COLOR_ID_GREEN>; + function = LED_FUNCTION_LAN; + linux,default-trigger = "netdev"; + default-state = "keep"; + }; + + led@1 { + reg = <1>; + color = <LED_COLOR_ID_AMBER>; + function = LED_FUNCTION_LAN; + linux,default-trigger = "netdev"; + default-state = "keep"; + }; + }; }; };
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi index 72ce1a7..48c7712 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -205,8 +205,8 @@ video-codec@1c0e000 { clock-names = "ahb", "mod", "ram"; resets = <&ccu RST_BUS_VE>; interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>; - allwinner,sram = <&ve_sram 1>; - iommus = <&iommu 3>; + allwinner,sram = <&ve_sram 1>, <&de2_sram 1>; + iommus = <&iommu 3>, <&iommu 1>; }; gpu: gpu@1800000 {
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi index 1598e86..c6b3a3f 100644 --- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi +++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
@@ -175,6 +175,18 @@ crypto: crypto@1904000 { resets = <&ccu RST_BUS_CE>; }; + video-codec@1c0e000 { + compatible = "allwinner,sun50i-h616-video-engine"; + reg = <0x01c0e000 0x2000>; + clocks = <&ccu CLK_BUS_VE>, <&ccu CLK_VE>, + <&ccu CLK_MBUS_VE>; + clock-names = "ahb", "mod", "ram"; + resets = <&ccu RST_BUS_VE>; + interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>; + iommus = <&iommu 3>, <&iommu 2>; + allwinner,sram = <&ve_sram 1>, <&sram_c 1>; + }; + syscon: syscon@3000000 { compatible = "allwinner,sun50i-h616-system-control"; reg = <0x03000000 0x1000>;
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-a4.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-a4.dtsi index fce4593..762754b 100644 --- a/arch/arm64/boot/dts/amlogic/amlogic-a4.dtsi +++ b/arch/arm64/boot/dts/amlogic/amlogic-a4.dtsi
@@ -207,6 +207,11 @@ gpio_intc: interrupt-controller@4080 { <10 11 12 13 14 15 16 17 18 19 20 21>; }; + clk_msr: clock-measure@48000 { + compatible = "amlogic,a4-clk-measure"; + reg = <0x0 0x48000 0x0 0x1c>; + }; + ao_pinctrl: pinctrl@8e700 { compatible = "amlogic,pinctrl-a4"; #address-cells = <2>;
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi index 2b12d828..0be176a 100644 --- a/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi +++ b/arch/arm64/boot/dts/amlogic/amlogic-a5.dtsi
@@ -157,4 +157,9 @@ gpio_intc: interrupt-controller@4080 { amlogic,channel-interrupts = <10 11 12 13 14 15 16 17 18 19 20 21>; }; + + clk_msr: clock-measure@48000 { + compatible = "amlogic,a5-clk-measure"; + reg = <0x0 0x48000 0x0 0x1c>; + }; };
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-a9.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-a9.dtsi index b0e0fad..91f4cf3 100644 --- a/arch/arm64/boot/dts/amlogic/amlogic-a9.dtsi +++ b/arch/arm64/boot/dts/amlogic/amlogic-a9.dtsi
@@ -185,6 +185,11 @@ gpio_intc: interrupt-controller@4080 { amlogic,channel-interrupts = <10 11 12 13 14 15 16 17 18 19 20 21>; }; + + clk_msr: clock-measure@48000 { + compatible = "amlogic,a9-clk-measure"; + reg = <0x0 0x48000 0x0 0x1c>; + }; }; gic: interrupt-controller@ff800000 {
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-s6.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-s6.dtsi index ab3acef..b0a1a05 100644 --- a/arch/arm64/boot/dts/amlogic/amlogic-s6.dtsi +++ b/arch/arm64/boot/dts/amlogic/amlogic-s6.dtsi
@@ -217,6 +217,11 @@ ao-secure@10220 { reg = <0x0 0x10220 0x0 0x140>; amlogic,has-chip-id; }; + + clk_msr: clock-measure@48000 { + compatible = "amlogic,s6-clk-measure"; + reg = <0x0 0x48000 0x0 0x1c>; + }; }; }; };
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi index a3faf4d..64440df 100644 --- a/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi +++ b/arch/arm64/boot/dts/amlogic/amlogic-s7.dtsi
@@ -239,6 +239,11 @@ ao-secure@10220 { reg = <0x0 0x10220 0x0 0x140>; amlogic,has-chip-id; }; + + clk_msr: clock-measure@48000 { + compatible = "amlogic,s7-clk-measure"; + reg = <0x0 0x48000 0x0 0x1c>; + }; }; }; };
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-s7d.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-s7d.dtsi index 0c4417b..5593ff9 100644 --- a/arch/arm64/boot/dts/amlogic/amlogic-s7d.dtsi +++ b/arch/arm64/boot/dts/amlogic/amlogic-s7d.dtsi
@@ -212,6 +212,11 @@ ao-secure@10220 { reg = <0x0 0x10220 0x0 0x140>; amlogic,has-chip-id; }; + + clk_msr: clock-measure@48000 { + compatible = "amlogic,s7d-clk-measure"; + reg = <0x0 0x48000 0x0 0x1c>; + }; }; }; };
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts index 77abfd5..0fa8336 100644 --- a/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7-a311d2-khadas-vim4.dts
@@ -256,6 +256,19 @@ xtal: xtal-clk { }; }; +&i2c_m_ao_a { + status = "okay"; + pinctrl-0 = <&i2c0_ao_d_pins>; + pinctrl-names = "default"; + + khadas_mcu: system-controller@18 { + compatible = "khadas,vim4-mcu"; + reg = <0x18>; + fan-supply = <&vcc5v>; + #cooling-cells = <2>; + }; +}; + &pwm_ab { status = "okay"; pinctrl-0 = <&pwm_a_pins>;
diff --git a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi index 719e111..6894c06 100644 --- a/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi +++ b/arch/arm64/boot/dts/amlogic/amlogic-t7.dtsi
@@ -756,14 +756,25 @@ pwm_ao_cd: pwm@60000 { status = "disabled"; }; + i2c_m_ao_a: i2c@76000 { + compatible = "amlogic,t7-i2c", "amlogic,meson-axg-i2c"; + reg = <0x0 0x76000 0x0 0x48>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <GIC_SPI 330 IRQ_TYPE_EDGE_RISING>; + clocks = <&clkc_periphs CLKID_SYS_I2C_AO_A>; + status = "disabled"; + }; + sd_emmc_a: mmc@88000 { compatible = "amlogic,t7-mmc", "amlogic,meson-axg-mmc"; reg = <0x0 0x88000 0x0 0x800>; interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clkc_periphs CLKID_SYS_SD_EMMC_A>, <&clkc_periphs CLKID_SD_EMMC_A>, - <&scmi_clk CLKID_FCLK_DIV2>; - clock-names = "core", "clkin0", "clkin1"; + <&scmi_clk CLKID_FCLK_DIV2>, + <&clkc_periphs CLKID_SYS_AMPIPE_NAND>; + clock-names = "core", "clkin0", "clkin1", "pipeline"; resets = <&reset RESET_SD_EMMC_A>; assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_A_SEL>; assigned-clock-parents = <&xtal>; @@ -776,8 +787,9 @@ sd_emmc_b: mmc@8a000 { interrupts = <GIC_SPI 177 IRQ_TYPE_EDGE_RISING>; clocks = <&clkc_periphs CLKID_SYS_SD_EMMC_B>, <&clkc_periphs CLKID_SD_EMMC_B>, - <&scmi_clk CLKID_FCLK_DIV2>; - clock-names = "core", "clkin0", "clkin1"; + <&scmi_clk CLKID_FCLK_DIV2>, + <&clkc_periphs CLKID_SYS_AMPIPE_NAND>; + clock-names = "core", "clkin0", "clkin1", "pipeline"; resets = <&reset RESET_SD_EMMC_B>; assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_B_SEL>; assigned-clock-parents = <&xtal>; @@ -790,8 +802,9 @@ sd_emmc_c: mmc@8c000 { interrupts = <GIC_SPI 178 IRQ_TYPE_EDGE_RISING>; clocks = <&clkc_periphs CLKID_SYS_SD_EMMC_C>, <&clkc_periphs CLKID_SD_EMMC_C>, - <&scmi_clk CLKID_FCLK_DIV2>; - clock-names = "core", "clkin0", "clkin1"; + <&scmi_clk CLKID_FCLK_DIV2>, + <&clkc_periphs CLKID_SYS_AMPIPE_NAND>; + clock-names = "core", "clkin0", "clkin1", "pipeline"; resets = <&reset RESET_SD_EMMC_C>; assigned-clocks = <&clkc_periphs CLKID_SD_EMMC_C_SEL>; assigned-clock-parents = <&xtal>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi index 00609d2..3135566 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi
@@ -615,6 +615,15 @@ mux { }; }; + nor_hold_wp_pins: nor-hold-wp { + mux { + groups = "nor_hold", + "nor_wp"; + function = "nor"; + bias-disable; + }; + }; + pdm_din0_a_pins: pdm-din0-a { mux { groups = "pdm_din0_a";
diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-go-ultra.dts b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-go-ultra.dts index cac73c5..348baa4 100644 --- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-go-ultra.dts +++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-go-ultra.dts
@@ -608,7 +608,7 @@ &periphs_pinctrl { keypad_gpio_pins: keypad-gpio-state { mux { groups = "GPIOX_0", "GPIOX_1", "GPIOX_2", "GPIOX_3", - "GPIOX_4", "GPIOX_5", "GPIOX_6", "GPIOX_7", + "GPIOX_4", "GPIOX_5", "GPIOX_6", "GPIOX_7", "GPIOX_8", "GPIOX_9", "GPIOX_10", "GPIOX_11", "GPIOX_12", "GPIOX_13", "GPIOX_14", "GPIOX_15", "GPIOX_16", "GPIOX_17", "GPIOX_18", "GPIOX_19";
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts index 5d9ddb8..e353f0e 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-nanopi-k2.dts
@@ -70,7 +70,7 @@ vddio_tf: regulator-vddio-tf { gpios-states = <0>; states = <3300000 0>, - <1800000 1>; + <1800000 1>; regulator-settling-time-up-us = <100>; regulator-settling-time-down-us = <5000>;
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi index a9c830a..5c2fe9d 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxbb.dtsi
@@ -781,7 +781,7 @@ &pwrc { "dvin", "rdma", "venci", "vencp", "vdac", "vdi6", "vencl", "vid_lock"; clocks = <&clkc CLKID_VPU>, - <&clkc CLKID_VAPB>; + <&clkc CLKID_VAPB>; clock-names = "vpu", "vapb"; /* * VPU clocking is provided by two identical clock paths
diff --git a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi index d5e0f72..f257fe3 100644 --- a/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi +++ b/arch/arm64/boot/dts/amlogic/meson-gxl.dtsi
@@ -851,7 +851,7 @@ &pwrc { "dvin", "rdma", "venci", "vencp", "vdac", "vdi6", "vencl", "vid_lock"; clocks = <&clkc CLKID_VPU>, - <&clkc CLKID_VAPB>; + <&clkc CLKID_VAPB>; clock-names = "vpu", "vapb"; /* * VPU clocking is provided by two identical clock paths
diff --git a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts index 3ece30a..5f15c229 100644 --- a/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts +++ b/arch/arm64/boot/dts/amlogic/meson-sm1-odroid-hc4.dts
@@ -126,7 +126,7 @@ &sd_emmc_c { &spifc { status = "okay"; - pinctrl-0 = <&nor_pins>; + pinctrl-0 = <&nor_pins>, <&nor_hold_wp_pins>; pinctrl-names = "default"; flash@0 { @@ -134,7 +134,7 @@ flash@0 { #size-cells = <1>; compatible = "jedec,spi-nor"; reg = <0>; - spi-max-frequency = <104000000>; + spi-max-frequency = <40000000>; }; };
diff --git a/arch/arm64/boot/dts/apple/Makefile b/arch/arm64/boot/dts/apple/Makefile index 9fea43f..4f31bee 100644 --- a/arch/arm64/boot/dts/apple/Makefile +++ b/arch/arm64/boot/dts/apple/Makefile
@@ -103,3 +103,10 @@ dtb-$(CONFIG_ARCH_APPLE) += t8122-j504.dtb dtb-$(CONFIG_ARCH_APPLE) += t8122-j613.dtb dtb-$(CONFIG_ARCH_APPLE) += t8122-j615.dtb +dtb-$(CONFIG_ARCH_APPLE) += t8132-j604.dtb +dtb-$(CONFIG_ARCH_APPLE) += t8132-j623.dtb +dtb-$(CONFIG_ARCH_APPLE) += t8132-j624.dtb +dtb-$(CONFIG_ARCH_APPLE) += t8132-j713.dtb +dtb-$(CONFIG_ARCH_APPLE) += t8132-j715.dtb +dtb-$(CONFIG_ARCH_APPLE) += t8132-j773g.dtb +dtb-$(CONFIG_ARCH_APPLE) += t8140-j700.dtb
diff --git a/arch/arm64/boot/dts/apple/t6001.dtsi b/arch/arm64/boot/dts/apple/t6001.dtsi index 4fb934d..e0acf2b 100644 --- a/arch/arm64/boot/dts/apple/t6001.dtsi +++ b/arch/arm64/boot/dts/apple/t6001.dtsi
@@ -35,18 +35,17 @@ soc { #define DIE #define DIE_NO 0 +#define SOC_NODE {/soc} -&{/soc} { - #include "t600x-die0.dtsi" - #include "t600x-dieX.dtsi" - #include "t600x-nvme.dtsi" -}; - +#include "t600x-die0.dtsi" +#include "t600x-dieX.dtsi" +#include "t600x-nvme.dtsi" #include "t600x-gpio-pins.dtsi" #include "t600x-pmgr.dtsi" #undef DIE #undef DIE_NO +#undef SOC_NODE &aic {
diff --git a/arch/arm64/boot/dts/apple/t6002.dtsi b/arch/arm64/boot/dts/apple/t6002.dtsi index 0f81fc6..91ce9a6 100644 --- a/arch/arm64/boot/dts/apple/t6002.dtsi +++ b/arch/arm64/boot/dts/apple/t6002.dtsi
@@ -254,30 +254,28 @@ die1: soc@2200000000 { #define DIE #define DIE_NO 0 +#define SOC_NODE die0 -&die0 { - #include "t600x-die0.dtsi" - #include "t600x-dieX.dtsi" -}; - +#include "t600x-die0.dtsi" +#include "t600x-dieX.dtsi" #include "t600x-pmgr.dtsi" #include "t600x-gpio-pins.dtsi" #undef DIE #undef DIE_NO +#undef SOC_NODE #define DIE _die1 #define DIE_NO 1 +#define SOC_NODE die1 -&die1 { - #include "t600x-dieX.dtsi" - #include "t600x-nvme.dtsi" -}; - +#include "t600x-dieX.dtsi" +#include "t600x-nvme.dtsi" #include "t600x-pmgr.dtsi" #undef DIE #undef DIE_NO +#undef SOC_NODE &aic { affinities {
diff --git a/arch/arm64/boot/dts/apple/t600x-die0.dtsi b/arch/arm64/boot/dts/apple/t600x-die0.dtsi index 49b23f3..122a566 100644 --- a/arch/arm64/boot/dts/apple/t600x-die0.dtsi +++ b/arch/arm64/boot/dts/apple/t600x-die0.dtsi
@@ -6,7 +6,7 @@ * Copyright The Asahi Linux Contributors */ - +&SOC_NODE { nco: clock-controller@28e03c000 { compatible = "apple,t6000-nco", "apple,nco"; reg = <0x2 0x8e03c000 0x0 0x14000>; @@ -537,3 +537,4 @@ port03: pci@3,0 { status = "disabled"; }; }; +};
diff --git a/arch/arm64/boot/dts/apple/t600x-dieX.dtsi b/arch/arm64/boot/dts/apple/t600x-dieX.dtsi index 9676d51..7ab6087 100644 --- a/arch/arm64/boot/dts/apple/t600x-dieX.dtsi +++ b/arch/arm64/boot/dts/apple/t600x-dieX.dtsi
@@ -6,6 +6,7 @@ * Copyright The Asahi Linux Contributors */ +&SOC_NODE { DIE_NODE(cpufreq_e): cpufreq@210e20000 { compatible = "apple,t6000-cluster-cpufreq", "apple,t8103-cluster-cpufreq", "apple,cluster-cpufreq"; reg = <0x2 0x10e20000 0 0x1000>; @@ -331,3 +332,4 @@ DIE_NODE(atcphy3): phy@1303000000 { mode-switch; power-domains = <&DIE_NODE(ps_atc3_usb)>; }; +};
diff --git a/arch/arm64/boot/dts/apple/t600x-nvme.dtsi b/arch/arm64/boot/dts/apple/t600x-nvme.dtsi index 7dff738..3a8e229 100644 --- a/arch/arm64/boot/dts/apple/t600x-nvme.dtsi +++ b/arch/arm64/boot/dts/apple/t600x-nvme.dtsi
@@ -5,6 +5,7 @@ * Copyright The Asahi Linux Contributors */ +&SOC_NODE { DIE_NODE(ans_mbox): mbox@38f408000 { compatible = "apple,t6000-asc-mailbox", "apple,asc-mailbox-v4"; reg = <0x3 0x8f408000 0x0 0x4000>; @@ -40,3 +41,4 @@ DIE_NODE(nvme): nvme@393cc0000 { power-domain-names = "ans", "apcie0", "apcie1"; resets = <&DIE_NODE(ps_ans2)>; }; +};
diff --git a/arch/arm64/boot/dts/apple/t6021.dtsi b/arch/arm64/boot/dts/apple/t6021.dtsi index 5175797..3cddc169 100644 --- a/arch/arm64/boot/dts/apple/t6021.dtsi +++ b/arch/arm64/boot/dts/apple/t6021.dtsi
@@ -35,13 +35,11 @@ soc { #define DIE #define DIE_NO 0 +#define SOC_NODE {/soc} -&{/soc} { - #include "t602x-die0.dtsi" - #include "t602x-dieX.dtsi" - #include "t602x-nvme.dtsi" -}; - +#include "t602x-die0.dtsi" +#include "t602x-dieX.dtsi" +#include "t602x-nvme.dtsi" #include "t602x-gpio-pins.dtsi" #include "t602x-pmgr.dtsi"
diff --git a/arch/arm64/boot/dts/apple/t6022.dtsi b/arch/arm64/boot/dts/apple/t6022.dtsi index 7585fd6..0feda70 100644 --- a/arch/arm64/boot/dts/apple/t6022.dtsi +++ b/arch/arm64/boot/dts/apple/t6022.dtsi
@@ -294,32 +294,30 @@ die1: soc@2200000000 { #define DIE #define DIE_NO 0 +#define SOC_NODE die0 -&die0 { - #include "t602x-die0.dtsi" - #include "t602x-dieX.dtsi" -}; - +#include "t602x-die0.dtsi" +#include "t602x-dieX.dtsi" #include "t602x-pmgr.dtsi" #include "t602x-gpio-pins.dtsi" #undef DIE #undef DIE_NO +#undef SOC_NODE #define DIE _die1 #define DIE_NO 1 +#define SOC_NODE die1 -&die1 { - #include "t602x-dieX.dtsi" - #include "t602x-nvme.dtsi" -}; - +#include "t602x-dieX.dtsi" +#include "t602x-nvme.dtsi" #include "t602x-pmgr.dtsi" /delete-node/ &ps_pmp_die1; #undef DIE #undef DIE_NO +#undef SOC_NODE &aic { affinities {
diff --git a/arch/arm64/boot/dts/apple/t602x-common.dtsi b/arch/arm64/boot/dts/apple/t602x-common.dtsi index 9c800a3..66b6f83 100644 --- a/arch/arm64/boot/dts/apple/t602x-common.dtsi +++ b/arch/arm64/boot/dts/apple/t602x-common.dtsi
@@ -254,7 +254,7 @@ l2_cache_2: l2-cache-2 { cache-unified; cache-size = <0x1000000>; }; - }; + }; blizzard_opp: opp-table-0 { compatible = "operating-points-v2";
diff --git a/arch/arm64/boot/dts/apple/t602x-die0.dtsi b/arch/arm64/boot/dts/apple/t602x-die0.dtsi index c33623f..0581975 100644 --- a/arch/arm64/boot/dts/apple/t602x-die0.dtsi +++ b/arch/arm64/boot/dts/apple/t602x-die0.dtsi
@@ -6,6 +6,7 @@ * Copyright The Asahi Linux Contributors */ +&SOC_NODE { nco: clock-controller@28e03c000 { compatible = "apple,t6020-nco", "apple,t8103-nco"; reg = <0x2 0x8e03c000 0x0 0x14000>; @@ -590,3 +591,4 @@ pcie0_dart_3: iommu@597000000 { power-domains = <&ps_apcie_gp_sys>; status = "disabled"; }; +};
diff --git a/arch/arm64/boot/dts/apple/t602x-dieX.dtsi b/arch/arm64/boot/dts/apple/t602x-dieX.dtsi index ae3d535..4044c4f 100644 --- a/arch/arm64/boot/dts/apple/t602x-dieX.dtsi +++ b/arch/arm64/boot/dts/apple/t602x-dieX.dtsi
@@ -5,6 +5,7 @@ * Copyright The Asahi Linux Contributors */ +&SOC_NODE { DIE_NODE(cpufreq_e): cpufreq@210e20000 { compatible = "apple,t6020-cluster-cpufreq", "apple,t8112-cluster-cpufreq"; reg = <0x2 0x10e20000 0 0x1000>; @@ -338,3 +339,4 @@ DIE_NODE(atcphy3): phy@1303000000 { mode-switch; power-domains = <&DIE_NODE(ps_atc3_usb)>; }; +};
diff --git a/arch/arm64/boot/dts/apple/t602x-nvme.dtsi b/arch/arm64/boot/dts/apple/t602x-nvme.dtsi index 590cec8..d1f4267 100644 --- a/arch/arm64/boot/dts/apple/t602x-nvme.dtsi +++ b/arch/arm64/boot/dts/apple/t602x-nvme.dtsi
@@ -5,6 +5,7 @@ * Copyright The Asahi Linux Contributors */ +&SOC_NODE { DIE_NODE(ans_mbox): mbox@347408000 { compatible = "apple,t6020-asc-mailbox", "apple,asc-mailbox-v4"; reg = <0x3 0x47408000 0x0 0x4000>; @@ -40,3 +41,4 @@ DIE_NODE(nvme): nvme@34bcc0000 { power-domain-names = "ans", "apcie0", "apcie1"; resets = <&DIE_NODE(ps_ans2)>; }; +};
diff --git a/arch/arm64/boot/dts/apple/t6030-pmgr.dtsi b/arch/arm64/boot/dts/apple/t6030-pmgr.dtsi index 932388e..b890d62 100644 --- a/arch/arm64/boot/dts/apple/t6030-pmgr.dtsi +++ b/arch/arm64/boot/dts/apple/t6030-pmgr.dtsi
@@ -1434,4 +1434,3 @@ ps_atc3_usb: power-controller@f0 { power-domains = <&ps_atc3_usb_aon>, <&ps_atc3_common>; }; }; -
diff --git a/arch/arm64/boot/dts/apple/t6030.dtsi b/arch/arm64/boot/dts/apple/t6030.dtsi index dda9568..524e532 100644 --- a/arch/arm64/boot/dts/apple/t6030.dtsi +++ b/arch/arm64/boot/dts/apple/t6030.dtsi
@@ -15,6 +15,13 @@ / { #address-cells = <2>; #size-cells = <2>; + clkref: clock-ref { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "clkref"; + }; + cpus { #address-cells = <2>; #size-cells = <0>; @@ -24,18 +31,23 @@ cluster0 { core0 { cpu = <&cpu_e00>; }; + core1 { cpu = <&cpu_e01>; }; + core2 { cpu = <&cpu_e02>; }; + core3 { cpu = <&cpu_e03>; }; + core4 { cpu = <&cpu_e04>; }; + core5 { cpu = <&cpu_e05>; }; @@ -45,18 +57,23 @@ cluster1 { core0 { cpu = <&cpu_p00>; }; + core1 { cpu = <&cpu_p01>; }; + core2 { cpu = <&cpu_p02>; }; + core3 { cpu = <&cpu_p03>; }; + core4 { cpu = <&cpu_p04>; }; + core5 { cpu = <&cpu_p05>; }; @@ -64,300 +81,302 @@ core5 { }; cpu_e00: cpu@0 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x0>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* to be filled by loader */ - next-level-cache = <&l2_cache_0>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; }; cpu_e01: cpu@1 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x1>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* to be filled by loader */ - next-level-cache = <&l2_cache_0>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; }; cpu_e02: cpu@2 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x2>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* to be filled by loader */ - next-level-cache = <&l2_cache_0>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; }; cpu_e03: cpu@3 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x3>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* to be filled by loader */ - next-level-cache = <&l2_cache_0>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; }; cpu_e04: cpu@4 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x4>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* to be filled by loader */ - next-level-cache = <&l2_cache_0>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; }; cpu_e05: cpu@5 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x5>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* to be filled by loader */ - next-level-cache = <&l2_cache_0>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; }; cpu_p00: cpu@10100 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10100>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_1>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; }; cpu_p01: cpu@10101 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10101>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_1>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; }; cpu_p02: cpu@10102 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10102>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_1>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; }; cpu_p03: cpu@10103 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10103>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_1>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; }; cpu_p04: cpu@10104 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10104>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_1>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; }; cpu_p05: cpu@10105 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10105>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_1>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; }; l2_cache_0: l2-cache-0 { compatible = "cache"; cache-level = <2>; - cache-unified; cache-size = <0x400000>; + cache-unified; }; l2_cache_1: l2-cache-1 { compatible = "cache"; cache-level = <2>; - cache-unified; cache-size = <0x1000000>; + cache-unified; }; - }; - - timer { - compatible = "arm,armv8-timer"; - interrupt-parent = <&aic>; - interrupt-names = "phys", "virt", "hyp-phys", "hyp-virt"; - interrupts = <AIC_FIQ AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>, - <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>, - <AIC_FIQ AIC_TMR_HV_PHYS IRQ_TYPE_LEVEL_HIGH>, - <AIC_FIQ AIC_TMR_HV_VIRT IRQ_TYPE_LEVEL_HIGH>; - }; - - clkref: clock-ref { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <24000000>; - clock-output-names = "clkref"; }; reserved-memory { + ranges; #address-cells = <2>; #size-cells = <2>; - ranges; }; soc: soc { compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <2>; - ranges; - nonposted-mmio; + #address-cells = <2>; /* Required to get >32-bit DMA via DARTs */ dma-ranges = <0 0 0 0 0xffffffff 0xffffc000>; + nonposted-mmio; + #size-cells = <2>; i2c1: i2c@289014000 { compatible = "apple,t6030-i2c", "apple,t8103-i2c"; reg = <0x2 0x89014000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 890 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c1_pins>; pinctrl-names = "default"; - #address-cells = <0x1>; - #size-cells = <0x0>; power-domains = <&ps_i2c1>; + #size-cells = <0x0>; + status = "disabled"; }; i2c2: i2c@289018000 { compatible = "apple,t6030-i2c", "apple,t8103-i2c"; reg = <0x2 0x89018000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 891 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c2_pins>; pinctrl-names = "default"; - #address-cells = <0x1>; - #size-cells = <0x0>; power-domains = <&ps_i2c2>; + #size-cells = <0x0>; + status = "disabled"; }; i2c3: i2c@28901c000 { compatible = "apple,t6030-i2c", "apple,t8103-i2c"; reg = <0x2 0x8901c000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 892 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c3_pins>; pinctrl-names = "default"; - #address-cells = <0x1>; - #size-cells = <0x0>; power-domains = <&ps_i2c3>; + #size-cells = <0x0>; + status = "disabled"; }; i2c4: i2c@289020000 { compatible = "apple,t6030-i2c", "apple,t8103-i2c"; reg = <0x2 0x89020000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 893 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c4_pins>; pinctrl-names = "default"; - #address-cells = <0x1>; - #size-cells = <0x0>; power-domains = <&ps_i2c4>; + #size-cells = <0x0>; + status = "disabled"; }; i2c6: i2c@289028000 { compatible = "apple,t6030-i2c", "apple,t8103-i2c"; reg = <0x2 0x89028000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 895 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c6_pins>; pinctrl-names = "default"; - #address-cells = <0x1>; - #size-cells = <0x0>; power-domains = <&ps_i2c6>; + #size-cells = <0x0>; + status = "disabled"; }; i2c8: i2c@289030000 { compatible = "apple,t6030-i2c", "apple,t8103-i2c"; reg = <0x2 0x89030000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 897 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c8_pins>; pinctrl-names = "default"; - #address-cells = <0x1>; - #size-cells = <0x0>; power-domains = <&ps_i2c8>; + #size-cells = <0x0>; + status = "disabled"; }; fpwm0: pwm@289040000 { compatible = "apple,t6030-fpwm", "apple,s5l-fpwm"; reg = <0x2 0x89040000 0x0 0x4000>; - power-domains = <&ps_fpwm0>; clocks = <&clkref>; + power-domains = <&ps_fpwm0>; #pwm-cells = <2>; + status = "disabled"; }; serial0: serial@289200000 { compatible = "apple,s5l-uart"; reg = <0x2 0x89200000 0x0 0x1000>; - reg-io-width = <4>; - interrupt-parent = <&aic>; - interrupts = <AIC_IRQ 866 IRQ_TYPE_LEVEL_HIGH>; /* * TODO: figure out the clocking properly, there may * be a third selectable clock. */ clocks = <&clkref>, <&clkref>; clock-names = "uart", "clk_uart_baud0"; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 866 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&ps_uart0>; + reg-io-width = <4>; + status = "disabled"; }; pmgr_gfx: power-management@290e80000 { - compatible = "apple,t6030-pmgr", "apple,t8103-pmgr", "syscon", "simple-mfd"; + compatible = "apple,t6030-pmgr", "apple,t8103-pmgr", + "syscon", "simple-mfd"; + reg = <0x2 0x90e80000 0 0x4000>; #address-cells = <1>; #size-cells = <1>; - - reg = <0x2 0x90e80000 0 0x4000>; /* child nodes are added in t6030-pmgr.dtsi */ }; @@ -365,6 +384,12 @@ pinctrl_ap: pinctrl@347100000 { compatible = "apple,t6030-pinctrl", "apple,t8103-pinctrl"; reg = <0x3 0x47100000 0x0 0x4000>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pinctrl_ap 0 0 224>; + + #interrupt-cells = <2>; + interrupt-controller; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 273 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 274 IRQ_TYPE_LEVEL_HIGH>, @@ -375,15 +400,8 @@ pinctrl_ap: pinctrl@347100000 { <AIC_IRQ 279 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&ps_gpio>; - - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinctrl_ap 0 0 224>; apple,npins = <224>; - interrupt-controller; - #interrupt-cells = <2>; - i2c1_pins: i2c1-pins { pinmux = <APPLE_PINMUX(37, 1)>, <APPLE_PINMUX(36, 1)>; @@ -416,22 +434,22 @@ i2c8_pins: i2c8-pins { }; pmgr: power-management@350700000 { - compatible = "apple,t6030-pmgr", "apple,t8103-pmgr", "syscon", "simple-mfd"; + compatible = "apple,t6030-pmgr", "apple,t8103-pmgr", + "syscon", "simple-mfd"; + reg = <0x3 0x50700000 0 0x14000>; #address-cells = <1>; #size-cells = <1>; - - reg = <0x3 0x50700000 0 0x14000>; /* child nodes are added in t6030-pmgr.dtsi */ }; aic: interrupt-controller@351000000 { compatible = "apple,t6030-aic3", "apple,t8122-aic3"; - #interrupt-cells = <3>; - interrupt-controller; - reg = <0x3 0x51000000 0x0 0x184000>, <0x3 0x51040000 0x0 0x4000>; reg-names = "core", "event"; + + #interrupt-cells = <3>; + interrupt-controller; power-domains = <&ps_aic>; }; @@ -439,6 +457,12 @@ pinctrl_nub: pinctrl@3641f0000 { compatible = "apple,t6030-pinctrl", "apple,t8103-pinctrl"; reg = <0x3 0x641f0000 0x0 0x4000>; + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pinctrl_nub 0 0 37>; + + #interrupt-cells = <2>; + interrupt-controller; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 472 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 473 IRQ_TYPE_LEVEL_HIGH>, @@ -448,21 +472,15 @@ pinctrl_nub: pinctrl@3641f0000 { <AIC_IRQ 477 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 478 IRQ_TYPE_LEVEL_HIGH>; - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinctrl_nub 0 0 37>; apple,npins = <37>; - - interrupt-controller; - #interrupt-cells = <2>; }; pmgr_mini: power-management@364280000 { - compatible = "apple,t6030-pmgr", "apple,t8103-pmgr", "syscon", "simple-mfd"; + compatible = "apple,t6030-pmgr", "apple,t8103-pmgr", + "syscon", "simple-mfd"; + reg = <0x3 0x64280000 0 0x4000>; #address-cells = <1>; #size-cells = <1>; - - reg = <0x3 0x64280000 0 0x4000>; /* child nodes are added in t6030-pmgr.dtsi */ }; @@ -478,13 +496,12 @@ pinctrl_smc: pinctrl@36c820000 { compatible = "apple,t6030-pinctrl", "apple,t8103-pinctrl"; reg = <0x3 0x6c820000 0x0 0x4000>; - gpio-controller; #gpio-cells = <2>; + gpio-controller; gpio-ranges = <&pinctrl_smc 0 0 18>; - apple,npins = <18>; - interrupt-controller; #interrupt-cells = <2>; + interrupt-controller; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 545 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 546 IRQ_TYPE_LEVEL_HIGH>, @@ -493,12 +510,22 @@ pinctrl_smc: pinctrl@36c820000 { <AIC_IRQ 549 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 550 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 551 IRQ_TYPE_LEVEL_HIGH>; + + apple,npins = <18>; }; pinctrl_aop: pinctrl@374824000 { compatible = "apple,t6030-pinctrl", "apple,t8103-pinctrl"; reg = <0x3 0x74824000 0x0 0x4000>; + clocks = <&clkref>; + + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&pinctrl_aop 0 0 54>; + + #interrupt-cells = <2>; + interrupt-controller; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 394 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 395 IRQ_TYPE_LEVEL_HIGH>, @@ -508,17 +535,19 @@ pinctrl_aop: pinctrl@374824000 { <AIC_IRQ 399 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 400 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clkref>; - - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&pinctrl_aop 0 0 54>; apple,npins = <54>; - - interrupt-controller; - #interrupt-cells = <2>; }; }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&aic>; + interrupts = <AIC_FIQ AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>, + <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>, + <AIC_FIQ AIC_TMR_HV_PHYS IRQ_TYPE_LEVEL_HIGH>, + <AIC_FIQ AIC_TMR_HV_VIRT IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "phys", "virt", "hyp-phys", "hyp-virt"; + }; }; #include "t6030-pmgr.dtsi"
diff --git a/arch/arm64/boot/dts/apple/t6031-base.dtsi b/arch/arm64/boot/dts/apple/t6031-base.dtsi index 74e1fa5..f62ce06 100644 --- a/arch/arm64/boot/dts/apple/t6031-base.dtsi +++ b/arch/arm64/boot/dts/apple/t6031-base.dtsi
@@ -11,6 +11,13 @@ / { #address-cells = <2>; #size-cells = <2>; + clkref: clock-ref { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "clkref"; + }; + cpus { #address-cells = <2>; #size-cells = <0>; @@ -20,12 +27,15 @@ cluster0 { core0 { cpu = <&cpu_e00>; }; + core1 { cpu = <&cpu_e01>; }; + core2 { cpu = <&cpu_e02>; }; + core3 { cpu = <&cpu_e03>; }; @@ -35,18 +45,23 @@ cluster1 { core0 { cpu = <&cpu_p00>; }; + core1 { cpu = <&cpu_p01>; }; + core2 { cpu = <&cpu_p02>; }; + core3 { cpu = <&cpu_p03>; }; + core4 { cpu = <&cpu_p04>; }; + core5 { cpu = <&cpu_p05>; }; @@ -56,18 +71,23 @@ cluster2 { core0 { cpu = <&cpu_p10>; }; + core1 { cpu = <&cpu_p11>; }; + core2 { cpu = <&cpu_p12>; }; + core3 { cpu = <&cpu_p13>; }; + core4 { cpu = <&cpu_p14>; }; + core5 { cpu = <&cpu_p15>; }; @@ -75,223 +95,232 @@ core5 { }; cpu_e00: cpu@0 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x0>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* to be filled by loader */ - next-level-cache = <&l2_cache_0>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; }; cpu_e01: cpu@1 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x1>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* to be filled by loader */ - next-level-cache = <&l2_cache_0>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; }; cpu_e02: cpu@2 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x2>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* to be filled by loader */ - next-level-cache = <&l2_cache_0>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; }; cpu_e03: cpu@3 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x3>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* to be filled by loader */ - next-level-cache = <&l2_cache_0>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; }; cpu_p00: cpu@10100 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10100>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_1>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; }; cpu_p01: cpu@10101 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10101>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_1>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; }; cpu_p02: cpu@10102 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10102>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_1>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; }; cpu_p03: cpu@10103 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10103>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_1>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; }; cpu_p04: cpu@10104 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10104>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_1>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; }; cpu_p05: cpu@10105 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10105>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_1>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; }; cpu_p10: cpu@10200 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10200>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_2>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_2>; }; cpu_p11: cpu@10201 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10201>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_2>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_2>; }; cpu_p12: cpu@10202 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10202>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_2>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_2>; }; cpu_p13: cpu@10203 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10203>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_2>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_2>; }; cpu_p14: cpu@10204 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10204>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_2>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_2>; }; cpu_p15: cpu@10205 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10205>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_2>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_2>; }; l2_cache_0: l2-cache-0 { compatible = "cache"; cache-level = <2>; - cache-unified; cache-size = <0x400000>; + cache-unified; }; l2_cache_1: l2-cache-1 { compatible = "cache"; cache-level = <2>; - cache-unified; cache-size = <0x1000000>; + cache-unified; }; l2_cache_2: l2-cache-2 { compatible = "cache"; cache-level = <2>; - cache-unified; cache-size = <0x1000000>; + cache-unified; }; }; + reserved-memory { + ranges; + #address-cells = <2>; + #size-cells = <2>; + }; + timer { compatible = "arm,armv8-timer"; interrupt-parent = <&aic>; - interrupt-names = "phys", "virt", "hyp-phys", "hyp-virt"; interrupts = <AIC_FIQ 0 AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>, <AIC_FIQ 0 AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>, <AIC_FIQ 0 AIC_TMR_HV_PHYS IRQ_TYPE_LEVEL_HIGH>, <AIC_FIQ 0 AIC_TMR_HV_VIRT IRQ_TYPE_LEVEL_HIGH>; - }; - - clkref: clock-ref { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <24000000>; - clock-output-names = "clkref"; - }; - - reserved-memory { - #address-cells = <2>; - #size-cells = <2>; - ranges; + interrupt-names = "phys", "virt", "hyp-phys", "hyp-virt"; }; };
diff --git a/arch/arm64/boot/dts/apple/t6031-die0.dtsi b/arch/arm64/boot/dts/apple/t6031-die0.dtsi index 47d0867..b144434 100644 --- a/arch/arm64/boot/dts/apple/t6031-die0.dtsi +++ b/arch/arm64/boot/dts/apple/t6031-die0.dtsi
@@ -6,14 +6,15 @@ * Copyright The Asahi Linux Contributors */ +&SOC_NODE { aic: interrupt-controller@292400000 { compatible = "apple,t6031-aic3", "apple,t8122-aic3"; - #interrupt-cells = <4>; - interrupt-controller; - reg = <0x00000002 0x92400000 0x00000000 0x1cc000>, <0x00000002 0x92440000 0x00000000 0x4000>; reg-names = "core", "event"; + + #interrupt-cells = <4>; + interrupt-controller; power-domains = <&ps_aic>; }; @@ -29,169 +30,181 @@ pinctrl_smc: pinctrl@2a4820000 { compatible = "apple,t6031-pinctrl", "apple,t8103-pinctrl"; reg = <0x2 0xa4820000 0x0 0x4000>; - gpio-controller; #gpio-cells = <2>; + gpio-controller; gpio-ranges = <&pinctrl_smc 0 0 30>; - apple,npins = <30>; - interrupt-controller; #interrupt-cells = <2>; + interrupt-controller; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 0 904 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ 0 905 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ 0 906 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ 0 907 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ 0 908 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ 0 909 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ 0 910 IRQ_TYPE_LEVEL_HIGH>; + <AIC_IRQ 0 905 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 0 906 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 0 907 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 0 908 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 0 909 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 0 910 IRQ_TYPE_LEVEL_HIGH>; + + apple,npins = <30>; }; i2c0: i2c@391010000 { compatible = "apple,t6031-i2c", "apple,t8103-i2c"; reg = <0x3 0x91010000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 0 1326 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c0_pins>; pinctrl-names = "default"; power-domains = <&ps_i2c0>; - #address-cells = <0x1>; #size-cells = <0x0>; }; i2c1: i2c@391014000 { compatible = "apple,t6031-i2c", "apple,t8103-i2c"; reg = <0x3 0x91014000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 0 1327 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c1_pins>; pinctrl-names = "default"; power-domains = <&ps_i2c1>; - #address-cells = <0x1>; #size-cells = <0x0>; + status = "disabled"; }; i2c2: i2c@391018000 { compatible = "apple,t6031-i2c", "apple,t8103-i2c"; reg = <0x3 0x91018000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 0 1328 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c2_pins>; pinctrl-names = "default"; power-domains = <&ps_i2c2>; - #address-cells = <0x1>; #size-cells = <0x0>; + status = "disabled"; }; i2c3: i2c@39101c000 { compatible = "apple,t6031-i2c", "apple,t8103-i2c"; reg = <0x3 0x9101c000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 0 1329 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c3_pins>; pinctrl-names = "default"; power-domains = <&ps_i2c3>; - #address-cells = <0x1>; #size-cells = <0x0>; + status = "disabled"; }; i2c4: i2c@391020000 { compatible = "apple,t6031-i2c", "apple,t8103-i2c"; reg = <0x3 0x91020000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 0 1330 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c4_pins>; pinctrl-names = "default"; power-domains = <&ps_i2c4>; - #address-cells = <0x1>; #size-cells = <0x0>; + status = "disabled"; }; i2c5: i2c@391024000 { compatible = "apple,t6031-i2c", "apple,t8103-i2c"; reg = <0x3 0x91024000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 0 1331 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c5_pins>; pinctrl-names = "default"; power-domains = <&ps_i2c5>; - #address-cells = <0x1>; #size-cells = <0x0>; + status = "disabled"; }; i2c6: i2c@391028000 { compatible = "apple,t6031-i2c", "apple,t8103-i2c"; reg = <0x3 0x91028000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 0 1332 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c6_pins>; pinctrl-names = "default"; power-domains = <&ps_i2c6>; - #address-cells = <0x1>; #size-cells = <0x0>; + status = "disabled"; }; i2c7: i2c@39102c000 { compatible = "apple,t6031-i2c", "apple,t8103-i2c"; reg = <0x3 0x9102c000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 0 1333 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c7_pins>; pinctrl-names = "default"; power-domains = <&ps_i2c7>; - #address-cells = <0x1>; #size-cells = <0x0>; + status = "disabled"; }; i2c8: i2c@391030000 { compatible = "apple,t6031-i2c", "apple,t8103-i2c"; reg = <0x3 0x91030000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 0 1334 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c8_pins>; pinctrl-names = "default"; power-domains = <&ps_i2c8>; - #address-cells = <0x1>; #size-cells = <0x0>; + status = "disabled"; }; fpwm0: pwm@391040000 { compatible = "apple,t6031-fpwm", "apple,s5l-fpwm"; reg = <0x3 0x91040000 0x0 0x4000>; - power-domains = <&ps_fpwm0>; clocks = <&clkref>; + power-domains = <&ps_fpwm0>; #pwm-cells = <2>; + status = "disabled"; }; serial0: serial@391200000 { compatible = "apple,s5l-uart"; reg = <0x3 0x91200000 0x0 0x4000>; - reg-io-width = <4>; - interrupt-parent = <&aic>; - interrupts = <AIC_IRQ 0 1303 IRQ_TYPE_LEVEL_HIGH>; /* * TODO: figure out the clocking properly, there may * be a third selectable clock. */ clocks = <&clkref>, <&clkref>; clock-names = "uart", "clk_uart_baud0"; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 0 1303 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&ps_uart0>; + reg-io-width = <4>; + status = "disabled"; }; +};
diff --git a/arch/arm64/boot/dts/apple/t6031-dieX.dtsi b/arch/arm64/boot/dts/apple/t6031-dieX.dtsi index 2e9d3d2..1624651 100644 --- a/arch/arm64/boot/dts/apple/t6031-dieX.dtsi +++ b/arch/arm64/boot/dts/apple/t6031-dieX.dtsi
@@ -6,102 +6,106 @@ * Copyright The Asahi Linux Contributors */ +&SOC_NODE { DIE_NODE(pmgr): power-management@292280000 { - compatible = "apple,t6031-pmgr", "apple,t8103-pmgr", "syscon", "simple-mfd"; + compatible = "apple,t6031-pmgr", "apple,t8103-pmgr", + "syscon", "simple-mfd"; + reg = <0x2 0x92280000 0 0xc000>; #address-cells = <1>; #size-cells = <1>; - - reg = <0x2 0x92280000 0 0xc000>; }; DIE_NODE(pmgr1): power-management@292800000 { - compatible = "apple,t6031-pmgr", "apple,t8103-pmgr", "syscon", "simple-mfd"; + compatible = "apple,t6031-pmgr", "apple,t8103-pmgr", + "syscon", "simple-mfd"; + reg = <0x2 0x92800000 0 0x4000>; #address-cells = <1>; #size-cells = <1>; - - reg = <0x2 0x92800000 0 0x4000>; }; DIE_NODE(pinctrl_nub): pinctrl@2a01f0000 { compatible = "apple,t6031-pinctrl", "apple,t8103-pinctrl"; reg = <0x2 0xa01f0000 0x0 0x4000>; - power-domains = <&DIE_NODE(ps_nub_gpio)>; - gpio-controller; #gpio-cells = <2>; + gpio-controller; gpio-ranges = <&DIE_NODE(pinctrl_nub) 0 0 59>; - apple,npins = <59>; - interrupt-controller; #interrupt-cells = <2>; + interrupt-controller; interrupt-parent = <&aic>; interrupts = <AIC_IRQ DIE_NO 710 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 711 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 712 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 713 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 714 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 715 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 716 IRQ_TYPE_LEVEL_HIGH>; + <AIC_IRQ DIE_NO 711 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ DIE_NO 712 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ DIE_NO 713 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ DIE_NO 714 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ DIE_NO 715 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ DIE_NO 716 IRQ_TYPE_LEVEL_HIGH>; + + power-domains = <&DIE_NODE(ps_nub_gpio)>; + apple,npins = <59>; }; DIE_NODE(pmgr_mini): power-management@2a0280000 { - compatible = "apple,t6031-pmgr", "apple,t8103-pmgr", "syscon", "simple-mfd"; + compatible = "apple,t6031-pmgr", "apple,t8103-pmgr", + "syscon", "simple-mfd"; + reg = <0x2 0xa0280000 0 0x4000>; #address-cells = <1>; #size-cells = <1>; - - reg = <0x2 0xa0280000 0 0x4000>; }; DIE_NODE(pinctrl_aop): pinctrl@2a8824000 { compatible = "apple,t6031-pinctrl", "apple,t8103-pinctrl"; reg = <0x2 0xa8824000 0x0 0x4000>; - gpio-controller; #gpio-cells = <2>; + gpio-controller; gpio-ranges = <&DIE_NODE(pinctrl_aop) 0 0 102>; - apple,npins = <102>; - interrupt-controller; #interrupt-cells = <2>; + interrupt-controller; interrupt-parent = <&aic>; interrupts = <AIC_IRQ DIE_NO 595 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 596 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 597 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 598 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 599 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 600 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 601 IRQ_TYPE_LEVEL_HIGH>; + <AIC_IRQ DIE_NO 596 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ DIE_NO 597 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ DIE_NO 598 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ DIE_NO 599 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ DIE_NO 600 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ DIE_NO 601 IRQ_TYPE_LEVEL_HIGH>; + + apple,npins = <102>; }; DIE_NODE(pinctrl_ap): pinctrl@2b3000000 { compatible = "apple,t6031-pinctrl", "apple,t8103-pinctrl"; reg = <0x2 0xb3000000 0x0 0x4000>; + clocks = <&clkref>; + + #gpio-cells = <2>; + gpio-controller; + gpio-ranges = <&DIE_NODE(pinctrl_ap) 0 0 200>; + + #interrupt-cells = <2>; + interrupt-controller; interrupt-parent = <&aic>; interrupts = <AIC_IRQ DIE_NO 458 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 459 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 460 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 461 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 462 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 463 IRQ_TYPE_LEVEL_HIGH>, - <AIC_IRQ DIE_NO 464 IRQ_TYPE_LEVEL_HIGH>; + <AIC_IRQ DIE_NO 459 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ DIE_NO 460 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ DIE_NO 461 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ DIE_NO 462 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ DIE_NO 463 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ DIE_NO 464 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&clkref>; power-domains = <&DIE_NODE(ps_gpio)>; - - gpio-controller; - #gpio-cells = <2>; - gpio-ranges = <&DIE_NODE(pinctrl_ap) 0 0 200>; apple,npins = <200>; - - interrupt-controller; - #interrupt-cells = <2>; }; DIE_NODE(pmgr_gfx): power-management@408e80000 { - compatible = "apple,t6031-pmgr", "apple,t8103-pmgr", "syscon", "simple-mfd"; + compatible = "apple,t6031-pmgr", "apple,t8103-pmgr", + "syscon", "simple-mfd"; + reg = <0x4 0x8e80000 0 0x4000>; #address-cells = <1>; #size-cells = <1>; - - reg = <0x4 0x8e80000 0 0x4000>; }; +};
diff --git a/arch/arm64/boot/dts/apple/t6031-gpio-pins.dtsi b/arch/arm64/boot/dts/apple/t6031-gpio-pins.dtsi index 5e4727e..0c0d099 100644 --- a/arch/arm64/boot/dts/apple/t6031-gpio-pins.dtsi +++ b/arch/arm64/boot/dts/apple/t6031-gpio-pins.dtsi
@@ -8,46 +8,46 @@ &pinctrl_ap { i2c0_pins: i2c0-pins { pinmux = <APPLE_PINMUX(56, 1)>, - <APPLE_PINMUX(57, 1)>; + <APPLE_PINMUX(57, 1)>; }; i2c1_pins: i2c1-pins { pinmux = <APPLE_PINMUX(58, 1)>, - <APPLE_PINMUX(59, 1)>; + <APPLE_PINMUX(59, 1)>; }; i2c2_pins: i2c2-pins { pinmux = <APPLE_PINMUX(60, 1)>, - <APPLE_PINMUX(61, 1)>; + <APPLE_PINMUX(61, 1)>; }; i2c3_pins: i2c3-pins { pinmux = <APPLE_PINMUX(62, 1)>, - <APPLE_PINMUX(63, 1)>; + <APPLE_PINMUX(63, 1)>; }; i2c4_pins: i2c4-pins { pinmux = <APPLE_PINMUX(64, 1)>, - <APPLE_PINMUX(65, 1)>; + <APPLE_PINMUX(65, 1)>; }; i2c5_pins: i2c5-pins { pinmux = <APPLE_PINMUX(66, 1)>, - <APPLE_PINMUX(67, 1)>; + <APPLE_PINMUX(67, 1)>; }; i2c6_pins: i2c6-pins { pinmux = <APPLE_PINMUX(68, 1)>, - <APPLE_PINMUX(69, 1)>; + <APPLE_PINMUX(69, 1)>; }; i2c7_pins: i2c7-pins { pinmux = <APPLE_PINMUX(70, 1)>, - <APPLE_PINMUX(71, 1)>; + <APPLE_PINMUX(71, 1)>; }; i2c8_pins: i2c8-pins { pinmux = <APPLE_PINMUX(72, 1)>, - <APPLE_PINMUX(73, 1)>; + <APPLE_PINMUX(73, 1)>; }; };
diff --git a/arch/arm64/boot/dts/apple/t6031-pmgr.dtsi b/arch/arm64/boot/dts/apple/t6031-pmgr.dtsi index f80ee5f..721ab2e 100644 --- a/arch/arm64/boot/dts/apple/t6031-pmgr.dtsi +++ b/arch/arm64/boot/dts/apple/t6031-pmgr.dtsi
@@ -1383,6 +1383,7 @@ DIE_NODE(ps_afi_d2d_0): power-controller@2d0 { #reset-cells = <0>; label = DIE_LABEL(afi_d2d_0); apple,always-on; + status = "disabled"; }; @@ -1393,6 +1394,7 @@ DIE_NODE(ps_afi_d2d_1): power-controller@2e0 { #reset-cells = <0>; label = DIE_LABEL(afi_d2d_1); apple,always-on; + status = "disabled"; }; @@ -1403,6 +1405,7 @@ DIE_NODE(ps_afc_d2d_0): power-controller@2f0 { #reset-cells = <0>; label = DIE_LABEL(afc_d2d_0); apple,always-on; + status = "disabled"; }; @@ -1413,6 +1416,7 @@ DIE_NODE(ps_afc_d2d_1): power-controller@300 { #reset-cells = <0>; label = DIE_LABEL(afc_d2d_1); apple,always-on; + status = "disabled"; }; @@ -1423,6 +1427,7 @@ DIE_NODE(ps_afr_d2d_0): power-controller@310 { #reset-cells = <0>; label = DIE_LABEL(afr_d2d_0); apple,always-on; + status = "disabled"; }; @@ -1433,6 +1438,7 @@ DIE_NODE(ps_afr_d2d_1): power-controller@320 { #reset-cells = <0>; label = DIE_LABEL(afr_d2d_1); apple,always-on; + status = "disabled"; };
diff --git a/arch/arm64/boot/dts/apple/t6031.dtsi b/arch/arm64/boot/dts/apple/t6031.dtsi index 0059afe..a2aa64e 100644 --- a/arch/arm64/boot/dts/apple/t6031.dtsi +++ b/arch/arm64/boot/dts/apple/t6031.dtsi
@@ -21,13 +21,12 @@ / { soc: soc { compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <2>; - ranges; - nonposted-mmio; + #address-cells = <2>; /* Required to get >32-bit DMA via DARTs */ dma-ranges = <0 0 0 0 0xffffffff 0xffffc000>; + nonposted-mmio; + #size-cells = <2>; // filled via templated includes at the end of the file }; @@ -35,14 +34,13 @@ soc: soc { #define DIE #define DIE_NO 0 +#define SOC_NODE soc -&soc { - #include "t6031-die0.dtsi" - #include "t6031-dieX.dtsi" -}; - +#include "t6031-die0.dtsi" +#include "t6031-dieX.dtsi" #include "t6031-gpio-pins.dtsi" #include "t6031-pmgr.dtsi" #undef DIE #undef DIE_NO +#undef SOC_NODE
diff --git a/arch/arm64/boot/dts/apple/t6032-j575d.dts b/arch/arm64/boot/dts/apple/t6032-j575d.dts index 56edfb1..1299154 100644 --- a/arch/arm64/boot/dts/apple/t6032-j575d.dts +++ b/arch/arm64/boot/dts/apple/t6032-j575d.dts
@@ -20,18 +20,20 @@ aliases { }; chosen { + ranges; #address-cells = <2>; #size-cells = <2>; - ranges; stdout-path = "serial0"; - framebuffer0: framebuffer@0 { - compatible = "apple,simple-framebuffer", "simple-framebuffer"; + framebuffer@0 { + compatible = "apple,simple-framebuffer", + "simple-framebuffer"; reg = <0 0 0 0>; /* To be filled by loader */ /* Format properties will be added by loader */ - status = "disabled"; power-domains = <&ps_dispext0_cpu>; + + status = "disabled"; }; };
diff --git a/arch/arm64/boot/dts/apple/t6032.dtsi b/arch/arm64/boot/dts/apple/t6032.dtsi index bbf19ec..efe56d2 100644 --- a/arch/arm64/boot/dts/apple/t6032.dtsi +++ b/arch/arm64/boot/dts/apple/t6032.dtsi
@@ -33,12 +33,15 @@ cluster3 { core0 { cpu = <&cpu_e10>; }; + core1 { cpu = <&cpu_e11>; }; + core2 { cpu = <&cpu_e12>; }; + core3 { cpu = <&cpu_e13>; }; @@ -48,18 +51,23 @@ cluster4 { core0 { cpu = <&cpu_p20>; }; + core1 { cpu = <&cpu_p21>; }; + core2 { cpu = <&cpu_p22>; }; + core3 { cpu = <&cpu_p23>; }; + core4 { cpu = <&cpu_p24>; }; + core5 { cpu = <&cpu_p25>; }; @@ -69,18 +77,23 @@ cluster5 { core0 { cpu = <&cpu_p30>; }; + core1 { cpu = <&cpu_p31>; }; + core2 { cpu = <&cpu_p32>; }; + core3 { cpu = <&cpu_p33>; }; + core4 { cpu = <&cpu_p34>; }; + core5 { cpu = <&cpu_p35>; }; @@ -88,228 +101,244 @@ core5 { }; cpu_e10: cpu@800 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x800>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* to be filled by loader */ - next-level-cache = <&l2_cache_3>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_3>; }; cpu_e11: cpu@801 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x801>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* to be filled by loader */ - next-level-cache = <&l2_cache_3>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_3>; }; cpu_e12: cpu@802 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x802>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* to be filled by loader */ - next-level-cache = <&l2_cache_3>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_3>; }; cpu_e13: cpu@803 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x803>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* to be filled by loader */ - next-level-cache = <&l2_cache_3>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_3>; }; cpu_p20: cpu@10900 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10900>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_4>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_4>; }; cpu_p21: cpu@10901 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10901>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_4>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_4>; }; cpu_p22: cpu@10902 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10902>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_4>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_4>; }; cpu_p23: cpu@10903 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10903>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_4>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_4>; }; cpu_p24: cpu@10904 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10904>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_4>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_4>; }; cpu_p25: cpu@10905 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10905>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_4>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_4>; }; cpu_p30: cpu@10a00 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10a00>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_5>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_5>; }; cpu_p31: cpu@10a01 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10a01>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_5>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_5>; }; cpu_p32: cpu@10a02 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10a02>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_5>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_5>; }; cpu_p33: cpu@10a03 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10a03>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_5>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_5>; }; cpu_p34: cpu@10a04 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10a04>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_5>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_5>; }; cpu_p35: cpu@10a05 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10a05>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_5>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_5>; }; l2_cache_3: l2-cache-3 { compatible = "cache"; cache-level = <2>; - cache-unified; cache-size = <0x400000>; + cache-unified; }; l2_cache_4: l2-cache-4 { compatible = "cache"; cache-level = <2>; - cache-unified; cache-size = <0x1000000>; + cache-unified; }; l2_cache_5: l2-cache-5 { compatible = "cache"; cache-level = <2>; - cache-unified; cache-size = <0x1000000>; + cache-unified; }; - }; + }; die0: soc@200000000 { compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <2>; ranges = <0x02 0x00000000 0x02 0x00000000 0x4 0x00000000>, <0x05 0x80000000 0x05 0x80000000 0x1 0x80000000>, <0x07 0x00000000 0x07 0x00000000 0xf 0x80000000>, <0x16 0x80000000 0x16 0x80000000 0x5 0x80000000>; - nonposted-mmio; + #address-cells = <2>; /* Required to get >32-bit DMA via DARTs */ dma-ranges = <0 0 0 0 0xffffffff 0xffffc000>; + nonposted-mmio; + #size-cells = <2>; // filled via templated includes at the end of the file }; die1: soc@2200000000 { compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <2>; ranges = <0x02 0x00000000 0x22 0x00000000 0x4 0x00000000>, <0x07 0x00000000 0x27 0x00000000 0xf 0x80000000>, <0x16 0x80000000 0x36 0x80000000 0x5 0x80000000>; - nonposted-mmio; + #address-cells = <2>; /* Required to get >32-bit DMA via DARTs */ dma-ranges = <0 0 0 0 0xffffffff 0xffffc000>; + nonposted-mmio; + #size-cells = <2>; // filled via templated includes at the end of the file }; @@ -317,31 +346,29 @@ die1: soc@2200000000 { #define DIE #define DIE_NO 0 +#define SOC_NODE die0 -&die0 { - #include "t6031-die0.dtsi" - #include "t6031-dieX.dtsi" -}; - +#include "t6031-die0.dtsi" +#include "t6031-dieX.dtsi" #include "t6031-pmgr.dtsi" #include "t6031-gpio-pins.dtsi" #undef DIE #undef DIE_NO +#undef SOC_NODE #define DIE _die1 #define DIE_NO 1 +#define SOC_NODE die1 -&die1 { - #include "t6031-dieX.dtsi" -}; - +#include "t6031-dieX.dtsi" #include "t6031-pmgr.dtsi" /delete-node/ &ps_pmp_die1; #undef DIE #undef DIE_NO +#undef SOC_NODE /* delete non-present DISP power-states */ /delete-node/ &ps_disp_cpu;
diff --git a/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi b/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi index 517b84c1..bbee373 100644 --- a/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi +++ b/arch/arm64/boot/dts/apple/t603x-j514-j516.dtsi
@@ -25,18 +25,20 @@ aliases { }; chosen { + ranges; #address-cells = <2>; #size-cells = <2>; - ranges; stdout-path = "serial0"; framebuffer0: framebuffer@0 { - compatible = "apple,simple-framebuffer", "simple-framebuffer"; + compatible = "apple,simple-framebuffer", + "simple-framebuffer"; reg = <0 0 0 0>; /* To be filled by loader */ /* Format properties will be added by loader */ - status = "disabled"; power-domains = <&ps_disp_fe>; + + status = "disabled"; }; }; @@ -47,12 +49,13 @@ memory@10000000000 { led-controller { compatible = "pwm-leds"; + led-0 { - pwms = <&fpwm0 0 40000>; - function = LED_FUNCTION_KBD_BACKLIGHT; color = <LED_COLOR_ID_WHITE>; - max-brightness = <255>; default-state = "keep"; + function = LED_FUNCTION_KBD_BACKLIGHT; + max-brightness = <255>; + pwms = <&fpwm0 0 40000>; }; }; };
diff --git a/arch/arm64/boot/dts/apple/t8122-j504.dts b/arch/arm64/boot/dts/apple/t8122-j504.dts index 464491b5..e60ec30 100644 --- a/arch/arm64/boot/dts/apple/t8122-j504.dts +++ b/arch/arm64/boot/dts/apple/t8122-j504.dts
@@ -20,13 +20,14 @@ / { led-controller { compatible = "pwm-leds"; + led-0 { - pwms = <&fpwm1 0 40000>; - label = "kbd_backlight"; - function = LED_FUNCTION_KBD_BACKLIGHT; color = <LED_COLOR_ID_WHITE>; - max-brightness = <255>; default-state = "keep"; + function = LED_FUNCTION_KBD_BACKLIGHT; + label = "kbd_backlight"; + max-brightness = <255>; + pwms = <&fpwm1 0 40000>; }; }; }; @@ -34,4 +35,3 @@ led-0 { &fpwm1 { status = "okay"; }; -
diff --git a/arch/arm64/boot/dts/apple/t8122-j613.dts b/arch/arm64/boot/dts/apple/t8122-j613.dts index 51894ea..40274a9 100644 --- a/arch/arm64/boot/dts/apple/t8122-j613.dts +++ b/arch/arm64/boot/dts/apple/t8122-j613.dts
@@ -19,13 +19,14 @@ / { led-controller { compatible = "pwm-leds"; + led-0 { - pwms = <&fpwm1 0 40000>; - label = "kbd_backlight"; - function = LED_FUNCTION_KBD_BACKLIGHT; color = <LED_COLOR_ID_WHITE>; - max-brightness = <255>; default-state = "keep"; + function = LED_FUNCTION_KBD_BACKLIGHT; + label = "kbd_backlight"; + max-brightness = <255>; + pwms = <&fpwm1 0 40000>; }; }; };
diff --git a/arch/arm64/boot/dts/apple/t8122-j615.dts b/arch/arm64/boot/dts/apple/t8122-j615.dts index 2a1970c..61833f6 100644 --- a/arch/arm64/boot/dts/apple/t8122-j615.dts +++ b/arch/arm64/boot/dts/apple/t8122-j615.dts
@@ -19,13 +19,14 @@ / { led-controller { compatible = "pwm-leds"; + led-0 { - pwms = <&fpwm1 0 40000>; - label = "kbd_backlight"; - function = LED_FUNCTION_KBD_BACKLIGHT; color = <LED_COLOR_ID_WHITE>; - max-brightness = <255>; default-state = "keep"; + function = LED_FUNCTION_KBD_BACKLIGHT; + label = "kbd_backlight"; + max-brightness = <255>; + pwms = <&fpwm1 0 40000>; }; }; };
diff --git a/arch/arm64/boot/dts/apple/t8122-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8122-jxxx.dtsi index dd85f0c..2dbdb77 100644 --- a/arch/arm64/boot/dts/apple/t8122-jxxx.dtsi +++ b/arch/arm64/boot/dts/apple/t8122-jxxx.dtsi
@@ -15,9 +15,9 @@ aliases { }; chosen { + ranges; #address-cells = <2>; #size-cells = <2>; - ranges; stdout-path = "serial0"; @@ -26,14 +26,15 @@ framebuffer0: framebuffer@0 { reg = <0 0 0 0>; /* To be filled by loader */ power-domains = <&ps_disp_cpu>, <&ps_dptx_ext_phy>; /* Format properties will be added by loader */ + status = "disabled"; }; }; reserved-memory { + ranges; #address-cells = <2>; #size-cells = <2>; - ranges; /* To be filled by loader */ };
diff --git a/arch/arm64/boot/dts/apple/t8122-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8122-pmgr.dtsi index 6409379..3f8be74 100644 --- a/arch/arm64/boot/dts/apple/t8122-pmgr.dtsi +++ b/arch/arm64/boot/dts/apple/t8122-pmgr.dtsi
@@ -1004,7 +1004,6 @@ ps_disp_cpu: power-controller@10000 { }; &pmgr_mini { - ps_debug_gated: power-controller@0 { compatible = "apple,t8122-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; reg = <0x0 4>;
diff --git a/arch/arm64/boot/dts/apple/t8122.dtsi b/arch/arm64/boot/dts/apple/t8122.dtsi index 1ee61c5..52257fa 100644 --- a/arch/arm64/boot/dts/apple/t8122.dtsi +++ b/arch/arm64/boot/dts/apple/t8122.dtsi
@@ -20,6 +20,13 @@ / { #address-cells = <2>; #size-cells = <2>; + clkref: clock-ref { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "clkref"; + }; + cpus { #address-cells = <2>; #size-cells = <0>; @@ -29,12 +36,15 @@ cluster0 { core0 { cpu = <&cpu_e0>; }; + core1 { cpu = <&cpu_e1>; }; + core2 { cpu = <&cpu_e2>; }; + core3 { cpu = <&cpu_e3>; }; @@ -44,12 +54,15 @@ cluster1 { core0 { cpu = <&cpu_p0>; }; + core1 { cpu = <&cpu_p1>; }; + core2 { cpu = <&cpu_p2>; }; + core3 { cpu = <&cpu_p3>; }; @@ -57,272 +70,238 @@ core3 { }; cpu_e0: cpu@0 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x0>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_0>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; }; cpu_e1: cpu@1 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x1>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_0>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; }; cpu_e2: cpu@2 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x2>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_0>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; }; cpu_e3: cpu@3 { - compatible = "apple,sawtooth"; device_type = "cpu"; + compatible = "apple,sawtooth"; reg = <0x0 0x3>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_0>; - i-cache-size = <0x20000>; + enable-method = "spin-table"; + d-cache-size = <0x10000>; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; }; cpu_p0: cpu@10100 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10100>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_1>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; }; cpu_p1: cpu@10101 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10101>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_1>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; }; cpu_p2: cpu@10102 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10102>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_1>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; }; cpu_p3: cpu@10103 { - compatible = "apple,everest"; device_type = "cpu"; + compatible = "apple,everest"; reg = <0x0 0x10103>; - enable-method = "spin-table"; cpu-release-addr = <0 0>; /* To be filled by loader */ - next-level-cache = <&l2_cache_1>; - i-cache-size = <0x30000>; + enable-method = "spin-table"; + d-cache-size = <0x20000>; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; }; l2_cache_0: l2-cache-0 { compatible = "cache"; cache-level = <2>; - cache-unified; cache-size = <0x400000>; + cache-unified; }; l2_cache_1: l2-cache-1 { compatible = "cache"; cache-level = <2>; - cache-unified; cache-size = <0x1000000>; + cache-unified; }; }; - timer { - compatible = "arm,armv8-timer"; - interrupt-parent = <&aic>; - interrupt-names = "phys", "virt", "hyp-phys", "hyp-virt"; - interrupts = <AIC_FIQ AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>, - <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>, - <AIC_FIQ AIC_TMR_HV_PHYS IRQ_TYPE_LEVEL_HIGH>, - <AIC_FIQ AIC_TMR_HV_VIRT IRQ_TYPE_LEVEL_HIGH>; - }; - - clkref: clock-ref { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <24000000>; - clock-output-names = "clkref"; - }; - soc { compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <2>; - ranges; - nonposted-mmio; + #address-cells = <2>; + /* Required to get >32-bit DMA via DARTs */ dma-ranges = <0 0 0 0 0xffffffff 0xffffc000>; + nonposted-mmio; + #size-cells = <2>; i2c0: i2c@2a1010000 { compatible = "apple,t8122-i2c", "apple,t8103-i2c"; reg = <0x2 0xa1010000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 780 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c0_pins>; pinctrl-names = "default"; - #address-cells = <0x1>; - #size-cells = <0x0>; power-domains = <&ps_i2c0>; + #size-cells = <0x0>; + status = "disabled"; }; i2c1: i2c@2a1014000 { compatible = "apple,t8122-i2c", "apple,t8103-i2c"; reg = <0x2 0xa1014000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 781 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c1_pins>; pinctrl-names = "default"; - #address-cells = <0x1>; - #size-cells = <0x0>; power-domains = <&ps_i2c1>; + #size-cells = <0x0>; + status = "disabled"; }; i2c2: i2c@2a1018000 { compatible = "apple,t8122-i2c", "apple,t8103-i2c"; reg = <0x2 0xa1018000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 782 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c2_pins>; pinctrl-names = "default"; - #address-cells = <0x1>; - #size-cells = <0x0>; power-domains = <&ps_i2c2>; + #size-cells = <0x0>; + status = "disabled"; }; i2c3: i2c@2a101c000 { compatible = "apple,t8122-i2c", "apple,t8103-i2c"; reg = <0x2 0xa101c000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 783 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c3_pins>; pinctrl-names = "default"; - #address-cells = <0x1>; - #size-cells = <0x0>; power-domains = <&ps_i2c3>; + #size-cells = <0x0>; + status = "disabled"; }; i2c4: i2c@2a1020000 { compatible = "apple,t8122-i2c", "apple,t8103-i2c"; reg = <0x2 0xa1020000 0x0 0x4000>; + #address-cells = <0x1>; clocks = <&clkref>; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 784 IRQ_TYPE_LEVEL_HIGH>; pinctrl-0 = <&i2c4_pins>; pinctrl-names = "default"; - #address-cells = <0x1>; - #size-cells = <0x0>; power-domains = <&ps_i2c4>; + #size-cells = <0x0>; + status = "disabled"; }; fpwm1: pwm@2a1044000 { compatible = "apple,t8122-fpwm", "apple,s5l-fpwm"; reg = <0x2 0xa1044000 0x0 0x4000>; - power-domains = <&ps_fpwm1>; clocks = <&clkref>; + power-domains = <&ps_fpwm1>; #pwm-cells = <2>; + status = "disabled"; }; serial0: serial@2a1200000 { compatible = "apple,s5l-uart"; reg = <0x2 0xa1200000 0x0 0x1000>; - reg-io-width = <4>; - interrupt-parent = <&aic>; - interrupts = <AIC_IRQ 757 IRQ_TYPE_LEVEL_HIGH>; /* * TODO: figure out the clocking properly, there may * be a third selectable clock. */ clocks = <&clkref>, <&clkref>; clock-names = "uart", "clk_uart_baud0"; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 757 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&ps_uart0>; + reg-io-width = <4>; + status = "disabled"; }; - aic: interrupt-controller@2d1000000 { - compatible = "apple,t8122-aic3"; - #interrupt-cells = <3>; - interrupt-controller; - reg = <0x2 0xd1000000 0x0 0x184000>, - <0x2 0xd1040000 0x0 0x4>; - reg-names = "core", "event"; - power-domains = <&ps_aic>; - - affinities { - e-core-pmu-affinity { - apple,fiq-index = <AIC_CPU_PMU_E>; - cpus = <&cpu_e0 &cpu_e1 &cpu_e2 &cpu_e3>; - }; - - p-core-pmu-affinity { - apple,fiq-index = <AIC_CPU_PMU_P>; - cpus = <&cpu_p0 &cpu_p1 &cpu_p2 &cpu_p3>; - }; - }; - }; - - pmgr: power-management@2d0700000 { - compatible = "apple,t8122-pmgr", "apple,t8103-pmgr", "syscon", "simple-mfd"; - #address-cells = <1>; - #size-cells = <1>; - reg = <0x2 0xd0700000 0 0x14000>; - /* child nodes are added in t8122-pmgr.dtsi */ - }; - pinctrl_ap: pinctrl@2c7100000 { compatible = "apple,t8122-pinctrl", "apple,t8103-pinctrl"; reg = <0x2 0xc7100000 0x0 0x100000>; - power-domains = <&ps_gpio>; - gpio-controller; #gpio-cells = <2>; + gpio-controller; gpio-ranges = <&pinctrl_ap 0 0 224>; - apple,npins = <224>; - interrupt-controller; #interrupt-cells = <2>; + interrupt-controller; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 241 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 242 IRQ_TYPE_LEVEL_HIGH>, @@ -332,6 +311,9 @@ pinctrl_ap: pinctrl@2c7100000 { <AIC_IRQ 246 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 247 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&ps_gpio>; + apple,npins = <224>; + i2c0_pins: i2c0-pins { pinmux = <APPLE_PINMUX(145, 1)>, <APPLE_PINMUX(144, 1)>; @@ -356,21 +338,49 @@ i2c4_pins: i2c4-pins { pinmux = <APPLE_PINMUX(149, 1)>, <APPLE_PINMUX(148, 1)>; }; + }; + pmgr: power-management@2d0700000 { + compatible = "apple,t8122-pmgr", "apple,t8103-pmgr", + "syscon", "simple-mfd"; + reg = <0x2 0xd0700000 0 0x14000>; + #address-cells = <1>; + #size-cells = <1>; + /* child nodes are added in t8122-pmgr.dtsi */ + }; + + aic: interrupt-controller@2d1000000 { + compatible = "apple,t8122-aic3"; + reg = <0x2 0xd1000000 0x0 0x184000>, + <0x2 0xd1040000 0x0 0x4>; + reg-names = "core", "event"; + #interrupt-cells = <3>; + interrupt-controller; + power-domains = <&ps_aic>; + + affinities { + e-core-pmu-affinity { + cpus = <&cpu_e0 &cpu_e1 &cpu_e2 &cpu_e3>; + apple,fiq-index = <AIC_CPU_PMU_E>; + }; + + p-core-pmu-affinity { + cpus = <&cpu_p0 &cpu_p1 &cpu_p2 &cpu_p3>; + apple,fiq-index = <AIC_CPU_PMU_P>; + }; + }; }; pinctrl_nub: pinctrl@2e41f0000 { compatible = "apple,t8122-pinctrl", "apple,t8103-pinctrl"; reg = <0x2 0xe41f0000 0x0 0x4000>; - power-domains = <&ps_nub_gpio>; - gpio-controller; #gpio-cells = <2>; + gpio-controller; gpio-ranges = <&pinctrl_nub 0 0 32>; - apple,npins = <32>; - interrupt-controller; #interrupt-cells = <2>; + interrupt-controller; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 424 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 425 IRQ_TYPE_LEVEL_HIGH>, @@ -379,13 +389,17 @@ pinctrl_nub: pinctrl@2e41f0000 { <AIC_IRQ 428 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 429 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 430 IRQ_TYPE_LEVEL_HIGH>; + + power-domains = <&ps_nub_gpio>; + apple,npins = <32>; }; pmgr_mini: power-management@2e4280000 { - compatible = "apple,t8122-pmgr", "apple,t8103-pmgr", "syscon", "simple-mfd"; + compatible = "apple,t8122-pmgr", "apple,t8103-pmgr", + "syscon", "simple-mfd"; + reg = <0x2 0xe4280000 0 0x4000>; #address-cells = <1>; #size-cells = <1>; - reg = <0x2 0xe4280000 0 0x4000>; /* child nodes are added in t8122-pmgr.dtsi */ }; @@ -401,13 +415,12 @@ pinctrl_smc: pinctrl@2ec820000 { compatible = "apple,t8122-pinctrl", "apple,t8103-pinctrl"; reg = <0x2 0xec820000 0x0 0x4000>; - gpio-controller; #gpio-cells = <2>; + gpio-controller; gpio-ranges = <&pinctrl_smc 0 0 18>; - apple,npins = <18>; - interrupt-controller; #interrupt-cells = <2>; + interrupt-controller; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 493 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 494 IRQ_TYPE_LEVEL_HIGH>, @@ -416,19 +429,20 @@ pinctrl_smc: pinctrl@2ec820000 { <AIC_IRQ 497 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 498 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 499 IRQ_TYPE_LEVEL_HIGH>; + + apple,npins = <18>; }; pinctrl_aop: pinctrl@2f4824000 { compatible = "apple,t8122-pinctrl", "apple,t8103-pinctrl"; reg = <0x2 0xf4824000 0x0 0x4000>; - gpio-controller; #gpio-cells = <2>; + gpio-controller; gpio-ranges = <&pinctrl_aop 0 0 54>; - apple,npins = <54>; - interrupt-controller; #interrupt-cells = <2>; + interrupt-controller; interrupt-parent = <&aic>; interrupts = <AIC_IRQ 346 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 347 IRQ_TYPE_LEVEL_HIGH>, @@ -437,8 +451,20 @@ pinctrl_aop: pinctrl@2f4824000 { <AIC_IRQ 350 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 351 IRQ_TYPE_LEVEL_HIGH>, <AIC_IRQ 352 IRQ_TYPE_LEVEL_HIGH>; + + apple,npins = <54>; }; }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&aic>; + interrupts = <AIC_FIQ AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>, + <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>, + <AIC_FIQ AIC_TMR_HV_PHYS IRQ_TYPE_LEVEL_HIGH>, + <AIC_FIQ AIC_TMR_HV_VIRT IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "phys", "virt", "hyp-phys", "hyp-virt"; + }; }; #include "t8122-pmgr.dtsi"
diff --git a/arch/arm64/boot/dts/apple/t8132-j604.dts b/arch/arm64/boot/dts/apple/t8132-j604.dts new file mode 100644 index 0000000..c4be915 --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8132-j604.dts
@@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Apple MacBook Pro (14-inch, M4, 2024) + * + * target-type: J604 + * + * Copyright The Asahi Linux Contributors + */ + +/dts-v1/; + +#include "t8132.dtsi" +#include "t8132-jxxx.dtsi" +#include <dt-bindings/leds/common.h> + +/ { + compatible = "apple,j604", "apple,t8132", "apple,arm-platform"; + model = "Apple MacBook Pro (14-inch, M4, 2024)"; + + led-controller { + compatible = "pwm-leds"; + led-0 { + pwms = <&fpwm1 0 40000>; + label = "kbd_backlight"; + function = LED_FUNCTION_KBD_BACKLIGHT; + color = <LED_COLOR_ID_WHITE>; + max-brightness = <255>; + default-state = "keep"; + }; + }; +}; + +&fpwm1 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/apple/t8132-j623.dts b/arch/arm64/boot/dts/apple/t8132-j623.dts new file mode 100644 index 0000000..508e260 --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8132-j623.dts
@@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Apple iMac (24-inch, 2x USB-C, M4, 2024) + * + * target-type: J623 + * + * Copyright The Asahi Linux Contributors + */ + +/dts-v1/; + +#include "t8132.dtsi" +#include "t8132-jxxx.dtsi" + +/ { + compatible = "apple,j623", "apple,t8132", "apple,arm-platform"; + model = "Apple iMac (24-inch, 2x USB-C, M4, 2024)"; +};
diff --git a/arch/arm64/boot/dts/apple/t8132-j624.dts b/arch/arm64/boot/dts/apple/t8132-j624.dts new file mode 100644 index 0000000..84bdd8e --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8132-j624.dts
@@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Apple iMac (24-inch, 4x USB-C, M4, 2024) + * + * target-type: J624 + * + * Copyright The Asahi Linux Contributors + */ + +/dts-v1/; + +#include "t8132.dtsi" +#include "t8132-jxxx.dtsi" + +/ { + compatible = "apple,j624", "apple,t8132", "apple,arm-platform"; + model = "Apple iMac (24-inch, 4x USB-C, M4, 2024)"; +};
diff --git a/arch/arm64/boot/dts/apple/t8132-j713.dts b/arch/arm64/boot/dts/apple/t8132-j713.dts new file mode 100644 index 0000000..e1fc5d4 --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8132-j713.dts
@@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Apple MacBook Air (13-inch, M4, 2025) + * + * target-type: J713 + * + * Copyright The Asahi Linux Contributors + */ + +/dts-v1/; + +#include "t8132.dtsi" +#include "t8132-jxxx.dtsi" +#include <dt-bindings/leds/common.h> + +/ { + compatible = "apple,j713", "apple,t8132", "apple,arm-platform"; + model = "Apple MacBook Air (13-inch, M4, 2025)"; + + led-controller { + compatible = "pwm-leds"; + led-0 { + pwms = <&fpwm1 0 40000>; + label = "kbd_backlight"; + function = LED_FUNCTION_KBD_BACKLIGHT; + color = <LED_COLOR_ID_WHITE>; + max-brightness = <255>; + default-state = "keep"; + }; + }; +}; + +&fpwm1 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/apple/t8132-j715.dts b/arch/arm64/boot/dts/apple/t8132-j715.dts new file mode 100644 index 0000000..2672914 --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8132-j715.dts
@@ -0,0 +1,35 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Apple MacBook Air (15-inch, M4, 2025) + * + * target-type: J715 + * + * Copyright The Asahi Linux Contributors + */ + +/dts-v1/; + +#include "t8132.dtsi" +#include "t8132-jxxx.dtsi" +#include <dt-bindings/leds/common.h> + +/ { + compatible = "apple,j715", "apple,t8132", "apple,arm-platform"; + model = "Apple MacBook Air (15-inch, M4, 2025)"; + + led-controller { + compatible = "pwm-leds"; + led-0 { + pwms = <&fpwm1 0 40000>; + label = "kbd_backlight"; + function = LED_FUNCTION_KBD_BACKLIGHT; + color = <LED_COLOR_ID_WHITE>; + max-brightness = <255>; + default-state = "keep"; + }; + }; +}; + +&fpwm1 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/apple/t8132-j773g.dts b/arch/arm64/boot/dts/apple/t8132-j773g.dts new file mode 100644 index 0000000..0583cb9 --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8132-j773g.dts
@@ -0,0 +1,25 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Apple Mac mini (M4, 2024) + * + * target-type: J773g + * + * Copyright The Asahi Linux Contributors + */ + +/dts-v1/; + +#include "t8132.dtsi" +#include "t8132-jxxx.dtsi" + +/ { + compatible = "apple,j773g", "apple,t8132", "apple,arm-platform"; + model = "Apple Mac mini (M4, 2024)"; +}; + +/* + * Keep the power-domains used for the HDMI port on. + */ +&framebuffer0 { + power-domains = <&ps_dispext0_fe>, <&ps_dptx_phy>; +};
diff --git a/arch/arm64/boot/dts/apple/t8132-jxxx.dtsi b/arch/arm64/boot/dts/apple/t8132-jxxx.dtsi new file mode 100644 index 0000000..9882ea3 --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8132-jxxx.dtsi
@@ -0,0 +1,48 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Apple M4 Mac mini, MacBook Air/Pro, iMac 24" (M4, 2024/2025) + * + * This file contains parts common to all Apple M4 devices using the t8132. + * + * target-type: J604, J623, J624, J713, J715, J773g + * + * Copyright The Asahi Linux Contributors + */ + +/ { + aliases { + serial0 = &serial0; + }; + + chosen { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + stdout-path = "serial0"; + + framebuffer0: framebuffer@0 { + compatible = "apple,simple-framebuffer", "simple-framebuffer"; + reg = <0 0 0 0>; /* To be filled by loader */ + power-domains = <&ps_disp_fe>, <&ps_dptx_phy>; + /* Format properties will be added by loader */ + status = "disabled"; + }; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + /* To be filled by loader */ + }; + + memory@800000000 { + device_type = "memory"; + reg = <0x8 0 0x2 0>; /* To be filled by loader */ + }; +}; + +&serial0 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/apple/t8132-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8132-pmgr.dtsi new file mode 100644 index 0000000..6fbf09e --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8132-pmgr.dtsi
@@ -0,0 +1,1130 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * PMGR Power domains for the Apple T8132 "M4" SoC + * + * Copyright The Asahi Linux Contributors + */ + +&pmgr { + ps_msg: power-controller@108 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x108 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "msg"; + }; + + ps_aic: power-controller@110 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x110 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "aic"; + apple,always-on; /* Core device */ + }; + + ps_dwi: power-controller@118 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x118 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dwi"; + }; + + ps_gpio: power-controller@120 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x120 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "gpio"; + }; + + ps_pmc: power-controller@138 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x138 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "pmc"; + }; + + ps_pms_fpwm0: power-controller@140 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x140 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "pms_fpwm0"; + }; + + ps_pms_fpwm1: power-controller@148 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x148 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "pms_fpwm1"; + }; + + ps_pms_fpwm2: power-controller@150 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x150 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "pms_fpwm2"; + }; + + ps_pms_fpwm3: power-controller@158 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x158 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "pms_fpwm3"; + }; + + ps_pms_fpwm4: power-controller@160 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x160 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "pms_fpwm4"; + }; + + ps_pms_c1ppt: power-controller@168 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x168 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "pms_c1ppt"; + }; + + ps_soc_rc: power-controller@170 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x170 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "soc_rc"; + }; + + ps_soc_dpe: power-controller@178 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x178 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "soc_dpe"; + apple,always-on; + }; + + ps_pmgr_soc_ocla: power-controller@180 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x180 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "pmgr_soc_ocla"; + }; + + ps_ap_tmm: power-controller@1b8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x1b8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "ap_tmm"; + }; + + ps_dispext0_sys: power-controller@1d8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x1d8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dispext0_sys"; + }; + + ps_dispext0_fe: power-controller@1e0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x1e0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dispext0_fe"; + power-domains = <&ps_dispext0_sys>; + }; + + ps_dispext0_cpu: power-controller@1e8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x1e8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dispext0_cpu"; + power-domains = <&ps_dispext0_fe>; + + status = "disabled"; /* Locked, don't touch it */ + }; + + ps_scodec: power-controller@228 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x228 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "scodec"; + }; + + ps_scodec_streaming: power-controller@230 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x230 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "scodec_streaming"; + power-domains = <&ps_scodec>; + }; + + ps_disp_sys: power-controller@240 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x240 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "disp_sys"; + apple,always-on; /* TODO: figure out if we can enable PM here */ + }; + + ps_disp_fe: power-controller@248 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x248 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "disp_fe"; + power-domains = <&ps_disp_sys>; + apple,always-on; /* TODO: figure out if we can enable PM here */ + }; + + ps_gfx: power-controller@250 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x250 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "gfx"; + }; + + ps_sio_cpu: power-controller@268 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x268 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "sio_cpu"; + }; + + ps_fpwm0: power-controller@270 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x270 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "fpwm0"; + }; + + ps_fpwm1: power-controller@278 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x278 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "fpwm1"; + }; + + ps_fpwm2: power-controller@280 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x280 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "fpwm2"; + }; + + ps_i2c0: power-controller@288 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x288 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "i2c0"; + }; + + ps_i2c1: power-controller@290 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x290 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "i2c1"; + }; + + ps_i2c2: power-controller@298 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x298 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "i2c2"; + }; + + ps_i2c3: power-controller@2a0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2a0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "i2c3"; + }; + + ps_i2c4: power-controller@2a8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2a8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "i2c4"; + }; + + ps_i2c5: power-controller@2b0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2b0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "i2c5"; + }; + + ps_i2c6: power-controller@2b8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2b8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "i2c6"; + }; + + ps_i2c7: power-controller@2c0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2c0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "i2c7"; + }; + + ps_i2c8: power-controller@2c8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2c8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "i2c8"; + }; + + ps_spi_p: power-controller@2d0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2d0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "spi_p"; + apple,always-on; + }; + + ps_uart_p: power-controller@2d8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2d8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "uart_p"; + apple,always-on; + }; + + ps_dpa_p: power-controller@2e0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2e0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dpa_p"; + apple,always-on; + }; + + ps_aes: power-controller@2e8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2e8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "aes"; + }; + + ps_spi0: power-controller@2f0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2f0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "spi0"; + power-domains = <&ps_spi_p>; + }; + + ps_afiaft: power-controller@300 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x300 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "afiaft"; + }; + + ps_venc_sys: power-controller@308 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x308 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "venc_sys"; + }; + + ps_spi1: power-controller@370 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x370 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "spi1"; + power-domains = <&ps_spi_p>; + }; + + ps_atc0_common: power-controller@378 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x378 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc0_common"; + }; + + ps_spi2: power-controller@380 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x380 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "spi2"; + power-domains = <&ps_spi_p>; + }; + + ps_spi3: power-controller@388 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x388 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "spi3"; + power-domains = <&ps_spi_p>; + }; + + ps_spi4: power-controller@390 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x390 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "spi4"; + power-domains = <&ps_spi_p>; + }; + + ps_trace_fab: power-controller@398 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x398 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "trace_fab"; + }; + + ps_atc0_pcie: power-controller@3a0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3a0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc0_pcie"; + power-domains = <&ps_atc0_common>; + }; + + ps_atc0_cio: power-controller@3a8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3a8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc0_cio"; + power-domains = <&ps_atc0_common>; + }; + + ps_atc0_cio_pcie: power-controller@3b0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3b0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc0_cio_pcie"; + power-domains = <&ps_atc0_cio>; + }; + + ps_spi5: power-controller@3b8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3b8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "spi5"; + power-domains = <&ps_spi_p>; + }; + + ps_qspi: power-controller@3c0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3c0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "qspi"; + power-domains = <&ps_spi_p>; + }; + + ps_dptx_phy: power-controller@3c8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3c8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dptx_phy"; + }; + + ps_uart_n: power-controller@3d0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3d0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "uart_n"; + power-domains = <&ps_uart_p>; + }; + + ps_uart0: power-controller@3d8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3d8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "uart0"; + power-domains = <&ps_uart_p>; + }; + + ps_uart1: power-controller@3e0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3e0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "uart1"; + power-domains = <&ps_uart_p>; + }; + + ps_uart2: power-controller@3e8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3e8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "uart2"; + power-domains = <&ps_uart_p>; + }; + + ps_uart3: power-controller@3f0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3f0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "uart3"; + power-domains = <&ps_uart_p>; + }; + + ps_uart4: power-controller@3f8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3f8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "uart4"; + power-domains = <&ps_uart_p>; + }; + + ps_uart5: power-controller@400 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x400 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "uart5"; + power-domains = <&ps_uart_p>; + }; + + ps_uart6: power-controller@408 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x408 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "uart6"; + power-domains = <&ps_uart_p>; + }; + + ps_dpa0: power-controller@410 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x410 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dpa0"; + power-domains = <&ps_dpa_p>; + }; + + ps_dpa1: power-controller@418 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x418 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dpa1"; + power-domains = <&ps_dpa_p>; + }; + + ps_atc0_cio_usb: power-controller@420 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x420 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc0_cio_usb"; + power-domains = <&ps_atc0_cio>; + }; + + ps_atc1_common: power-controller@428 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x428 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc1_common"; + }; + + ps_atc1_pcie: power-controller@430 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x430 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc1_pcie"; + power-domains = <&ps_atc1_common>; + }; + + ps_atc1_cio: power-controller@438 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x438 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc1_cio"; + power-domains = <&ps_atc1_common>; + }; + + ps_atc1_cio_pcie: power-controller@440 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x440 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc1_cio_pcie"; + power-domains = <&ps_atc1_cio>; + }; + + ps_atc1_cio_usb: power-controller@448 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x448 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc1_cio_usb"; + power-domains = <&ps_atc1_cio>; + }; + + ps_atc2_common: power-controller@450 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x450 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc2_common"; + }; + + ps_atc2_pcie: power-controller@458 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x458 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc2_pcie"; + power-domains = <&ps_atc2_common>; + }; + + ps_atc2_cio: power-controller@460 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x460 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc2_cio"; + power-domains = <&ps_atc2_common>; + }; + + ps_atc2_cio_pcie: power-controller@468 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x468 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc2_cio_pcie"; + power-domains = <&ps_atc2_cio>; + }; + + ps_dpa2: power-controller@470 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x470 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dpa2"; + power-domains = <&ps_dpa_p>; + }; + + ps_atc2_cio_usb: power-controller@478 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x478 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc2_cio_usb"; + power-domains = <&ps_atc2_cio>; + }; + + ps_atc3_common: power-controller@480 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x480 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc3_common"; + }; + + ps_pmp: power-controller@488 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x488 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "pmp"; + apple,always-on; + }; + + ps_pms_sram: power-controller@490 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x490 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "pms_sram"; + apple,always-on; + }; + + ps_atc3_pcie: power-controller@498 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x498 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc3_pcie"; + power-domains = <&ps_atc3_common>; + }; + + ps_atc3_cio: power-controller@4a0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x4a0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc3_cio"; + power-domains = <&ps_atc3_common>; + }; + + ps_dpa3: power-controller@4a8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x4a8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dpa3"; + power-domains = <&ps_dpa_p>; + }; + + ps_atc3_cio_pcie: power-controller@4b0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x4b0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc3_cio_pcie"; + power-domains = <&ps_atc3_cio>; + }; + + ps_atc3_cio_usb: power-controller@4b8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x4b8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc3_cio_usb"; + power-domains = <&ps_atc3_cio>; + }; + + ps_dpa4: power-controller@4c0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x4c0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dpa4"; + power-domains = <&ps_dpa_p>; + }; + + ps_apcie_gp: power-controller@4d0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x4d0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "apcie_gp"; + }; + + ps_apcie_sys_gp: power-controller@4d8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x4d8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "apcie_sys_gp"; + power-domains = <&ps_apcie_gp>; + }; + + ps_dispext1_sys: power-controller@4e0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x4e0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dispext1_sys"; + }; + + ps_dispext1_fe: power-controller@4e8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x4e8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dispext1_fe"; + power-domains = <&ps_dispext1_sys>; + }; + + ps_dispext1_cpu: power-controller@4f0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x4f0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "dispext1_cpu"; + power-domains = <&ps_dispext1_fe>; + + status = "disabled"; /* Locked, don't touch it */ + }; + + ps_ans: power-controller@538 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x538 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "ans"; + apple,always-on; /* Device reboots after 3-5 mintues if disabled */ + }; + + ps_apcie_st: power-controller@540 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x540 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "apcie_st"; + power-domains = <&ps_ans>; + }; + + ps_apcie_sys_st: power-controller@548 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x548 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "apcie_sys_st"; + power-domains = <&ps_ans>, <&ps_apcie_st>; + }; + + ps_apcie_phy_sw: power-controller@550 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x550 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "apcie_phy_sw"; + power-domains = <&ps_apcie_sys_st>, <&ps_apcie_sys_gp>; + }; + + ps_msr: power-controller@560 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x560 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "msr"; + }; + + ps_msr_ase_core: power-controller@568 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x568 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "msr_ase_core"; + power-domains = <&ps_msr>; + }; + + ps_ane_sys: power-controller@570 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x570 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "ane_sys"; + }; + + ps_jpg: power-controller@578 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x578 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "jpg"; + }; + + ps_avd_sys: power-controller@580 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x580 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "avd_sys"; + }; + + ps_sep: power-controller@c00 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xc00 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "sep"; + apple,always-on; + }; + + ps_venc_dma: power-controller@8000 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x8000 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "venc_dma"; + power-domains = <&ps_venc_sys>; + }; + + ps_venc_pipe4: power-controller@8008 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x8008 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "venc_pipe4"; + power-domains = <&ps_venc_dma>; + }; + + ps_venc_pipe5: power-controller@8010 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x8010 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "venc_pipe5"; + power-domains = <&ps_venc_dma>; + }; + + ps_venc_me0: power-controller@8018 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x8018 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "venc_me0"; + power-domains = <&ps_venc_dma>; + }; + + ps_venc_me1: power-controller@8020 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x8020 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "venc_me1"; + power-domains = <&ps_venc_me0>; + }; + + ps_ane_mpm: power-controller@c000 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xc000 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "ane_mpm"; + power-domains = <&ps_ane_sys>; + }; + + ps_ane_cpu: power-controller@c008 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xc008 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "ane_cpu"; + power-domains = <&ps_ane_sys>; + }; + + ps_ane_td: power-controller@c010 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xc010 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "ane_td"; + power-domains = <&ps_ane_sys>; + }; + + ps_ane_base: power-controller@c018 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xc018 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "ane_base"; + power-domains = <&ps_ane_td>; + }; + + ps_disp_cpu: power-controller@10000 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x10000 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "disp_cpu"; + power-domains = <&ps_disp_fe>; + + status = "disabled"; /* Locked, don't touch it */ + }; +}; + +&pmgr_mini { + ps_debug_gated: power-controller@0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "debug_gated"; + apple,always-on; + }; + + ps_nub_spmi0: power-controller@58 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x58 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "nub_spmi0"; + apple,always-on; + }; + + ps_nub_spmi1: power-controller@60 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x60 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "nub_spmi1"; + apple,always-on; + }; + + ps_nub_spmi_a0: power-controller@68 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x68 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "nub_spmi_a0"; + apple,always-on; + }; + + ps_nub_spmi_a1: power-controller@70 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x70 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "nub_spmi_a1"; + apple,always-on; + }; + + ps_nub_spi0: power-controller@80 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x80 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "nub_spi0"; + apple,always-on; + }; + + ps_nub_ocla: power-controller@88 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x88 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "nub_ocla"; + apple,always-on; + }; + + ps_nub_gpio: power-controller@90 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x90 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "nub_gpio"; + apple,always-on; + }; + + ps_nub_sram: power-controller@a0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xa0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "nub_sram"; + apple,always-on; + }; + + ps_debug_switch: power-controller@a8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xa8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "debug_switch"; + apple,always-on; + }; + + ps_atc0_usb_aon: power-controller@b0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xb0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc0_usb_aon"; + }; + + ps_atc1_usb_aon: power-controller@b8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xb8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc1_usb_aon"; + }; + + ps_atc0_usb: power-controller@c0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xc0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc0_usb"; + power-domains = <&ps_atc0_common>, <&ps_atc0_usb_aon>; + }; + + ps_atc1_usb: power-controller@c8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xc8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc1_usb"; + power-domains = <&ps_atc1_common>, <&ps_atc1_usb_aon>; + }; + + ps_atc2_usb_aon: power-controller@d0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xd0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc2_usb_aon"; + }; + + ps_atc3_usb_aon: power-controller@d8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xd8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc3_usb_aon"; + }; + + ps_atc2_usb: power-controller@e0 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xe0 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc2_usb"; + power-domains = <&ps_atc2_common>, <&ps_atc2_usb_aon>; + }; + + ps_atc3_usb: power-controller@e8 { + compatible = "apple,t8132-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xe8 4>; + #power-domain-cells = <0>; + #reset-cells = <0>; + label = "atc3_usb"; + power-domains = <&ps_atc3_common>, <&ps_atc3_usb_aon>; + }; +};
diff --git a/arch/arm64/boot/dts/apple/t8132.dtsi b/arch/arm64/boot/dts/apple/t8132.dtsi new file mode 100644 index 0000000..afec92a --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8132.dtsi
@@ -0,0 +1,467 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Apple T8132 "M4" SoC + * + * Copyright The Asahi Linux Contributors + */ + +#include <dt-bindings/interrupt-controller/apple-aic.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/pinctrl/apple.h> + +/ { + compatible = "apple,t8132", "apple,arm-platform"; + + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&cpu_e0>; + }; + core1 { + cpu = <&cpu_e1>; + }; + core2 { + cpu = <&cpu_e2>; + }; + core3 { + cpu = <&cpu_e3>; + }; + core4 { + cpu = <&cpu_e4>; + }; + core5 { + cpu = <&cpu_e5>; + }; + }; + + cluster1 { + core0 { + cpu = <&cpu_p0>; + }; + core1 { + cpu = <&cpu_p1>; + }; + core2 { + cpu = <&cpu_p2>; + }; + core3 { + cpu = <&cpu_p3>; + }; + }; + }; + + cpu_e0: cpu@0 { + compatible = "apple,donan-e"; + device_type = "cpu"; + reg = <0x0 0x0>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; + next-level-cache = <&l2_cache_0>; + i-cache-size = <0x20000>; + d-cache-size = <0x10000>; + }; + + cpu_e1: cpu@1 { + compatible = "apple,donan-e"; + device_type = "cpu"; + reg = <0x0 0x1>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; + next-level-cache = <&l2_cache_0>; + i-cache-size = <0x20000>; + d-cache-size = <0x10000>; + }; + + cpu_e2: cpu@2 { + compatible = "apple,donan-e"; + device_type = "cpu"; + reg = <0x0 0x2>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; + next-level-cache = <&l2_cache_0>; + i-cache-size = <0x20000>; + d-cache-size = <0x10000>; + }; + + cpu_e3: cpu@3 { + compatible = "apple,donan-e"; + device_type = "cpu"; + reg = <0x0 0x3>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; + next-level-cache = <&l2_cache_0>; + i-cache-size = <0x20000>; + d-cache-size = <0x10000>; + }; + + cpu_e4: cpu@4 { + compatible = "apple,donan-e"; + device_type = "cpu"; + reg = <0x0 0x4>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; + next-level-cache = <&l2_cache_0>; + i-cache-size = <0x20000>; + d-cache-size = <0x10000>; + }; + + cpu_e5: cpu@5 { + compatible = "apple,donan-e"; + device_type = "cpu"; + reg = <0x0 0x5>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; + next-level-cache = <&l2_cache_0>; + i-cache-size = <0x20000>; + d-cache-size = <0x10000>; + }; + + cpu_p0: cpu@10100 { + compatible = "apple,donan-p"; + device_type = "cpu"; + reg = <0x0 0x10100>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; + next-level-cache = <&l2_cache_1>; + i-cache-size = <0x30000>; + d-cache-size = <0x20000>; + }; + + cpu_p1: cpu@10101 { + compatible = "apple,donan-p"; + device_type = "cpu"; + reg = <0x0 0x10101>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; + next-level-cache = <&l2_cache_1>; + i-cache-size = <0x30000>; + d-cache-size = <0x20000>; + }; + + cpu_p2: cpu@10102 { + compatible = "apple,donan-p"; + device_type = "cpu"; + reg = <0x0 0x10102>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; + next-level-cache = <&l2_cache_1>; + i-cache-size = <0x30000>; + d-cache-size = <0x20000>; + }; + + cpu_p3: cpu@10103 { + compatible = "apple,donan-p"; + device_type = "cpu"; + reg = <0x0 0x10103>; + enable-method = "spin-table"; + cpu-release-addr = <0 0>; + next-level-cache = <&l2_cache_1>; + i-cache-size = <0x30000>; + d-cache-size = <0x20000>; + }; + + l2_cache_0: l2-cache-0 { + compatible = "cache"; + cache-level = <2>; + cache-unified; + cache-size = <0x400000>; + }; + + l2_cache_1: l2-cache-1 { + compatible = "cache"; + cache-level = <2>; + cache-unified; + cache-size = <0x1000000>; + }; + }; + + clkref: clock-ref { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "clkref"; + }; + + soc: soc { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + + ranges; + nonposted-mmio; + + pmgr: power-management@380700000 { + compatible = "apple,t8132-pmgr", "apple,t8103-pmgr", "syscon", "simple-mfd"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x3 0x80700000 0 0x14000>; + /* child nodes are added in t8132-pmgr.dtsi */ + }; + + aic: interrupt-controller@381000000 { + compatible = "apple,t8132-aic3", "apple,t8122-aic3"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x3 0x81000000 0x0 0x1cc000>, + <0x3 0x81040000 0x0 0x4000>; + reg-names = "core", "event"; + power-domains = <&ps_aic>; + + affinities { + e-core-pmu-affinity { + apple,fiq-index = <AIC_CPU_PMU_E>; + cpus = <&cpu_e0 &cpu_e1 &cpu_e2 &cpu_e3 &cpu_e4 &cpu_e5>; + }; + + p-core-pmu-affinity { + apple,fiq-index = <AIC_CPU_PMU_P>; + cpus = <&cpu_p0 &cpu_p1 &cpu_p2 &cpu_p3>; + }; + }; + }; + + pinctrl_nub: pinctrl@3881f0000 { + compatible = "apple,t8132-pinctrl", "apple,t8103-pinctrl"; + reg = <0x3 0x881f0000 0x0 0x4000>; + power-domains = <&ps_nub_gpio>; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl_nub 0 0 32>; + apple,npins = <32>; + + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 499 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 500 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 501 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 502 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 503 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 504 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 505 IRQ_TYPE_LEVEL_HIGH>; + }; + + pmgr_mini: power-management@388280000 { + compatible = "apple,t8132-pmgr", "apple,t8103-pmgr", "syscon", "simple-mfd"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x3 0x88280000 0 0x4000>; + /* child nodes are added in t8132-pmgr.dtsi */ + }; + + wdt: watchdog@3882b0000 { + compatible = "apple,t8132-wdt", "apple,t8103-wdt"; + reg = <0x3 0x882b0000 0x0 0x4000>; + clocks = <&clkref>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 507 IRQ_TYPE_LEVEL_HIGH>; + }; + + pinctrl_smc: pinctrl@38c820000 { + compatible = "apple,t8132-pinctrl", "apple,t8103-pinctrl"; + reg = <0x3 0x8c820000 0x0 0x4000>; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl_smc 0 0 18>; + apple,npins = <18>; + + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 552 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 553 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 554 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 555 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 556 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 557 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 558 IRQ_TYPE_LEVEL_HIGH>; + }; + + pinctrl_aop: pinctrl@390824000 { + compatible = "apple,t8132-pinctrl", "apple,t8103-pinctrl"; + reg = <0x3 0x90824000 0x0 0x4000>; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl_aop 0 0 57>; + apple,npins = <57>; + + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 423 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 424 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 425 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 426 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 427 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 428 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 429 IRQ_TYPE_LEVEL_HIGH>; + }; + + pinctrl_ap: pinctrl@39a000000 { + compatible = "apple,t8132-pinctrl", "apple,t8103-pinctrl"; + reg = <0x3 0x9a000000 0x0 0x100000>; + power-domains = <&ps_gpio>; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pinctrl_ap 0 0 224>; + apple,npins = <224>; + + interrupt-controller; + #interrupt-cells = <2>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 303 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 304 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 305 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 306 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 307 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 308 IRQ_TYPE_LEVEL_HIGH>, + <AIC_IRQ 309 IRQ_TYPE_LEVEL_HIGH>; + + i2c0_pins: i2c0-pins { + pinmux = <APPLE_PINMUX(104, 1)>, + <APPLE_PINMUX(103, 1)>; + }; + + i2c1_pins: i2c1-pins { + pinmux = <APPLE_PINMUX(106, 1)>, + <APPLE_PINMUX(105, 1)>; + }; + + i2c2_pins: i2c2-pins { + pinmux = <APPLE_PINMUX(44, 1)>, + <APPLE_PINMUX(43, 1)>; + }; + + i2c3_pins: i2c3-pins { + pinmux = <APPLE_PINMUX(42, 1)>, + <APPLE_PINMUX(41, 1)>; + }; + + i2c4_pins: i2c4-pins { + pinmux = <APPLE_PINMUX(108, 1)>, + <APPLE_PINMUX(107, 1)>; + }; + }; + + i2c0: i2c@3ad010000 { + compatible = "apple,t8132-i2c", "apple,t8103-i2c"; + reg = <0x3 0xad010000 0x0 0x4000>; + clocks = <&clkref>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 1062 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-0 = <&i2c0_pins>; + pinctrl-names = "default"; + #address-cells = <0x1>; + #size-cells = <0x0>; + power-domains = <&ps_i2c0>; + + status = "disabled"; + }; + + i2c1: i2c@3ad014000 { + compatible = "apple,t8132-i2c", "apple,t8103-i2c"; + reg = <0x3 0xad014000 0x0 0x4000>; + clocks = <&clkref>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 1063 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-0 = <&i2c1_pins>; + pinctrl-names = "default"; + #address-cells = <0x1>; + #size-cells = <0x0>; + power-domains = <&ps_i2c1>; + + status = "disabled"; + }; + + i2c2: i2c@3ad018000 { + compatible = "apple,t8132-i2c", "apple,t8103-i2c"; + reg = <0x3 0xad018000 0x0 0x4000>; + clocks = <&clkref>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 1064 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-0 = <&i2c2_pins>; + pinctrl-names = "default"; + #address-cells = <0x1>; + #size-cells = <0x0>; + power-domains = <&ps_i2c2>; + + status = "disabled"; + }; + + i2c3: i2c@3ad01c000 { + compatible = "apple,t8132-i2c", "apple,t8103-i2c"; + reg = <0x3 0xad01c000 0x0 0x4000>; + clocks = <&clkref>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 1065 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-0 = <&i2c3_pins>; + pinctrl-names = "default"; + #address-cells = <0x1>; + #size-cells = <0x0>; + power-domains = <&ps_i2c3>; + + status = "disabled"; + }; + + i2c4: i2c@3ad020000 { + compatible = "apple,t8132-i2c", "apple,t8103-i2c"; + reg = <0x3 0xad020000 0x0 0x4000>; + clocks = <&clkref>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 1066 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-0 = <&i2c4_pins>; + pinctrl-names = "default"; + #address-cells = <0x1>; + #size-cells = <0x0>; + power-domains = <&ps_i2c4>; + + status = "disabled"; + }; + + fpwm1: pwm@3ad044000 { + compatible = "apple,t8132-fpwm", "apple,s5l-fpwm"; + reg = <0x3 0xad044000 0x0 0x4000>; + power-domains = <&ps_fpwm1>; + clocks = <&clkref>; + #pwm-cells = <2>; + + status = "disabled"; + }; + + serial0: serial@3ad200000 { + compatible = "apple,s5l-uart"; + reg = <0x3 0xad200000 0x0 0x1000>; + reg-io-width = <4>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 1046 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clkref>, <&clkref>; + clock-names = "uart", "clk_uart_baud0"; + power-domains = <&ps_uart0>; + + status = "disabled"; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&aic>; + interrupt-names = "phys", "virt", "hyp-phys", "hyp-virt"; + interrupts = <AIC_FIQ AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>, + <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>, + <AIC_FIQ AIC_TMR_HV_PHYS IRQ_TYPE_LEVEL_HIGH>, + <AIC_FIQ AIC_TMR_HV_VIRT IRQ_TYPE_LEVEL_HIGH>; + }; +}; + +#include "t8132-pmgr.dtsi"
diff --git a/arch/arm64/boot/dts/apple/t8140-j700.dts b/arch/arm64/boot/dts/apple/t8140-j700.dts new file mode 100644 index 0000000..227b58a --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8140-j700.dts
@@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Apple MacBook Neo (A18 Pro, 2026) + * + * target-type: J700 + * + * Copyright The Asahi Linux Contributors + */ + +/dts-v1/; + +#include "t8140.dtsi" + +/ { + compatible = "apple,j700", "apple,t8140", "apple,arm-platform"; + model = "Apple MacBook Neo (A18 Pro, 2026)"; + + aliases { + serial0 = &serial0; + }; + + chosen { + ranges; + #address-cells = <2>; + #size-cells = <2>; + + stdout-path = "serial0"; + + framebuffer@0 { + compatible = "apple,simple-framebuffer", + "simple-framebuffer"; + reg = <0 0 0 0>; /* To be filled by loader */ + /* Format properties will be added by loader */ + + status = "disabled"; + }; + }; + + memory@800000000 { + device_type = "memory"; + reg = <0x8 0 0x2 0>; /* To be filled by loader */ + }; + + reserved-memory { + ranges; + #address-cells = <2>; + #size-cells = <2>; + /* To be filled by loader */ + }; +}; + +&serial0 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/apple/t8140-pmgr.dtsi b/arch/arm64/boot/dts/apple/t8140-pmgr.dtsi new file mode 100644 index 0000000..dd43520 --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8140-pmgr.dtsi
@@ -0,0 +1,777 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * PMGR Power domains for the Apple T8140 "A18 Pro" SoC + * + * Copyright The Asahi Linux Contributors + */ + +&pmgr { + ps_sep_aon: power-controller@60 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x60 4>; + label = "sep_aon"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_msg: power-controller@108 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x108 4>; + label = "msg"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_aic: power-controller@110 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x110 4>; + label = "aic"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_dwi: power-controller@118 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x118 4>; + label = "dwi"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_gpio: power-controller@120 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x120 4>; + label = "gpio"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_pmc: power-controller@138 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x138 4>; + label = "pmc"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_pms_fpwm0: power-controller@140 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x140 4>; + label = "pms_fpwm0"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_pms_fpwm1: power-controller@148 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x148 4>; + label = "pms_fpwm1"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_pms_fpwm2: power-controller@150 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x150 4>; + label = "pms_fpwm2"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_pms_fpwm3: power-controller@158 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x158 4>; + label = "pms_fpwm3"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_pms_fpwm4: power-controller@160 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x160 4>; + label = "pms_fpwm4"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_pms_c1ppt: power-controller@168 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x168 4>; + label = "pms_c1ppt"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_soc_rc: power-controller@170 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x170 4>; + label = "soc_rc"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_soc_dpe: power-controller@178 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x178 4>; + label = "soc_dpe"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_pmgr_soc_ocla: power-controller@180 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x180 4>; + label = "pmgr_soc_ocla"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_ispsens0: power-controller@188 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x188 4>; + label = "ispsens0"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_ispsens1: power-controller@190 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x190 4>; + label = "ispsens1"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_ap_tmm: power-controller@1a0 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x1a0 4>; + label = "ap_tmm"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_afggfxni0: power-controller@1b8 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x1b8 4>; + label = "afggfxni0"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_gfx: power-controller@1f0 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x1f0 4>; + label = "gfx"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_jpg: power-controller@230 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x230 4>; + label = "jpg"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_msr: power-controller@238 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x238 4>; + label = "msr"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_venc0_sys: power-controller@240 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x240 4>; + label = "venc0_sys"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_prores: power-controller@250 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x250 4>; + label = "prores"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_apcie_gp: power-controller@258 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x258 4>; + label = "apcie_gp"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_isp_sys: power-controller@268 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x268 4>; + label = "isp_sys"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_ans: power-controller@278 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x278 4>; + label = "ans"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_disp_sys: power-controller@280 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x280 4>; + label = "disp_sys"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; /* TODO: figure out if we can enable PM here */ + }; + + ps_dispext0_sys: power-controller@288 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x288 4>; + label = "dispext0_sys"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_ane_sys: power-controller@290 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x290 4>; + label = "ane_sys"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_msr_ase_core: power-controller@298 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x298 4>; + label = "msr_ase_core"; + #power-domain-cells = <0>; + power-domains = <&ps_msr>; + #reset-cells = <0>; + }; + + ps_apcie_sys_gp: power-controller@2a0 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2a0 4>; + label = "apcie_sys_gp"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_sio_cpu: power-controller@2a8 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2a8 4>; + label = "sio_cpu"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_fpwm0: power-controller@2b0 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2b0 4>; + label = "fpwm0"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_fpwm1: power-controller@2b8 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2b8 4>; + label = "fpwm1"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_fpwm2: power-controller@2c0 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2c0 4>; + label = "fpwm2"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_i2c0: power-controller@2c8 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2c8 4>; + label = "i2c0"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_i2c1: power-controller@2d0 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2d0 4>; + label = "i2c1"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_i2c2: power-controller@2d8 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2d8 4>; + label = "i2c2"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_i2c3: power-controller@2e0 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2e0 4>; + label = "i2c3"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_i2c4: power-controller@2e8 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2e8 4>; + label = "i2c4"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_spi_p: power-controller@2f0 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2f0 4>; + label = "spi_p"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_uart_p: power-controller@2f8 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x2f8 4>; + label = "uart_p"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_dpa_p: power-controller@300 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x300 4>; + label = "dpa_p"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_aes: power-controller@308 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x308 4>; + label = "aes"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_apcie_st: power-controller@310 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x310 4>; + label = "apcie_st"; + #power-domain-cells = <0>; + power-domains = <&ps_ans>; + #reset-cells = <0>; + }; + + ps_disp_fe: power-controller@318 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x318 4>; + label = "disp_fe"; + #power-domain-cells = <0>; + power-domains = <&ps_disp_sys>; + #reset-cells = <0>; + apple,always-on; /* TODO: figure out if we can enable PM here */ + }; + + ps_dispext0_fe: power-controller@320 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x320 4>; + label = "dispext0_fe"; + #power-domain-cells = <0>; + power-domains = <&ps_dispext0_sys>; + #reset-cells = <0>; + }; + + ps_dispext0_cpu: power-controller@328 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x328 4>; + label = "dispext0_cpu"; + #power-domain-cells = <0>; + power-domains = <&ps_dispext0_fe>; + #reset-cells = <0>; + + status = "disabled"; /* Locked, don't touch it */ + }; + + ps_spi0: power-controller@330 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x330 4>; + label = "spi0"; + #power-domain-cells = <0>; + power-domains = <&ps_spi_p>; + #reset-cells = <0>; + }; + + ps_spi1: power-controller@338 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x338 4>; + label = "spi1"; + #power-domain-cells = <0>; + power-domains = <&ps_spi_p>; + #reset-cells = <0>; + }; + + ps_spi2: power-controller@340 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x340 4>; + label = "spi2"; + #power-domain-cells = <0>; + power-domains = <&ps_spi_p>; + #reset-cells = <0>; + }; + + ps_spi3: power-controller@348 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x348 4>; + label = "spi3"; + #power-domain-cells = <0>; + power-domains = <&ps_spi_p>; + #reset-cells = <0>; + }; + + ps_qspi: power-controller@350 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x350 4>; + label = "qspi"; + #power-domain-cells = <0>; + power-domains = <&ps_spi_p>; + #reset-cells = <0>; + }; + + ps_uart_n: power-controller@358 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x358 4>; + label = "uart_n"; + #power-domain-cells = <0>; + power-domains = <&ps_uart_p>; + #reset-cells = <0>; + }; + + ps_uart0: power-controller@360 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x360 4>; + label = "uart0"; + #power-domain-cells = <0>; + power-domains = <&ps_uart_p>; + #reset-cells = <0>; + }; + + ps_uart1: power-controller@368 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x368 4>; + label = "uart1"; + #power-domain-cells = <0>; + power-domains = <&ps_uart_p>; + #reset-cells = <0>; + }; + + ps_uart2: power-controller@370 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x370 4>; + label = "uart2"; + #power-domain-cells = <0>; + power-domains = <&ps_uart_p>; + #reset-cells = <0>; + }; + + ps_uart3: power-controller@378 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x378 4>; + label = "uart3"; + #power-domain-cells = <0>; + power-domains = <&ps_uart_p>; + #reset-cells = <0>; + }; + + ps_uart4: power-controller@380 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x380 4>; + label = "uart4"; + #power-domain-cells = <0>; + power-domains = <&ps_uart_p>; + #reset-cells = <0>; + }; + + ps_uart5: power-controller@388 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x388 4>; + label = "uart5"; + #power-domain-cells = <0>; + power-domains = <&ps_uart_p>; + #reset-cells = <0>; + }; + + ps_dpa0: power-controller@390 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x390 4>; + label = "dpa0"; + #power-domain-cells = <0>; + power-domains = <&ps_dpa_p>; + #reset-cells = <0>; + }; + + ps_dpa1: power-controller@398 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x398 4>; + label = "dpa1"; + #power-domain-cells = <0>; + power-domains = <&ps_dpa_p>; + #reset-cells = <0>; + }; + + ps_apcie_sys_st: power-controller@3a0 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3a0 4>; + label = "apcie_sys_st"; + #power-domain-cells = <0>; + power-domains = <&ps_ans>, <&ps_apcie_st>; + #reset-cells = <0>; + }; + + ps_apcie_phy_sw: power-controller@3c0 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3c0 4>; + label = "apcie_phy_sw"; + #power-domain-cells = <0>; + power-domains = <&ps_apcie_sys_st>, <&ps_apcie_sys_gp>; + #reset-cells = <0>; + }; + + ps_pmp: power-controller@3d0 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3d0 4>; + label = "pmp"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_pms_sram: power-controller@3d8 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3d8 4>; + label = "pms_sram"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_atc0_usb_aon: power-controller@3e0 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3e0 4>; + label = "atc0_usb_aon"; + #power-domain-cells = <0>; + #reset-cells = <0>; + }; + + ps_atc0_common: power-controller@3e8 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3e8 4>; + label = "atc0_common"; + #power-domain-cells = <0>; + power-domains = <&ps_atc0_usb_aon>; + #reset-cells = <0>; + }; + + ps_atc0_usb: power-controller@3f0 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x3f0 4>; + label = "atc0_usb"; + #power-domain-cells = <0>; + power-domains = <&ps_atc0_common>; + #reset-cells = <0>; + }; + + ps_sep: power-controller@c00 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xc00 4>; + label = "sep"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_venc0_dma: power-controller@8000 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x8000 4>; + label = "venc0_dma"; + #power-domain-cells = <0>; + power-domains = <&ps_venc0_sys>; + #reset-cells = <0>; + }; + + ps_venc0_pipe4: power-controller@8008 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x8008 4>; + label = "venc0_pipe4"; + #power-domain-cells = <0>; + power-domains = <&ps_venc0_dma>; + #reset-cells = <0>; + }; + + ps_venc0_pipe5: power-controller@8010 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x8010 4>; + label = "venc0_pipe5"; + #power-domain-cells = <0>; + power-domains = <&ps_venc0_dma>; + #reset-cells = <0>; + }; + + ps_venc0_me0: power-controller@8018 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x8018 4>; + label = "venc0_me0"; + #power-domain-cells = <0>; + power-domains = <&ps_venc0_dma>; + #reset-cells = <0>; + }; + + ps_venc0_me1: power-controller@8020 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x8020 4>; + label = "venc0_me1"; + #power-domain-cells = <0>; + power-domains = <&ps_venc0_me0>; + #reset-cells = <0>; + }; +}; + +&pmgr_mini { + ps_debug_gated: power-controller@0 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x0 4>; + label = "debug_gated"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_nub_spmi0: power-controller@58 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x58 4>; + label = "nub_spmi0"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_nub_spmi1: power-controller@60 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x60 4>; + label = "nub_spmi1"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_nub_spmi_a0: power-controller@68 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x68 4>; + label = "nub_spmi_a0"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_nub_aon_nogate: power-controller@78 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x78 4>; + label = "nub_aon_nogate"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_nub_ocla: power-controller@80 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x80 4>; + label = "nub_ocla"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_nub_gpio: power-controller@88 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x88 4>; + label = "nub_gpio"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_nub_fabric: power-controller@a0 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xa0 4>; + label = "nub_fabric"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_nub_sram: power-controller@a8 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xa8 4>; + label = "nub_sram"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_debug_switch: power-controller@b0 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0xb0 4>; + label = "debug_switch"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_smc_i2cm0: power-controller@8028 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x8028 4>; + label = "smc_i2cm0"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_smc_i2cm1: power-controller@8030 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x8030 4>; + label = "smc_i2cm1"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; + + ps_smc_i2cm2: power-controller@8038 { + compatible = "apple,t8140-pmgr-pwrstate", "apple,t8103-pmgr-pwrstate"; + reg = <0x8038 4>; + label = "smc_i2cm2"; + #power-domain-cells = <0>; + #reset-cells = <0>; + apple,always-on; + }; +};
diff --git a/arch/arm64/boot/dts/apple/t8140.dtsi b/arch/arm64/boot/dts/apple/t8140.dtsi new file mode 100644 index 0000000..150d91b --- /dev/null +++ b/arch/arm64/boot/dts/apple/t8140.dtsi
@@ -0,0 +1,207 @@ +// SPDX-License-Identifier: GPL-2.0+ OR MIT +/* + * Apple T8140 "A18 Pro" SoC + * + * Copyright The Asahi Linux Contributors + */ + +#include <dt-bindings/interrupt-controller/apple-aic.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + compatible = "apple,t8140", "apple,arm-platform"; + + #address-cells = <2>; + #size-cells = <2>; + + clkref: clock-ref { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + clock-output-names = "clkref"; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&cpu_e0>; + }; + + core1 { + cpu = <&cpu_e1>; + }; + + core2 { + cpu = <&cpu_e2>; + }; + + core3 { + cpu = <&cpu_e3>; + }; + }; + + cluster1 { + core0 { + cpu = <&cpu_p0>; + }; + + core1 { + cpu = <&cpu_p1>; + }; + }; + }; + + cpu_e0: cpu@0 { + device_type = "cpu"; + compatible = "apple,tahiti-e"; + reg = <0x0 0x0>; + cpu-release-addr = <0 0>; + d-cache-size = <0x10000>; + enable-method = "spin-table"; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; + }; + + cpu_e1: cpu@1 { + device_type = "cpu"; + compatible = "apple,tahiti-e"; + reg = <0x0 0x1>; + cpu-release-addr = <0 0>; + d-cache-size = <0x10000>; + enable-method = "spin-table"; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; + }; + + cpu_e2: cpu@2 { + device_type = "cpu"; + compatible = "apple,tahiti-e"; + reg = <0x0 0x2>; + cpu-release-addr = <0 0>; + d-cache-size = <0x10000>; + enable-method = "spin-table"; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; + }; + + cpu_e3: cpu@3 { + device_type = "cpu"; + compatible = "apple,tahiti-e"; + reg = <0x0 0x3>; + cpu-release-addr = <0 0>; + d-cache-size = <0x10000>; + enable-method = "spin-table"; + i-cache-size = <0x20000>; + next-level-cache = <&l2_cache_0>; + }; + + cpu_p0: cpu@10100 { + device_type = "cpu"; + compatible = "apple,tahiti-p"; + reg = <0x0 0x10100>; + cpu-release-addr = <0 0>; + d-cache-size = <0x20000>; + enable-method = "spin-table"; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; + }; + + cpu_p1: cpu@10101 { + device_type = "cpu"; + compatible = "apple,tahiti-p"; + reg = <0x0 0x10101>; + cpu-release-addr = <0 0>; + d-cache-size = <0x20000>; + enable-method = "spin-table"; + i-cache-size = <0x30000>; + next-level-cache = <&l2_cache_1>; + }; + + l2_cache_0: l2-cache-0 { + compatible = "cache"; + cache-level = <2>; + cache-size = <0x400000>; + cache-unified; + }; + + l2_cache_1: l2-cache-1 { + compatible = "cache"; + cache-level = <2>; + cache-size = <0x1000000>; + cache-unified; + }; + }; + + soc: soc { + compatible = "simple-bus"; + ranges; + #address-cells = <2>; + nonposted-mmio; + #size-cells = <2>; + + pmgr: power-management@300700000 { + compatible = "apple,t8140-pmgr", "apple,t8103-pmgr", + "syscon", "simple-mfd"; + reg = <0x3 0x700000 0 0x14000>; + #address-cells = <1>; + #size-cells = <1>; + /* child nodes are added in t8140-pmgr.dtsi */ + }; + + aic: interrupt-controller@301000000 { + compatible = "apple,t8140-aic3", "apple,t8122-aic3"; + reg = <0x3 0x01000000 0x0 0x1cc000>, + <0x3 0x01040000 0x0 0x4000>; + reg-names = "core", "event"; + #interrupt-cells = <3>; + interrupt-controller; + power-domains = <&ps_aic>; + }; + + pmgr_mini: power-management@308280000 { + compatible = "apple,t8140-pmgr", "apple,t8103-pmgr", + "syscon", "simple-mfd"; + reg = <0x3 0x8280000 0 0xc000>; + #address-cells = <1>; + #size-cells = <1>; + /* child nodes are added in t8140-pmgr.dtsi */ + }; + + wdt: watchdog@3082b0000 { + compatible = "apple,t8140-wdt", "apple,t8103-wdt"; + reg = <0x3 0x082b0000 0x0 0x4000>; + clocks = <&clkref>; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 507 IRQ_TYPE_LEVEL_HIGH>; + }; + + serial0: serial@385200000 { + compatible = "apple,s5l-uart"; + reg = <0x3 0x85200000 0x0 0x1000>; + clocks = <&clkref>, <&clkref>; + clock-names = "uart", "clk_uart_baud0"; + interrupt-parent = <&aic>; + interrupts = <AIC_IRQ 1092 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&ps_uart0>; + reg-io-width = <4>; + + status = "disabled"; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupt-parent = <&aic>; + interrupts = <AIC_FIQ AIC_TMR_GUEST_PHYS IRQ_TYPE_LEVEL_HIGH>, + <AIC_FIQ AIC_TMR_GUEST_VIRT IRQ_TYPE_LEVEL_HIGH>, + <AIC_FIQ AIC_TMR_HV_PHYS IRQ_TYPE_LEVEL_HIGH>, + <AIC_FIQ AIC_TMR_HV_VIRT IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "phys", "virt", "hyp-phys", "hyp-virt"; + }; +}; + +#include "t8140-pmgr.dtsi"
diff --git a/arch/arm64/boot/dts/arm/fvp-base-revc.dts b/arch/arm64/boot/dts/arm/fvp-base-revc.dts index 68a69f1..d184a07 100644 --- a/arch/arm64/boot/dts/arm/fvp-base-revc.dts +++ b/arch/arm64/boot/dts/arm/fvp-base-revc.dts
@@ -44,6 +44,38 @@ cpus { #address-cells = <2>; #size-cells = <0>; + cpu-map { + cluster0 { + core0 { + cpu = <&cpu0>; + }; + core1 { + cpu = <&cpu1>; + }; + core2 { + cpu = <&cpu2>; + }; + core3 { + cpu = <&cpu3>; + }; + }; + + cluster1 { + core0 { + cpu = <&cpu4>; + }; + core1 { + cpu = <&cpu5>; + }; + core2 { + cpu = <&cpu6>; + }; + core3 { + cpu = <&cpu7>; + }; + }; + }; + idle-states { entry-method = "psci"; @@ -262,6 +294,13 @@ frame@2a830000 { }; }; + watchdog@2a440000 { + compatible = "arm,sbsa-gwdt"; + reg = <0x0 0x2a440000 0 0x1000>, // Watchdog control frame + <0x0 0x2a450000 0 0x1000>; // Refresh frame + interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; + }; + pmu { compatible = "arm,armv8-pmuv3"; interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>; @@ -334,7 +373,8 @@ pci: pci@40000000 { device_type = "pci"; bus-range = <0x0 0xff>; reg = <0x0 0x40000000 0x0 0x10000000>; - ranges = <0x2000000 0x0 0x50000000 0x0 0x50000000 0x0 0x10000000>; + ranges = <0x2000000 0x0 0x50000000 0x0 0x50000000 0x0 0x10000000 + 0x3000000 0x40 0x00000000 0x40 0x00000000 0x1 0x00000000>; interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, <0 0 0 2 &gic 0 0 GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>, <0 0 0 3 &gic 0 0 GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-d-rpi-5-b.dts b/arch/arm64/boot/dts/broadcom/bcm2712-d-rpi-5-b.dts index 127be0f..ae4b7c5 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2712-d-rpi-5-b.dts +++ b/arch/arm64/boot/dts/broadcom/bcm2712-d-rpi-5-b.dts
@@ -3,6 +3,11 @@ #include "bcm2712-rpi-5-b.dts" +/ { + compatible = "raspberrypi,5-model-b-d0", "brcm,bcm2712-d0"; + model = "Raspberry Pi 5 d0 Stepping"; +}; + &gio_aon { brcm,gpio-bank-widths = <15 6>;
diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b-base.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b-base.dtsi index b7a6bc3..e5030da 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b-base.dtsi +++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b-base.dtsi
@@ -3,6 +3,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> +#include <dt-bindings/power/raspberrypi-power.h> #include "bcm2712.dtsi" / { @@ -104,6 +105,18 @@ wl_on_reg: wl-on-reg { }; }; +&ddc0 { + status = "okay"; +}; + +&ddc1 { + status = "okay"; +}; + +&disp_intr { + status = "okay"; +}; + &pinctrl { bt_shutdown_default: bt-shutdown-default-state { function = "gpio"; @@ -227,19 +240,35 @@ bluetooth: bluetooth { }; }; +&usb { + power-domains = <&power RPI_POWER_DOMAIN_USB>; + status = "okay"; +}; + &hvs { clocks = <&firmware_clocks 4>, <&firmware_clocks 16>; clock-names = "core", "disp"; + status = "okay"; }; &hdmi0 { clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 0>, <&clk_27MHz>; clock-names = "hdmi", "bvb", "audio", "cec"; + status = "okay"; }; &hdmi1 { clocks = <&firmware_clocks 13>, <&firmware_clocks 14>, <&dvp 1>, <&clk_27MHz>; clock-names = "hdmi", "bvb", "audio", "cec"; + status = "okay"; +}; + +&mop { + status = "okay"; +}; + +&moplet { + status = "okay"; }; &pcie1 { @@ -250,6 +279,18 @@ &pcie2 { status = "okay"; }; +&pixelvalve0 { + status = "okay"; +}; + +&pixelvalve1 { + status = "okay"; +}; + &v3d { clocks = <&firmware_clocks 5>; }; + +&vc4 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts index 0fc57e7..75b262e 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts +++ b/arch/arm64/boot/dts/broadcom/bcm2712-rpi-5-b.dts
@@ -64,11 +64,31 @@ phy1: ethernet-phy@1 { }; &rp1_gpio { + fan_pwm_default_state: fan-pwm-default-state { + function = "pwm1"; + pins = "gpio45"; + bias-pull-down; + }; + usb_vbus_default_state: usb-vbus-default-state { function = "vbus1"; groups = "vbus1"; }; + rp1_spi0_default_state: rp1-spi0-default-state { + function = "spi0"; + groups = "spi0"; + bias-disable; + drive-strength = <12>; + slew-rate = <1>; + }; + + rp1_spi0_cs_default_state: rp1-spi0-cs-default-state { + function = "gpio"; + pins = "gpio7", "gpio8"; + bias-pull-up; + }; + rp1_i2c4_default_state: rp1-i2c4-default-state { function = "i2c4"; groups = "i2c4_2"; @@ -94,6 +114,20 @@ &rp1_i2c6 { pinctrl-names = "default"; }; +&rp1_spi0 { + pinctrl-0 = <&rp1_spi0_default_state &rp1_spi0_cs_default_state>; + pinctrl-names = "default"; + + num-cs = <2>; + cs-gpios = <&rp1_gpio 8 GPIO_ACTIVE_LOW &rp1_gpio 7 GPIO_ACTIVE_LOW>; +}; + +&rp1_pwm1 { + pinctrl-0 = <&fan_pwm_default_state>; + pinctrl-names = "default"; + status = "okay"; +}; + &rp1_usb0 { pinctrl-0 = <&usb_vbus_default_state>; pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi index 45aa8ec..edae2f35 100644 --- a/arch/arm64/boot/dts/broadcom/bcm2712.dtsi +++ b/arch/arm64/boot/dts/broadcom/bcm2712.dtsi
@@ -10,6 +10,15 @@ / { interrupt-parent = <&gicv2>; + arm-pmu { + compatible = "arm,cortex-a76-pmu"; + interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 18 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 19 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&cpu0>, <&cpu1>, <&cpu2>, <&cpu3>; + }; + clocks { /* The oscillator is the root of the clock tree. */ clk_osc: clk-osc { @@ -46,6 +55,13 @@ clk_sw_baud: clk-sw-baud { clock-frequency = <96000000>; clock-output-names = "sw-baud"; }; + + clk_usb: clk-usb { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <480000000>; + clock-output-names = "otg"; + }; }; cpus: cpus { @@ -359,12 +375,14 @@ pixelvalve0: pixelvalve@7c410000 { compatible = "brcm,bcm2712-pixelvalve0"; reg = <0x7c410000 0x100>; interrupts = <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; }; pixelvalve1: pixelvalve@7c411000 { compatible = "brcm,bcm2712-pixelvalve1"; reg = <0x7c411000 0x100>; interrupts = <GIC_SPI 110 IRQ_TYPE_LEVEL_HIGH>; + status = "disabled"; }; mop: mop@7c500000 { @@ -372,6 +390,7 @@ mop: mop@7c500000 { reg = <0x7c500000 0x28>; interrupt-parent = <&disp_intr>; interrupts = <1>; + status = "disabled"; }; moplet: moplet@7c501000 { @@ -379,6 +398,7 @@ moplet: moplet@7c501000 { reg = <0x7c501000 0x20>; interrupt-parent = <&disp_intr>; interrupts = <0>; + status = "disabled"; }; disp_intr: interrupt-controller@7c502000 { @@ -387,6 +407,7 @@ disp_intr: interrupt-controller@7c502000 { interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>; interrupt-controller; #interrupt-cells = <1>; + status = "disabled"; }; dvp: clock@7c700000 { @@ -405,6 +426,7 @@ ddc0: i2c@7d508200 { clock-frequency = <97500>; #address-cells = <1>; #size-cells = <0>; + status = "disabled"; }; ddc1: i2c@7d508280 { @@ -415,6 +437,7 @@ ddc1: i2c@7d508280 { clock-frequency = <97500>; #address-cells = <1>; #size-cells = <0>; + status = "disabled"; }; bsc_irq: interrupt-controller@7d508380 { @@ -460,6 +483,7 @@ hdmi0: hdmi@7c701400 { interrupt-names = "cec-tx", "cec-rx", "cec-low", "hpd-connected", "hpd-removed"; ddc = <&ddc0>; + status = "disabled"; }; hdmi1: hdmi@7c706400 { @@ -489,6 +513,19 @@ hdmi1: hdmi@7c706400 { interrupt-names = "cec-tx", "cec-rx", "cec-low", "hpd-connected", "hpd-removed"; ddc = <&ddc1>; + status = "disabled"; + }; + + avs_monitor: avs-monitor@7d542000 { + compatible = "brcm,bcm2711-avs-monitor", + "syscon", "simple-mfd"; + reg = <0x7d542000 0xf00>; + status = "okay"; + + thermal: thermal { + compatible = "brcm,bcm2711-thermal"; + #thermal-sensor-cells = <0>; + }; }; }; @@ -626,6 +663,19 @@ pcie2: pcie@1000120000 { status = "disabled"; }; + iommu4: iommu@1000005200 { + /* IOMMU for VC4 (HVS & MPL/TXP), Unicam, PISP-FE, MiniBVN */ + compatible = "brcm,bcm2712-iommu"; + reg = <0x10 0x5200 0x0 0x80>; + #iommu-cells = <0>; + brcm,iommu-cache = <&iommuc>; + }; + + iommuc: iommuc@1000005b00 { + compatible = "brcm,bcm2712-iommuc"; + reg = <0x10 0x5b00 0x0 0x80>; + }; + mip0: msi-controller@1000130000 { compatible = "brcm,bcm2712-mip"; reg = <0x10 0x00130000 0x00 0xc0>, @@ -663,10 +713,24 @@ v3d: gpu@1002000000 { interrupts = <GIC_SPI 250 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 249 IRQ_TYPE_LEVEL_HIGH>; }; + + usb: usb@1000480000 { + compatible = "brcm,bcm2835-usb"; + reg = <0x10 0x00480000 0x0 0x10000>; + interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk_usb>; + clock-names = "otg"; + phys = <&usbphy>; + phy-names = "usb2-phy"; + status = "disabled"; + }; }; vc4: gpu { compatible = "brcm,bcm2712-vc6"; + status = "disabled"; }; timer { @@ -701,5 +765,32 @@ hvs: hvs@107c580000 { interrupt-parent = <&disp_intr>; interrupts = <2>, <9>, <16>; interrupt-names = "ch0-eof", "ch1-eof", "ch2-eof"; + iommus = <&iommu4>; + status = "disabled"; + }; + + thermal-zones { + cpu_thermal: cpu-thermal { + polling-delay-passive = <1000>; + polling-delay = <1000>; + coefficients = <(-550) 450000>; + thermal-sensors = <&thermal>; + + thermal_trips: trips { + cpu_crit: cpu-crit { + temperature = <110000>; + hysteresis = <0>; + type = "critical"; + }; + }; + + cooling_maps: cooling-maps { + }; + }; + }; + + usbphy: phy { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; }; };
diff --git a/arch/arm64/boot/dts/broadcom/rp1-common.dtsi b/arch/arm64/boot/dts/broadcom/rp1-common.dtsi index 16f5359..980a5f3 100644 --- a/arch/arm64/boot/dts/broadcom/rp1-common.dtsi +++ b/arch/arm64/boot/dts/broadcom/rp1-common.dtsi
@@ -26,6 +26,125 @@ rp1_clocks: clocks@40018000 { <200000000>; // RP1_CLK_SYS }; + rp1_spi8: spi@4004c000 { + compatible = "snps,dw-apb-ssi"; + reg = <0x00 0x4004c000 0x0 0x130>; + interrupts = <56 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rp1_clocks RP1_CLK_SYS>; + clock-names = "ssi_clk"; + #address-cells = <1>; + #size-cells = <0>; + num-cs = <2>; + + status = "disabled"; + }; + + rp1_spi0: spi@40050000 { + compatible = "snps,dw-apb-ssi"; + reg = <0x00 0x40050000 0x0 0x130>; + interrupts = <19 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rp1_clocks RP1_CLK_SYS>; + clock-names = "ssi_clk"; + #address-cells = <1>; + #size-cells = <0>; + num-cs = <4>; + + status = "disabled"; + }; + + rp1_spi1: spi@40054000 { + compatible = "snps,dw-apb-ssi"; + reg = <0x00 0x40054000 0x0 0x130>; + interrupts = <20 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rp1_clocks RP1_CLK_SYS>; + clock-names = "ssi_clk"; + #address-cells = <1>; + #size-cells = <0>; + num-cs = <3>; + + status = "disabled"; + }; + + rp1_spi2: spi@40058000 { + compatible = "snps,dw-apb-ssi"; + reg = <0x00 0x40058000 0x0 0x130>; + interrupts = <21 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rp1_clocks RP1_CLK_SYS>; + clock-names = "ssi_clk"; + #address-cells = <1>; + #size-cells = <0>; + num-cs = <2>; + + status = "disabled"; + }; + + rp1_spi3: spi@4005c000 { + compatible = "snps,dw-apb-ssi"; + reg = <0x00 0x4005c000 0x0 0x130>; + interrupts = <22 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rp1_clocks RP1_CLK_SYS>; + clock-names = "ssi_clk"; + #address-cells = <1>; + #size-cells = <0>; + num-cs = <2>; + + status = "disabled"; + }; + + rp1_spi4: spi@40060000 { + compatible = "snps,dw-apb-ssi"; + reg = <0x00 0x40060000 0x0 0x130>; + interrupts = <23 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rp1_clocks RP1_CLK_SYS>; + clock-names = "ssi_clk"; + #address-cells = <0>; + #size-cells = <0>; + num-cs = <1>; + spi-slave; + + status = "disabled"; + }; + + rp1_spi5: spi@40064000 { + compatible = "snps,dw-apb-ssi"; + reg = <0x00 0x40064000 0x0 0x130>; + interrupts = <24 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rp1_clocks RP1_CLK_SYS>; + clock-names = "ssi_clk"; + #address-cells = <1>; + #size-cells = <0>; + num-cs = <2>; + + status = "disabled"; + }; + + rp1_spi6: spi@40068000 { + compatible = "snps,dw-apb-ssi"; + reg = <0x00 0x40068000 0x0 0x130>; + interrupts = <54 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rp1_clocks RP1_CLK_SYS>; + clock-names = "ssi_clk"; + #address-cells = <1>; + #size-cells = <0>; + num-cs = <3>; + + status = "disabled"; + }; + + rp1_spi7: spi@4006c000 { + compatible = "snps,dw-apb-ssi"; + reg = <0x00 0x4006c000 0x0 0x130>; + interrupts = <55 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rp1_clocks RP1_CLK_SYS>; + clock-names = "ssi_clk"; + #address-cells = <0>; + #size-cells = <0>; + num-cs = <1>; + spi-slave; + + status = "disabled"; + }; + rp1_i2c0: i2c@40070000 { compatible = "snps,designware-i2c"; reg = <0x0 0x40070000 0x0 0x1000>; @@ -33,7 +152,16 @@ rp1_i2c0: i2c@40070000 { clocks = <&rp1_clocks RP1_CLK_SYS>; i2c-scl-rising-time-ns = <65>; i2c-scl-falling-time-ns = <100>; + status = "disabled"; + }; + rp1_pwm1: pwm@4009c000 { + compatible = "raspberrypi,rp1-pwm"; + reg = <0x00 0x4009c000 0x0 0x100>; + clocks = <&rp1_clocks RP1_CLK_PWM1>; + assigned-clocks = <&rp1_clocks RP1_CLK_PWM1>; + assigned-clock-rates = <50000000>; + #pwm-cells = <3>; status = "disabled"; };
diff --git a/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi b/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi index 70430cb..5bcc220 100644 --- a/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi +++ b/arch/arm64/boot/dts/cavium/thunder-88xx.dtsi
@@ -355,9 +355,9 @@ cpu@20f { timer { compatible = "arm,armv8-timer"; interrupts = <1 13 4>, - <1 14 4>, - <1 11 4>, - <1 10 4>; + <1 14 4>, + <1 11 4>, + <1 10 4>; }; pmu {
diff --git a/arch/arm64/boot/dts/exynos/Makefile b/arch/arm64/boot/dts/exynos/Makefile index 8c48ce2..7534b77 100644 --- a/arch/arm64/boot/dts/exynos/Makefile +++ b/arch/arm64/boot/dts/exynos/Makefile
@@ -13,6 +13,7 @@ exynos7870-j7xelte.dtb \ exynos7870-on7xelte.dtb \ exynos7885-jackpotlte.dtb \ + exynos850-a217f.dtb \ exynos850-e850-96.dtb \ exynos8855-smdk.dtb \ exynos8895-dreamlte.dtb \
diff --git a/arch/arm64/boot/dts/exynos/axis/artpec8.dtsi b/arch/arm64/boot/dts/exynos/axis/artpec8.dtsi index db98332..9cfaf49 100644 --- a/arch/arm64/boot/dts/exynos/axis/artpec8.dtsi +++ b/arch/arm64/boot/dts/exynos/axis/artpec8.dtsi
@@ -22,6 +22,22 @@ aliases { pinctrl1 = &pinctrl_peric; }; + fin_pll: clock-finpll { + compatible = "fixed-factor-clock"; + clocks = <&osc_clk>; + #clock-cells = <0>; + clock-div = <2>; + clock-mult = <1>; + clock-output-names = "fin_pll"; + }; + + osc_clk: clock-osc { + /* XXTI */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-output-names = "osc_clk"; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -65,31 +81,15 @@ idle-states { cpu_sleep: cpu-sleep { compatible = "arm,idle-state"; - arm,psci-suspend-param = <0x0010000>; local-timer-stop; entry-latency-us = <300>; exit-latency-us = <1200>; min-residency-us = <2000>; + arm,psci-suspend-param = <0x0010000>; }; }; }; - fin_pll: clock-finpll { - compatible = "fixed-factor-clock"; - clocks = <&osc_clk>; - #clock-cells = <0>; - clock-div = <2>; - clock-mult = <1>; - clock-output-names = "fin_pll"; - }; - - osc_clk: clock-osc { - /* XXTI */ - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-output-names = "osc_clk"; - }; - pmu { compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>, @@ -229,8 +229,8 @@ serial_0: serial@16cc0000 { <&cmu_fsys CLK_GOUT_FSYS_UART0_SCLK_UART>; clock-names = "uart", "clk_uart_baud0"; interrupts = <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&serial0_bus>; + pinctrl-names = "default"; }; };
diff --git a/arch/arm64/boot/dts/exynos/axis/artpec9.dtsi b/arch/arm64/boot/dts/exynos/axis/artpec9.dtsi index cd46aaf..a92af2e 100644 --- a/arch/arm64/boot/dts/exynos/axis/artpec9.dtsi +++ b/arch/arm64/boot/dts/exynos/axis/artpec9.dtsi
@@ -23,6 +23,22 @@ aliases { pinctrl2 = &pinctrl_peric; }; + fin_pll: clock-finpll { + compatible = "fixed-factor-clock"; + clocks = <&osc_clk>; + #clock-cells = <0>; + clock-div = <2>; + clock-mult = <1>; + clock-output-names = "fin_pll"; + }; + + osc_clk: clock-osc { + /* XXTI */ + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-output-names = "osc_clk"; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -82,31 +98,15 @@ idle-states { cpu_sleep: cpu-sleep { compatible = "arm,idle-state"; - arm,psci-suspend-param = <0x0010000>; local-timer-stop; entry-latency-us = <300>; exit-latency-us = <1200>; min-residency-us = <2000>; + arm,psci-suspend-param = <0x0010000>; }; }; }; - fin_pll: clock-finpll { - compatible = "fixed-factor-clock"; - clocks = <&osc_clk>; - #clock-cells = <0>; - clock-div = <2>; - clock-mult = <1>; - clock-output-names = "fin_pll"; - }; - - osc_clk: clock-osc { - /* XXTI */ - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-output-names = "osc_clk"; - }; - pmu { compatible = "arm,cortex-a55-pmu"; interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; @@ -261,8 +261,8 @@ serial_0: serial@14c70000 { <&cmu_fsys1 CLK_GOUT_FSYS1_UART0_SCLK_UART>; clock-names = "uart", "clk_uart_baud0"; interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&serial0_bus>; + pinctrl-names = "default"; samsung,uart-fifosize = <64>; }; };
diff --git a/arch/arm64/boot/dts/exynos/exynos2200-g0s.dts b/arch/arm64/boot/dts/exynos/exynos2200-g0s.dts index 458f1bc..30772bf 100644 --- a/arch/arm64/boot/dts/exynos/exynos2200-g0s.dts +++ b/arch/arm64/boot/dts/exynos/exynos2200-g0s.dts
@@ -17,10 +17,6 @@ / { chassis-type = "handset"; chosen { - #address-cells = <2>; - #size-cells = <2>; - ranges; - framebuffer: framebuffer { compatible = "simple-framebuffer"; memory-region = <&cont_splash_mem>; @@ -52,9 +48,9 @@ gpio-keys { volup-key { label = "Volume Up"; - linux,code = <KEY_VOLUMEUP>; gpios = <&gpa3 0 GPIO_ACTIVE_LOW>; wakeup-source; + linux,code = <KEY_VOLUMEUP>; }; }; @@ -71,9 +67,9 @@ reg_dummy: regulator-0 { }; reserved-memory { + ranges; #address-cells = <2>; #size-cells = <2>; - ranges; cont_splash_mem: framebuffer@f6200000 { reg = <0x0 0xf6200000 0x0 (1080 * 2340 * 4)>;
diff --git a/arch/arm64/boot/dts/exynos/exynos2200-pinctrl.dtsi b/arch/arm64/boot/dts/exynos/exynos2200-pinctrl.dtsi index 5877da7..d5aede3a 100644 --- a/arch/arm64/boot/dts/exynos/exynos2200-pinctrl.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos2200-pinctrl.dtsi
@@ -702,7 +702,6 @@ uart20_bus_dual: uart20-bus-dual-pins { samsung,pin-function = <EXYNOS_PIN_FUNC_2>; samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; }; - }; &pinctrl_hsi1 { @@ -1171,7 +1170,6 @@ uart12_bus_dual: uart12-bus-dual-pins { samsung,pin-function = <EXYNOS_PIN_FUNC_2>; samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; }; - }; &pinctrl_peric2 {
diff --git a/arch/arm64/boot/dts/exynos/exynos2200.dtsi b/arch/arm64/boot/dts/exynos/exynos2200.dtsi index b1c134f..3b853d6 100644 --- a/arch/arm64/boot/dts/exynos/exynos2200.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos2200.dtsi
@@ -712,7 +712,6 @@ hsi2c_21: i2c@10970000 { status = "disabled"; }; - }; cmu_hsi0: clock-controller@10a00000 {
diff --git a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi index 0ad02a0..a17a7d0 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433-tm2-common.dtsi
@@ -56,32 +56,32 @@ memory@20000000 { gpio-keys { compatible = "gpio-keys"; + homepage-key { + gpios = <&gpa0 3 GPIO_ACTIVE_LOW>; + label = "homepage key"; + debounce-interval = <10>; + linux,code = <KEY_MENU>; + }; + power-key { gpios = <&gpa2 7 GPIO_ACTIVE_LOW>; - linux,code = <KEY_POWER>; label = "power key"; debounce-interval = <10>; + linux,code = <KEY_POWER>; }; volume-up-key { gpios = <&gpa2 0 GPIO_ACTIVE_LOW>; - linux,code = <KEY_VOLUMEUP>; label = "volume-up key"; debounce-interval = <10>; + linux,code = <KEY_VOLUMEUP>; }; volume-down-key { gpios = <&gpa2 1 GPIO_ACTIVE_LOW>; - linux,code = <KEY_VOLUMEDOWN>; label = "volume-down key"; debounce-interval = <10>; - }; - - homepage-key { - gpios = <&gpa0 3 GPIO_ACTIVE_LOW>; - linux,code = <KEY_MENU>; - label = "homepage key"; - debounce-interval = <10>; + linux,code = <KEY_VOLUMEDOWN>; }; }; @@ -103,13 +103,6 @@ max98504: amplifier@31 { }; }; - vph_pwr_regulator: regulator-vph-pwr { - compatible = "regulator-fixed"; - regulator-name = "VPH_PWR"; - regulator-min-microvolt = <4200000>; - regulator-max-microvolt = <4200000>; - }; - irda_regulator: regulator-irda { compatible = "regulator-fixed"; enable-active-high; @@ -117,6 +110,13 @@ irda_regulator: regulator-irda { regulator-name = "irda_regulator"; }; + vph_pwr_regulator: regulator-vph-pwr { + compatible = "regulator-fixed"; + regulator-name = "VPH_PWR"; + regulator-min-microvolt = <4200000>; + regulator-max-microvolt = <4200000>; + }; + sound { compatible = "samsung,tm2-audio"; audio-codec = <&wm5110>, <&hdmi>; @@ -358,11 +358,12 @@ tv_to_hdmi: endpoint { &dsi { vddcore-supply = <&ldo6_reg>; vddio-supply = <&ldo7_reg>; + pinctrl-0 = <&te_irq>; + pinctrl-names = "default"; + samsung,burst-clock-frequency = <512000000>; samsung,esc-clock-frequency = <16000000>; samsung,pll-clock-frequency = <24000000>; - pinctrl-names = "default"; - pinctrl-0 = <&te_irq>; status = "okay"; }; @@ -410,11 +411,11 @@ &hsi2c_0 { pmic@66 { compatible = "samsung,s2mps13-pmic"; + reg = <0x66>; interrupt-parent = <&gpa0>; interrupts = <7 IRQ_TYPE_LEVEL_LOW>; - reg = <0x66>; - samsung,s2mps11-wrstbi-ground; wakeup-source; + samsung,s2mps11-wrstbi-ground; s2mps13_osc: clocks { compatible = "samsung,s2mps13-clk"; @@ -859,8 +860,8 @@ &hsi2c_7 { status = "okay"; bridge@39 { - reg = <0x39>; compatible = "sil,sii8620"; + reg = <0x39>; cvcc10-supply = <&ldo36_reg>; iovcc18-supply = <&ldo34_reg>; interrupt-parent = <&gpf0>; @@ -897,9 +898,9 @@ &hsi2c_8 { pmic@66 { compatible = "maxim,max77843"; + reg = <0x66>; interrupt-parent = <&gpa1>; interrupts = <5 IRQ_TYPE_EDGE_FALLING>; - reg = <0x66>; muic: extcon { compatible = "maxim,max77843-muic"; @@ -997,18 +998,19 @@ &mshc_0 { cap-mmc-highspeed; non-removable; card-detect-delay = <200>; + fifo-depth = <0x80>; + pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_qrdy &sd0_bus1 &sd0_bus4 + &sd0_bus8 &sd0_rdqs>; + pinctrl-names = "default"; + bus-width = <8>; + assigned-clocks = <&cmu_top CLK_SCLK_MMC0_FSYS>; + assigned-clock-rates = <800000000>; + 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 3>; samsung,read-strobe-delay = <90>; - fifo-depth = <0x80>; - pinctrl-names = "default"; - pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_qrdy &sd0_bus1 &sd0_bus4 - &sd0_bus8 &sd0_rdqs>; - bus-width = <8>; - assigned-clocks = <&cmu_top CLK_SCLK_MMC0_FSYS>; - assigned-clock-rates = <800000000>; status = "okay"; }; @@ -1018,20 +1020,21 @@ &mshc_2 { disable-wp; cd-gpios = <&gpa2 4 GPIO_ACTIVE_LOW>; card-detect-delay = <200>; + fifo-depth = <0x80>; + pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus1 &sd2_bus4>; + pinctrl-names = "default"; + bus-width = <4>; + samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; samsung,dw-mshc-ddr-timing = <0 2>; - fifo-depth = <0x80>; - pinctrl-names = "default"; - pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus1 &sd2_bus4>; - bus-width = <4>; status = "okay"; }; &pcie { - pinctrl-names = "default"; pinctrl-0 = <&pcie_bus &pcie_wlanen>; + pinctrl-names = "default"; vdd10-supply = <&ldo6_reg>; vdd18-supply = <&ldo7_reg>; assigned-clocks = <&cmu_fsys CLK_MOUT_SCLK_PCIE_100_USER>, @@ -1064,14 +1067,14 @@ &ppmu_d1_general { events { ppmu_event0_d1_general: ppmu-event0-d1-general { - event-name = "ppmu-event0-d1-general"; - }; + event-name = "ppmu-event0-d1-general"; + }; }; }; &pinctrl_alive { - pinctrl-names = "default"; pinctrl-0 = <&initial_alive>; + pinctrl-names = "default"; initial_alive: initial-state { PIN_IN(gpa0-0, DOWN, FAST_SR1); @@ -1154,8 +1157,8 @@ te_irq: te-irq-pins { }; &pinctrl_cpif { - pinctrl-names = "default"; pinctrl-0 = <&initial_cpif>; + pinctrl-names = "default"; initial_cpif: initial-state { PIN_IN(gpv6-0, DOWN, FAST_SR1); @@ -1164,8 +1167,8 @@ initial_cpif: initial-state { }; &pinctrl_ese { - pinctrl-names = "default"; pinctrl-0 = <&initial_ese>; + pinctrl-names = "default"; pcie_wlanen: pcie-wlanen-pins { samsung,pins = "gpj2-0"; @@ -1181,8 +1184,8 @@ initial_ese: initial-state { }; &pinctrl_fsys { - pinctrl-names = "default"; pinctrl-0 = <&initial_fsys>; + pinctrl-names = "default"; initial_fsys: initial-state { PIN_IN(gpr3-0, NONE, FAST_SR1); @@ -1194,8 +1197,8 @@ initial_fsys: initial-state { }; &pinctrl_imem { - pinctrl-names = "default"; pinctrl-0 = <&initial_imem>; + pinctrl-names = "default"; initial_imem: initial-state { PIN_IN(gpf0-0, UP, FAST_SR1); @@ -1210,8 +1213,8 @@ initial_imem: initial-state { }; &pinctrl_nfc { - pinctrl-names = "default"; pinctrl-0 = <&initial_nfc>; + pinctrl-names = "default"; initial_nfc: initial-state { PIN_IN(gpj0-2, DOWN, FAST_SR1); @@ -1219,8 +1222,8 @@ initial_nfc: initial-state { }; &pinctrl_peric { - pinctrl-names = "default"; pinctrl-0 = <&initial_peric>; + pinctrl-names = "default"; initial_peric: initial-state { PIN_IN(gpv7-0, DOWN, FAST_SR1); @@ -1274,8 +1277,8 @@ initial_peric: initial-state { }; &pinctrl_touch { - pinctrl-names = "default"; pinctrl-0 = <&initial_touch>; + pinctrl-names = "default"; initial_touch: initial-state { PIN_IN(gpj1-2, DOWN, FAST_SR1);
diff --git a/arch/arm64/boot/dts/exynos/exynos5433.dtsi b/arch/arm64/boot/dts/exynos/exynos5433.dtsi index d318c87..a6352c0 100644 --- a/arch/arm64/boot/dts/exynos/exynos5433.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos5433.dtsi
@@ -93,8 +93,8 @@ core3 { cpu0: cpu@100 { device_type = "cpu"; compatible = "arm,cortex-a53"; - enable-method = "psci"; reg = <0x100>; + enable-method = "psci"; clocks = <&cmu_apollo CLK_SCLK_APOLLO>; clock-names = "apolloclk"; operating-points-v2 = <&cluster_a53_opp_table>; @@ -111,8 +111,8 @@ cpu0: cpu@100 { cpu1: cpu@101 { device_type = "cpu"; compatible = "arm,cortex-a53"; - enable-method = "psci"; reg = <0x101>; + enable-method = "psci"; operating-points-v2 = <&cluster_a53_opp_table>; #cooling-cells = <2>; i-cache-size = <0x8000>; @@ -127,8 +127,8 @@ cpu1: cpu@101 { cpu2: cpu@102 { device_type = "cpu"; compatible = "arm,cortex-a53"; - enable-method = "psci"; reg = <0x102>; + enable-method = "psci"; operating-points-v2 = <&cluster_a53_opp_table>; #cooling-cells = <2>; i-cache-size = <0x8000>; @@ -143,8 +143,8 @@ cpu2: cpu@102 { cpu3: cpu@103 { device_type = "cpu"; compatible = "arm,cortex-a53"; - enable-method = "psci"; reg = <0x103>; + enable-method = "psci"; operating-points-v2 = <&cluster_a53_opp_table>; #cooling-cells = <2>; i-cache-size = <0x8000>; @@ -159,8 +159,8 @@ cpu3: cpu@103 { cpu4: cpu@0 { device_type = "cpu"; compatible = "arm,cortex-a57"; - enable-method = "psci"; reg = <0x0>; + enable-method = "psci"; clocks = <&cmu_atlas CLK_SCLK_ATLAS>; clock-names = "atlasclk"; operating-points-v2 = <&cluster_a57_opp_table>; @@ -177,8 +177,8 @@ cpu4: cpu@0 { cpu5: cpu@1 { device_type = "cpu"; compatible = "arm,cortex-a57"; - enable-method = "psci"; reg = <0x1>; + enable-method = "psci"; operating-points-v2 = <&cluster_a57_opp_table>; #cooling-cells = <2>; i-cache-size = <0xc000>; @@ -193,8 +193,8 @@ cpu5: cpu@1 { cpu6: cpu@2 { device_type = "cpu"; compatible = "arm,cortex-a57"; - enable-method = "psci"; reg = <0x2>; + enable-method = "psci"; operating-points-v2 = <&cluster_a57_opp_table>; #cooling-cells = <2>; i-cache-size = <0xc000>; @@ -209,8 +209,8 @@ cpu6: cpu@2 { cpu7: cpu@3 { device_type = "cpu"; compatible = "arm,cortex-a57"; - enable-method = "psci"; reg = <0x3>; + enable-method = "psci"; operating-points-v2 = <&cluster_a57_opp_table>; #cooling-cells = <2>; i-cache-size = <0xc000>; @@ -385,9 +385,9 @@ psci { soc: soc@0 { compatible = "simple-bus"; + ranges = <0x0 0x0 0x0 0x18000000>; #address-cells = <1>; #size-cells = <1>; - ranges = <0x0 0x0 0x0 0x18000000>; chipid@10000000 { compatible = "samsung,exynos5433-chipid", @@ -1005,13 +1005,13 @@ decon: decon@13800000 { "pclk_smmu_decon1x", "sclk_decon_vclk", "sclk_decon_eclk", "dsd"; power-domains = <&pd_disp>; - interrupt-names = "fifo", "vsync", "lcd_sys"; interrupts = <GIC_SPI 201 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 203 IRQ_TYPE_LEVEL_HIGH>; - samsung,disp-sysreg = <&syscon_disp>; + interrupt-names = "fifo", "vsync", "lcd_sys"; iommus = <&sysmmu_decon0x>, <&sysmmu_decon1x>; iommu-names = "m0", "m1"; + samsung,disp-sysreg = <&syscon_disp>; status = "disabled"; @@ -1049,14 +1049,14 @@ decon_tv: decon@13880000 { "aclk_smmu_decon1x", "aclk_xiu_decon1x", "pclk_smmu_decon1x", "sclk_decon_vclk", "sclk_decon_eclk", "dsd"; - samsung,disp-sysreg = <&syscon_disp>; power-domains = <&pd_disp>; - interrupt-names = "fifo", "vsync", "lcd_sys"; interrupts = <GIC_SPI 210 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 211 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 212 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "fifo", "vsync", "lcd_sys"; iommus = <&sysmmu_tv0x>, <&sysmmu_tv1x>; iommu-names = "m0", "m1"; + samsung,disp-sysreg = <&syscon_disp>; status = "disabled"; }; @@ -1151,9 +1151,9 @@ hdmi: hdmi@13970000 { "oscclk", "i_spdif_clk"; phy = <&hdmiphy>; ddc = <&hsi2c_11>; + #sound-dai-cells = <0>; samsung,syscon-phandle = <&pmu_system_controller>; samsung,sysreg-phandle = <&syscon_disp>; - #sound-dai-cells = <0>; status = "disabled"; }; @@ -1479,8 +1479,8 @@ serial_0: serial@14c10000 { clocks = <&cmu_peric CLK_PCLK_UART0>, <&cmu_peric CLK_SCLK_UART0>; clock-names = "uart", "clk_uart_baud0"; - pinctrl-names = "default"; pinctrl-0 = <&uart0_bus>; + pinctrl-names = "default"; status = "disabled"; }; @@ -1492,8 +1492,8 @@ serial_1: serial@14c20000 { clocks = <&cmu_peric CLK_PCLK_UART1>, <&cmu_peric CLK_SCLK_UART1>; clock-names = "uart", "clk_uart_baud0"; - pinctrl-names = "default"; pinctrl-0 = <&uart1_bus>; + pinctrl-names = "default"; status = "disabled"; }; @@ -1505,8 +1505,8 @@ serial_2: serial@14c30000 { clocks = <&cmu_peric CLK_PCLK_UART2>, <&cmu_peric CLK_SCLK_UART2>; clock-names = "uart", "clk_uart_baud0"; - pinctrl-names = "default"; pinctrl-0 = <&uart2_bus>; + pinctrl-names = "default"; status = "disabled"; }; @@ -1523,11 +1523,11 @@ spi_0: spi@14d20000 { <&cmu_peric CLK_SCLK_SPI0>, <&cmu_peric CLK_SCLK_IOCLK_SPI0>; clock-names = "spi", "spi_busclk0", "spi_ioclk"; - samsung,spi-src-clk = <0>; - pinctrl-names = "default"; pinctrl-0 = <&spi0_bus>; + pinctrl-names = "default"; num-cs = <1>; fifo-depth = <256>; + samsung,spi-src-clk = <0>; status = "disabled"; }; @@ -1544,11 +1544,11 @@ spi_1: spi@14d30000 { <&cmu_peric CLK_SCLK_SPI1>, <&cmu_peric CLK_SCLK_IOCLK_SPI1>; clock-names = "spi", "spi_busclk0", "spi_ioclk"; - samsung,spi-src-clk = <0>; - pinctrl-names = "default"; pinctrl-0 = <&spi1_bus>; + pinctrl-names = "default"; num-cs = <1>; fifo-depth = <64>; + samsung,spi-src-clk = <0>; status = "disabled"; }; @@ -1565,11 +1565,11 @@ spi_2: spi@14d40000 { <&cmu_peric CLK_SCLK_SPI2>, <&cmu_peric CLK_SCLK_IOCLK_SPI2>; clock-names = "spi", "spi_busclk0", "spi_ioclk"; - samsung,spi-src-clk = <0>; - pinctrl-names = "default"; pinctrl-0 = <&spi2_bus>; + pinctrl-names = "default"; num-cs = <1>; fifo-depth = <64>; + samsung,spi-src-clk = <0>; status = "disabled"; }; @@ -1586,11 +1586,11 @@ spi_3: spi@14d50000 { <&cmu_peric CLK_SCLK_SPI3>, <&cmu_peric CLK_SCLK_IOCLK_SPI3>; clock-names = "spi", "spi_busclk0", "spi_ioclk"; - samsung,spi-src-clk = <0>; - pinctrl-names = "default"; pinctrl-0 = <&spi3_bus>; + pinctrl-names = "default"; num-cs = <1>; fifo-depth = <64>; + samsung,spi-src-clk = <0>; status = "disabled"; }; @@ -1607,11 +1607,11 @@ spi_4: spi@14d00000 { <&cmu_peric CLK_SCLK_SPI4>, <&cmu_peric CLK_SCLK_IOCLK_SPI4>; clock-names = "spi", "spi_busclk0", "spi_ioclk"; - samsung,spi-src-clk = <0>; - pinctrl-names = "default"; pinctrl-0 = <&spi4_bus>; + pinctrl-names = "default"; num-cs = <1>; fifo-depth = <64>; + samsung,spi-src-clk = <0>; status = "disabled"; }; @@ -1651,10 +1651,10 @@ pwm: pwm@14dd0000 { <GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>; - samsung,pwm-outputs = <0>, <1>, <2>, <3>; clocks = <&cmu_peric CLK_PCLK_PWM>; clock-names = "timers"; #pwm-cells = <3>; + samsung,pwm-outputs = <0>, <1>, <2>, <3>; status = "disabled"; }; @@ -1666,8 +1666,8 @@ hsi2c_0: i2c@14e40000 { interrupts = <GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c0_bus>; + pinctrl-names = "default"; clocks = <&cmu_peric CLK_PCLK_HSI2C0>; clock-names = "hsi2c"; @@ -1681,8 +1681,8 @@ hsi2c_1: i2c@14e50000 { interrupts = <GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c1_bus>; + pinctrl-names = "default"; clocks = <&cmu_peric CLK_PCLK_HSI2C1>; clock-names = "hsi2c"; @@ -1696,8 +1696,8 @@ hsi2c_2: i2c@14e60000 { interrupts = <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c2_bus>; + pinctrl-names = "default"; clocks = <&cmu_peric CLK_PCLK_HSI2C2>; clock-names = "hsi2c"; @@ -1711,8 +1711,8 @@ hsi2c_3: i2c@14e70000 { interrupts = <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c3_bus>; + pinctrl-names = "default"; clocks = <&cmu_peric CLK_PCLK_HSI2C3>; clock-names = "hsi2c"; @@ -1726,8 +1726,8 @@ hsi2c_4: i2c@14ec0000 { interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c4_bus>; + pinctrl-names = "default"; clocks = <&cmu_peric CLK_PCLK_HSI2C4>; clock-names = "hsi2c"; @@ -1741,8 +1741,8 @@ hsi2c_5: i2c@14ed0000 { interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c5_bus>; + pinctrl-names = "default"; clocks = <&cmu_peric CLK_PCLK_HSI2C5>; clock-names = "hsi2c"; @@ -1756,8 +1756,8 @@ hsi2c_6: i2c@14ee0000 { interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c6_bus>; + pinctrl-names = "default"; clocks = <&cmu_peric CLK_PCLK_HSI2C6>; clock-names = "hsi2c"; @@ -1771,8 +1771,8 @@ hsi2c_7: i2c@14ef0000 { interrupts = <GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c7_bus>; + pinctrl-names = "default"; clocks = <&cmu_peric CLK_PCLK_HSI2C7>; clock-names = "hsi2c"; @@ -1786,8 +1786,8 @@ hsi2c_8: i2c@14d90000 { interrupts = <GIC_SPI 443 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c8_bus>; + pinctrl-names = "default"; clocks = <&cmu_peric CLK_PCLK_HSI2C8>; clock-names = "hsi2c"; @@ -1801,8 +1801,8 @@ hsi2c_9: i2c@14da0000 { interrupts = <GIC_SPI 444 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c9_bus>; + pinctrl-names = "default"; clocks = <&cmu_peric CLK_PCLK_HSI2C9>; clock-names = "hsi2c"; @@ -1816,8 +1816,8 @@ hsi2c_10: i2c@14de0000 { interrupts = <GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c10_bus>; + pinctrl-names = "default"; clocks = <&cmu_peric CLK_PCLK_HSI2C10>; clock-names = "hsi2c"; @@ -1831,8 +1831,8 @@ hsi2c_11: i2c@14df0000 { interrupts = <GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c11_bus>; + pinctrl-names = "default"; clocks = <&cmu_peric CLK_PCLK_HSI2C11>; clock-names = "hsi2c"; @@ -1841,6 +1841,7 @@ hsi2c_11: i2c@14df0000 { usbdrd30: usb@15400000 { compatible = "samsung,exynos5433-dwusb3"; + ranges = <0x0 0x15400000 0x10000>; clocks = <&cmu_fsys CLK_ACLK_USBDRD30>, <&cmu_fsys CLK_SCLK_USBDRD30>, <&cmu_fsys CLK_PHYCLK_USBDRD30_UDRD30_PHYCLOCK>, @@ -1848,17 +1849,16 @@ usbdrd30: usb@15400000 { clock-names = "aclk", "susp_clk", "phyclk", "pipe_pclk"; #address-cells = <1>; #size-cells = <1>; - ranges = <0x0 0x15400000 0x10000>; status = "disabled"; usbdrd_dwc3: usb@0 { compatible = "snps,dwc3"; + reg = <0x0 0x10000>; clocks = <&cmu_fsys CLK_SCLK_USBDRD30>, <&cmu_fsys CLK_ACLK_USBDRD30>, <&cmu_fsys CLK_SCLK_USBDRD30>; clock-names = "ref", "bus_early", "suspend"; - reg = <0x0 0x10000>; interrupts = <GIC_SPI 231 IRQ_TYPE_LEVEL_HIGH>; phys = <&usbdrd30_phy 0>, <&usbdrd30_phy 1>; phy-names = "usb2-phy", "usb3-phy"; @@ -1895,6 +1895,7 @@ usbhost30_phy: phy@15580000 { usbhost30: usb@15a00000 { compatible = "samsung,exynos5433-dwusb3"; + ranges = <0x0 0x15a00000 0x10000>; clocks = <&cmu_fsys CLK_ACLK_USBHOST30>, <&cmu_fsys CLK_SCLK_USBHOST30>, <&cmu_fsys CLK_PHYCLK_USBHOST30_UHOST30_PHYCLOCK>, @@ -1902,17 +1903,16 @@ usbhost30: usb@15a00000 { clock-names = "aclk", "susp_clk", "phyclk", "pipe_pclk"; #address-cells = <1>; #size-cells = <1>; - ranges = <0x0 0x15a00000 0x10000>; status = "disabled"; usbhost_dwc3: usb@0 { compatible = "snps,dwc3"; + reg = <0x0 0x10000>; clocks = <&cmu_fsys CLK_SCLK_USBHOST30>, <&cmu_fsys CLK_ACLK_USBHOST30>, <&cmu_fsys CLK_SCLK_USBHOST30>; clock-names = "ref", "bus_early", "suspend"; - reg = <0x0 0x10000>; interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>; phys = <&usbhost30_phy 0>, <&usbhost30_phy 1>; phy-names = "usb2-phy", "usb3-phy"; @@ -1922,10 +1922,10 @@ usbhost_dwc3: usb@0 { mshc_0: mmc@15540000 { compatible = "samsung,exynos5433-dw-mshc-smu", "samsung,exynos7-dw-mshc-smu"; + reg = <0x15540000 0x2000>; interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - reg = <0x15540000 0x2000>; clocks = <&cmu_fsys CLK_ACLK_MMC0>, <&cmu_fsys CLK_SCLK_MMC0>; clock-names = "biu", "ciu"; @@ -1937,10 +1937,10 @@ mshc_0: mmc@15540000 { mshc_1: mmc@15550000 { compatible = "samsung,exynos5433-dw-mshc-smu", "samsung,exynos7-dw-mshc-smu"; + reg = <0x15550000 0x2000>; interrupts = <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - reg = <0x15550000 0x2000>; clocks = <&cmu_fsys CLK_ACLK_MMC1>, <&cmu_fsys CLK_SCLK_MMC1>; clock-names = "biu", "ciu"; @@ -1952,10 +1952,10 @@ mshc_1: mmc@15550000 { mshc_2: mmc@15560000 { compatible = "samsung,exynos5433-dw-mshc-smu", "samsung,exynos7-dw-mshc-smu"; + reg = <0x15560000 0x2000>; interrupts = <GIC_SPI 227 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - reg = <0x15560000 0x2000>; clocks = <&cmu_fsys CLK_ACLK_MMC2>, <&cmu_fsys CLK_SCLK_MMC2>; clock-names = "biu", "ciu"; @@ -1985,12 +1985,12 @@ pdma1: dma-controller@15600000 { audio-subsystem@11400000 { compatible = "samsung,exynos5433-lpass"; reg = <0x11400000 0x100>, <0x11500000 0x08>; + ranges; clocks = <&cmu_aud CLK_PCLK_SFR0_CTRL>; clock-names = "sfr0_ctrl"; power-domains = <&pd_aud>; #address-cells = <1>; #size-cells = <1>; - ranges; adma: dma-controller@11420000 { compatible = "arm,pl330", "arm,primecell"; @@ -2016,8 +2016,8 @@ i2s0: i2s@11440000 { <&cmu_aud CLK_SCLK_I2S_BCLK>; clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; #clock-cells = <1>; - pinctrl-names = "default"; pinctrl-0 = <&i2s0_bus>; + pinctrl-names = "default"; power-domains = <&pd_aud>; #sound-dai-cells = <1>; @@ -2031,8 +2031,8 @@ serial_3: serial@11460000 { clocks = <&cmu_aud CLK_PCLK_AUD_UART>, <&cmu_aud CLK_SCLK_AUD_UART>; clock-names = "uart", "clk_uart_baud0"; - pinctrl-names = "default"; pinctrl-0 = <&uart_aud_bus>; + pinctrl-names = "default"; power-domains = <&pd_aud>; status = "disabled"; @@ -2042,22 +2042,24 @@ serial_3: serial@11460000 { pcie_phy: pcie-phy@15680000 { compatible = "samsung,exynos5433-pcie-phy"; reg = <0x15680000 0x1000>; + #phy-cells = <0>; samsung,pmu-syscon = <&pmu_system_controller>; samsung,fsys-sysreg = <&syscon_fsys>; - #phy-cells = <0>; status = "disabled"; }; pcie: pcie@15700000 { + device_type = "pci"; compatible = "samsung,exynos5433-pcie"; reg = <0x15700000 0x1000>, <0x156b0000 0x1000>, <0x0c000000 0x1000>; reg-names = "dbi", "elbi", "config"; + ranges = <0x81000000 0 0 0x0c001000 0 0x00010000>, + <0x82000000 0 0x0c011000 0x0c011000 0 0x03feefff>; #address-cells = <3>; #size-cells = <2>; #interrupt-cells = <1>; - device_type = "pci"; interrupts = <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>; clocks = <&cmu_fsys CLK_PCIE>, <&cmu_fsys CLK_PCLK_PCIE_PHY>; @@ -2066,8 +2068,6 @@ pcie: pcie@15700000 { num-viewport = <3>; bus-range = <0x00 0xff>; phys = <&pcie_phy>; - ranges = <0x81000000 0 0 0x0c001000 0 0x00010000>, - <0x82000000 0 0x0c011000 0x0c011000 0 0x03feefff>; status = "disabled"; };
diff --git a/arch/arm64/boot/dts/exynos/exynos7870-a2corelte.dts b/arch/arm64/boot/dts/exynos/exynos7870-a2corelte.dts index 0888cd2..67f317a 100644 --- a/arch/arm64/boot/dts/exynos/exynos7870-a2corelte.dts +++ b/arch/arm64/boot/dts/exynos/exynos7870-a2corelte.dts
@@ -34,8 +34,8 @@ gpio-keys { compatible = "gpio-keys"; label = "GPIO Keys"; - pinctrl-names = "default"; pinctrl-0 = <&key_power &key_voldown &key_volup>; + pinctrl-names = "default"; key-power { label = "Power Key"; @@ -86,9 +86,9 @@ vdd_fixed_proxled: regulator-fixed-proxled { }; reserved-memory { + ranges; #address-cells = <2>; #size-cells = <1>; - ranges; ramoops@46800000 { compatible = "ramoops"; @@ -166,8 +166,8 @@ pmic@66 { interrupt-parent = <&gpa0>; interrupts = <2 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default"; pinctrl-0 = <&pmic_irq>; + pinctrl-names = "default"; regulators { vdd_buck1: buck1 { @@ -402,8 +402,8 @@ accelerometer@1d { interrupt-parent = <&gpa2>; interrupts = <3 IRQ_TYPE_EDGE_RISING>; - pinctrl-names = "default"; pinctrl-0 = <&accel_irq>; + pinctrl-names = "default"; st,drdy-int-pin = <1>; }; @@ -414,8 +414,8 @@ proximity@48 { interrupt-parent = <&gpa0>; interrupts = <5 IRQ_TYPE_EDGE_BOTH>; - pinctrl-names = "default"; pinctrl-0 = <&proxm_irq>; + pinctrl-names = "default"; proximity-near-level = <25>; }; @@ -435,8 +435,8 @@ touchscreen@4b { #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&touch_irq>; + pinctrl-names = "default"; vdd-supply = <&vdd_ldo35>; @@ -461,18 +461,19 @@ rmi4-f12@12 { }; &mmc0 { - pinctrl-names = "default"; pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_rdqs &sd0_bus1 &sd0_bus4 &sd0_bus8>; + pinctrl-names = "default"; vmmc-supply = <&vdd_ldo26>; vqmmc-supply = <&vdd_ldo27>; bus-width = <8>; fifo-depth = <64>; + non-removable; + samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; samsung,dw-mshc-ddr-timing = <2 4>; - non-removable; status = "okay"; }; @@ -481,36 +482,37 @@ &mmc1 { #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus1 &sd1_bus4>; + pinctrl-names = "default"; mmc-pwrseq = <&pwrseq_mmc1>; bus-width = <4>; fifo-depth = <64>; - samsung,dw-mshc-ciu-div = <3>; - samsung,dw-mshc-sdr-timing = <0 3>; - samsung,dw-mshc-ddr-timing = <1 2>; non-removable; cap-sd-highspeed; cap-sdio-irq; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <0 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + status = "okay"; wifi@1 { compatible = "brcm,bcm43430a1-fmac", "brcm,bcm4329-fmac"; reg = <0x1>; - interrupt-names = "host-wake"; interrupt-parent = <&gpa2>; interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "host-wake"; reset-gpios = <&gpd3 6 GPIO_ACTIVE_LOW>; }; }; &mmc2 { - pinctrl-names = "default"; pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus1 &sd2_bus4 &dwmmc2_irq>; + pinctrl-names = "default"; vmmc-supply = <&vdd_fixed_mmc2>; vqmmc-supply = <&vdd_ldo2>; @@ -518,14 +520,15 @@ &mmc2 { bus-width = <4>; card-detect-delay = <200>; fifo-depth = <64>; - samsung,dw-mshc-ciu-div = <3>; - samsung,dw-mshc-sdr-timing = <0 3>; - samsung,dw-mshc-ddr-timing = <1 2>; sd-uhs-sdr50; sd-uhs-sdr104; broken-cd; disable-wp; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <0 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + status = "okay"; }; @@ -629,8 +632,8 @@ &serial1 { bluetooth { compatible = "brcm,bcm43430a1-bt"; - pinctrl-names = "default"; pinctrl-0 = <&bt_btwake &bt_hostwake &bt_enable>; + pinctrl-names = "default"; device-wakeup-gpios = <&gpa1 2 GPIO_ACTIVE_HIGH>; host-wakeup-gpios = <&gpa1 6 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm64/boot/dts/exynos/exynos7870-j5y17lte.dts b/arch/arm64/boot/dts/exynos/exynos7870-j5y17lte.dts index 36c3276..84421a3 100644 --- a/arch/arm64/boot/dts/exynos/exynos7870-j5y17lte.dts +++ b/arch/arm64/boot/dts/exynos/exynos7870-j5y17lte.dts
@@ -26,9 +26,9 @@ aliases { }; chosen { + ranges; #address-cells = <2>; #size-cells = <1>; - ranges; stdout-path = &serial2; @@ -44,35 +44,35 @@ framebuffer@67000000 { gpio-keys { compatible = "gpio-keys"; - pinctrl-names = "default"; pinctrl-0 = <&key_power &key_voldown &key_volup>; + pinctrl-names = "default"; key-home { interrupt-parent = <&gpa1>; - linux,code = <KEY_HOMEPAGE>; label = "gpio-keys: KEY_HOMEPAGE"; gpios = <&gpa1 7 GPIO_ACTIVE_LOW>; + linux,code = <KEY_HOMEPAGE>; }; key-power { interrupt-parent = <&gpa0>; - linux,code = <KEY_POWER>; label = "gpio-keys: KEY_POWER"; gpios = <&gpa0 0 GPIO_ACTIVE_LOW>; + linux,code = <KEY_POWER>; }; key-voldown { interrupt-parent = <&gpa2>; - linux,code = <KEY_VOLUMEDOWN>; label = "gpio-keys: KEY_VOLUMEDOWN"; gpios = <&gpa2 1 GPIO_ACTIVE_LOW>; + linux,code = <KEY_VOLUMEDOWN>; }; key-volup { interrupt-parent = <&gpa2>; - linux,code = <KEY_VOLUMEUP>; label = "gpio-keys: KEY_VOLUMEUP"; gpios = <&gpa2 0 GPIO_ACTIVE_LOW>; + linux,code = <KEY_VOLUMEUP>; }; }; @@ -98,9 +98,9 @@ vdd_fixed_mmc2: regulator-fixed-mmc2 { }; reserved-memory { + ranges; #address-cells = <2>; #size-cells = <1>; - ranges; ramoops@46e00000 { compatible = "ramoops"; @@ -137,8 +137,8 @@ pmic@66 { interrupt-parent = <&gpa0>; interrupts = <2 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default"; pinctrl-0 = <&pmic_irq>; + pinctrl-names = "default"; regulators { vdd_buck1: buck1 { @@ -368,8 +368,8 @@ touchscreen@50 { interrupt-parent = <&gpa0>; interrupts = <6 IRQ_TYPE_EDGE_FALLING>; - pinctrl-names = "default"; pinctrl-0 = <&touch_irq>; + pinctrl-names = "default"; touchscreen-size-x = <720>; touchscreen-size-y = <1280>; @@ -379,17 +379,18 @@ touchscreen@50 { }; &mmc0 { - pinctrl-names = "default"; pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_rdqs &sd0_bus1 &sd0_bus4 &sd0_bus8>; + pinctrl-names = "default"; vmmc-supply = <&vdd_ldo26>; vqmmc-supply = <&vdd_ldo27>; fifo-depth = <64>; + non-removable; + samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; samsung,dw-mshc-ddr-timing = <2 4>; - non-removable; status = "okay"; }; @@ -398,29 +399,30 @@ &mmc1 { #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus1 &sd1_bus4>; + pinctrl-names = "default"; mmc-pwrseq = <&pwrseq_mmc1>; bus-width = <4>; fifo-depth = <64>; - samsung,dw-mshc-ciu-div = <3>; - samsung,dw-mshc-sdr-timing = <0 3>; - samsung,dw-mshc-ddr-timing = <1 2>; non-removable; cap-sd-highspeed; cap-sdio-irq; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <0 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + status = "okay"; wifi@0 { compatible = "brcm,bcm43455-fmac", "brcm,bcm4329-fmac"; reg = <0x0>; - interrupt-names = "host-wake"; interrupt-parent = <&gpa2>; interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "host-wake"; reset-gpios = <&gpd3 6 GPIO_ACTIVE_LOW>; };
diff --git a/arch/arm64/boot/dts/exynos/exynos7870-j6lte.dts b/arch/arm64/boot/dts/exynos/exynos7870-j6lte.dts index 02bab3a..8bd6892 100644 --- a/arch/arm64/boot/dts/exynos/exynos7870-j6lte.dts +++ b/arch/arm64/boot/dts/exynos/exynos7870-j6lte.dts
@@ -34,16 +34,16 @@ gpio-hall-effect-sensor { compatible = "gpio-keys"; label = "GPIO Hall Effect Sensor"; - pinctrl-names = "default"; pinctrl-0 = <&hall_irq>; + pinctrl-names = "default"; event-hall-effect-sensor { label = "Hall Effect Sensor"; gpios = <&gpa1 3 GPIO_ACTIVE_LOW>; + wakeup-source; linux,input-type = <EV_SW>; linux,code = <SW_LID>; linux,can-disable; - wakeup-source; }; }; @@ -51,8 +51,8 @@ gpio-keys { compatible = "gpio-keys"; label = "GPIO Keys"; - pinctrl-names = "default"; pinctrl-0 = <&key_power &key_voldown &key_volup>; + pinctrl-names = "default"; key-power { label = "Power Key"; @@ -95,9 +95,9 @@ vdd_fixed_mmc2: regulator-fixed-mmc2 { }; reserved-memory { + ranges; #address-cells = <2>; #size-cells = <1>; - ranges; ramoops@46e00000 { compatible = "ramoops"; @@ -159,8 +159,8 @@ pmic@66 { interrupt-parent = <&gpa0>; interrupts = <2 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default"; pinctrl-0 = <&pmic_irq>; + pinctrl-names = "default"; regulators { vdd_buck1: buck1 { @@ -394,8 +394,8 @@ accelerometer@1d { interrupt-parent = <&gpa2>; interrupts = <3 IRQ_TYPE_EDGE_RISING>; - pinctrl-names = "default"; pinctrl-0 = <&accel_irq>; + pinctrl-names = "default"; mount-matrix = "-1", "0", "0", "0", "1", "0", @@ -417,8 +417,8 @@ touchscreen@20 { interrupt-parent = <&gpa0>; interrupts = <6 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default"; pinctrl-0 = <&touch_irq>; + pinctrl-names = "default"; touchscreen-size-x = <720>; touchscreen-size-y = <1480>; @@ -428,18 +428,19 @@ touchscreen@20 { }; &mmc0 { - pinctrl-names = "default"; pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_rdqs &sd0_bus1 &sd0_bus4 &sd0_bus8>; + pinctrl-names = "default"; vmmc-supply = <&vdd_ldo26>; vqmmc-supply = <&vdd_ldo27>; bus-width = <8>; fifo-depth = <64>; + non-removable; + samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; samsung,dw-mshc-ddr-timing = <2 4>; - non-removable; status = "okay"; }; @@ -448,36 +449,37 @@ &mmc1 { #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus1 &sd1_bus4>; + pinctrl-names = "default"; mmc-pwrseq = <&pwrseq_mmc1>; bus-width = <4>; fifo-depth = <64>; - samsung,dw-mshc-ciu-div = <3>; - samsung,dw-mshc-sdr-timing = <0 3>; - samsung,dw-mshc-ddr-timing = <1 2>; non-removable; cap-sd-highspeed; cap-sdio-irq; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <0 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + status = "okay"; wifi@1 { compatible = "brcm,bcm43430a1-fmac", "brcm,bcm4329-fmac"; reg = <0x1>; - interrupt-names = "host-wake"; interrupt-parent = <&gpa2>; interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "host-wake"; reset-gpios = <&gpd3 6 GPIO_ACTIVE_LOW>; }; }; &mmc2 { - pinctrl-names = "default"; pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus1 &sd2_bus4 &dwmmc2_irq>; + pinctrl-names = "default"; vmmc-supply = <&vdd_fixed_mmc2>; vqmmc-supply = <&vdd_ldo2>; @@ -596,8 +598,8 @@ &serial1 { bluetooth { compatible = "brcm,bcm43430a1-bt"; - pinctrl-names = "default"; pinctrl-0 = <&bt_btwake &bt_hostwake &bt_enable>; + pinctrl-names = "default"; device-wakeup-gpios = <&gpa1 2 GPIO_ACTIVE_HIGH>; host-wakeup-gpios = <&gpa1 6 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm64/boot/dts/exynos/exynos7870-j7xelte.dts b/arch/arm64/boot/dts/exynos/exynos7870-j7xelte.dts index 079b2b5..d258eec 100644 --- a/arch/arm64/boot/dts/exynos/exynos7870-j7xelte.dts +++ b/arch/arm64/boot/dts/exynos/exynos7870-j7xelte.dts
@@ -26,9 +26,9 @@ aliases { }; chosen { + ranges; #address-cells = <2>; #size-cells = <1>; - ranges; stdout-path = &serial2; @@ -46,8 +46,8 @@ gpio-keys { compatible = "gpio-keys"; label = "GPIO Keys"; - pinctrl-names = "default"; pinctrl-0 = <&key_home &key_power &key_voldown &key_volup>; + pinctrl-names = "default"; key-home { label = "Home Key"; @@ -86,9 +86,9 @@ pwrseq_mmc1: pwrseq-mmc1 { }; reserved-memory { + ranges; #address-cells = <2>; #size-cells = <1>; - ranges; ramoops@46e00000 { compatible = "ramoops"; @@ -136,8 +136,8 @@ pmic@66 { interrupt-parent = <&gpa0>; interrupts = <2 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default"; pinctrl-0 = <&pmic_irq>; + pinctrl-names = "default"; regulators { vdd_buck1: buck1 { @@ -346,23 +346,24 @@ touchscreen@48 { interrupt-parent = <&gpc3>; interrupts = <2 IRQ_TYPE_EDGE_FALLING>; - pinctrl-names = "default"; pinctrl-0 = <&touch_irq>; + pinctrl-names = "default"; }; }; &mmc0 { - pinctrl-names = "default"; pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_rdqs &sd0_bus1 &sd0_bus4 &sd0_bus8>; + pinctrl-names = "default"; vmmc-supply = <&vdd_ldo26>; vqmmc-supply = <&vdd_ldo27>; fifo-depth = <64>; + non-removable; + samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; samsung,dw-mshc-ddr-timing = <2 4>; - non-removable; status = "okay"; }; @@ -371,37 +372,38 @@ &mmc1 { #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus1 &sd1_bus4>; + pinctrl-names = "default"; mmc-pwrseq = <&pwrseq_mmc1>; bus-width = <4>; fifo-depth = <64>; - samsung,dw-mshc-ciu-div = <3>; - samsung,dw-mshc-sdr-timing = <0 3>; - samsung,dw-mshc-ddr-timing = <1 2>; non-removable; cap-sd-highspeed; cap-sdio-irq; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <0 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + status = "okay"; wifi@1 { compatible = "brcm,bcm43430a1-fmac", "brcm,bcm4329-fmac"; reg = <0x1>; - interrupt-names = "host-wake"; interrupt-parent = <&gpa2>; interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "host-wake"; reset-gpios = <&gpd3 6 GPIO_ACTIVE_LOW>; }; }; &mmc2 { - pinctrl-names = "default"; pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus1 &sd2_bus4 &dwmmc2_irq>; + pinctrl-names = "default"; vmmc-supply = <&vdd_fixed_mmc2>; vqmmc-supply = <&vdd_ldo2>; @@ -409,14 +411,15 @@ &mmc2 { bus-width = <4>; card-detect-delay = <200>; fifo-depth = <64>; - samsung,dw-mshc-ciu-div = <3>; - samsung,dw-mshc-sdr-timing = <0 3>; - samsung,dw-mshc-ddr-timing = <1 2>; sd-uhs-sdr50; sd-uhs-sdr104; broken-cd; disable-wp; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <0 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + status = "okay"; };
diff --git a/arch/arm64/boot/dts/exynos/exynos7870-on7xelte.dts b/arch/arm64/boot/dts/exynos/exynos7870-on7xelte.dts index 29be476..5bb95aa 100644 --- a/arch/arm64/boot/dts/exynos/exynos7870-on7xelte.dts +++ b/arch/arm64/boot/dts/exynos/exynos7870-on7xelte.dts
@@ -34,8 +34,8 @@ gpio-keys { compatible = "gpio-keys"; label = "GPIO Keys"; - pinctrl-names = "default"; pinctrl-0 = <&key_home &key_power &key_voldown &key_volup>; + pinctrl-names = "default"; key-home { label = "Home Key"; @@ -84,9 +84,9 @@ vdd_fixed_mmc2: regulator-fixed-mmc2 { }; reserved-memory { + ranges; #address-cells = <2>; #size-cells = <1>; - ranges; ramoops@46e00000 { compatible = "ramoops"; @@ -168,8 +168,8 @@ pmic@66 { interrupt-parent = <&gpa0>; interrupts = <2 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default"; pinctrl-0 = <&pmic_irq>; + pinctrl-names = "default"; regulators { vdd_buck1: buck1 { @@ -411,8 +411,8 @@ touchscreen@70 { #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&touch_irq>; + pinctrl-names = "default"; syna,reset-delay-ms = <200>; syna,startup-delay-ms = <200>; @@ -446,8 +446,8 @@ accelerometer@1d { interrupt-parent = <&gpa2>; interrupts = <3 IRQ_TYPE_EDGE_RISING>; - pinctrl-names = "default"; pinctrl-0 = <&accel_irq>; + pinctrl-names = "default"; mount-matrix = "1", "0", "0", "0", "-1", "0", @@ -469,26 +469,27 @@ proximity@48 { interrupt-parent = <&gpa0>; interrupts = <5 IRQ_TYPE_EDGE_BOTH>; - pinctrl-names = "default"; pinctrl-0 = <&proxm_irq>; + pinctrl-names = "default"; proximity-near-level = <25>; }; }; &mmc0 { - pinctrl-names = "default"; pinctrl-0 = <&sd0_clk &sd0_cmd &sd0_rdqs &sd0_bus1 &sd0_bus4 &sd0_bus8>; + pinctrl-names = "default"; vmmc-supply = <&vdd_ldo26>; vqmmc-supply = <&vdd_ldo27>; bus-width = <8>; fifo-depth = <64>; + non-removable; + samsung,dw-mshc-ciu-div = <3>; samsung,dw-mshc-sdr-timing = <0 4>; samsung,dw-mshc-ddr-timing = <2 4>; - non-removable; status = "okay"; }; @@ -497,36 +498,37 @@ &mmc1 { #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&sd1_clk &sd1_cmd &sd1_bus1 &sd1_bus4>; + pinctrl-names = "default"; mmc-pwrseq = <&pwrseq_mmc1>; bus-width = <4>; fifo-depth = <64>; - samsung,dw-mshc-ciu-div = <3>; - samsung,dw-mshc-sdr-timing = <0 3>; - samsung,dw-mshc-ddr-timing = <1 2>; non-removable; cap-sd-highspeed; cap-sdio-irq; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <0 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + status = "okay"; wifi@1 { compatible = "brcm,bcm43430a1-fmac", "brcm,bcm4329-fmac"; reg = <0x1>; - interrupt-names = "host-wake"; interrupt-parent = <&gpa2>; interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + interrupt-names = "host-wake"; reset-gpios = <&gpd3 6 GPIO_ACTIVE_LOW>; }; }; &mmc2 { - pinctrl-names = "default"; pinctrl-0 = <&sd2_clk &sd2_cmd &sd2_bus1 &sd2_bus4 &dwmmc2_irq>; + pinctrl-names = "default"; vmmc-supply = <&vdd_fixed_mmc2>; vqmmc-supply = <&vdd_ldo2>; @@ -534,14 +536,15 @@ &mmc2 { bus-width = <4>; card-detect-delay = <200>; fifo-depth = <64>; - samsung,dw-mshc-ciu-div = <3>; - samsung,dw-mshc-sdr-timing = <0 3>; - samsung,dw-mshc-ddr-timing = <1 2>; sd-uhs-sdr50; sd-uhs-sdr104; broken-cd; disable-wp; + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <0 3>; + samsung,dw-mshc-ddr-timing = <1 2>; + status = "okay"; }; @@ -661,8 +664,8 @@ &serial1 { bluetooth { compatible = "brcm,bcm43430a1-bt"; - pinctrl-names = "default"; pinctrl-0 = <&bt_btwake &bt_hostwake &bt_enable>; + pinctrl-names = "default"; device-wakeup-gpios = <&gpa1 2 GPIO_ACTIVE_HIGH>; host-wakeup-gpios = <&gpa1 6 GPIO_ACTIVE_HIGH>;
diff --git a/arch/arm64/boot/dts/exynos/exynos7870.dtsi b/arch/arm64/boot/dts/exynos/exynos7870.dtsi index 9e3ec6c..c397f57 100644 --- a/arch/arm64/boot/dts/exynos/exynos7870.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos7870.dtsi
@@ -156,8 +156,6 @@ cmu_peri: clock-controller@101f0000 { reg = <0x101f0000 0x1000>; #clock-cells = <1>; - clock-names = "oscclk", "bus", "spi0", "spi1", "spi2", - "spi3", "spi4", "uart0", "uart1", "uart2"; clocks = <&oscclk>, <&cmu_mif CLK_GOUT_MIF_CMU_PERI_BUS>, <&cmu_mif CLK_GOUT_MIF_CMU_PERI_SPI0>, @@ -168,6 +166,8 @@ cmu_peri: clock-controller@101f0000 { <&cmu_mif CLK_GOUT_MIF_CMU_PERI_UART0>, <&cmu_mif CLK_GOUT_MIF_CMU_PERI_UART1>, <&cmu_mif CLK_GOUT_MIF_CMU_PERI_UART2>; + clock-names = "oscclk", "bus", "spi0", "spi1", "spi2", + "spi3", "spi4", "uart0", "uart1", "uart2"; }; cmu_mif: clock-controller@10460000 { @@ -175,8 +175,8 @@ cmu_mif: clock-controller@10460000 { reg = <0x10460000 0x1000>; #clock-cells = <1>; - clock-names = "oscclk"; clocks = <&oscclk>; + clock-names = "oscclk"; }; pmu_system_controller: system-controller@10480000 { @@ -219,11 +219,11 @@ hsi2c0: i2c@10510000 { reg = <0x10510000 0x2000>; interrupts = <GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&hsi2c0_bus>; + pinctrl-names = "default"; - clock-names = "hsi2c"; clocks = <&cmu_mif CLK_GOUT_MIF_HSI2C_IPCLK>; + clock-names = "hsi2c"; #address-cells = <1>; #size-cells = <0>; @@ -240,14 +240,14 @@ pinctrl_mif: pinctrl@10530000 { gpu: gpu@11400000 { compatible = "samsung,exynos7870-mali", "arm,mali-t830"; reg = <0x11400000 0x5000>; - interrupt-names = "job", "mmu", "gpu"; interrupts = <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 281 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "job", "mmu", "gpu"; - clock-names = "core", "bus"; clocks = <&cmu_g3d CLK_GOUT_G3D_CLK>, <&cmu_g3d CLK_GOUT_G3D_ASYNCS_D0_CLK>; + clock-names = "core", "bus"; status = "disabled"; }; @@ -257,9 +257,9 @@ cmu_g3d: clock-controller@11460000 { reg = <0x11460000 0x1000>; #clock-cells = <1>; - clock-names = "oscclk", "switch"; clocks = <&oscclk>, <&cmu_mif CLK_GOUT_MIF_CMU_G3D_SWITCH>; + clock-names = "oscclk", "switch"; }; cmu_mfcmscl: clock-controller@12cb0000 { @@ -267,10 +267,10 @@ cmu_mfcmscl: clock-controller@12cb0000 { reg = <0x12cb0000 0x1000>; #clock-cells = <1>; - clock-names = "oscclk", "mfc", "mscl"; clocks = <&oscclk>, <&cmu_mif CLK_GOUT_MIF_CMU_MFCMSCL_MFC>, <&cmu_mif CLK_GOUT_MIF_CMU_MFCMSCL_MSCL>; + clock-names = "oscclk", "mfc", "mscl"; }; mmc0: mmc@13540000 { @@ -278,9 +278,9 @@ mmc0: mmc@13540000 { reg = <0x13540000 0x2000>; interrupts = <GIC_SPI 245 IRQ_TYPE_LEVEL_HIGH>; - clock-names = "biu", "ciu"; clocks = <&cmu_fsys CLK_GOUT_FSYS_MMC0_ACLK>, <&cmu_mif CLK_GOUT_MIF_CMU_FSYS_MMC0>; + clock-names = "biu", "ciu"; status = "disabled"; }; @@ -290,9 +290,9 @@ mmc1: mmc@13550000 { reg = <0x13550000 0x2000>; interrupts = <GIC_SPI 246 IRQ_TYPE_LEVEL_HIGH>; - clock-names = "biu", "ciu"; clocks = <&cmu_fsys CLK_GOUT_FSYS_MMC1_ACLK>, <&cmu_mif CLK_GOUT_MIF_CMU_FSYS_MMC1>; + clock-names = "biu", "ciu"; status = "disabled"; }; @@ -302,9 +302,9 @@ mmc2: mmc@13560000 { reg = <0x13560000 0x2000>; interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH>; - clock-names = "biu", "ciu"; clocks = <&cmu_fsys CLK_GOUT_FSYS_MMC2_ACLK>, <&cmu_mif CLK_GOUT_MIF_CMU_FSYS_MMC2>; + clock-names = "biu", "ciu"; status = "disabled"; }; @@ -314,9 +314,9 @@ usbdrd_phy: phy@135c0000 { reg = <0x135c0000 0x100>; #phy-cells = <1>; - clock-names = "phy", "ref"; clocks = <&cmu_fsys CLK_GOUT_FSYS_MUX_USB20DRD_PHYCLOCK_USER>, <&cmu_fsys CLK_GOUT_FSYS_MUX_USB_PLL>; + clock-names = "phy", "ref"; samsung,pmu-syscon = <&pmu_system_controller>; }; @@ -327,10 +327,10 @@ usbdrd: usb@13600000 { #address-cells = <1>; #size-cells = <1>; - clock-names = "bus_early", "ref", "ctrl"; clocks = <&cmu_fsys CLK_GOUT_FSYS_USB20DRD_ACLK_HSDRD>, <&cmu_fsys CLK_GOUT_FSYS_USB20DRD_HSDRD_REF_CLK>, <&cmu_fsys CLK_GOUT_FSYS_USB20DRD_HCLK_USB20_CTRL>; + clock-names = "bus_early", "ref", "ctrl"; status = "disabled"; @@ -339,8 +339,8 @@ usb@0 { reg = <0x0 0x10000>; interrupts = <GIC_SPI 230 IRQ_TYPE_LEVEL_HIGH>; - phy-names = "usb2-phy"; phys = <&usbdrd_phy 0>; + phy-names = "usb2-phy"; usb-role-switch; snps,usb2-gadget-lpm-disable; @@ -352,10 +352,10 @@ cmu_fsys: clock-controller@13730000 { reg = <0x13730000 0x1000>; #clock-cells = <1>; - clock-names = "oscclk", "bus", "usb20drd"; clocks = <&oscclk>, <&cmu_mif CLK_GOUT_MIF_CMU_FSYS_BUS>, <&cmu_mif CLK_GOUT_MIF_CMU_FSYS_USB20DRD_REFCLK>; + clock-names = "oscclk", "bus", "usb20drd"; }; pinctrl_fsys: pinctrl@13750000 { @@ -370,12 +370,12 @@ serial0: serial@13800000 { reg = <0x13800000 0x100>; interrupts = <GIC_SPI 421 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&uart0_bus>; + pinctrl-names = "default"; - clock-names = "uart", "clk_uart_baud0"; clocks = <&cmu_peri CLK_GOUT_PERI_UART0_PCLK>, <&cmu_peri CLK_GOUT_PERI_UART0_EXT_UCLK>; + clock-names = "uart", "clk_uart_baud0"; samsung,uart-fifosize = <16>; @@ -388,12 +388,12 @@ serial1: serial@13810000 { reg = <0x13810000 0x100>; interrupts = <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&uart1_bus>; + pinctrl-names = "default"; - clock-names = "uart", "clk_uart_baud0"; clocks = <&cmu_peri CLK_GOUT_PERI_UART1_PCLK>, <&cmu_peri CLK_GOUT_PERI_UART1_EXT_UCLK>; + clock-names = "uart", "clk_uart_baud0"; samsung,uart-fifosize = <256>; @@ -406,12 +406,12 @@ serial2: serial@13820000 { reg = <0x13820000 0x100>; interrupts = <GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&uart2_bus>; + pinctrl-names = "default"; - clock-names = "uart", "clk_uart_baud0"; clocks = <&cmu_peri CLK_GOUT_PERI_UART2_PCLK>, <&cmu_peri CLK_GOUT_PERI_UART2_EXT_UCLK>; + clock-names = "uart", "clk_uart_baud0"; samsung,uart-fifosize = <256>; @@ -424,11 +424,11 @@ i2c0: i2c@13830000 { reg = <0x13830000 0x100>; interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&i2c0_bus>; + pinctrl-names = "default"; - clock-names = "i2c"; clocks = <&cmu_peri CLK_GOUT_PERI_I2C0_PCLK>; + clock-names = "i2c"; #address-cells = <1>; #size-cells = <0>; @@ -442,11 +442,11 @@ i2c1: i2c@13840000 { reg = <0x13840000 0x100>; interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&i2c1_bus>; + pinctrl-names = "default"; - clock-names = "i2c"; clocks = <&cmu_peri CLK_GOUT_PERI_I2C1_PCLK>; + clock-names = "i2c"; #address-cells = <1>; #size-cells = <0>; @@ -460,11 +460,11 @@ i2c2: i2c@13850000 { reg = <0x13850000 0x100>; interrupts = <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&i2c2_bus>; + pinctrl-names = "default"; - clock-names = "i2c"; clocks = <&cmu_peri CLK_GOUT_PERI_I2C2_PCLK>; + clock-names = "i2c"; #address-cells = <1>; #size-cells = <0>; @@ -478,11 +478,11 @@ i2c3: i2c@13860000 { reg = <0x13860000 0x100>; interrupts = <GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&i2c3_bus>; + pinctrl-names = "default"; - clock-names = "i2c"; clocks = <&cmu_peri CLK_GOUT_PERI_I2C3_PCLK>; + clock-names = "i2c"; #address-cells = <1>; #size-cells = <0>; @@ -496,11 +496,11 @@ i2c4: i2c@13870000 { reg = <0x13870000 0x100>; interrupts = <GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&i2c4_bus>; + pinctrl-names = "default"; - clock-names = "i2c"; clocks = <&cmu_peri CLK_GOUT_PERI_I2C4_PCLK>; + clock-names = "i2c"; #address-cells = <1>; #size-cells = <0>; @@ -514,11 +514,11 @@ i2c5: i2c@13880000 { reg = <0x13880000 0x100>; interrupts = <GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&i2c5_bus>; + pinctrl-names = "default"; - clock-names = "i2c"; clocks = <&cmu_peri CLK_GOUT_PERI_I2C5_PCLK>; + clock-names = "i2c"; #address-cells = <1>; #size-cells = <0>; @@ -532,11 +532,11 @@ i2c6: i2c@13890000 { reg = <0x13890000 0x100>; interrupts = <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&i2c6_bus>; + pinctrl-names = "default"; - clock-names = "i2c"; clocks = <&cmu_peri CLK_GOUT_PERI_I2C6_PCLK>; + clock-names = "i2c"; #address-cells = <1>; #size-cells = <0>; @@ -550,11 +550,11 @@ hsi2c1: i2c@138a0000 { reg = <0x138a0000 0x1000>; interrupts = <GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&hsi2c1_bus>; + pinctrl-names = "default"; - clock-names = "hsi2c"; clocks = <&cmu_peri CLK_GOUT_PERI_HSI2C1_IPCLK>; + clock-names = "hsi2c"; #address-cells = <1>; #size-cells = <0>; @@ -568,11 +568,11 @@ hsi2c2: i2c@138b0000 { reg = <0x138b0000 0x1000>; interrupts = <GIC_SPI 450 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&hsi2c2_bus>; + pinctrl-names = "default"; - clock-names = "hsi2c"; clocks = <&cmu_peri CLK_GOUT_PERI_HSI2C2_IPCLK>; + clock-names = "hsi2c"; #address-cells = <1>; #size-cells = <0>; @@ -586,11 +586,11 @@ hsi2c3: i2c@138c0000 { reg = <0x138c0000 0x1000>; interrupts = <GIC_SPI 451 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&hsi2c3_bus>; + pinctrl-names = "default"; - clock-names = "hsi2c"; clocks = <&cmu_peri CLK_GOUT_PERI_HSI2C3_IPCLK>; + clock-names = "hsi2c"; #address-cells = <1>; #size-cells = <0>; @@ -604,11 +604,11 @@ i2c7: i2c@138d0000 { reg = <0x138d0000 0x100>; interrupts = <GIC_SPI 453 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&i2c7_bus>; + pinctrl-names = "default"; - clock-names = "i2c"; clocks = <&cmu_peri CLK_GOUT_PERI_I2C7_PCLK>; + clock-names = "i2c"; #address-cells = <1>; #size-cells = <0>; @@ -622,11 +622,11 @@ i2c8: i2c@138e0000 { reg = <0x138e0000 0x100>; interrupts = <GIC_SPI 454 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&i2c8_bus>; + pinctrl-names = "default"; - clock-names = "i2c"; clocks = <&cmu_peri CLK_GOUT_PERI_I2C8_PCLK>; + clock-names = "i2c"; #address-cells = <1>; #size-cells = <0>; @@ -640,11 +640,11 @@ hsi2c4: i2c@138f0000 { reg = <0x138f0000 0x1000>; interrupts = <GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&hsi2c4_bus>; + pinctrl-names = "default"; - clock-names = "hsi2c"; clocks = <&cmu_peri CLK_GOUT_PERI_HSI2C4_IPCLK>; + clock-names = "hsi2c"; #address-cells = <1>; #size-cells = <0>; @@ -658,11 +658,11 @@ hsi2c5: i2c@13950000 { reg = <0x13950000 0x1000>; interrupts = <GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&hsi2c5_bus>; + pinctrl-names = "default"; - clock-names = "hsi2c"; clocks = <&cmu_peri CLK_GOUT_PERI_HSI2C5_IPCLK>; + clock-names = "hsi2c"; #address-cells = <1>; #size-cells = <0>; @@ -676,11 +676,11 @@ hsi2c6: i2c@13960000 { reg = <0x13960000 0x1000>; interrupts = <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&hsi2c6_bus>; + pinctrl-names = "default"; - clock-names = "hsi2c"; clocks = <&cmu_peri CLK_GOUT_PERI_HSI2C6_IPCLK>; + clock-names = "hsi2c"; #address-cells = <1>; #size-cells = <0>; @@ -729,11 +729,11 @@ cmu_isp: clock-controller@144d0000 { reg = <0x144d0000 0x1000>; #clock-cells = <1>; - clock-names = "oscclk", "cam", "isp", "vra"; clocks = <&oscclk>, <&cmu_mif CLK_GOUT_MIF_CMU_ISP_CAM>, <&cmu_mif CLK_GOUT_MIF_CMU_ISP_ISP>, <&cmu_mif CLK_GOUT_MIF_CMU_ISP_VRA>; + clock-names = "oscclk", "cam", "isp", "vra"; }; syscon_cam0: system-controller@144f1040 { @@ -818,11 +818,11 @@ cmu_dispaud: clock-controller@148d0000 { reg = <0x148d0000 0x1000>; #clock-cells = <1>; - clock-names = "oscclk", "bus", "decon_eclk", "decon_vclk"; clocks = <&oscclk>, <&cmu_mif CLK_GOUT_MIF_CMU_DISPAUD_BUS>, <&cmu_mif CLK_GOUT_MIF_CMU_DISPAUD_DECON_ECLK>, <&cmu_mif CLK_GOUT_MIF_CMU_DISPAUD_DECON_VCLK>; + clock-names = "oscclk", "bus", "decon_eclk", "decon_vclk"; }; syscon_disp: system-controller@148f100c {
diff --git a/arch/arm64/boot/dts/exynos/exynos850-a217f.dts b/arch/arm64/boot/dts/exynos/exynos850-a217f.dts new file mode 100644 index 0000000..b5b66c0 --- /dev/null +++ b/arch/arm64/boot/dts/exynos/exynos850-a217f.dts
@@ -0,0 +1,200 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Samsung Galaxy A21s (a21s/SM-A217F) device tree source + * + * Copyright (c) 2026, Thomas Turner <tturner@lineageos.org> + */ + +/dts-v1/; +#include "exynos850.dtsi" +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> + +/ { + model = "Samsung Galaxy A21s"; + compatible = "samsung,a217f", "samsung,exynos850"; + + chosen { + ranges; + #address-cells = <2>; + #size-cells = <1>; + + framebuffer0: framebuffer@fa000000 { + compatible = "simple-framebuffer"; + reg = <0x0 0xfa000000 (720 * 1600 * 4)>; + width = <720>; + height = <1600>; + stride = <(720 * 4)>; + format = "a8r8g8b8"; + clocks = <&cmu_dpu CLK_GOUT_DPU_DECON0_ACLK>, + <&cmu_dpu CLK_GOUT_DPU_DMA_ACLK>, + <&cmu_dpu CLK_GOUT_DPU_DPP_ACLK>, + <&cmu_dpu CLK_GOUT_DPU_PPMU_ACLK>, + <&cmu_dpu CLK_GOUT_DPU_PPMU_PCLK>, + <&cmu_dpu CLK_GOUT_DPU_SMMU_CLK>; + }; + }; + + /* + * RTC clock (XrtcXTI); external, must be 32.768 kHz. + * + * TODO: Remove this once RTC clock is implemented properly as part of + * PMIC driver. + */ + rtcclk: clock-rtcclk { + compatible = "fixed-clock"; + clock-output-names = "rtcclk"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-0 = <&key_voldown &key_volup>; + pinctrl-names = "default"; + + voldown-key { + label = "Volume Down"; + gpios = <&gpa1 0 GPIO_ACTIVE_LOW>; + linux,code = <KEY_VOLUMEDOWN>; + }; + + volup-key { + label = "Volume Up"; + gpios = <&gpa0 7 GPIO_ACTIVE_LOW>; + linux,code = <KEY_VOLUMEUP>; + }; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x3c900000>, + <0x0 0xc0000000 0x20000000>, + <0x0 0xe0d00000 0x1f300000>, + <0x8 0x80000000 0x20000000>, + <0x8 0xa0000000 0x20000000>; + }; + + /* TODO: Remove this once PMIC is implemented */ + reg_dummy: regulator-0 { + compatible = "regulator-fixed"; + regulator-name = "dummy_reg"; + }; + + reserved-memory { + ranges; + #address-cells = <2>; + #size-cells = <1>; + + ramoops@f0000000 { + compatible = "ramoops"; + reg = <0x0 0xf0000000 0x200000>; + record-size = <0x20000>; + console-size = <0x20000>; + ftrace-size = <0x100000>; + pmsg-size = <0x20000>; + }; + + cont_splash_mem: framebuffer@fa000000 { + reg = <0x0 0xfa000000 (720 * 1600 * 4)>; + no-map; + }; + }; +}; + +&cmu_hsi { + clocks = <&oscclk>, <&rtcclk>, + <&cmu_top CLK_DOUT_HSI_BUS>, + <&cmu_top CLK_DOUT_HSI_MMC_CARD>, + <&cmu_top CLK_DOUT_HSI_USB20DRD>; + clock-names = "oscclk", "rtcclk", "dout_hsi_bus", + "dout_hsi_mmc_card", "dout_hsi_usb20drd"; +}; + +&gpu { + mali-supply = <®_dummy>; + + status = "okay"; +}; + +&mmc_0 { + compatible = "samsung,exynos7-dw-mshc"; + mmc-hs200-1_8v; + mmc-hs400-1_8v; + cap-mmc-highspeed; + non-removable; + mmc-hs400-enhanced-strobe; + card-detect-delay = <200>; + clock-frequency = <800000000>; + bus-width = <8>; + + pinctrl-0 = <&sd0_clk_pins &sd0_cmd_pins &sd0_rdqs_pins &sd0_nreset_pins + &sd0_bus1_pins &sd0_bus4_pins &sd0_bus8_pins>; + pinctrl-names = "default"; + + samsung,dw-mshc-ciu-div = <3>; + samsung,dw-mshc-sdr-timing = <0 4>; + samsung,dw-mshc-ddr-timing = <2 4>; + samsung,dw-mshc-hs400-timing = <0 2>; + + status = "okay"; +}; + +&oscclk { + clock-frequency = <26000000>; +}; + +&pinctrl_alive { + key_voldown: key-voldown-pins { + samsung,pins = "gpa1-0"; + samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>; + }; + + key_volup: key-volup-pins { + samsung,pins = "gpa0-7"; + samsung,pin-function = <EXYNOS_PIN_FUNC_EINT>; + samsung,pin-pud = <EXYNOS_PIN_PULL_NONE>; + samsung,pin-drv = <EXYNOS5420_PIN_DRV_LV1>; + }; +}; + +&rtc { + clocks = <&cmu_apm CLK_GOUT_RTC_PCLK>, <&rtcclk>; + clock-names = "rtc", "rtc_src"; + + status = "disabled"; +}; + +&timer { + /* + * Non-updatable, broken stock Samsung bootloader does not + * configure CNTFRQ_EL0 + */ + clock-frequency = <26000000>; +}; + +&usbdrd { + vdd10-supply = <®_dummy>; + vdd33-supply = <®_dummy>; + + status = "okay"; +}; + +&usbdrd_dwc3 { + dr_mode = "otg"; + maximum-speed = "high-speed"; +}; + +&usbdrd_phy { + status = "okay"; +}; + +&watchdog_cl0 { + status = "okay"; +}; + +&watchdog_cl1 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/exynos/exynos850.dtsi b/arch/arm64/boot/dts/exynos/exynos850.dtsi index 9116430..8a47718 100644 --- a/arch/arm64/boot/dts/exynos/exynos850.dtsi +++ b/arch/arm64/boot/dts/exynos/exynos850.dtsi
@@ -160,7 +160,7 @@ psci { method = "smc"; }; - timer { + timer: timer { compatible = "arm,armv8-timer"; /* Hypervisor Virtual Timer interrupt is not wired to GIC */ interrupts = @@ -176,6 +176,11 @@ soc: soc@0 { #size-cells = <1>; ranges = <0x0 0x0 0x0 0x20000000>; + apm_sram: sram@2039000 { + compatible = "samsung,exynos850-acpm-sram"; + reg = <0x2039000 0x30000>; + }; + chipid@10000000 { compatible = "samsung,exynos850-chipid"; reg = <0x10000000 0x100>; @@ -310,6 +315,19 @@ cmu_g3d: clock-controller@11400000 { clock-names = "oscclk", "dout_g3d_switch"; }; + gpu: gpu@11500000 { + compatible = "samsung,exynos850-mali", "arm,mali-bifrost"; + reg = <0x11500000 0x5000>; + interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "job", "mmu", "gpu"; + clocks = <&cmu_g3d CLK_GOUT_G3D_GPU_CLK>; + clock-names = "core"; + + status = "disabled"; + }; + cmu_apm: clock-controller@11800000 { compatible = "samsung,exynos850-cmu-apm"; reg = <0x11800000 0x8000>; @@ -319,6 +337,15 @@ cmu_apm: clock-controller@11800000 { clock-names = "oscclk", "dout_clkcmu_apm_bus"; }; + ap2apm_mailbox: mailbox@11900000 { + compatible = "samsung,exynos850-mbox"; + reg = <0x11900000 0x1000>; + clocks = <&cmu_apm CLK_GOUT_MAILBOX_APM_AP_PCLK>; + clock-names = "pclk"; + interrupts = <GIC_SPI 49 IRQ_TYPE_LEVEL_HIGH>; + #mbox-cells = <0>; + }; + cmu_cmgp: clock-controller@11c00000 { compatible = "samsung,exynos850-cmu-cmgp"; reg = <0x11c00000 0x8000>;
diff --git a/arch/arm64/boot/dts/exynos/exynos8855-smdk.dts b/arch/arm64/boot/dts/exynos/exynos8855-smdk.dts index e74ff8a..ec6db81 100644 --- a/arch/arm64/boot/dts/exynos/exynos8855-smdk.dts +++ b/arch/arm64/boot/dts/exynos/exynos8855-smdk.dts
@@ -14,7 +14,7 @@ / { model = "Samsung Exynos8855 SMDK board"; - compatible = "samsung,exynos8855-smdk","samsung,exynos8855"; + compatible = "samsung,exynos8855-smdk", "samsung,exynos8855"; chosen { };
diff --git a/arch/arm64/boot/dts/exynos/exynosautov920.dtsi b/arch/arm64/boot/dts/exynos/exynosautov920.dtsi index 399b56b..b5e1e44 100644 --- a/arch/arm64/boot/dts/exynos/exynosautov920.dtsi +++ b/arch/arm64/boot/dts/exynos/exynosautov920.dtsi
@@ -1429,7 +1429,7 @@ wakeup-interrupt-controller { pmu_system_controller: system-controller@11860000 { compatible = "samsung,exynosautov920-pmu", - "samsung,exynos7-pmu","syscon"; + "samsung,exynos7-pmu", "syscon"; reg = <0x11860000 0x10000>; };
diff --git a/arch/arm64/boot/dts/exynos/google/gs101-pixel-common.dtsi b/arch/arm64/boot/dts/exynos/google/gs101-pixel-common.dtsi index a12f2b8..05bd9f4 100644 --- a/arch/arm64/boot/dts/exynos/google/gs101-pixel-common.dtsi +++ b/arch/arm64/boot/dts/exynos/google/gs101-pixel-common.dtsi
@@ -42,25 +42,25 @@ gpio-keys { pinctrl-0 = <&key_voldown>, <&key_volup>, <&key_power>; pinctrl-names = "default"; + button-power { + label = "KEY_POWER"; + gpios = <&gpa10 1 GPIO_ACTIVE_LOW>; + wakeup-source; + linux,code = <KEY_POWER>; + }; + button-vol-down { label = "KEY_VOLUMEDOWN"; - linux,code = <KEY_VOLUMEDOWN>; gpios = <&gpa7 3 GPIO_ACTIVE_LOW>; wakeup-source; + linux,code = <KEY_VOLUMEDOWN>; }; button-vol-up { label = "KEY_VOLUMEUP"; - linux,code = <KEY_VOLUMEUP>; gpios = <&gpa8 1 GPIO_ACTIVE_LOW>; wakeup-source; - }; - - button-power { - label = "KEY_POWER"; - linux,code = <KEY_POWER>; - gpios = <&gpa10 1 GPIO_ACTIVE_LOW>; - wakeup-source; + linux,code = <KEY_VOLUMEUP>; }; }; @@ -109,8 +109,8 @@ &acpm_ipc { pmic-1 { compatible = "samsung,s2mpg10-pmic"; interrupts-extended = <&gpa0 6 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default"; pinctrl-0 = <&pmic_int>; + pinctrl-names = "default"; system-power-controller; wakeup-source; @@ -429,8 +429,8 @@ ldo27m { pmic-2 { compatible = "samsung,s2mpg11-pmic"; interrupts-extended = <&gpa0 7 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default"; pinctrl-0 = <&sub_pmic_int>; + pinctrl-names = "default"; wakeup-source; vinl1s-supply = <&s2mpg10_buck8m>; @@ -527,15 +527,6 @@ buck10s { regulator-always-on; }; - buckd { - regulator-name = "vcc_ufs"; - regulator-min-microvolt = <2400000>; - regulator-max-microvolt = <3300000>; - regulator-ramp-delay = <6250>; - regulator-always-on; - samsung,ext-control = <S2MPG11_EXTCTRL_UFS_EN>; - }; - s2mpg11_bucka: bucka { /* lots, IO */ regulator-name = "bucka"; @@ -551,6 +542,15 @@ s2mpg11_buckboost: buckboost { regulator-max-microvolt = <3600000>; }; + buckd { + regulator-name = "vcc_ufs"; + regulator-min-microvolt = <2400000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <6250>; + regulator-always-on; + samsung,ext-control = <S2MPG11_EXTCTRL_UFS_EN>; + }; + ldo1s { regulator-name = "vdd_g3d_m"; regulator-min-microvolt = <450000>; @@ -646,12 +646,13 @@ &hsi2c_12 { status = "okay"; /* TODO: add the devices once drivers exist */ - usb-typec@25 { + maxtcpci: usb-typec@25 { compatible = "maxim,max77759-tcpci", "maxim,max33359"; reg = <0x25>; interrupts-extended = <&gpa8 2 IRQ_TYPE_LEVEL_LOW>; pinctrl-0 = <&typec_int>; pinctrl-names = "default"; + vbus-supply = <&chgin_otg_reg>; connector { compatible = "usb-c-connector"; @@ -738,9 +739,10 @@ fuel-gauge@36 { interrupts-extended = <&gpa9 3 IRQ_TYPE_LEVEL_LOW>; shunt-resistor-micro-ohms = <5000>; + power-supplies = <&max77759_pmic>; }; - pmic@66 { + max77759_pmic: pmic@66 { compatible = "maxim,max77759"; reg = <0x66>; @@ -750,6 +752,11 @@ pmic@66 { interrupt-controller; #interrupt-cells = <2>; + power-supplies = <&maxtcpci>; + + chgin_otg_reg: chgin-otg-regulator { + regulator-name = "chgin-otg"; + }; gpio { compatible = "maxim,max77759-gpio";
diff --git a/arch/arm64/boot/dts/exynos/google/gs101.dtsi b/arch/arm64/boot/dts/exynos/google/gs101.dtsi index bfceea5..b218ff50 100644 --- a/arch/arm64/boot/dts/exynos/google/gs101.dtsi +++ b/arch/arm64/boot/dts/exynos/google/gs101.dtsi
@@ -30,6 +30,18 @@ aliases { pinctrl7 = &pinctrl_hsi2; }; + ext_24_5m: clock-1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-output-names = "oscclk"; + }; + + ext_200m: clock-2 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-output-names = "ext-200m"; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -174,37 +186,50 @@ idle-states { entry-method = "psci"; ananke_cpu_sleep: cpu-ananke-sleep { - idle-state-name = "c2"; compatible = "arm,idle-state"; - arm,psci-suspend-param = <0x0010000>; + idle-state-name = "c2"; local-timer-stop; entry-latency-us = <70>; exit-latency-us = <160>; min-residency-us = <2000>; + arm,psci-suspend-param = <0x0010000>; }; enyo_cpu_sleep: cpu-enyo-sleep { - idle-state-name = "c2"; compatible = "arm,idle-state"; - arm,psci-suspend-param = <0x0010000>; + idle-state-name = "c2"; local-timer-stop; entry-latency-us = <150>; exit-latency-us = <190>; min-residency-us = <2500>; + arm,psci-suspend-param = <0x0010000>; }; hera_cpu_sleep: cpu-hera-sleep { - idle-state-name = "c2"; compatible = "arm,idle-state"; - arm,psci-suspend-param = <0x0010000>; + idle-state-name = "c2"; local-timer-stop; entry-latency-us = <235>; exit-latency-us = <220>; min-residency-us = <3500>; + arm,psci-suspend-param = <0x0010000>; }; }; }; + /* ect node is required to be present by bootloader */ + ect { + }; + + firmware { + acpm_ipc: power-management { + compatible = "google,gs101-acpm-ipc"; + #clock-cells = <1>; + mboxes = <&ap2apm_mailbox>; + shmem = <&apm_sram>; + }; + }; + cpucl0_opp_table: opp-table-0 { compatible = "operating-points-v2"; opp-shared; @@ -472,31 +497,6 @@ opp-2802000000 { }; }; - /* ect node is required to be present by bootloader */ - ect { - }; - - ext_24_5m: clock-1 { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-output-names = "oscclk"; - }; - - ext_200m: clock-2 { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-output-names = "ext-200m"; - }; - - firmware { - acpm_ipc: power-management { - compatible = "google,gs101-acpm-ipc"; - #clock-cells = <1>; - mboxes = <&ap2apm_mailbox>; - shmem = <&apm_sram>; - }; - }; - pmu-0 { compatible = "arm,cortex-a55-pmu"; interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH &ppi_cluster0>; @@ -525,9 +525,9 @@ psci { }; reserved_memory: reserved-memory { + ranges; #address-cells = <2>; #size-cells = <1>; - ranges; gsa_reserved_protected: gsa@90200000 { reg = <0x0 0x90200000 0x400000>; @@ -572,9 +572,9 @@ bldr_log_hist_reserved: bldr-log-hist-reserved@fd900000 { soc: soc@0 { compatible = "simple-bus"; + ranges = <0x0 0x0 0x0 0x40000000>; #address-cells = <1>; #size-cells = <1>; - ranges = <0x0 0x0 0x0 0x40000000>; efuse@10000000 { compatible = "google,gs101-otp"; @@ -657,11 +657,11 @@ trng: rng@10141400 { gic: interrupt-controller@10400000 { compatible = "arm,gic-v3"; + reg = <0x10400000 0x10000>, /* GICD */ + <0x10440000 0x100000>;/* GICR * 8 */ #address-cells = <0>; #interrupt-cells = <4>; interrupt-controller; - reg = <0x10400000 0x10000>, /* GICD */ - <0x10440000 0x100000>;/* GICR * 8 */ interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>; ppi-partitions { @@ -1778,10 +1778,10 @@ ufs_0_phy: phy@14704000 { compatible = "google,gs101-ufs-phy"; reg = <0x14704000 0x3000>; reg-names = "phy-pma"; - samsung,pmu-syscon = <&pmu_system_controller>; #phy-cells = <0>; clocks = <&ext_24_5m>; clock-names = "ref_clk"; + samsung,pmu-syscon = <&pmu_system_controller>; status = "disabled"; }; @@ -1806,17 +1806,6 @@ pmu_system_controller: system-controller@17460000 { reg = <0x17460000 0x10000>; google,pmu-intr-gen-syscon = <&pmu_intr_gen>; - poweroff: syscon-poweroff { - compatible = "syscon-poweroff"; - offset = <0x3e9c>; /* PAD_CTRL_PWR_HOLD */ - mask = <0x00000100>; - value = <0x0>; - }; - - reboot: syscon-reboot { - compatible = "google,gs101-reboot"; - }; - reboot-mode { compatible = "syscon-reboot-mode"; offset = <0x0810>; /* EXYNOS_PMU_SYSIP_DAT0 */ @@ -1830,6 +1819,17 @@ reboot-mode { mode-shutdown-thermal = <0x51>; mode-shutdown-thermal-battery = <0x51>; }; + + poweroff: syscon-poweroff { + compatible = "syscon-poweroff"; + offset = <0x3e9c>; /* PAD_CTRL_PWR_HOLD */ + mask = <0x00000100>; + value = <0x0>; + }; + + reboot: syscon-reboot { + compatible = "google,gs101-reboot"; + }; }; pmu_intr_gen: syscon@17470000 { @@ -1920,9 +1920,9 @@ cmu_top: clock-controller@1e080000 { apm_sram: sram@2039000 { compatible = "mmio-sram"; reg = <0x0 0x2039000 0x40000>; + ranges = <0x0 0x0 0x2039000 0x40000>; #address-cells = <1>; #size-cells = <1>; - ranges = <0x0 0x0 0x2039000 0x40000>; }; timer {
diff --git a/arch/arm64/boot/dts/freescale/Makefile b/arch/arm64/boot/dts/freescale/Makefile index 95ae85a..a80cccf 100644 --- a/arch/arm64/boot/dts/freescale/Makefile +++ b/arch/arm64/boot/dts/freescale/Makefile
@@ -55,6 +55,8 @@ dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-half-twins.dtb DTC_FLAGS_fsl-lx2160a-honeycomb := -Wno-interrupt_map dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-honeycomb.dtb +DTC_FLAGS_fsl-lx2160a-nbxv3 := -Wno-interrupt_map +dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-nbxv3.dtb DTC_FLAGS_fsl-lx2160a-qds := -Wno-interrupt_map dtb-$(CONFIG_ARCH_LAYERSCAPE) += fsl-lx2160a-qds.dtb DTC_FLAGS_fsl-lx2160a-rdb := -Wno-interrupt_map @@ -119,7 +121,81 @@ dtb-$(CONFIG_ARCH_MXC) += imx8dxp-tqma8xdp-mba8xx.dtb dtb-$(CONFIG_ARCH_MXC) += imx8dxp-tqma8xdps-mb-smarc-2.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-beacon-kit.dtb -dtb-$(CONFIG_ARCH_MXC) += imx8mm-data-modul-edm-sbc.dtb + +imx8mm-data-modul-edm-sbc-overlay-cm4-dtbs := \ + imx8mm-data-modul-edm-sbc.dtb \ + imx8mm-data-modul-edm-sbc-overlay-cm4.dtbo + +imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-dtbs := \ + imx8mm-data-modul-edm-sbc.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtbo + +imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio-dtbs := \ + imx8mm-data-modul-edm-sbc.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtbo + +imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi-dtbs := \ + imx8mm-data-modul-edm-sbc.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtbo + +imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01-dtbs := \ + imx8mm-data-modul-edm-sbc.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtbo + +imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01-dtbs := \ + imx8mm-data-modul-edm-sbc.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtbo + +imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01-dtbs := \ + imx8mm-data-modul-edm-sbc.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtbo + +imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01-dtbs := \ + imx8mm-data-modul-edm-sbc.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtbo + +imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011-dtbs := \ + imx8mm-data-modul-edm-sbc.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtbo + +imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30-dtbs := \ + imx8mm-data-modul-edm-sbc.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtbo + +imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11-dtbs := \ + imx8mm-data-modul-edm-sbc.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtbo + +imx8mm-data-modul-edm-sbc-overlay-edm-sbc-imx8mm-rev900-dtbs := \ + imx8mm-data-modul-edm-sbc.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-sbc-imx8mm-rev900.dtbo + +dtb-$(CONFIG_ARCH_MXC) += imx8mm-data-modul-edm-sbc.dtb \ + imx8mm-data-modul-edm-sbc-overlay-cm4.dtb \ + imx8mm-data-modul-edm-sbc-overlay-cm4.dtbo \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtbo \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtbo \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtbo \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtbo \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtbo \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtbo \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtbo \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtbo \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtbo \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtbo \ + imx8mm-data-modul-edm-sbc-overlay-edm-sbc-imx8mm-rev900.dtb \ + imx8mm-data-modul-edm-sbc-overlay-edm-sbc-imx8mm-rev900.dtbo + dtb-$(CONFIG_ARCH_MXC) += imx8mm-ddr4-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-emcon-avari.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mm-emtop-baseboard.dtb @@ -245,15 +321,25 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mn-var-som-symphony-legacy.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mn-venice-gw7902.dtb +imx8mn-vhip4-evalboard-v1-overlay-eeprom-1000-dtbs := imx8mn-vhip4-evalboard-v1.dtb \ + imx8mn-vhip4-overlay-eeprom-1000.dtbo +imx8mn-vhip4-evalboard-v1-overlay-eeprom-1100-dtbs := imx8mn-vhip4-evalboard-v1.dtb \ + imx8mn-vhip4-overlay-eeprom-1100.dtbo imx8mn-vhip4-evalboard-v1-overlay-ksz8794-dtbs := imx8mn-vhip4-evalboard-v1.dtb \ imx8mn-vhip4-evalboard-v1-overlay-ksz8794.dtbo imx8mn-vhip4-evalboard-v1-overlay-ksz9031-dtbs := imx8mn-vhip4-evalboard-v1.dtb \ imx8mn-vhip4-evalboard-v1-overlay-ksz9031.dtbo imx8mn-vhip4-evalboard-v2-overlay-adin1300-dtbs := imx8mn-vhip4-evalboard-v2.dtb \ imx8mn-vhip4-evalboard-v2-overlay-adin1300.dtbo +imx8mn-vhip4-evalboard-v2-overlay-eeprom-1100-dtbs := imx8mn-vhip4-evalboard-v2.dtb \ + imx8mn-vhip4-overlay-eeprom-1100.dtbo +imx8mn-vhip4-evalboard-v2-overlay-eeprom-2000-dtbs := imx8mn-vhip4-evalboard-v2.dtb \ + imx8mn-vhip4-overlay-eeprom-2000.dtbo imx8mn-vhip4-evalboard-v2-overlay-ksz8794-dtbs := imx8mn-vhip4-evalboard-v2.dtb \ imx8mn-vhip4-evalboard-v2-overlay-ksz8794.dtbo dtb-$(CONFIG_ARCH_MXC) += imx8mn-vhip4-evalboard-v1.dtb \ + imx8mn-vhip4-evalboard-v1-overlay-eeprom-1000.dtb \ + imx8mn-vhip4-evalboard-v1-overlay-eeprom-1100.dtb \ imx8mn-vhip4-evalboard-v1-overlay-ksz8794.dtb \ imx8mn-vhip4-evalboard-v1-overlay-ksz8794.dtbo \ imx8mn-vhip4-evalboard-v1-overlay-ksz9031.dtb \ @@ -261,8 +347,13 @@ imx8mn-vhip4-evalboard-v2.dtb \ imx8mn-vhip4-evalboard-v2-overlay-adin1300.dtb \ imx8mn-vhip4-evalboard-v2-overlay-adin1300.dtbo \ + imx8mn-vhip4-evalboard-v2-overlay-eeprom-1100.dtb \ + imx8mn-vhip4-evalboard-v2-overlay-eeprom-2000.dtb \ imx8mn-vhip4-evalboard-v2-overlay-ksz8794.dtb \ - imx8mn-vhip4-evalboard-v2-overlay-ksz8794.dtbo + imx8mn-vhip4-evalboard-v2-overlay-ksz8794.dtbo \ + imx8mn-vhip4-overlay-eeprom-1000.dtbo \ + imx8mn-vhip4-overlay-eeprom-1100.dtbo \ + imx8mn-vhip4-overlay-eeprom-2000.dtbo imx8mn-tqma8mqnl-mba8mx-lvds-g133han01-dtbs += imx8mn-tqma8mqnl-mba8mx.dtb imx8mm-tqma8mqml-mba8mx-lvds-g133han01.dtbo imx8mn-tqma8mqnl-mba8mx-lvds-tm070jvhg33-dtbs += imx8mn-tqma8mqnl-mba8mx.dtb imx8mn-tqma8mqnl-mba8mx-lvds-tm070jvhg33.dtbo @@ -280,7 +371,145 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mp-beacon-kit.dtb DTC_FLAGS_imx8mp-cubox-m := -@ dtb-$(CONFIG_ARCH_MXC) += imx8mp-cubox-m.dtb -dtb-$(CONFIG_ARCH_MXC) += imx8mp-data-modul-edm-sbc.dtb + +imx8mp-data-modul-edm-sbc-overlay-cm7-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-cm7.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g070y2-l01-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g070y2-l01.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g101ice-l01-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g101ice-l01.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g121xce-l01-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g121xce-l01.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g156hce-l01-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g156hce-l01.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g215hvn011-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g215hvn011.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-mi0700a2t-30-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-mi0700a2t-30.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-mi1010z1t-1cp11-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-mi1010z1t-1cp11.dtbo + +DTC_FLAGS_imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01 := -@ + +imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-rev900-dtbs := \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-rev900.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-rev900.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-rev902-dtbs := \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-rev902.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-rev902.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-rev900-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-rev900.dtbo + +imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-rev902-dtbs := \ + imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-rev902.dtbo + +dtb-$(CONFIG_ARCH_MXC) += imx8mp-data-modul-edm-sbc.dtb \ + imx8mp-data-modul-edm-sbc-overlay-cm7.dtb \ + imx8mp-data-modul-edm-sbc-overlay-cm7.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g070y2-l01.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g070y2-l01.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g101ice-l01.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g101ice-l01.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g121xce-l01.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g121xce-l01.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g156hce-l01.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g156hce-l01.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g215hvn011.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g215hvn011.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-mi0700a2t-30.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-mi0700a2t-30.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-mi1010z1t-1cp11.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-mi1010z1t-1cp11.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-rev900.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-rev900.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-rev902.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-rev902.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-rev900.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-rev900.dtbo \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-rev902.dtb \ + imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-rev902.dtbo + dtb-$(CONFIG_ARCH_MXC) += imx8mp-debix-model-a.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-debix-som-a-bmb-08.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-dhcom-drc02.dtb @@ -456,6 +685,8 @@ imx8mp-phyboard-pollux-peb-av-10-etml1010g3dra.dtbo imx8mp-phyboard-pollux-peb-av-10-ph128800t006-dtbs += imx8mp-phyboard-pollux-rdk.dtb \ imx8mp-phyboard-pollux-peb-av-10-ph128800t006.dtbo +imx8mp-phyboard-pollux-peb-wlbt-07-dtbs += imx8mp-phyboard-pollux-rdk.dtb \ + imx8mp-phyboard-pollux-peb-wlbt-07.dtbo imx8mp-phyboard-pollux-ph128800t006-dtbs += imx8mp-phyboard-pollux-rdk.dtb \ imx8mp-phyboard-pollux-ph128800t006.dtbo imx8mp-phyboard-pollux-rdk-no-eth-dtbs += imx8mp-phyboard-pollux-rdk.dtb imx8mp-phycore-no-eth.dtbo @@ -465,6 +696,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-peb-av-10.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-peb-av-10-etml1010g3dra.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-peb-av-10-ph128800t006.dtb +dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-peb-wlbt-07.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-ph128800t006.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-rdk-no-eth.dtb dtb-$(CONFIG_ARCH_MXC) += imx8mp-phyboard-pollux-wlbt.dtb @@ -610,9 +842,17 @@ dtb-$(CONFIG_ARCH_MXC) += imx8ulp-9x9-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx8ulp-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx91-9x9-qsb.dtb + +imx91-9x9-qsb-tianma-tm050rdh03-dtbs += imx91-9x9-qsb.dtb imx91-9x9-qsb-tianma-tm050rdh03.dtbo +dtb-$(CONFIG_ARCH_MXC) += imx91-9x9-qsb-tianma-tm050rdh03.dtb + dtb-$(CONFIG_ARCH_MXC) += imx91-11x11-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx91-11x11-frdm.dtb dtb-$(CONFIG_ARCH_MXC) += imx91-11x11-frdm-s.dtb +imx91-11x11-evk-mqs-dtbs += imx91-11x11-evk.dtb imx9-mqs.dtbo +dtb-$(CONFIG_ARCH_MXC) += imx91-11x11-evk-mqs.dtb +dtb-$(CONFIG_ARCH_MXC) += imx91-lino-verdin-dahlia.dtb +dtb-$(CONFIG_ARCH_MXC) += imx91-lino-verdin-dev.dtb dtb-$(CONFIG_ARCH_MXC) += imx91-phyboard-segin.dtb imx91-9x9-qsb-can1-dtbs += imx91-9x9-qsb.dtb imx91-9x9-qsb-can1.dtbo @@ -620,6 +860,8 @@ dtb-$(CONFIG_ARCH_MXC) += imx91-9x9-qsb-can1.dtb dtb-$(CONFIG_ARCH_MXC) += imx91-phyboard-segin-peb-av-18.dtb +dtb-$(CONFIG_ARCH_MXC) += imx91-toradex-osm-dev.dtb + dtb-$(CONFIG_ARCH_MXC) += imx91-tqma9131-mba91xxca.dtb dtb-$(CONFIG_ARCH_MXC) += imx91-tqma9131-mba93xxca.dtb @@ -645,6 +887,8 @@ imx93-11x11-evk-dy1212w-4856-dtbs += imx93-11x11-evk.dtb imx93-11x11-evk-dy1212w-4856.dtbo dtb-$(CONFIG_ARCH_MXC) += imx93-11x11-evk-dy1212w-4856.dtb +imx93-11x11-evk-mqs-dtbs += imx93-11x11-evk.dtb imx9-mqs.dtbo +dtb-$(CONFIG_ARCH_MXC) += imx93-11x11-evk-mqs.dtb dtb-$(CONFIG_ARCH_MXC) += imx93-11x11-frdm.dtb @@ -652,7 +896,11 @@ dtb-$(CONFIG_ARCH_MXC) += imx93-11x11-frdm-pixpaper.dtb dtb-$(CONFIG_ARCH_MXC) += imx93-14x14-evk.dtb +imx93-14x14-evk-mqs-dtbs += imx93-14x14-evk.dtb imx9-mqs.dtbo +dtb-$(CONFIG_ARCH_MXC) += imx93-14x14-evk-mqs.dtb dtb-$(CONFIG_ARCH_MXC) += imx93-kontron-bl-osm-s.dtb +dtb-$(CONFIG_ARCH_MXC) += imx93-lino-verdin-dahlia.dtb +dtb-$(CONFIG_ARCH_MXC) += imx93-lino-verdin-dev.dtb dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-nash.dtb dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-segin.dtb @@ -673,6 +921,8 @@ dtb-$(CONFIG_ARCH_MXC) += imx93-phyboard-segin-peb-wlbt-05.dtb dtb-$(CONFIG_ARCH_MXC) += imx93-phycore-rpmsg.dtb +dtb-$(CONFIG_ARCH_MXC) += imx93-toradex-osm-dev.dtb + dtb-$(CONFIG_ARCH_MXC) += imx93-tqma9352-mba91xxca.dtb dtb-$(CONFIG_ARCH_MXC) += imx93-tqma9352-mba93xxca.dtb dtb-$(CONFIG_ARCH_MXC) += imx93-tqma9352-mba93xxla.dtb @@ -695,6 +945,7 @@ dtb-$(CONFIG_ARCH_MXC) += imx93-var-dart-sonata.dtb dtb-$(CONFIG_ARCH_MXC) += imx93-var-som-symphony.dtb dtb-$(CONFIG_ARCH_MXC) += imx93w-evk.dtb +dtb-$(CONFIG_ARCH_MXC) += imx93w-frdm.dtb dtb-$(CONFIG_ARCH_MXC) += imx943-evk.dtb imx943-evk-pcie0-ep-dtbs += imx943-evk.dtb imx-pcie0-ep.dtbo @@ -703,6 +954,8 @@ imx943-evk-sdwifi-dtbs := imx943-evk.dtb imx943-evk-sdwifi.dtbo dtb-$(CONFIG_ARCH_MXC) += imx943-evk-sdwifi.dtb +imx943-evk-mqs-dtbs += imx943-evk.dtb imx9-mqs.dtbo +dtb-$(CONFIG_ARCH_MXC) += imx943-evk-mqs.dtb dtb-$(CONFIG_ARCH_MXC) += imx95-15x15-ab2.dtb dtb-$(CONFIG_ARCH_MXC) += imx95-15x15-evk.dtb @@ -712,6 +965,8 @@ dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-frdm-pro.dtb dtb-$(CONFIG_ARCH_MXC) += imx95-aquila-clover.dtb dtb-$(CONFIG_ARCH_MXC) += imx95-aquila-dev.dtb +dtb-$(CONFIG_ARCH_MXC) += imx95-navq.dtb +dtb-$(CONFIG_ARCH_MXC) += imx95-toradex-osm-dev.dtb dtb-$(CONFIG_ARCH_MXC) += imx95-toradex-smarc-dev.dtb dtb-$(CONFIG_ARCH_MXC) += imx95-tqma9596la-mba95xxca.dtb dtb-$(CONFIG_ARCH_MXC) += imx95-tqma9596sa-mb-smarc-2.dtb @@ -734,6 +989,8 @@ imx95-15x15-evk-pcie0-ep-dtbs = imx95-15x15-evk-pcie.dtb imx-pcie0-ep.dtbo dtb-$(CONFIG_ARCH_MXC) += imx95-15x15-evk-pcie0-ep.dtb +imx95-15x15-evk-mqs-dtbs += imx95-15x15-evk.dtb imx9-mqs.dtbo +dtb-$(CONFIG_ARCH_MXC) += imx95-15x15-evk-mqs.dtb imx95-19x19-evk-pcie0-ep-dtbs += imx95-19x19-evk.dtb imx-pcie0-ep.dtbo imx95-19x19-evk-pcie1-ep-dtbs += imx95-19x19-evk.dtb imx-pcie1-ep.dtbo dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-evk-pcie0-ep.dtb imx95-19x19-evk-pcie1-ep.dtb @@ -742,6 +999,10 @@ dtb-$(CONFIG_ARCH_MXC) += imx95-19x19-verdin-evk.dtb dtb-$(CONFIG_ARCH_MXC) += imx952-evk.dtb +imx952-evk-mqs-dtbs += imx952-evk.dtb imx9-mqs.dtbo +dtb-$(CONFIG_ARCH_MXC) += imx952-evk-mqs.dtb + +dtb-$(CONFIG_ARCH_MXC) += imx952-frdm.dtb imx8mm-kontron-dl-dtbs := imx8mm-kontron-bl.dtb imx8mm-kontron-dl.dtbo imx8mm-kontron-bl-lte-dtbs := imx8mm-kontron-bl.dtb imx8mm-kontron-bl-lte.dtbo
diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi index ef62968..ed81093 100644 --- a/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a.dtsi
@@ -105,7 +105,7 @@ osc_27m: clock-osc-27m { }; firmware { - optee: optee { + optee: optee { compatible = "linaro,optee-tz"; method = "smc"; status = "disabled";
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-nbxv3.dts b/arch/arm64/boot/dts/freescale/fsl-lx2160a-nbxv3.dts new file mode 100644 index 0000000..cc02204 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-nbxv3.dts
@@ -0,0 +1,34 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Free Mobile Nodebox v3 CPU Module (LX2160A) + * + * Copyright 2026 Free Mobile, Vincent Jardin + */ + +/dts-v1/; + +#include "fsl-lx2160a-rev2.dtsi" +#include "fsl-lx2160a-nbxv3.dtsi" + +/ { + compatible = "freemobile,nbxv3", "fsl,lx2160a"; + model = "Free Mobile Nodebox v3 CPU Module (LX2160A)"; +}; + +&fspi { + pinctrl-0 = <&fspi_dqs_sck_cs10_pins>, <&fspi_data30_pins>; + pinctrl-names = "default"; +}; + +&gpio1 { + pinctrl-0 = <&gpio1_31_28_pins>; + pinctrl-names = "default"; +}; + +&pcs_mdio13 { + status = "okay"; +}; + +&pcs_mdio14 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx2160a-nbxv3.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx2160a-nbxv3.dtsi new file mode 100644 index 0000000..9c5588a --- /dev/null +++ b/arch/arm64/boot/dts/freescale/fsl-lx2160a-nbxv3.dtsi
@@ -0,0 +1,330 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Free Mobile Nodebox v3 CPU Module (LX2160A) + * + * Copyright 2026 Free Mobile, Vincent Jardin + * + * This file is shared by the Linux kernel and U-Boot. + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-restart { + compatible = "gpio-restart"; + gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; + priority = <128>; + }; + + reg_ethsw_mdio: regulator-ethsw-mdio { + compatible = "regulator-fixed"; + gpio = <&gpio3 25 GPIO_ACTIVE_LOW>; + regulator-always-on; + regulator-boot-on; + regulator-name = "ethsw-mdio-en"; + }; +}; + +&crypto { + status = "okay"; +}; + +&dpmac13 { + phy-connection-type = "10gbase-r"; + phy-handle = <&lan8023_phy_s0>; + + status = "okay"; +}; + +&dpmac14 { + phy-connection-type = "10gbase-r"; + phy-handle = <&lan8023_phy_s1>; + + status = "okay"; +}; + +&dpmac17 { + phy-connection-type = "rgmii-id"; + phy-handle = <&rtl8211fd>; + + status = "okay"; +}; + +&dspi0 { + status = "okay"; + + dpll@0 { + compatible = "microchip,zl30733"; + reg = <0>; + spi-max-frequency = <12500000>; + }; +}; + +&dspi2 { + status = "okay"; +}; + +&emdio1 { + status = "okay"; + + /* Microchip LAN8023 dual 10G PCS/retimer, Clause 45 only, one address per slice */ + lan8023_phy_s0: ethernet-phy@2 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <2>; + }; + + lan8023_phy_s1: ethernet-phy@3 { + compatible = "ethernet-phy-ieee802.3-c45"; + reg = <3>; + }; + + rtl8211fd: ethernet-phy@6 { + compatible = "ethernet-phy-id001c.c916"; + reg = <6>; + }; +}; + +&emdio2 { + status = "okay"; +}; + +&esdhc1 { + bus-width = <8>; + mmc-hs200-1_8v; + mmc-hs400-1_8v; + non-removable; + + status = "okay"; +}; + +&fsl_mc { + status = "okay"; +}; + +&fspi { + status = "okay"; + + /* GigaDevice GD55LB02GF, 256 MiB boot NOR */ + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + #address-cells = <1>; + #size-cells = <1>; + reset-gpios = <&gpio1 28 GPIO_ACTIVE_LOW>; + spi-max-frequency = <150000000>; + spi-rx-bus-width = <1>; + spi-tx-bus-width = <1>; + }; +}; + +&gpio0 { + gpio-line-names = + "", "", + "altfn:iic1-sda", "altfn:iic1-scl", + "altfn:uart4-sin", "altfn:uart4-sout", + "altfn:uart2-sin", "altfn:uart2-sout", + "altfn:uart3-sin", "altfn:uart3-sout", + "altfn:uart1-sin", "altfn:uart1-sout", + "altfn:spi3-pcs3", "altfn:spi3-pcs2", + "altfn:spi3-pcs1", "altfn:spi3-pcs0", + "altfn:spi1-sck", "altfn:spi1-sin", + "altfn:spi1-pcs2", "altfn:spi1-pcs1", + "altfn:spi1-pcs0", "altfn:spi1-sout", + "altfn:iic6-sda", "altfn:iic6-scl", + "altfn:spi3-sin", "altfn:spi3-sout", + "altfn:iic4-sda", "altfn:iic4-scl", + "altfn:iic3-sda", "altfn:iic3-scl", + "altfn:iic2-sda", "altfn:iic2-scl"; + + status = "okay"; +}; + +&gpio1 { + gpio-line-names = + "", "", "", "", "", "", + "cfg-rcw-src2", "cfg-rcw-src3", + "reset-req-b", + "altfn:sdhc2-clk", "altfn:sdhc2-ds", + "altfn:sdhc2-dat0", "altfn:sdhc2-dat1", + "altfn:sdhc2-dat2", "altfn:sdhc2-dat3", + "altfn:sdhc2-dat4", "altfn:sdhc2-dat5", + "altfn:sdhc2-dat6", "altfn:sdhc2-dat7", + "altfn:sdhc2-cmd", + "cfg-svr1", + "altfn:xspi1-cs0", "altfn:xspi1-sck", + "altfn:xspi1-dqs", + "altfn:xspi1-data0", "altfn:xspi1-data1", + "", "", + "flash-reset#", "pltrst#", "", "ethsw-reset#"; + + status = "okay"; + + /* Platform reset, no consumer node: released at boot */ + pltrst-hog { + gpio-hog; + gpios = <29 GPIO_ACTIVE_LOW>; + line-name = "pltrst#"; + output-low; + }; +}; + +&gpio2 { + gpio-line-names = + "lan8023-mdint", + "i2c2-alert#", "i2c4-alert#", "i2c6-alert#", + "u800-tca9539-int#", + "spi3-alert#", + "wake0", "wake1", + "carrier-hot#", + "u1300-rtl8211fd-int#", + "ethsw-int#", + "", "", + "u1700-zl30733-clk-gpio0", "u1700-zl30733-clk-gpio1", + "u1700-zl30733-clk-gpio2", "u1700-zl30733-clk-gpio3", + "", "", "", "", "", "", "", "", + "", "", "", "", "", "", ""; + + status = "okay"; +}; + +&gpio3 { + gpio-line-names = + "altfn:ec1-txd3", "altfn:ec1-txd2", + "altfn:ec1-txd1", "altfn:ec1-txd0", + "altfn:ec1-tx-en", "altfn:ec1-gtx-clk", + "altfn:ec1-rxd3", "altfn:ec1-rxd2", + "altfn:ec1-rxd1", "altfn:ec1-rxd0", + "altfn:ec1-rx-clk", "altfn:ec1-rx-dv", + "", "", + "ptp-refclk-in", + "", "", "", "", "", "", "", "", + "u1700-zl30733-pps-out", + "", + "ethsw-mdio-en", + "usb1-oc#", /* USB1_PWRFAULT and USB2_PWRFAULT pads: one wired-OR net */ + "", + "usb2-oc#", + "altfn:spi3-sck", + "", ""; + + status = "okay"; +}; + +/* On-module management bus */ +&i2c0 { + status = "okay"; + + /* +0V8_VDD core rail, MPS MPQ8646 (MPQ8785 core) over PMBus */ + vdd08: regulator@10 { + compatible = "mps,mpq8646"; + reg = <0x10>; + }; + + /* SO-DIMM SPD temperature sensors */ + temperature-sensor@18 { + compatible = "jedec,jc-42.4-temp"; + reg = <0x18>; + }; + + temperature-sensor@19 { + compatible = "jedec,jc-42.4-temp"; + reg = <0x19>; + }; + + eeprom@52 { + compatible = "atmel,24c32"; + reg = <0x52>; + pagesize = <32>; + }; + + /* Board ID straps */ + gpio@74 { + compatible = "ti,tca9539"; + reg = <0x74>; + #gpio-cells = <2>; + gpio-controller; + gpio-line-names = + "boardid-0x0001", "boardid-0x0002", + "boardid-0x0004", "boardid-0x0008", + "boardid-0x0010", "boardid-0x0020", + "boardid-0x0040", "boardid-0x0080", + "boardid-0x0100", "boardid-0x0200", + "boardid-0x0400", "boardid-0x0800", + "boardid-0x1000", "boardid-0x2000", + "boardid-0x4000", "boardid-0x8000"; + }; + + u800: gpio@75 { + compatible = "ti,tca9539"; + reg = <0x75>; + #gpio-cells = <2>; + #interrupt-cells = <2>; + gpio-controller; + gpio-line-names = + "carrier-gpio0", "carrier-gpio1", + "carrier-gpio2", "carrier-gpio3", + "carrier-gpio4", "carrier-gpio5", + "carrier-gpio6", "carrier-gpio7", + "carrier-gpio8", "carrier-gpio9", + "carrier-gpio10", "carrier-gpio11", + "", "", "", + "lan8023-rst"; + interrupt-controller; + interrupt-parent = <&gpio2>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; + }; +}; + +&i2c1 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c3 { + status = "okay"; +}; + +&i2c5 { + status = "okay"; +}; + +&pcie3 { + status = "okay"; +}; + +&pcie4 { + status = "okay"; +}; + +&pcie5 { + status = "okay"; +}; + +&pcie6 { + status = "okay"; +}; + +&uart0 { + status = "okay"; +}; + +&usb0 { + status = "okay"; +}; + +&usb1 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/fsl-lx216x.dtsi b/arch/arm64/boot/dts/freescale/fsl-lx216x.dtsi index bccf2d6..2085362 100644 --- a/arch/arm64/boot/dts/freescale/fsl-lx216x.dtsi +++ b/arch/arm64/boot/dts/freescale/fsl-lx216x.dtsi
@@ -1536,6 +1536,7 @@ pinmux_i2crv: pinmux@70010012c { reg = <0x00000007 0x0010012c 0x0 0xc>; #address-cells = <1>; #size-cells = <0>; + #pinctrl-cells = <2>; pinctrl-single,bit-per-mux; pinctrl-single,register-width = <32>; pinctrl-single,function-mask = <0x7>;
diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi index 6f5af37..1d4e92f 100644 --- a/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8-apalis-eval.dtsi
@@ -133,7 +133,11 @@ &spdif0 { status = "okay"; }; -/* TODO: Apalis USBH2, Apalis USBH3 and on-module Wi-Fi via on-module HSIC Hub */ +/* Apalis USBH2, Apalis USBH3 and on-module Wi-Fi via on-module HSIC Hub */ +&usbh1 { + vbus-supply = <®_usb_host_vbus>; + status = "okay"; +}; /* Apalis USBO1 */ &usbotg1 {
diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi index 93f4851..68fb2eb8 100644 --- a/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.1.dtsi
@@ -222,7 +222,11 @@ &spdif0 { status = "okay"; }; -/* TODO: Apalis USBH2, Apalis USBH3 and on-module Wi-Fi via on-module HSIC Hub */ +/* Apalis USBH2, Apalis USBH3 and on-module Wi-Fi via on-module HSIC Hub */ +&usbh1 { + vbus-supply = <®_usb_host_vbus>; + status = "okay"; +}; /* Apalis USBO1 */ &usbotg1 {
diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi index 5c86bce..baf0962 100644 --- a/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8-apalis-ixora-v1.2.dtsi
@@ -271,7 +271,11 @@ &spdif0 { status = "okay"; }; -/* TODO: Apalis USBH2, Apalis USBH3 and on-module Wi-Fi via on-module HSIC Hub */ +/* Apalis USBH2, Apalis USBH3 and on-module Wi-Fi via on-module HSIC Hub */ +&usbh1 { + vbus-supply = <®_usb_host_vbus>; + status = "okay"; +}; /* Apalis USBO1 */ &usbotg1 {
diff --git a/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi b/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi index 681f248..64604f9 100644 --- a/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8-apalis-v1.1.dtsi
@@ -870,7 +870,21 @@ &spdif0 { status = "okay"; }; -/* TODO: Apalis USBH2, Apalis USBH3 and on-module Wi-Fi via on-module HSIC Hub */ +/* Apalis USBH2, Apalis USBH3 and on-module Wi-Fi via on-module HSIC Hub */ +&usbh1 { + pinctrl-names = "idle", "active"; + pinctrl-0 = <&pinctrl_usb_hsic_idle>; + pinctrl-1 = <&pinctrl_usb_hsic_active>; + adp-disable; + disable-over-current; + hnp-disable; + srp-disable; + status = "disabled"; +}; + +&usbphynop2 { + status = "okay"; +}; /* Apalis USBH4 */ &usb3_phy {
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts index 0ede0c7..71eff3e 100644 --- a/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8dxl-evk.dts
@@ -29,7 +29,7 @@ imx8dxl-cm4 { clocks = <&clk_dummy>; mbox-names = "tx", "rx", "rxdb"; mboxes = <&lsio_mu5 0 1 &lsio_mu5 1 1 &lsio_mu5 3 1>; - memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, + memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>; power-domains = <&pd IMX_SC_R_M4_0_PID0>, <&pd IMX_SC_R_M4_0_MU_1A>; fsl,resource-id = <IMX_SC_R_M4_0_PID0>; @@ -65,32 +65,32 @@ linux,cma { linux,cma-default; }; - vdev0vring0: memory0@90000000 { + vdev0vring0: vdev0vring0@90000000 { reg = <0 0x90000000 0 0x8000>; no-map; }; - vdev0vring1: memory@90008000 { + vdev0vring1: vdev0vring1@90008000 { reg = <0 0x90008000 0 0x8000>; no-map; }; - vdev1vring0: memory@90010000 { + vdev1vring0: vdev1vring0@90010000 { reg = <0 0x90010000 0 0x8000>; no-map; }; - vdev1vring1: memory@90018000 { + vdev1vring1: vdev1vring1@90018000 { reg = <0 0x90018000 0 0x8000>; no-map; }; - rsc_table: memory-rsc-table@900ff000 { + rsc_table: rsc-table@900ff000 { reg = <0 0x900ff000 0 0x1000>; no-map; }; - vdevbuffer: memory-vdevbuffer@90400000 { + vdev0buffer: vdev0buffer@90400000 { compatible = "shared-dma-pool"; reg = <0 0x90400000 0 0x100000>; no-map;
diff --git a/arch/arm64/boot/dts/freescale/imx8dxl-sr-som.dtsi b/arch/arm64/boot/dts/freescale/imx8dxl-sr-som.dtsi index 93a0eb4..83d22ae 100644 --- a/arch/arm64/boot/dts/freescale/imx8dxl-sr-som.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8dxl-sr-som.dtsi
@@ -26,7 +26,7 @@ imx8dxl-cm4 { clocks = <&clk_dummy>; mboxes = <&lsio_mu5 0 1 &lsio_mu5 1 1 &lsio_mu5 3 1>; mbox-names = "tx", "rx", "rxdb"; - memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, + memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>; power-domains = <&pd IMX_SC_R_M4_0_PID0>, <&pd IMX_SC_R_M4_0_MU_1A>; fsl,entry-address = <0x34fe0000>; @@ -103,32 +103,32 @@ linux,cma { linux,cma-default; }; - vdev0vring0: memory0@90000000 { + vdev0vring0: vdev0vring0@90000000 { reg = <0 0x90000000 0 0x8000>; no-map; }; - vdev0vring1: memory@90008000 { + vdev0vring1: vdev0vring1@90008000 { reg = <0 0x90008000 0 0x8000>; no-map; }; - vdev1vring0: memory@90010000 { + vdev1vring0: vdev1vring0@90010000 { reg = <0 0x90010000 0 0x8000>; no-map; }; - vdev1vring1: memory@90018000 { + vdev1vring1: vdev1vring1@90018000 { reg = <0 0x90018000 0 0x8000>; no-map; }; - rsc_table: memory-rsc-table@900ff000 { + rsc_table: rsc-table@900ff000 { reg = <0 0x900ff000 0 0x1000>; no-map; }; - vdevbuffer: memory-vdevbuffer@90400000 { + vdev0buffer: vdev0buffer@90400000 { compatible = "shared-dma-pool"; reg = <0 0x90400000 0 0x100000>; no-map;
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi index ea1d5b9..94e1835 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-beacon-baseboard.dtsi
@@ -49,7 +49,7 @@ pcie0_refclk: pcie0-refclk { clock-frequency = <100000000>; }; - pcie0_refclk_gated: pcie0-refclk-gated { + pcie0_refclk_gated: pcie0-refclk-gated { compatible = "gpio-gate-clock"; clocks = <&pcie0_refclk>; #clock-cells = <0>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-cm4.dtso b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-cm4.dtso new file mode 100644 index 0000000..0bd770a --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-cm4.dtso
@@ -0,0 +1,56 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2023-2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +#include <dt-bindings/clock/imx8mm-clock.h> + +&{/} { + #address-cells = <2>; + #size-cells = <2>; + + reserved-memory { /* CM4 reserved memory */ + #address-cells = <2>; + #size-cells = <2>; + ranges; + + m_core_reserved: m_core@b7000000 { + reg = <0 0xb7000000 0 0x1000000>; + no-map; + }; + + vdev0vring0: vdev0vring0@b8000000 { + reg = <0 0xb8000000 0 0x8000>; + no-map; + }; + + vdev0vring1: vdev0vring1@b8008000 { + reg = <0 0xb8008000 0 0x8000>; + no-map; + }; + + rsc_table: rsc-table@b80ff000 { + reg = <0 0xb80ff000 0 0x1000>; + no-map; + }; + + vdev0buffer: vdev0buffer@b8400000 { + compatible = "shared-dma-pool"; + reg = <0 0xb8400000 0 0x100000>; + no-map; + }; + }; + + imx8mm-cm4 { + compatible = "fsl,imx8mm-cm4"; + clocks = <&clk IMX8MM_CLK_M4_CORE>; + mbox-names = "tx", "rx", "rxdb"; + mboxes = <&mu 0 1 + &mu 1 1 + &mu 3 1>; + memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, <&rsc_table>; + syscon = <&src>; + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-common.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-common.dtsi new file mode 100644 index 0000000..8a95dc0 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-common.dtsi
@@ -0,0 +1,59 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> + +&{/} { + reg_backlight_en_level: regulator-backlight-en-level { + compatible = "regulator-gpio"; + regulator-name = "Backlight_SEL_EN"; + regulator-type = "voltage"; + states = <3300000 0x0>, + <5000000 0x1>; + + /* Default setting: lowest supported voltage. */ + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + reg_backlight_pwm_level: regulator-backlight-pwm-level { + compatible = "regulator-gpio"; + regulator-name = "Backlight_SEL_PWM"; + regulator-type = "voltage"; + gpios = <&gpio_display 2 GPIO_ACTIVE_HIGH>; /* SEL_PWM */ + states = <3300000 0x0>, + <5000000 0x1>; + + /* Default setting: lowest supported voltage. */ + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + reg_panel_bl: regulator-panel-bl { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_panel_backlight>; + regulator-name = "PANEL_BL"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&gpio3 0 0>; + enable-active-high; + /* Used by panels which enable PWM signal before BL ON/OFF */ + status = "disabled"; + }; +}; + +®_panel_vcc { + compatible = "regulator-gpio"; + regulator-type = "voltage"; + enable-active-high; + status = "okay"; + + /* Default setting: lowest supported voltage. */ + gpios-states = <0 0>; /* Default GPIO state is LOW/LOW, so 3V3 out */ + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtsi new file mode 100644 index 0000000..8b38b5c --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtsi
@@ -0,0 +1,99 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> + +&{/} { + can_osc: can-osc { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <20000000>; + }; + + sound-fio { + compatible = "simple-audio-card"; + simple-audio-card,name = "SGTL5000-FIO1"; + simple-audio-card,format = "i2s"; + simple-audio-card,bitclock-master = <&codec_dai_fio>; + simple-audio-card,frame-master = <&codec_dai_fio>; + simple-audio-card,widgets = "Headphone", "Headphone Jack"; + simple-audio-card,routing = "Headphone Jack", "HP_OUT"; + + simple-audio-card,cpu { + sound-dai = <&sai2>; + }; + + codec_dai_fio: simple-audio-card,codec { + sound-dai = <&sgtl5000_fio>; + }; + }; +}; + +&ecspi2 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + can_fio: can@0 { + compatible = "microchip,mcp2518fd"; + reg = <0>; + clocks = <&can_osc>; + spi-max-frequency = <10000000>; + }; +}; + +&i2c_feature { /* Feature connector I2C */ + #address-cells = <1>; + #size-cells = <0>; + + sgtl5000_fio: codec@a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + #sound-dai-cells = <0>; + clocks = <&sai5clk 1>; + VDDA-supply = <&buck4_reg>; + VDDD-supply = <&buck5_reg>; + VDDIO-supply = <&buck4_reg>; + }; + + gpio_feature: io-expander@20 { + compatible = "nxp,pca9554"; + reg = <0x20>; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + gpio-line-names = + "GPI0", "GPI1", "GPI2", "GPI3", + "GPO0", "GPO1", "GPO2", "GPO3"; + }; + + eeprom@50 { + compatible = "atmel,24c32"; + reg = <0x50>; + pagesize = <32>; + }; +}; + +&sai2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sai2>; + assigned-clock-rates = <24576000>; + fsl,sai-asynchronous; + fsl,sai-mclk-direction-output; + status = "okay"; +}; + +&uart2 { /* RS422 J12 */ + linux,rs485-enabled-at-boot-time; + uart-has-rtscts; + status = "okay"; +}; + +/* UART4 is blocked by RDC and used as CM4 console UART */ +&uart4 { /* UART to 1-Wire J5 */ + status = "disabled"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtso b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtso new file mode 100644 index 0000000..88fa705 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtso
@@ -0,0 +1,79 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2024-2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +#include <dt-bindings/clock/imx8mm-clock.h> + +#include "imx8mm-pinfunc.h" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtsi" + +&can_fio { + interrupts-extended = <&gpio4 25 IRQ_TYPE_LEVEL_LOW>; +}; + +&gpio_feature { + interrupt-parent = <&gpio5>; + interrupts = <4 IRQ_TYPE_LEVEL_LOW>; +}; + +&iomuxc { + pinctrl_codec_mclk: codec-mclk_feature-grp { + fsl,pins = < + /* GPIO4_IO27 */ + MX8MM_IOMUXC_SAI2_MCLK_SAI5_MCLK 0x2 + >; + }; + + pinctrl_sai2: sai2_feature-grp { + fsl,pins = < + MX8MM_IOMUXC_SAI2_RXC_SAI2_RX_BCLK 0x90 + MX8MM_IOMUXC_SAI2_TXD0_SAI2_TX_DATA0 0x96 + MX8MM_IOMUXC_SAI2_RXD0_SAI2_RX_DATA0 0x90 + MX8MM_IOMUXC_SAI2_TXFS_SAI2_TX_SYNC 0x96 + >; + }; +}; + +&pinctrl_hog_feature { + fsl,pins = < + /* GPIO5_IO03 */ + MX8MM_IOMUXC_SPDIF_TX_GPIO5_IO3 0x40000006 + /* GPIO5_IO04 */ + MX8MM_IOMUXC_SPDIF_RX_GPIO5_IO4 0x40000006 + + /* CAN_INT# */ + MX8MM_IOMUXC_SAI2_TXC_GPIO4_IO25 0x40000090 + >; +}; + +&sai2 { + assigned-clocks = <&clk IMX8MM_CLK_SAI2>; + assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>; + fsl,sai-bit-clock-swap; +}; + +&spba2 { + #address-cells = <1>; + #size-cells = <1>; + + sai5clk: clock-controller@30050000 { /* SAI5 */ + compatible = "fsl,imx8mm-sai-clock", "fsl,imx8mq-sai-clock"; + reg = <0x30050000 0x10000>; + #clock-cells = <1>; + clocks = <&clk IMX8MM_CLK_SAI5_IPG>, + <&clk IMX8MM_CLK_SAI5_ROOT>; + clock-names = "bus", "mclk1"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_codec_mclk>; + assigned-clocks = <&clk IMX8MM_CLK_SAI5>, + <&clk IMX8MM_CLK_CLKOUT1_SEL>, + <&clk IMX8MM_CLK_CLKOUT2_SEL>; + assigned-clock-parents = <&clk IMX8MM_CLK_24M>, + <&clk IMX8MM_CLK_24M>, + <&clk IMX8MM_CLK_24M>; + assigned-clock-rates = <24000000>; + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtsi new file mode 100644 index 0000000..905db21 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtsi
@@ -0,0 +1,69 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> + +&{/} { + can_osc: can-osc { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <20000000>; + }; +}; + +&ecspi2 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + can_fio: can@0 { + compatible = "microchip,mcp2515"; + reg = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can>; + clocks = <&can_osc>; + spi-max-frequency = <5000000>; + }; +}; + +&i2c_feature { /* Feature connector I2C */ + #address-cells = <1>; + #size-cells = <0>; + + gpio_feature: io-expander@20 { + compatible = "nxp,pca9554"; + reg = <0x20>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_expander>; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&gpio4>; + interrupts = <27 IRQ_TYPE_LEVEL_LOW>; + gpio-line-names = + "GPIO1_output", "GPIO1_input", + "GPIO2_output", "GPIO2_input", + "GPIO3_output", "GPIO3_input", + "PCA9511A_READY", ""; + }; + + eeprom@50 { + compatible = "atmel,24c32"; + reg = <0x50>; + pagesize = <32>; + }; +}; + +&uart1 { /* J500/J501 */ + status = "okay"; +}; + +&uart2 { /* RS485 J302/J303 */ + linux,rs485-enabled-at-boot-time; + uart-has-rtscts; + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtso b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtso new file mode 100644 index 0000000..ad410db --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtso
@@ -0,0 +1,59 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2022-2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +#include "imx8mm-pinfunc.h" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtsi" + +&{/} { + beeper { + compatible = "pwm-beeper"; + beeper-hz = <1000>; + pwms = <&pwm3 0 250000 0>; + }; +}; + +&can_fio { + interrupts-extended = <&gpio4 25 IRQ_TYPE_LEVEL_LOW>; +}; + +&iomuxc { + pinctrl_can: can-feature-grp { + fsl,pins = < + /* CAN_INT# */ + MX8MM_IOMUXC_SAI2_TXC_GPIO4_IO25 0x400000d6 + /* CAN_RST# */ + MX8MM_IOMUXC_SAI2_TXD0_GPIO4_IO26 0x6 + >; + }; + + pinctrl_gpio_expander: gpio-expander-feature-grp { + fsl,pins = < + /* GPIO4_IO27 */ + MX8MM_IOMUXC_SAI2_MCLK_GPIO4_IO27 0x6 + >; + }; + + pinctrl_pwm3: pwm3-buzzer-feature-grp { + fsl,pins = < + /* Buzzer PWM output */ + MX8MM_IOMUXC_SPDIF_TX_PWM3_OUT 0x100 + >; + }; +}; + +&pinctrl_hog_feature { + fsl,pins = < + /* GPIO5_IO04 */ + MX8MM_IOMUXC_SPDIF_RX_GPIO5_IO4 0x6 + >; +}; + +&pwm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm3>; + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtsi new file mode 100644 index 0000000..59f15d5 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtsi
@@ -0,0 +1,94 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> + +&{/} { + hdmi-out { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con: endpoint { + remote-endpoint = <<9611_out>; + }; + }; + }; +}; + +&i2c_display { /* Display connector I2C */ + #address-cells = <1>; + #size-cells = <0>; + + lt9611_codec: hdmi-bridge@3b { + compatible = "lontium,lt9611"; + reg = <0x3b>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_panel_expansion>; + vcc-supply = <&buck4_reg>; /* X400 pin 55, +3V3_S0 */ + vdd-supply = <&buck5_reg>; /* X400 pin 51, +1V8_S0 */ + + /* Audio I2S not described */ + #sound-dai-cells = <1>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + lt9611_a: endpoint { + remote-endpoint = <&mipi_dsi_bridge1_out>; + }; + }; + + port@2 { + reg = <2>; + + lt9611_out: endpoint { + remote-endpoint = <&hdmi_con>; + }; + }; + }; + }; + + eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +&iomuxc { + /* Free &pinctrl_panel_expansion from hog for lt9611_codec above */ + pinctrl-0 = <&pinctrl_hog_misc>, <&pinctrl_hog_feature>, + <&pinctrl_hog_panel>, <&pinctrl_hog_sbc>; +}; + +&mipi_dsi { + /* HDMI 148.5 MHz x2 (DDR) x3 (24bpp / 8) */ + samsung,burst-clock-frequency = <891000000>; + samsung,esc-clock-frequency = <10000000>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + mipi_dsi_bridge1_out: endpoint { + clock-lanes = <0>; + data-lanes = <1 2 3 4>; + /* Clock and data lanes have DN/DP swapped */ + lane-polarities = <1 1 1 1 1>; + remote-endpoint = <<9611_a>; + }; + }; + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtso b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtso new file mode 100644 index 0000000..334ba29 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtso
@@ -0,0 +1,17 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2022-2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtsi" + +<9611_codec { + interrupts-extended = <&gpio2 3 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>; +}; + +&lcdif { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-common.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-common.dtsi new file mode 100644 index 0000000..9abd188 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-common.dtsi
@@ -0,0 +1,118 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +&{/} { + reg_lt9211_vcc18: regulator-lt9211-vcc18 { + compatible = "regulator-fixed"; + regulator-name = "LT9211_VCC18"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&buck5_reg>; /* X400 pin 51, +1V8_S0 */ + }; +}; + +&i2c_display { /* Display connector I2C */ + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <100000>; + + lt9211_codec: bridge@2d { + compatible = "lontium,lt9211"; + reg = <0x2d>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_panel_expansion>; + interrupts-extended = <&gpio2 3 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>; + vccio-supply = <®_lt9211_vcc18>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + lt9211_a: endpoint { + data-lanes = <1 2 3 4>; + remote-endpoint = <&mipi_dsi_bridge1_out>; + }; + }; + }; + }; + + gpio_display: io-expander@41 { + compatible = "nxp,pca9536"; + reg = <0x41>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "SEL_12V", "SEL_5V", "SEL_PWM", "SEL_EN"; + }; + + eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +®_backlight_en_level { + gpios = <&gpio_display 3 GPIO_ACTIVE_HIGH>; /* SEL_EN */ +}; + +®_backlight_pwm_level { + gpios = <&gpio_display 2 GPIO_ACTIVE_HIGH>; /* SEL_PWM */ +}; + +®_panel_bl { + gpio = <&gpio3 0 0>; +}; + +&iomuxc { + /* Free &pinctrl_panel_expansion from hog for lt9211_codec above */ + pinctrl-0 = <&pinctrl_hog_misc>, <&pinctrl_hog_feature>, + <&pinctrl_hog_panel>, <&pinctrl_hog_sbc>; +}; + +&mipi_dsi { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + mipi_dsi_bridge1_out: endpoint { + clock-lanes = <0>; + data-lanes = <1 2 3 4>; + /* Clock and data lanes have DN/DP swapped */ + lane-polarities = <1 1 1 1 1>; + remote-endpoint = <<9211_a>; + }; + }; + }; +}; + +&pwm1 { + status = "okay"; +}; + +®_panel_vcc { + /* + * AP63300 voltage divider settings: + * R1=16k2 + * R2=5k23 with optional series Rs=7k68 (5V) or Rt=1k5 (12V) + * + * 1 / Rx = (1 / R2) [ + (1 / Rs)][ + (1 / Rt)] + * Vout = 0.8 * ((R1 / Rx) + 1) + */ + gpios = <&gpio_display 1 GPIO_ACTIVE_HIGH>, /* 5V */ + <&gpio_display 0 GPIO_ACTIVE_HIGH>; /* 12V */ + states = <3300000 0x0>, + <5000000 0x1>, + <12000000 0x2>, + <3900000 0x3>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-dual.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-dual.dtsi new file mode 100644 index 0000000..abe50eb --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-dual.dtsi
@@ -0,0 +1,32 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +<9211_codec { + ports { + port@2 { + reg = <2>; + + lt9211_out_a: endpoint { + remote-endpoint = <&panel_lvds_a>; + }; + }; + + port@3 { + reg = <3>; + + lt9211_out_b: endpoint { + remote-endpoint = <&panel_lvds_b>; + }; + }; + }; +}; + +&panel_lvds_a { + remote-endpoint = <<9211_out_a>; +}; + +&panel_lvds_b { + remote-endpoint = <<9211_out_b>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtsi new file mode 100644 index 0000000..cca5246 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtsi
@@ -0,0 +1,12 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-g070y2-l01.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-single.dtsi" + +&mipi_dsi { + samsung,burst-clock-frequency = <216000000>; /* RX ByteClock ~27 MHz */ + samsung,esc-clock-frequency = <10000000>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtso b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtso new file mode 100644 index 0000000..5d1ea31 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtso
@@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2022-2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtsi new file mode 100644 index 0000000..52d216f --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtsi
@@ -0,0 +1,12 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-g101ice-l01.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-single.dtsi" + +&mipi_dsi { + samsung,burst-clock-frequency = <515000000>; + samsung,esc-clock-frequency = <10000000>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtso b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtso new file mode 100644 index 0000000..2d1bbdd --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtso
@@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2023-2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtsi new file mode 100644 index 0000000..aba3c9a --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtsi
@@ -0,0 +1,12 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-g121xce-l01.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-single.dtsi" + +&mipi_dsi { + samsung,burst-clock-frequency = <470000000>; + samsung,esc-clock-frequency = <10000000>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtso b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtso new file mode 100644 index 0000000..bc2f6fe --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtso
@@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2024-2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtsi new file mode 100644 index 0000000..f478f4e --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtsi
@@ -0,0 +1,12 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-g156hce-l01.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-dual.dtsi" + +&mipi_dsi { + samsung,burst-clock-frequency = <864000000>; + samsung,esc-clock-frequency = <10000000>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtso b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtso new file mode 100644 index 0000000..5bd417c --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtso
@@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2023-2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtsi new file mode 100644 index 0000000..21bec8a --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtsi
@@ -0,0 +1,12 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-g215hvn011.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-dual.dtsi" + +&mipi_dsi { + samsung,burst-clock-frequency = <864000000>; /* RX ByteClock ~27 MHz */ + samsung,esc-clock-frequency = <10000000>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtso b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtso new file mode 100644 index 0000000..75ae12d --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtso
@@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2022-2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtsi new file mode 100644 index 0000000..38a3a9a --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtsi
@@ -0,0 +1,12 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-mi0700a2t-30.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-single.dtsi" + +&mipi_dsi { + samsung,burst-clock-frequency = <216000000>; /* RX ByteClock ~27 MHz */ + samsung,esc-clock-frequency = <10000000>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtso b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtso new file mode 100644 index 0000000..ee2c796 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtso
@@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2024-2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtsi new file mode 100644 index 0000000..98b5c58 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtsi
@@ -0,0 +1,12 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-mi1010z1t-1cp11.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-single.dtsi" + +&mipi_dsi { + samsung,burst-clock-frequency = <400000000>; + samsung,esc-clock-frequency = <10000000>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtso b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtso new file mode 100644 index 0000000..d05f0dc --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtso
@@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2024-2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-single.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-single.dtsi new file mode 100644 index 0000000..9e70c14 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-single.dtsi
@@ -0,0 +1,20 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +<9211_codec { + ports { + port@2 { + reg = <2>; + + lt9211_out_a: endpoint { + remote-endpoint = <&panel_lvds>; + }; + }; + }; +}; + +&panel_lvds { + remote-endpoint = <<9211_out_a>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi new file mode 100644 index 0000000..31598aa --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi
@@ -0,0 +1,22 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2022-2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-common.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-common.dtsi" + +&lcdif { + status = "okay"; +}; + +<9211_codec { + interrupts-extended = <&gpio2 3 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>; +}; + +®_panel_vcc { + enable-gpios = <&gpio3 6 0>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-sbc-imx8mm-rev900.dtso b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-sbc-imx8mm-rev900.dtso new file mode 100644 index 0000000..1403821 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-edm-sbc-imx8mm-rev900.dtso
@@ -0,0 +1,18 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2023-2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +&fec1 { + phy-handle = <&fec1_phy_ath>; +}; + +&fec1_phy_ath { + status = "okay"; +}; + +&fec1_phy_bcm { + status = "disabled"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-3v3.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-3v3.dtsi new file mode 100644 index 0000000..0955764 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-3v3.dtsi
@@ -0,0 +1,19 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +®_backlight_pwm_level { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; +}; + +®_backlight_en_level { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; +}; + +®_panel_vcc { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-5v0.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-5v0.dtsi new file mode 100644 index 0000000..70ad6bb --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-5v0.dtsi
@@ -0,0 +1,19 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +®_backlight_pwm_level { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; +}; + +®_backlight_en_level { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; +}; + +®_panel_vcc { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-dual.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-dual.dtsi new file mode 100644 index 0000000..65f9ad8 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-dual.dtsi
@@ -0,0 +1,29 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +&panel { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dual-lvds-odd-pixels; + + panel_lvds_b: endpoint { + }; + }; + + port@1 { + reg = <1>; + dual-lvds-even-pixels; + + panel_lvds_a: endpoint { + }; + }; + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-g070y2-l01.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-g070y2-l01.dtsi new file mode 100644 index 0000000..80f7b74 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-g070y2-l01.dtsi
@@ -0,0 +1,31 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2023-2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-3v3.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-single.dtsi" + +&backlight { + power-supply = <®_panel_bl>; + /* 6.3 POWER ON/OFF SEQUENCE, T9 >= 10 ms */ + pwm-off-delay-ms = <10>; + /* 3.2 BACKLIGHT UNIT fPWM=200 Hz (Typ.), value below in ns */ + pwms = <&pwm1 0 5000000 0>; + status = "okay"; +}; + +&panel { + compatible = "innolux,g070y2-l01"; +}; + +®_panel_bl { + startup-delay-us = <10000>; /* T8 */ + off-on-delay-us = <550000>; /* T9 + T6 + T3 + T7 + T4 + T1 + T2 + T5 */ + status = "okay"; +}; + +®_panel_vcc { + /* 6.3 POWER ON/OFF SEQUENCE */ + startup-delay-us = <1000>; /* 0.5ms <= T1 + T2 <= 60 ms */ +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-g101ice-l01.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-g101ice-l01.dtsi new file mode 100644 index 0000000..1a2bd20 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-g101ice-l01.dtsi
@@ -0,0 +1,31 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2023-2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-3v3.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-single.dtsi" + +&backlight { + power-supply = <®_panel_bl>; + /* 6.3 POWER ON/OFF SEQUENCE, T9 >= 10 ms */ + pwm-off-delay-ms = <10>; + /* 3.2 BACKLIGHT UNIT fPWM=200 Hz (Typ.), value below in ns */ + pwms = <&pwm1 0 5000000 0>; + status = "okay"; +}; + +&panel { + compatible = "innolux,g101ice-l01"; +}; + +®_panel_bl { + startup-delay-us = <10000>; /* T8 */ + off-on-delay-us = <950000>; /* T9 + T6 + T3 + T7 + T4 + T1 + T2 + T5 */ + status = "okay"; +}; + +®_panel_vcc { + /* 6.3 POWER ON/OFF SEQUENCE */ + startup-delay-us = <1000>; /* 0.5ms <= T1 + T2 <= 60 ms */ +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-g121xce-l01.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-g121xce-l01.dtsi new file mode 100644 index 0000000..f87e8c8 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-g121xce-l01.dtsi
@@ -0,0 +1,31 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2024 Wael Karman <wkarman@data-modul.com> + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-3v3.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-single.dtsi" + +&backlight { + power-supply = <®_panel_bl>; + /* 6.2 POWER ON/OFF SEQUENCE, T9 >= 10 ms */ + pwm-off-delay-ms = <10>; + /* 3.2 BACKLIGHT UNIT fPWM=200 Hz (Typ.), value below in ns */ + pwms = <&pwm1 0 5000000 0>; + status = "okay"; +}; + +&panel { + compatible = "innolux,g121xce-l01"; +}; + +®_panel_bl { + startup-delay-us = <10000>; /* T8 */ + off-on-delay-us = <1180000>; /* T9 + T6 + T3 + T7 + T4 + T1 + T2 + T5 */ + status = "okay"; +}; + +®_panel_vcc { + /* 6.2 POWER ON/OFF SEQUENCE */ + startup-delay-us = <1000>; /* 0.5ms <= T1 + T2 <= 60 ms */ +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-g156hce-l01.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-g156hce-l01.dtsi new file mode 100644 index 0000000..46c8bc7 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-g156hce-l01.dtsi
@@ -0,0 +1,31 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2023-2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-3v3.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-dual.dtsi" + +&backlight { + power-supply = <®_panel_bl>; + /* 4.6 POWER ON/OFF SEQUENCE, T9 >= 10 ms */ + pwm-off-delay-ms = <10>; + /* 4.3.2 BACKLIGHT UNIT fPWM=200 Hz (Typ.), value below in ns */ + pwms = <&pwm1 0 5000000 0>; + status = "okay"; +}; + +&panel { + compatible = "innolux,g156hce-l01"; +}; + +®_panel_bl { + startup-delay-us = <10000>; /* T8 */ + off-on-delay-us = <1170000>; /* T9 + T6 + T3 + T7 + T4 + T1 + T2 + T5 */ + status = "okay"; +}; + +®_panel_vcc { + /* 4.6 POWER ON/OFF SEQUENCE */ + startup-delay-us = <1000>; /* 0.5ms <= T1 + T2 <= 60 ms */ +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-g215hvn011.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-g215hvn011.dtsi new file mode 100644 index 0000000..3585170 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-g215hvn011.dtsi
@@ -0,0 +1,30 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2022-2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-5v0.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-dual.dtsi" + +&backlight { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_panel_backlight>; + enable-gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>; + /* 6.5 POWER ON/OFF SEQUENCE, T6 >= 10 ms */ + post-pwm-on-delay-ms = <10>; + /* 6.5 POWER ON/OFF SEQUENCE, T7 >= 0 ms */ + pwm-off-delay-ms = <10>; + /* 5.2 BACKLIGHT UNIT 200Hz..20kHz, value below in ns */ + pwms = <&pwm1 0 66666 0>; /* 15 kHz = 66666ns */ + status = "okay"; +}; + +&panel { + /* The G215HVN01 is replacement for T215HVN01, which is supported. */ + compatible = "auo,t215hvn01"; +}; + +®_panel_vcc { + /* 6.5 POWER ON/OFF SEQUENCE */ + startup-delay-us = <40000>; /* 30.5ms <= T1 + T2 <= 60 ms */ +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-mi0700a2t-30.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-mi0700a2t-30.dtsi new file mode 100644 index 0000000..4a077e6 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-mi0700a2t-30.dtsi
@@ -0,0 +1,31 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2024-2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-3v3.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-single.dtsi" + +&backlight { + power-supply = <®_panel_bl>; + /* 1.5 POWER ON/OFF SEQUENCE, T4 >= 200 ms */ + pwm-off-delay-ms = <200>; + /* ELECTRICAL CHARACTERISTICS, BL_ADJ Frequency 20K HZ Typ., value below in ns */ + pwms = <&pwm1 0 50000 0>; + status = "okay"; +}; + +&panel { + compatible = "multi-inno,mi0700a2t-30"; +}; + +®_panel_bl { + startup-delay-us = <200000>; /* T3 */ + off-on-delay-us = <1450000>; /* T4 + T5 + T6 + T1 + T2 + T3 */ + status = "okay"; +}; + +®_panel_vcc { + /* 1.5 POWER ON/OFF SEQUENCE */ + startup-delay-us = <60000>; /* T1 + T2 >= 1 ms (typ. 60ms) */ +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-mi1010z1t-1cp11.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-mi1010z1t-1cp11.dtsi new file mode 100644 index 0000000..e8d8cd8 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-mi1010z1t-1cp11.dtsi
@@ -0,0 +1,31 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2024-2026 Marek Vasut + */ + +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-3v3.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-single.dtsi" + +&backlight { + power-supply = <®_panel_bl>; + /* 3 POWER ON/OFF SEQUENCE, T7 >= 200 ms */ + pwm-off-delay-ms = <200>; + /* ELECTRICAL CHARACTERISTICS, BL_ADJ Frequency 20K HZ Typ., value below in ns */ + pwms = <&pwm1 0 50000 0>; + status = "okay"; +}; + +&panel { + compatible = "multi-inno,mi1010z1t-1cp11"; +}; + +®_panel_bl { + startup-delay-us = <200000>; /* T6 */ + off-on-delay-us = <1450000>; /* T7 + T3 + T4 + T5 + T1 + T2 + T6 */ + status = "okay"; +}; + +®_panel_vcc { + /* 3 POWER ON/OFF SEQUENCE */ + startup-delay-us = <60000>; /* T1 + T2 >= 1 ms (typ. 60ms) */ +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-single.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-single.dtsi new file mode 100644 index 0000000..68c2069 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc-overlay-lvds-single.dtsi
@@ -0,0 +1,13 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 Marek Vasut + */ + +&panel { + status = "okay"; + + port { + panel_lvds: endpoint { + }; + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dts b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dts index 472c584..cb76471 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-data-modul-edm-sbc.dts
@@ -30,11 +30,8 @@ memory@40000000 { backlight: backlight { compatible = "pwm-backlight"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_panel_backlight>; brightness-levels = <0 1 10 20 30 40 50 60 70 75 80 90 100>; default-brightness-level = <7>; - enable-gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>; pwms = <&pwm1 0 5000000 0>; /* Disabled by default, unless display board plugged in. */ status = "disabled"; @@ -66,7 +63,6 @@ reg_panel_vcc: regulator-panel-vcc { regulator-name = "PANEL_VCC"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - gpio = <&gpio3 6 0>; enable-active-high; /* Disabled by default, unless display board plugged in. */ status = "disabled"; @@ -435,7 +431,63 @@ usb-hub@2c { eeprom: eeprom@50 { compatible = "atmel,24c32"; reg = <0x50>; + label = "dmo-board-info"; pagesize = <32>; + wp-gpios = <&gpio2 5 GPIO_ACTIVE_LOW>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + company-name@24 { + reg = <0x24 0xd>; + }; + + product-name@32 { + reg = <0x32 0x13>; + }; + + board-revision@4b { + reg = <0x4b 0x3>; + }; + + serial-number@4f { + reg = <0x4f 0x8>; + }; + + manufacturing-date@70 { + reg = <0x70 0xa>; + }; + + test-date@7b { + reg = <0x7b 0xa>; + }; + + product-number@86 { + reg = <0x86 0x8>; + }; + + board-variant@9a { + reg = <0x9a 0x9>; + }; + + company-acronym@a4 { + reg = <0xa4 0x3>; + }; + + mac-address@b0 { + reg = <0xb0 0x6>; + }; + + board-id@100 { + reg = <0x100 0x4>; + }; + + wifi-id@120 { + reg = <0x120 0x4>; + }; + }; }; rtc: rtc@68 { @@ -454,7 +506,7 @@ pcieclk: clk@6a { }; }; -&i2c3 { /* Display connector I2C */ +i2c_display: &i2c3 { /* Display connector I2C */ /* IMX8MM ERRATA e7805 -- I2C is limited to 384 kHz due to SoC bug */ clock-frequency = <320000>; pinctrl-names = "default", "gpio"; @@ -465,7 +517,7 @@ &i2c3 { /* Display connector I2C */ status = "okay"; }; -&i2c4 { /* Feature connector I2C */ +i2c_feature: &i2c4 { /* Feature connector I2C */ /* IMX8MM ERRATA e7805 -- I2C is limited to 384 kHz due to SoC bug */ clock-frequency = <320000>; pinctrl-names = "default", "gpio";
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts index dd59af0..27bfad5 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-kontron-bl.dts
@@ -5,6 +5,7 @@ /dts-v1/; +#include <dt-bindings/leds/common.h> #include "imx8mm-kontron-sl.dtsi" / { @@ -96,6 +97,7 @@ reg_vdd_5v: regulator-5v { }; }; +/* CAN */ &ecspi2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ecspi2>; @@ -121,8 +123,15 @@ &ecspi3 { pinctrl-0 = <&pinctrl_ecspi3>; cs-gpios = <&gpio5 25 GPIO_ACTIVE_LOW>; status = "okay"; + + eeram@0 { + compatible = "microchip,48l640"; + reg = <0>; + spi-max-frequency = <20000000>; + }; }; +/* ETH0 */ &fec1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_enet>; @@ -139,13 +148,47 @@ ethphy: ethernet-phy@0 { reset-assert-us = <1>; reset-deassert-us = <15000>; reset-gpios = <&gpio4 27 GPIO_ACTIVE_LOW>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = <LED_COLOR_ID_GREEN>; + function = LED_FUNCTION_LAN; + linux,default-trigger = "netdev"; + }; + + led@1 { + reg = <1>; + color = <LED_COLOR_ID_YELLOW>; + function = LED_FUNCTION_LAN; + linux,default-trigger = "netdev"; + }; + }; }; }; }; +/* DIO */ +&gpio1 { + gpio-line-names = "", "", "", "DOUT1", + "", "", "DIN1", "DOUT2", + "DIN2", "DOUT3", "DIN3", "DOUT4"; +}; + &gpio4 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_gpio4>; + gpio-line-names = "", "CAN_ADR0", "", "", + "CAN_ADR1", "CAN_ADR2", "CAN_ADR3", "LED6", + "LED4", "LED5", "", "", + "", "", "DSI_MUX_SEL", "DSI_MUX_OE", + "HDMI_IRQ", "LED1", "LED3", "LED2", + "", "", "", "", + "", "ETH_IRQ", "LVDS_EN", "PHY_RST", + "CAN_IRQ", "UART2_RTS"; dsi_mux_sel_hdmi: dsi-mux-sel-hdmi-hog { gpio-hog; @@ -170,6 +213,10 @@ dsi-mux-oe-hog { }; }; +&gpio5 { + gpio-line-names = "", "", "DIN4"; +}; + &i2c3 { clock-frequency = <400000>; pinctrl-names = "default"; @@ -254,6 +301,7 @@ &pwm2 { status = "okay"; }; +/* RS232 */ &uart1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart1>; @@ -261,6 +309,7 @@ &uart1 { status = "okay"; }; +/* RS485 */ &uart2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart2>; @@ -304,6 +353,7 @@ usbnet: ethernet@1 { }; }; +/* SD-card */ &usdhc2 { pinctrl-names = "default", "state_100mhz", "state_200mhz"; pinctrl-0 = <&pinctrl_usdhc2>; @@ -321,13 +371,13 @@ &iomuxc { pinctrl_adv7535: adv7535grp { fsl,pins = < - MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x19 + MX8MM_IOMUXC_SAI1_TXD4_GPIO4_IO16 0x19 /* HDMI_IRQ */ >; }; pinctrl_can: cangrp { fsl,pins = < - MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x19 + MX8MM_IOMUXC_SAI3_RXFS_GPIO4_IO28 0x19 /* CAN_IRQ */ >; }; @@ -336,7 +386,7 @@ pinctrl_ecspi2: ecspi2grp { MX8MM_IOMUXC_ECSPI2_MISO_ECSPI2_MISO 0x82 MX8MM_IOMUXC_ECSPI2_MOSI_ECSPI2_MOSI 0x82 MX8MM_IOMUXC_ECSPI2_SCLK_ECSPI2_SCLK 0x82 - MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x19 + MX8MM_IOMUXC_ECSPI2_SS0_GPIO5_IO13 0x19 /* ECSPI2_CS1 */ >; }; @@ -345,7 +395,7 @@ pinctrl_ecspi3: ecspi3grp { MX8MM_IOMUXC_UART2_RXD_ECSPI3_MISO 0x82 MX8MM_IOMUXC_UART1_TXD_ECSPI3_MOSI 0x82 MX8MM_IOMUXC_UART1_RXD_ECSPI3_SCLK 0x82 - MX8MM_IOMUXC_UART2_TXD_GPIO5_IO25 0x19 + MX8MM_IOMUXC_UART2_TXD_GPIO5_IO25 0x19 /* ECSPI3_CS1 */ >; }; @@ -365,40 +415,45 @@ MX8MM_IOMUXC_ENET_TXC_ENET1_RGMII_TXC 0x1f MX8MM_IOMUXC_ENET_RXC_ENET1_RGMII_RXC 0x91 MX8MM_IOMUXC_ENET_RX_CTL_ENET1_RGMII_RX_CTL 0x91 MX8MM_IOMUXC_ENET_TX_CTL_ENET1_RGMII_TX_CTL 0x1f - MX8MM_IOMUXC_SAI2_MCLK_GPIO4_IO27 0x19 /* PHY RST */ - MX8MM_IOMUXC_SAI2_TXC_GPIO4_IO25 0x19 /* ETH IRQ */ + MX8MM_IOMUXC_SAI2_MCLK_GPIO4_IO27 0x19 /* PHY_RST */ + MX8MM_IOMUXC_SAI2_TXC_GPIO4_IO25 0x19 /* ETH_IRQ */ >; }; pinctrl_gpio_led: gpioledgrp { fsl,pins = < MX8MM_IOMUXC_NAND_READY_B_GPIO3_IO16 0x19 - MX8MM_IOMUXC_SAI1_RXD5_GPIO4_IO7 0x19 - MX8MM_IOMUXC_SAI1_RXD6_GPIO4_IO8 0x19 - MX8MM_IOMUXC_SAI1_RXD7_GPIO4_IO9 0x19 - MX8MM_IOMUXC_SAI1_TXD5_GPIO4_IO17 0x19 - MX8MM_IOMUXC_SAI1_TXD6_GPIO4_IO18 0x19 - MX8MM_IOMUXC_SAI1_TXD7_GPIO4_IO19 0x19 + MX8MM_IOMUXC_SAI1_RXD5_GPIO4_IO7 0x19 /* LED6 */ + MX8MM_IOMUXC_SAI1_RXD6_GPIO4_IO8 0x19 /* LED4 */ + MX8MM_IOMUXC_SAI1_RXD7_GPIO4_IO9 0x19 /* LED5 */ + MX8MM_IOMUXC_SAI1_TXD5_GPIO4_IO17 0x19 /* LED1 */ + MX8MM_IOMUXC_SAI1_TXD6_GPIO4_IO18 0x19 /* LED3 */ + MX8MM_IOMUXC_SAI1_TXD7_GPIO4_IO19 0x19 /* LED2 */ >; }; pinctrl_gpio: gpiogrp { fsl,pins = < - MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x19 - MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x19 - MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19 - MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x19 - MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6 0x19 - MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x19 - MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x19 - MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x19 + MX8MM_IOMUXC_GPIO1_IO03_GPIO1_IO3 0x19 /* DOUT1 */ + MX8MM_IOMUXC_GPIO1_IO06_GPIO1_IO6 0x19 /* DIN1 */ + MX8MM_IOMUXC_GPIO1_IO07_GPIO1_IO7 0x19 /* DOUT2 */ + MX8MM_IOMUXC_GPIO1_IO08_GPIO1_IO8 0x19 /* DIN2 */ + MX8MM_IOMUXC_GPIO1_IO09_GPIO1_IO9 0x19 /* DOUT3 */ + MX8MM_IOMUXC_GPIO1_IO10_GPIO1_IO10 0x19 /* DIN3 */ + MX8MM_IOMUXC_GPIO1_IO11_GPIO1_IO11 0x19 /* DOUT4 */ + MX8MM_IOMUXC_SAI3_MCLK_GPIO5_IO2 0x19 /* DIN4 */ >; }; pinctrl_gpio4: gpio4grp { fsl,pins = < - MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x19 - MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x19 + /* CAN address DIP switches 1-4 */ + MX8MM_IOMUXC_SAI1_RXC_GPIO4_IO1 0x19 /* CAN_ADR0 */ + MX8MM_IOMUXC_SAI1_RXD2_GPIO4_IO4 0x19 /* CAN_ADR1 */ + MX8MM_IOMUXC_SAI1_RXD3_GPIO4_IO5 0x19 /* CAN_ADR2 */ + MX8MM_IOMUXC_SAI1_RXD4_GPIO4_IO6 0x19 /* CAN_ADR3 */ + MX8MM_IOMUXC_SAI1_TXD2_GPIO4_IO14 0x19 /* DSI_MUX_SEL */ + MX8MM_IOMUXC_SAI1_TXD3_GPIO4_IO15 0x19 /* DSI_MUX_OE */ >; }; @@ -424,7 +479,7 @@ MX8MM_IOMUXC_SPDIF_RX_PWM2_OUT 0x19 pinctrl_sn65dsi84: sn65dsi84grp { fsl,pins = < - MX8MM_IOMUXC_SAI2_TXD0_GPIO4_IO26 0x19 + MX8MM_IOMUXC_SAI2_TXD0_GPIO4_IO26 0x19 /* LVDS_EN */ MX8MM_IOMUXC_SD2_WP_GPIO2_IO20 0x19 >; }; @@ -443,13 +498,13 @@ pinctrl_uart2: uart2grp { MX8MM_IOMUXC_SAI3_TXFS_UART2_DCE_RX 0x0 MX8MM_IOMUXC_SAI3_TXC_UART2_DCE_TX 0x0 MX8MM_IOMUXC_SAI3_RXD_UART2_DCE_RTS_B 0x0 - MX8MM_IOMUXC_SAI3_RXC_GPIO4_IO29 0x19 + MX8MM_IOMUXC_SAI3_RXC_GPIO4_IO29 0x19 /* UART2_RTS */ >; }; pinctrl_usb_eth2: usbeth2grp { fsl,pins = < - MX8MM_IOMUXC_NAND_CE1_B_GPIO3_IO2 0x19 + MX8MM_IOMUXC_NAND_CE1_B_GPIO3_IO2 0x19 /* ETH_RST */ >; }; @@ -461,7 +516,7 @@ MX8MM_IOMUXC_SD2_DATA0_USDHC2_DATA0 0x1d0 MX8MM_IOMUXC_SD2_DATA1_USDHC2_DATA1 0x1d0 MX8MM_IOMUXC_SD2_DATA2_USDHC2_DATA2 0x1d0 MX8MM_IOMUXC_SD2_DATA3_USDHC2_DATA3 0x1d0 - MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19 + MX8MM_IOMUXC_SD2_CD_B_GPIO2_IO12 0x19 /* SD2_CD */ MX8MM_IOMUXC_GPIO1_IO04_USDHC2_VSELECT 0xd0 >; };
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tx8m-1610-moduline-iv-306-d.dts b/arch/arm64/boot/dts/freescale/imx8mm-tx8m-1610-moduline-iv-306-d.dts index 6cc04aa..d15297a4 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-tx8m-1610-moduline-iv-306-d.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-tx8m-1610-moduline-iv-306-d.dts
@@ -12,7 +12,6 @@ / { chassis-type = "embedded"; compatible = "gocontroll,moduline-iv-306-d", "karo,tx8m-1610", "fsl,imx8mm"; - hardware = "Moduline IV V3.06-D"; model = "GOcontroll Moduline IV"; aliases {
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-tx8m-1610-moduline-mini-111.dts b/arch/arm64/boot/dts/freescale/imx8mm-tx8m-1610-moduline-mini-111.dts index 39b7d90..9148ea7 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-tx8m-1610-moduline-mini-111.dts +++ b/arch/arm64/boot/dts/freescale/imx8mm-tx8m-1610-moduline-mini-111.dts
@@ -12,7 +12,6 @@ / { chassis-type = "embedded"; compatible = "gocontroll,moduline-mini-111", "karo,tx8m-1610", "fsl,imx8mm"; - hardware = "Moduline Mini V1.11"; model = "GOcontroll Moduline Mini"; aliases {
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-var-dart.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-var-dart.dtsi index 2324063..c5f0e22 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-var-dart.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-var-dart.dtsi
@@ -123,7 +123,7 @@ ethphy0: ethernet-phy@0 { reg = <0>; reset-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>; reset-assert-us = <10000>; - reset-deassert-us = <100000>; + reset-deassert-us = <200000>; vddio-supply = <®_phy_vddio>; }; }; @@ -138,6 +138,16 @@ &i2c1 { sda-gpios = <&gpio5 15 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; status = "okay"; + st33ktpm2xi2c_som: tpm@2e { + compatible = "st,st33ktpm2xi2c", "tcg,tpm-tis-i2c"; + reg = <0x2e>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_tpm_reset>; + label = "tpm"; + /* active-low TPM reset line. */ + reset-gpios = <&gpio4 31 GPIO_ACTIVE_LOW>; + }; + pmic@4b { compatible = "rohm,bd71847"; reg = <0x4b>; @@ -305,6 +315,7 @@ &sai3 { assigned-clock-parents = <&clk IMX8MM_AUDIO_PLL1_OUT>; assigned-clock-rates = <1536000>; fsl,sai-mclk-direction-output; + fsl,sai-synchronous-rx; status = "okay"; }; @@ -446,13 +457,17 @@ pinctrl_sai3: sai3grp { MX8MM_IOMUXC_SAI3_RXFS_SAI3_RX_SYNC 0xd6 MX8MM_IOMUXC_SAI3_RXC_SAI3_RX_BCLK 0xd6 MX8MM_IOMUXC_SAI3_RXD_SAI3_RX_DATA0 0xd6 - MX8MM_IOMUXC_SAI3_TXFS_SAI3_TX_SYNC 0xd6 - MX8MM_IOMUXC_SAI3_TXC_SAI3_TX_BCLK 0xd6 MX8MM_IOMUXC_SAI3_TXD_SAI3_TX_DATA0 0xd6 MX8MM_IOMUXC_SAI3_MCLK_SAI3_MCLK 0xd6 >; }; + pinctrl_tpm_reset: tpm-resetgrp { + fsl,pins = < + MX8MM_IOMUXC_SAI3_TXFS_GPIO4_IO31 0x19 + >; + }; + pinctrl_uart4: uart4grp { fsl,pins = < MX8MM_IOMUXC_ECSPI2_SCLK_UART4_DCE_RX 0x140
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin-ivy.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin-ivy.dtsi index 29075ff..b64751a 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-verdin-ivy.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin-ivy.dtsi
@@ -270,8 +270,8 @@ &gpio3 { "", "", "", - "DIG_1", /* SODIMM 56 */ - "DIG_2", /* SODIMM 58 */ + "DIGI_1", /* SODIMM 56 */ + "DIGI_2", /* SODIMM 58 */ "REL1", /* SODIMM 60 */ "REL2", /* SODIMM 62 */ "", /* 10 */
diff --git a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi index ac450fc..4f64c5d 100644 --- a/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mm-verdin.dtsi
@@ -353,7 +353,7 @@ &gpio2 { &gpio5 { gpio-line-names = "SODIMM_131", - "", + "SODIMM_256", "SODIMM_91", "SODIMM_16", "SODIMM_15",
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-solidsense-n8-compact.dts b/arch/arm64/boot/dts/freescale/imx8mn-solidsense-n8-compact.dts index c8c6760..9b8b971 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn-solidsense-n8-compact.dts +++ b/arch/arm64/boot/dts/freescale/imx8mn-solidsense-n8-compact.dts
@@ -226,8 +226,6 @@ phy0: ethernet-phy@0 { reset-assert-us = <10>; reset-deassert-us = <5000>; reset-gpios = <&gpio3 19 GPIO_ACTIVE_LOW>; - adi,led-polarity = <GPIO_ACTIVE_LOW>; - adi,link-st-polarity = <GPIO_ACTIVE_LOW>; status = "disabled"; leds {
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-vhip4-evalboard-common.dtsi b/arch/arm64/boot/dts/freescale/imx8mn-vhip4-evalboard-common.dtsi index aaf9761..d420ab3 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn-vhip4-evalboard-common.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mn-vhip4-evalboard-common.dtsi
@@ -142,9 +142,10 @@ &i2c1 { pinctrl-0 = <&pinctrl_i2c1>; pinctrl-1 = <&pinctrl_i2c1_gpio>; - eeprom@51 { + cfg_eeprom: eeprom@51 { compatible = "atmel,24c128"; reg = <0x51>; + label = "ifm-deviceinfo"; }; hw_rtc: rtc@52 {
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-vhip4-evalboard-v1.dts b/arch/arm64/boot/dts/freescale/imx8mn-vhip4-evalboard-v1.dts index a8f7c22..363f487 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn-vhip4-evalboard-v1.dts +++ b/arch/arm64/boot/dts/freescale/imx8mn-vhip4-evalboard-v1.dts
@@ -13,6 +13,11 @@ / { "ifm,imx8mn-vhip4", "fsl,imx8mn"; }; +&cfg_eeprom { + /* Shared with logging EEPROM on v1 hardware */ + wp-gpios = <&gpio5 20 GPIO_ACTIVE_HIGH>; +}; + &ifm_led { pinctrl-1 = <&pinctrl_gpio_led_v1>; @@ -91,6 +96,9 @@ temperature-sensor@48 { eeprom@50 { compatible = "atmel,24c128"; reg = <0x50>; + label = "ifm-logging"; + /* Shared with configuration EEPROM on v1 hardware */ + wp-gpios = <&gpio5 20 GPIO_ACTIVE_HIGH>; }; };
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-vhip4-evalboard-v2.dts b/arch/arm64/boot/dts/freescale/imx8mn-vhip4-evalboard-v2.dts index 43fd4d0..0fcffd1 100644 --- a/arch/arm64/boot/dts/freescale/imx8mn-vhip4-evalboard-v2.dts +++ b/arch/arm64/boot/dts/freescale/imx8mn-vhip4-evalboard-v2.dts
@@ -20,6 +20,12 @@ multi-led { }; }; +&cfg_eeprom { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_cfgeeprom>; + wp-gpios = <&gpio2 11 GPIO_ACTIVE_HIGH>; +}; + &ifm_led { pinctrl-1 = <&pinctrl_gpio_led_v2>; @@ -88,6 +94,10 @@ temperature-sensor@48 { eeprom@54 { compatible = "atmel,24c128"; reg = <0x54>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_logeeprom>; + label = "ifm-logging"; + wp-gpios = <&gpio5 3 GPIO_ACTIVE_HIGH>; }; }; @@ -103,6 +113,13 @@ &ifm_pmic { }; &iomuxc { + pinctrl_cfgeeprom: cfgeeprom-grp { + fsl,pins = < + /* CFG_EEPROM_WP */ + MX8MN_IOMUXC_SD1_STROBE_GPIO2_IO11 0x140 + >; + }; + pinctrl_ecspi1_cs: ecspi1-cs-grp { fsl,pins = < /* KS8794 nCS */ @@ -143,12 +160,8 @@ pinctrl_i2c1_gpio: i2c1-gpio-grp { fsl,pins = < MX8MN_IOMUXC_SD1_DATA4_GPIO2_IO6 0x56 MX8MN_IOMUXC_SD1_DATA5_GPIO2_IO7 0xd6 - /* CFG_EEPROM_WP */ - MX8MN_IOMUXC_SD1_STROBE_GPIO2_IO11 0x140 /* RTC_nIRQ */ MX8MN_IOMUXC_SPDIF_EXT_CLK_GPIO5_IO5 0x116 - /* LOG_EE_WP */ - MX8MN_IOMUXC_SPDIF_TX_GPIO5_IO3 0x140 >; }; @@ -166,6 +179,13 @@ MX8MN_IOMUXC_I2C3_SDA_GPIO5_IO19 0xd6 >; }; + pinctrl_logeeprom: logeeprom-grp { + fsl,pins = < + /* LOG_EE_WP */ + MX8MN_IOMUXC_SPDIF_TX_GPIO5_IO3 0x140 + >; + }; + pinctrl_mcp2518: mcp2518-grp { fsl,pins = < /* CAN0_CLKO */
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-vhip4-overlay-eeprom-1000.dtso b/arch/arm64/boot/dts/freescale/imx8mn-vhip4-overlay-eeprom-1000.dtso new file mode 100644 index 0000000..da3a40a --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mn-vhip4-overlay-eeprom-1000.dtso
@@ -0,0 +1,103 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +&cfg_eeprom { + cfg_eeprom_layout: nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + vhip-signature@0 { + reg = <0x0 0x4>; + }; + + vhip-version@4 { + reg = <0x4 0x4>; + }; + + vhip-size@8 { + reg = <0x8 0x4>; + }; + + device-serial@c { + reg = <0xc 0x10>; + }; + + order-number@1c { + reg = <0x1c 0x20>; + }; + + article-name@3c { + reg = <0x3c 0x20>; + }; + + article-rev@5c { + reg = <0x5c 0x4>; + }; + + hardware-rev@60 { + reg = <0x60 0x4>; + }; + + product-type@64 { + reg = <0x64 0x20>; + }; + + software-compatibility@84 { + reg = <0x84 0x4>; + }; + + manufacturing-date@88 { + reg = <0x88 0x20>; + }; + + production-order-number@a8 { + reg = <0xa8 0x20>; + }; + + /* Each MAC address is padded to 8 Bytes */ + cfg_eeprom_mac1: mac-address-1@c8 { + reg = <0xc8 0x8>; + }; + + cfg_eeprom_mac2: mac-address-2@d0 { + reg = <0xd0 0x8>; + }; + + cfg_eeprom_mac3: mac-address-3@d8 { + reg = <0xd8 0x8>; + }; + + cfg_eeprom_mac4: mac-address-4@e0 { + reg = <0xe0 0x8>; + }; + + cfg_eeprom_mac5: mac-address-5@e8 { + reg = <0xe8 0x8>; + }; + + cfg_eeprom_mac6: mac-address-6@f0 { + reg = <0xf0 0x8>; + }; + + cfg_eeprom_mac7: mac-address-7@f8 { + reg = <0xf8 0x8>; + }; + + cfg_eeprom_mac8: mac-address-8@100 { + reg = <0x100 0x8>; + }; + + next-block-offset@108 { + reg = <0x108 0x4>; + }; + + section-crc@10c { + reg = <0x10c 0x4>; + }; + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-vhip4-overlay-eeprom-1100.dtso b/arch/arm64/boot/dts/freescale/imx8mn-vhip4-overlay-eeprom-1100.dtso new file mode 100644 index 0000000..30df556 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mn-vhip4-overlay-eeprom-1100.dtso
@@ -0,0 +1,103 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +&cfg_eeprom { + cfg_eeprom_layout: nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + vhip-signature@0 { + reg = <0x0 0x4>; + }; + + vhip-version@4 { + reg = <0x4 0x4>; + }; + + vhip-size@8 { + reg = <0x8 0x4>; + }; + + device-serial@c { + reg = <0xc 0x10>; + }; + + order-number@1c { + reg = <0x1c 0x20>; + }; + + article-name@3c { + reg = <0x3c 0x40>; + }; + + article-rev@7c { + reg = <0x7c 0x4>; + }; + + hardware-rev@80 { + reg = <0x80 0x4>; + }; + + product-type@84 { + reg = <0x84 0x20>; + }; + + software-compatibility@a4 { + reg = <0xa4 0x4>; + }; + + manufacturing-date@a8 { + reg = <0xa8 0x20>; + }; + + production-order-number@c8 { + reg = <0xc8 0x20>; + }; + + /* Each MAC address is padded to 8 Bytes */ + cfg_eeprom_mac1: mac-address-1@e8 { + reg = <0xe8 0x8>; + }; + + cfg_eeprom_mac2: mac-address-2@f0 { + reg = <0xf0 0x8>; + }; + + cfg_eeprom_mac3: mac-address-3@f8 { + reg = <0xf8 0x8>; + }; + + cfg_eeprom_mac4: mac-address-4@100 { + reg = <0x100 0x8>; + }; + + cfg_eeprom_mac5: mac-address-5@108 { + reg = <0x108 0x8>; + }; + + cfg_eeprom_mac6: mac-address-6@110 { + reg = <0x110 0x8>; + }; + + cfg_eeprom_mac7: mac-address-7@118 { + reg = <0x118 0x8>; + }; + + cfg_eeprom_mac8: mac-address-8@120 { + reg = <0x120 0x8>; + }; + + next-block-offset@128 { + reg = <0x128 0x4>; + }; + + section-crc@12c { + reg = <0x12c 0x4>; + }; + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mn-vhip4-overlay-eeprom-2000.dtso b/arch/arm64/boot/dts/freescale/imx8mn-vhip4-overlay-eeprom-2000.dtso new file mode 100644 index 0000000..a2ca7ee8 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mn-vhip4-overlay-eeprom-2000.dtso
@@ -0,0 +1,107 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +&cfg_eeprom { + cfg_eeprom_layout: nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + vhip-signature@0 { + reg = <0x0 0x4>; + }; + + vhip-version@4 { + reg = <0x4 0x4>; + }; + + vhip-size@8 { + reg = <0x8 0x4>; + }; + + section-data-crc@c { + reg = <0xc 0x4>; + }; + + next-block-offset@10 { + reg = <0x10 0x4>; + }; + + section-header-crc@14 { + reg = <0x14 0x4>; + }; + + device-serial@18 { + reg = <0x18 0x10>; + }; + + order-number@28 { + reg = <0x28 0x20>; + }; + + article-name@48 { + reg = <0x48 0x40>; + }; + + article-rev@88 { + reg = <0x88 0x4>; + }; + + hardware-rev@8c { + reg = <0x8c 0x4>; + }; + + product-type@90 { + reg = <0x90 0x20>; + }; + + software-compatibility@b0 { + reg = <0xb0 0x4>; + }; + + manufacturing-date@b4 { + reg = <0xb4 0x20>; + }; + + production-order-number@d4 { + reg = <0xd4 0x20>; + }; + + /* Each MAC address is padded to 8 Bytes */ + cfg_eeprom_mac1: mac-address-1@f4 { + reg = <0xf4 0x8>; + }; + + cfg_eeprom_mac2: mac-address-2@fc { + reg = <0xfc 0x8>; + }; + + cfg_eeprom_mac3: mac-address-3@104 { + reg = <0x104 0x8>; + }; + + cfg_eeprom_mac4: mac-address-4@10c { + reg = <0x10c 0x8>; + }; + + cfg_eeprom_mac5: mac-address-5@114 { + reg = <0x114 0x8>; + }; + + cfg_eeprom_mac6: mac-address-6@11c { + reg = <0x11c 0x8>; + }; + + cfg_eeprom_mac7: mac-address-7@124 { + reg = <0x124 0x8>; + }; + + cfg_eeprom_mac8: mac-address-8@12c { + reg = <0x12c 0x8>; + }; + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-cm7.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-cm7.dtso new file mode 100644 index 0000000..11d3427 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-cm7.dtso
@@ -0,0 +1,57 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2023-2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +#include <dt-bindings/clock/imx8mp-clock.h> + +&{/} { + #address-cells = <2>; + #size-cells = <2>; + + reserved-memory { /* CM7 reserved memory */ + #address-cells = <2>; + #size-cells = <2>; + ranges; + + m_core_reserved: m_core@54000000 { + reg = <0 0x54000000 0 0x1000000>; + no-map; + }; + + vdev0vring0: vdev0vring0@55000000 { + reg = <0 0x55000000 0 0x8000>; + no-map; + }; + + vdev0vring1: vdev0vring1@55008000 { + reg = <0 0x55008000 0 0x8000>; + no-map; + }; + + rsc_table: rsc-table@550ff000 { + reg = <0 0x550ff000 0 0x1000>; + no-map; + }; + + vdev0buffer: vdev0buffer@55400000 { + compatible = "shared-dma-pool"; + reg = <0 0x55400000 0 0x100000>; + no-map; + }; + }; + + imx8mp-cm7 { + compatible = "fsl,imx8mp-cm7-mmio"; + clocks = <&clk IMX8MP_CLK_M7_CORE>; + fsl,iomuxc-gpr = <&gpr>; + mbox-names = "tx", "rx", "rxdb"; + mboxes = <&mu 0 1 + &mu 1 1 + &mu 3 1>; + memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, <&rsc_table>; + syscon = <&src>; + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtso new file mode 100644 index 0000000..4e21123 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtso
@@ -0,0 +1,67 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2024-2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +#include <dt-bindings/clock/imx8mp-clock.h> + +#include "imx8mp-pinfunc.h" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1-audio.dtsi" + +&can_fio { + interrupts-extended = <&gpio2 10 IRQ_TYPE_LEVEL_LOW>; +}; + +&gpio_feature { + interrupt-parent = <&gpio1>; + interrupts = <8 IRQ_TYPE_LEVEL_LOW>; +}; + +&iomuxc { + pinctrl_codec_mclk: codec-mclk_feature-grp { + fsl,pins = < + MX8MP_IOMUXC_SAI2_MCLK__AUDIOMIX_SAI5_MCLK 0xd6 + >; + }; + + sai2-grp { + fsl,pins = < + MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_SAI2_TX_SYNC 0xd6 + MX8MP_IOMUXC_SAI2_TXD0__AUDIOMIX_SAI2_TX_DATA00 0xd6 + MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_SAI2_TX_BCLK 0xd6 + MX8MP_IOMUXC_SAI2_RXD0__AUDIOMIX_SAI2_RX_DATA00 0xd6 + >; + }; + + uart1-grp { + fsl,pins = < + MX8MP_IOMUXC_SD1_CLK__UART1_DCE_TX 0x49 + MX8MP_IOMUXC_SD1_CMD__UART1_DCE_RX 0x49 + MX8MP_IOMUXC_SD1_DATA1__UART1_DCE_CTS 0x49 + >; + }; +}; + +&sai2 { + assigned-clocks = <&clk IMX8MP_CLK_SAI2>; + assigned-clock-parents = <&clk IMX8MP_AUDIO_PLL2_OUT>; +}; + +&spba5 { + #address-cells = <1>; + #size-cells = <1>; + + sai5clk: clock-controller@30c50000 { + compatible = "fsl,imx8mp-sai-clock", "fsl,imx8mq-sai-clock"; + reg = <0x30c50000 0x10000>; + #clock-cells = <1>; + clocks = <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_SAI5_IPG>, + <&audio_blk_ctrl IMX8MP_CLK_AUDIOMIX_SAI5_MCLK1>; + clock-names = "bus", "mclk1"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_codec_mclk>; + status = "okay"; + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtso new file mode 100644 index 0000000..0eccb7f --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtso
@@ -0,0 +1,46 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2022-2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +#include "imx8mp-pinfunc.h" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-fio1.dtsi" + +&can_fio { + interrupts-extended = <&gpio2 10 IRQ_TYPE_LEVEL_LOW>; +}; + +&iomuxc { + pinctrl_can: can-feature-grp { + fsl,pins = < + /* CAN_INT# */ + MX8MP_IOMUXC_SD1_RESET_B__GPIO2_IO10 0x400000d6 + >; + }; + + pinctrl_gpio_expander: gpio-expander-feature-grp { + fsl,pins = < + /* GPIO4_IO27 */ + MX8MP_IOMUXC_SAI2_MCLK__GPIO4_IO27 0x6 + >; + }; +}; + +&pinctrl_sai2 { + fsl,pins = < + MX8MP_IOMUXC_SAI2_TXFS__AUDIOMIX_SAI2_TX_SYNC 0xd6 + MX8MP_IOMUXC_SAI2_TXD0__AUDIOMIX_SAI2_TX_DATA00 0xd6 + MX8MP_IOMUXC_SAI2_TXC__AUDIOMIX_SAI2_TX_BCLK 0xd6 + >; +}; + +&pinctrl_hog_feature { + fsl,pins = < + /* GPIO5_IO03 */ + MX8MP_IOMUXC_GPIO1_IO07__GPIO1_IO07 0x40000006 + /* GPIO5_IO04 */ + MX8MP_IOMUXC_GPIO1_IO08__GPIO1_IO08 0x40000006 + >; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtso new file mode 100644 index 0000000..d8114fd --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtso
@@ -0,0 +1,17 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2022-2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-hdmi.dtsi" + +<9611_codec { + interrupts-extended = <&gpio4 19 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&gpio4 0 GPIO_ACTIVE_HIGH>; +}; + +&lcdif1 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtso new file mode 100644 index 0000000..6b6b160 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtso
@@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2022-2026 Marek Vasut + */ + +#include "imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g070y2-l01.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtso new file mode 100644 index 0000000..549ea2a --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtso
@@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2023-2026 Marek Vasut + */ + +#include "imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g101ice-l01.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtso new file mode 100644 index 0000000..c8c4328 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtso
@@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2024-2026 Marek Vasut + */ + +#include "imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g121xce-l01.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtso new file mode 100644 index 0000000..bf5b41a --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtso
@@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2023-2026 Marek Vasut + */ + +#include "imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g156hce-l01.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtso new file mode 100644 index 0000000..faf2c06 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtso
@@ -0,0 +1,11 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2022-2026 Marek Vasut + */ + +#include "imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-g215hvn011.dtsi" + +&backlight { + power-supply = <®_panel_bl_supply>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtso new file mode 100644 index 0000000..359a8b1 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtso
@@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2024-2026 Marek Vasut + */ + +#include "imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi0700a2t-30.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtso new file mode 100644 index 0000000..525cedb --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtso
@@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2024-2026 Marek Vasut + */ + +#include "imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-mi1010z1t-1cp11.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi new file mode 100644 index 0000000..6c346ba --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds.dtsi
@@ -0,0 +1,35 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2022-2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-common.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-lvds-common.dtsi" + +&{/} { + reg_panel_bl_supply: regulator-panel-bl-supply { + compatible = "regulator-fixed"; + regulator-name = "BKLT0"; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; +}; + +&lcdif1 { + status = "okay"; +}; + +<9211_codec { + interrupts-extended = <&gpio4 19 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&gpio4 0 GPIO_ACTIVE_HIGH>; +}; + +®_panel_bl { + vin-supply = <®_panel_bl_supply>; +}; + +®_panel_vcc { + enable-gpios = <&gpio3 6 0>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g070y2-l01.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g070y2-l01.dtso new file mode 100644 index 0000000..7a41262 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g070y2-l01.dtso
@@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2023-2026 Marek Vasut + */ + +#include "imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-g070y2-l01.dtsi" + +&media_blk_ctrl { + /* + * The G070Y2-L01 panel requires 29.5 MHz LVDS clock. + * Set IMX8MP_VIDEO_PLL1 to 206.5 MHz , since 206.5 MHz / 7 = 29.5 MHz . + */ + assigned-clock-rates = <500000000>, <200000000>, + <0>, <0>, <500000000>, <206500000>; +}; + +&ldb_lvds_ch1 { + remote-endpoint = <&panel_lvds>; +}; + +&panel_lvds { + remote-endpoint = <&ldb_lvds_ch1>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g101ice-l01.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g101ice-l01.dtso new file mode 100644 index 0000000..817d4ec --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g101ice-l01.dtso
@@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2023-2026 Marek Vasut + */ + +#include "imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-g101ice-l01.dtsi" + +&media_blk_ctrl { + /* + * The G101ICE-L01 panel requires 71.1 MHz LVDS clock. + * Set IMX8MP_VIDEO_PLL1 to 497.7 MHz , since 497.7 MHz / 7 = 71.1 MHz . + */ + assigned-clock-rates = <500000000>, <200000000>, + <0>, <0>, <500000000>, <497700000>; +}; + +&ldb_lvds_ch1 { + remote-endpoint = <&panel_lvds>; +}; + +&panel_lvds { + remote-endpoint = <&ldb_lvds_ch1>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g121xce-l01.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g121xce-l01.dtso new file mode 100644 index 0000000..729f477 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g121xce-l01.dtso
@@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2024 Wael Karman <wkarman@data-modul.com> + */ + +#include "imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-g121xce-l01.dtsi" + +&media_blk_ctrl { + /* + * The G121XCE-L01 panel requires 64.9 MHz LVDS clock. + * Set IMX8MP_VIDEO_PLL1 to 454.3 MHz , since 454.3 MHz / 7 = 64.9 MHz . + */ + assigned-clock-rates = <500000000>, <200000000>, + <0>, <0>, <500000000>, <454300000>; +}; + +&ldb_lvds_ch1 { + remote-endpoint = <&panel_lvds>; +}; + +&panel_lvds { + remote-endpoint = <&ldb_lvds_ch1>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g156hce-l01.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g156hce-l01.dtso new file mode 100644 index 0000000..86163d6 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g156hce-l01.dtso
@@ -0,0 +1,32 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2023-2026 Marek Vasut + */ + +#include "imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-g156hce-l01.dtsi" + +&media_blk_ctrl { + /* + * The G156HCE-L01 panel requires 141.86 MHz LVDS clock. + * Set IMX8MP_VIDEO_PLL1 to 993.2 MHz , since 993.2 MHz / 7 = 141.86 MHz . + */ + assigned-clock-rates = <500000000>, <200000000>, + <0>, <0>, <500000000>, <993020000>; +}; + +&ldb_lvds_ch0 { + remote-endpoint = <&panel_lvds_b>; +}; + +&ldb_lvds_ch1 { + remote-endpoint = <&panel_lvds_a>; +}; + +&panel_lvds_a { + remote-endpoint = <&ldb_lvds_ch1>; +}; + +&panel_lvds_b { + remote-endpoint = <&ldb_lvds_ch0>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g215hvn011.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g215hvn011.dtso new file mode 100644 index 0000000..a6d13c3 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-g215hvn011.dtso
@@ -0,0 +1,36 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2023-2026 Marek Vasut + */ + +#include "imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-g215hvn011.dtsi" + +&backlight { + power-supply = <®_panel_bl_supply>; +}; + +&media_blk_ctrl { + /* + * The G215HVN01 panel requires 148.8 MHz LVDS clock. + * Set IMX8MP_VIDEO_PLL1 to 1041.6 MHz , since 1041.6 MHz / 7 = 148.8 MHz . + */ + assigned-clock-rates = <500000000>, <200000000>, + <0>, <0>, <500000000>, <1041600000>; +}; + +&ldb_lvds_ch0 { + remote-endpoint = <&panel_lvds_b>; +}; + +&ldb_lvds_ch1 { + remote-endpoint = <&panel_lvds_a>; +}; + +&panel_lvds_a { + remote-endpoint = <&ldb_lvds_ch1>; +}; + +&panel_lvds_b { + remote-endpoint = <&ldb_lvds_ch0>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-mi0700a2t-30.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-mi0700a2t-30.dtso new file mode 100644 index 0000000..76bfbd3 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-mi0700a2t-30.dtso
@@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2024-2026 Marek Vasut + */ + +#include "imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-mi0700a2t-30.dtsi" + +&media_blk_ctrl { + /* + * The MI0700A2T-30 panel requires 33 MHz LVDS clock. + * Set IMX8MP_VIDEO_PLL1 to 231 MHz , since 231 MHz / 7 = 33 MHz . + */ + assigned-clock-rates = <500000000>, <200000000>, + <0>, <0>, <500000000>, <231000000>; +}; + +&ldb_lvds_ch1 { + remote-endpoint = <&panel_lvds>; +}; + +&panel_lvds { + remote-endpoint = <&ldb_lvds_ch1>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-mi1010z1t-1cp11.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-mi1010z1t-1cp11.dtso new file mode 100644 index 0000000..4066bac2 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-mi1010z1t-1cp11.dtso
@@ -0,0 +1,24 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2024-2026 Marek Vasut + */ + +#include "imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds.dtsi" +#include "imx8mm-data-modul-edm-sbc-overlay-lvds-mi1010z1t-1cp11.dtsi" + +&media_blk_ctrl { + /* + * The MI1010Z1T-1CP11 panel requires 51.2 MHz LVDS clock. + * Set IMX8MP_VIDEO_PLL1 to 358.4 MHz , since 358.4 MHz / 7 = 51.2 MHz . + */ + assigned-clock-rates = <500000000>, <200000000>, + <0>, <0>, <500000000>, <358400000>; +}; + +&ldb_lvds_ch1 { + remote-endpoint = <&panel_lvds>; +}; + +&panel_lvds { + remote-endpoint = <&ldb_lvds_ch1>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-rev900.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-rev900.dtso new file mode 100644 index 0000000..427585b --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-rev900.dtso
@@ -0,0 +1,41 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2023-2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +&{/} { + reg_panel_vcc_raw: regulator-panel-vcc-raw { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_panel_vcc_reg>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-name = "PANEL_VCC"; + }; +}; + +&panel { + power-supply = <®_panel_vcc_raw>; +}; + +®_backlight_en_level { + status = "disabled"; +}; + +®_backlight_pwm_level { + status = "disabled"; +}; + +®_panel_bl_supply { + status = "disabled"; +}; + +®_panel_bl { + gpio = <&gpio3 0 0>; +}; + +®_panel_vcc { + status = "disabled"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-rev902.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-rev902.dtso new file mode 100644 index 0000000..a21fea2 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds-rev902.dtso
@@ -0,0 +1,14 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2023-2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +®_panel_bl { + gpio = <&gpio3 0 0>; +}; + +®_panel_vcc { + enable-gpios = <&gpio3 6 0>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds.dtsi new file mode 100644 index 0000000..95f4761 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-lvds.dtsi
@@ -0,0 +1,79 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2023-2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +#include "imx8mm-data-modul-edm-sbc-overlay-edm-mod-imx8mm-common.dtsi" + +&{/} { + reg_panel_bl_supply: regulator-panel-bl-supply { + compatible = "regulator-gpio"; + regulator-type = "voltage"; + regulator-name = "PANEL_BL_SUPPLY"; + enable-gpios = <&gpiolvds 0 0>; + enable-active-high; + status = "okay"; + + /* + * MP2328 voltage divider settings: + * R1=51k1 + * R2=5k62 with optional series Rs=2k21 (12V) + * + * 1 / Rx = (1 / R2) [ + (1 / Rs)][ + (1 / Rt)] + * Vout = 0.5 + ((R1 / Rx) * 0.5) + */ + gpios = <&gpiolvds 1 GPIO_ACTIVE_HIGH>; /* 12V */ + states = <5000000 0x0>, + <12000000 0x1>; + + /* Default setting: lowest supported voltage. */ + gpios-states = <1>; /* Default GPIO state is HIGH, so 12V0 out */ + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; +}; + +&lcdif2 { + status = "okay"; +}; + +&lvds_bridge { + status = "okay"; +}; + +&pwm1 { + status = "okay"; +}; + +®_backlight_en_level { + gpios = <&gpiolvds 5 GPIO_ACTIVE_HIGH>; /* SEL_EN */ +}; + +®_backlight_pwm_level { + gpios = <&gpiolvds 4 GPIO_ACTIVE_HIGH>; /* SEL_PWM */ +}; + +®_panel_bl { + gpio = <&gpiowifi 0 0>; + vin-supply = <®_panel_bl_supply>; +}; + +®_panel_vcc { + enable-gpios = <&gpiowifi 4 0>; + /* + * MP2328 voltage divider settings: + * R1=51k1 + * R2=9k09 with optional series Rs=14k7 (5V) or Rt=2k94 (12V) + * + * 1 / Rx = (1 / R2) [ + (1 / Rs)][ + (1 / Rt)] + * Vout = 0.5 + ((R1 / Rx) * 0.5) + */ + gpios = <&gpiolvds 2 GPIO_ACTIVE_HIGH>, /* 5V */ + <&gpiolvds 3 GPIO_ACTIVE_HIGH>; /* 12V */ + states = <3300000 0x0>, + <5000000 0x1>, + <12000000 0x2>, + <14000000 0x3>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-rev900.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-rev900.dtso new file mode 100644 index 0000000..ec861aa --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-rev900.dtso
@@ -0,0 +1,97 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2023-2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +#include "imx8mp-pinfunc.h" + +&eeprom900 { + status = "okay"; +}; + +&eeprom902 { + status = "disabled"; +}; + +&eqos { /* First ethernet */ + phy-handle = <&phy_eqos_ath>; +}; + +&fec { /* Second ethernet */ + /* pinctrl_wifi is ENET2_INT# */ + pinctrl-0 = <&pinctrl_fec &pinctrl_wifi>; + phy-handle = <&phy_fec_ath>; +}; + +&gpiolvds { + status = "disabled"; +}; + +/* + * External pull ups on R242 and R243 on I2C2_SCL_3V3 and I2C2_SDA_3V3 + * are not populated on this early board revision, activate in-SoC pull + * up resistors instead to work around the missing external pull ups. + */ +&pinctrl_i2c2 { + fsl,pins = < + MX8MP_IOMUXC_I2C2_SCL__I2C2_SCL 0x400001c4 + MX8MP_IOMUXC_I2C2_SDA__I2C2_SDA 0x400001c4 + >; +}; + +&pinctrl_i2c2_gpio { + fsl,pins = < + MX8MP_IOMUXC_I2C2_SCL__GPIO5_IO16 0x1c4 + MX8MP_IOMUXC_I2C2_SDA__GPIO5_IO17 0x1c4 + >; +}; + +&pcie_phy { + status = "disabled"; +}; + +&pcie { + status = "disabled"; +}; + +&phy_eqos_ath { + /* + * The software support for combination of EEE capable PHY and EEE + * capable MAC is so far missing from the Linux kernel. By default, + * the AR8035 PHY does enable EEE functionality on the PHY side, + * while the EQoS/DWMAC MAC expects to handle the EEE functionality + * on the MAC side. Because the Linux kernel is currently unable to + * align EEE configuration of the PHY and MAC, enabling EEE leads + * to unreliable link. Disable EEE until the kernel support is in + * place. + */ + eee-broken-100tx; + eee-broken-1000t; + status = "okay"; +}; + +&phy_eqos_bcm { + status = "disabled"; +}; + +&phy_fec_ath { + status = "okay"; +}; + +&phy_fec_bcm { + status = "disabled"; +}; + +®_pcie0 { + status = "disabled"; +}; + +&tpm { + status = "disabled"; +}; + +&uart4 { + status = "disabled"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-rev902.dtso b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-rev902.dtso new file mode 100644 index 0000000..0141b5d --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc-overlay-edm-sbc-imx8mp-rev902.dtso
@@ -0,0 +1,69 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (C) 2024-2026 Marek Vasut + */ +/dts-v1/; +/plugin/; + +#include "imx8mp-pinfunc.h" + +&pinctrl_hog_misc { + fsl,pins = < + /* ENET_WOL# -- shared by both PHYs */ + MX8MP_IOMUXC_GPIO1_IO10__GPIO1_IO10 0x40000090 + + /* PG_V_IN_VAR# */ + MX8MP_IOMUXC_NAND_CE0_B__GPIO3_IO01 0x40000000 + /* CSI2_PD_1V8 */ + MX8MP_IOMUXC_NAND_DATA02__GPIO3_IO08 0x0 + /* CSI2_RESET_1V8# */ + MX8MP_IOMUXC_NAND_DATA03__GPIO3_IO09 0x0 + + /* DIS_USB_DN1 */ + MX8MP_IOMUXC_SAI2_RXFS__GPIO4_IO21 0x0 + /* DIS_USB_DN2 */ + MX8MP_IOMUXC_SAI2_RXC__GPIO4_IO22 0x0 + + /* EEPROM_WP_1V8# */ + MX8MP_IOMUXC_NAND_DQS__GPIO3_IO14 0x100 + /* PCIE_CLK_GEN_CLKPWRGD_PD_1V8# */ + MX8MP_IOMUXC_SAI5_RXD0__GPIO3_IO21 0x0 + /* GRAPHICS_PRSNT_1V8# */ + MX8MP_IOMUXC_SAI1_TXD6__GPIO4_IO18 0x40000000 + + /* CLK_CCM_CLKO1_3V3 */ + MX8MP_IOMUXC_GPIO1_IO14__CCM_CLKO1 0x10 + >; +}; + +&pinctrl_pcie0 { + fsl,pins = < + /* M2_PCIE_RST# */ + MX8MP_IOMUXC_GPIO1_IO05__GPIO1_IO05 0x2 + /* M2_W_DISABLE1_1V8# */ + MX8MP_IOMUXC_SAI5_RXD2__GPIO3_IO23 0x2 + /* M2_W_DISABLE2_1V8# */ + MX8MP_IOMUXC_SAI5_RXD3__GPIO3_IO24 0x2 + /* CLK_M2_32K768 */ + MX8MP_IOMUXC_GPIO1_IO00__CCM_EXT_CLK1 0x14 + /* M2_PCIE_WAKE# */ + MX8MP_IOMUXC_GPIO1_IO06__GPIO1_IO06 0x40000140 + /* M2_PCIE_CLKREQ# */ + MX8MP_IOMUXC_I2C4_SCL__PCIE_CLKREQ_B 0x61 + >; +}; + +&pinctrl_uart4 { + fsl,pins = < + MX8MP_IOMUXC_UART4_RXD__UART4_DCE_RX 0x49 + MX8MP_IOMUXC_UART4_TXD__UART4_DCE_TX 0x49 + >; +}; + +&gpiowifi { + status = "disabled"; +}; + +&uart4 { + status = "disabled"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts index cb28cf1..4614a0d 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-data-modul-edm-sbc.dts
@@ -30,11 +30,8 @@ memory@40000000 { backlight: backlight { compatible = "pwm-backlight"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_panel_backlight>; brightness-levels = <0 1 10 20 30 40 50 60 70 75 80 90 100>; default-brightness-level = <7>; - enable-gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>; pwms = <&pwm1 0 5000000 0>; /* Disabled by default, unless display board plugged in. */ status = "disabled"; @@ -86,9 +83,6 @@ reg_panel_vcc: regulator-panel-vcc { regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; regulator-name = "PANEL_VCC"; - /* GPIO flags are ignored, enable-active-high applies. */ - gpio = <&gpio3 6 GPIO_ACTIVE_HIGH>; - enable-active-high; /* Disabled by default, unless display board plugged in. */ status = "disabled"; }; @@ -116,7 +110,7 @@ reg_usdhc2_vmmc: regulator-usdhc2-vmmc { enable-active-high; off-on-delay-us = <12000>; startup-delay-us = <100>; - vin-supply = <&buck4>; + vin-supply = <&buck4_reg>; }; sound { @@ -152,19 +146,19 @@ watchdog { /* TPS3813 */ }; &A53_0 { - cpu-supply = <&buck2>; + cpu-supply = <&buck2_reg>; }; &A53_1 { - cpu-supply = <&buck2>; + cpu-supply = <&buck2_reg>; }; &A53_2 { - cpu-supply = <&buck2>; + cpu-supply = <&buck2_reg>; }; &A53_3 { - cpu-supply = <&buck2>; + cpu-supply = <&buck2_reg>; }; &ecspi1 { @@ -405,8 +399,8 @@ sgtl5000: audio-codec@a { reg = <0x0a>; #sound-dai-cells = <0>; clocks = <&clk_pwm4>; - VDDA-supply = <&buck4>; - VDDIO-supply = <&buck4>; + VDDA-supply = <&buck4_reg>; + VDDIO-supply = <&buck4_reg>; }; usb-hub@2c { @@ -427,14 +421,142 @@ tpm: tpm@2e { eeprom900: eeprom@50 { /* board rev.900 */ compatible = "atmel,24c32"; reg = <0x50>; + label = "dmo-board-info"; pagesize = <32>; + wp-gpios = <&gpio3 14 GPIO_ACTIVE_LOW>; status = "disabled"; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + company-name@24 { + reg = <0x24 0xd>; + }; + + product-name@32 { + reg = <0x32 0x18>; + }; + + board-revision@4b { + reg = <0x4b 0x3>; + }; + + serial-number@4f { + reg = <0x4f 0x8>; + }; + + manufacturing-date@70 { + reg = <0x70 0xa>; + }; + + test-date@7b { + reg = <0x7b 0xa>; + }; + + product-number@86 { + reg = <0x86 0x8>; + }; + + board-variant@9a { + reg = <0x9a 0x9>; + }; + + company-acronym@a4 { + reg = <0xa4 0x3>; + }; + + eeprom900mac: mac-address@b0 { + reg = <0xb0 0x6>; + }; + + board-id@100 { + reg = <0x100 0x4>; + }; + + wifi-id@120 { + reg = <0x120 0x4>; + }; + + board-lvds-id@140 { + reg = <0x140 0x4>; + }; + + camera-id@160 { + reg = <0x160 0x4>; + }; + }; }; eeprom902: eeprom@51 { /* board rev.902 */ compatible = "atmel,24c32"; reg = <0x51>; + label = "dmo-board-info"; pagesize = <32>; + wp-gpios = <&gpio3 14 GPIO_ACTIVE_LOW>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + company-name@24 { + reg = <0x24 0xd>; + }; + + product-name@32 { + reg = <0x32 0x18>; + }; + + board-revision@4b { + reg = <0x4b 0x3>; + }; + + serial-number@4f { + reg = <0x4f 0x8>; + }; + + manufacturing-date@70 { + reg = <0x70 0xa>; + }; + + test-date@7b { + reg = <0x7b 0xa>; + }; + + product-number@86 { + reg = <0x86 0x8>; + }; + + board-variant@9a { + reg = <0x9a 0x9>; + }; + + company-acronym@a4 { + reg = <0xa4 0x3>; + }; + + eeprom902mac: mac-address@b0 { + reg = <0xb0 0x6>; + }; + + board-id@100 { + reg = <0x100 0x4>; + }; + + wifi-id@120 { + reg = <0x120 0x4>; + }; + + board-lvds-id@140 { + reg = <0x140 0x4>; + }; + + camera-id@160 { + reg = <0x160 0x4>; + }; + }; }; rtc: rtc@68 { @@ -454,7 +576,9 @@ pcieclk: clk@6a { }; }; -&i2c2 { +i2c_display: &i2c2 { }; + +i2c_feature: &i2c2 { clock-frequency = <100000>; pinctrl-names = "default", "gpio"; pinctrl-0 = <&pinctrl_i2c2>; @@ -527,7 +651,7 @@ pmic: pmic@25 { * MIMX8ML8CVNKZAB */ regulators { - buck1: BUCK1 { /* VDD_SOC (dual-phase with BUCK3) */ + buck1_reg: BUCK1 { /* VDD_SOC (dual-phase with BUCK3) */ regulator-min-microvolt = <850000>; regulator-max-microvolt = <1000000>; regulator-ramp-delay = <3125>; @@ -535,7 +659,7 @@ buck1: BUCK1 { /* VDD_SOC (dual-phase with BUCK3) */ regulator-boot-on; }; - buck2: BUCK2 { /* VDD_ARM */ + buck2_reg: BUCK2 { /* VDD_ARM */ nxp,dvs-run-voltage = <950000>; nxp,dvs-standby-voltage = <850000>; regulator-min-microvolt = <850000>; @@ -545,47 +669,47 @@ buck2: BUCK2 { /* VDD_ARM */ regulator-boot-on; }; - buck4: BUCK4 { /* VDD_3V3 */ + buck4_reg: BUCK4 { /* VDD_3V3 */ regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; regulator-always-on; regulator-boot-on; }; - buck5: BUCK5 { /* VDD_1V8 */ + buck5_reg: BUCK5 { /* VDD_1V8 */ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-always-on; regulator-boot-on; }; - buck6: BUCK6 { /* NVCC_DRAM_1V1 */ + buck6_reg: BUCK6 { /* NVCC_DRAM_1V1 */ regulator-min-microvolt = <1100000>; regulator-max-microvolt = <1100000>; regulator-always-on; regulator-boot-on; }; - ldo1: LDO1 { /* NVCC_SNVS_1V8 */ + ldo1_reg: LDO1 { /* NVCC_SNVS_1V8 */ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-always-on; regulator-boot-on; }; - ldo3: LDO3 { /* VDDA_1V8 */ + ldo3_reg: LDO3 { /* VDDA_1V8 */ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; regulator-always-on; regulator-boot-on; }; - ldo4: LDO4 { /* PMIC_LDO4 */ + ldo4_reg: LDO4 { /* PMIC_LDO4 */ regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; }; - ldo5: LDO5 { /* NVCC_SD2 */ + ldo5_reg: LDO5 { /* NVCC_SD2 */ regulator-min-microvolt = <1800000>; regulator-max-microvolt = <3300000>; }; @@ -650,7 +774,7 @@ &usdhc2 { pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; vmmc-supply = <®_usdhc2_vmmc>; - vqmmc-supply = <&ldo5>; + vqmmc-supply = <&ldo5_reg>; bus-width = <4>; status = "okay"; }; @@ -661,8 +785,8 @@ &usdhc3 { pinctrl-0 = <&pinctrl_usdhc3>; pinctrl-1 = <&pinctrl_usdhc3_100mhz>; pinctrl-2 = <&pinctrl_usdhc3_200mhz>; - vmmc-supply = <&buck4>; - vqmmc-supply = <&buck5>; + vmmc-supply = <&buck4_reg>; + vqmmc-supply = <&buck5_reg>; bus-width = <8>; no-sd; no-sdio;
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dts b/arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dts index a02b31c..299d81a 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp-edimm2.2.dts
@@ -101,7 +101,7 @@ &usb_dwc3_1 { &usdhc2 { cd-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; bus-width = <4>; - pinctrl-names = "default" ; + pinctrl-names = "default"; pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; vmmc-supply = <®_usdhc2_vmmc>; status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp.dtsi index 69558ff..affcc20 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-icore-mx8mp.dtsi
@@ -49,7 +49,7 @@ buck1: BUCK1 { regulator-ramp-delay = <3125>; }; - buck2: BUCK2 { + buck2: BUCK2 { nxp,dvs-run-voltage = <950000>; nxp,dvs-standby-voltage = <850000>; regulator-always-on;
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-kontron-dl.dtso b/arch/arm64/boot/dts/freescale/imx8mp-kontron-dl.dtso index 41a2bb7..88b30ca 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-kontron-dl.dtso +++ b/arch/arm64/boot/dts/freescale/imx8mp-kontron-dl.dtso
@@ -6,6 +6,7 @@ /dts-v1/; /plugin/; +#include <dt-bindings/clock/imx8mp-clock.h> #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/irq.h> #include "imx8mp-pinfunc.h" @@ -99,6 +100,16 @@ &ldb_lvds_ch0 { &lvds_bridge { status = "okay"; + /* + * The video PLL clock frequency needs to be configured manually. + * The panel needs a LVDS clock of 50 MHz * 7 = 350 MHz. + * IMX8MP_CLK_MEDIA_LDB = IMX8MP_CLK_MEDIA_DISP2_PIX * 7 + * IMX8MP_VIDEO_PLL1 = IMX8MP_CLK_MEDIA_LDB * 2 + */ + assigned-clocks = <&clk IMX8MP_CLK_MEDIA_LDB>, + <&clk IMX8MP_VIDEO_PLL1>; + assigned-clock-parents = <&clk IMX8MP_VIDEO_PLL1_OUT>; + assigned-clock-rates = <0>, <700000000>; }; /* redefine to remove touch controller GPIOs */
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10.dtsi index bb740f8..8957b24 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-av-10.dtsi
@@ -77,13 +77,12 @@ sound { "MIC3R", "Microphone Jack", "Microphone Jack", "Mic Bias"; - simple-audio-card,cpu { + dailink_master: simple-audio-card,cpu { sound-dai = <&sai2>; }; - dailink_master: simple-audio-card,codec { + simple-audio-card,codec { sound-dai = <&codec>; - clocks = <&clk IMX8MP_CLK_SAI2>; }; }; };
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-wlbt-07.dtso b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-wlbt-07.dtso new file mode 100644 index 0000000..008b6f9 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx8mp-phyboard-pollux-peb-wlbt-07.dtso
@@ -0,0 +1,76 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* +* Copyright (C) 2026 PHYTEC Messtechnik GmbH +*/ + +#include <dt-bindings/clock/imx8mp-clock.h> +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include "imx8mp-pinfunc.h" + +/dts-v1/; +/plugin/; + +&{/} { + usdhc1_pwrseq: pwr-seq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&gpio2 7 GPIO_ACTIVE_LOW>; + }; +}; + +&iomuxc { + pinctrl_uart3: uart3grp { + fsl,pins = < + MX8MP_IOMUXC_SD1_RESET_B__UART3_DCE_RTS 0x140 /* RTS */ + MX8MP_IOMUXC_SD1_STROBE__UART3_DCE_CTS 0x140 /* CTS */ + MX8MP_IOMUXC_UART3_RXD__UART3_DCE_RX 0x140 /* RX */ + MX8MP_IOMUXC_UART3_TXD__UART3_DCE_TX 0x140 /* TX */ + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX8MP_IOMUXC_SD1_CLK__USDHC1_CLK 0x190 /* SDIO_CLK */ + MX8MP_IOMUXC_SD1_CMD__USDHC1_CMD 0x1d0 /* SDIO_CMD */ + MX8MP_IOMUXC_SD1_DATA0__USDHC1_DATA0 0x1d0 /* SDIO_D0 */ + MX8MP_IOMUXC_SD1_DATA1__USDHC1_DATA1 0x1d0 /* SDIO_D1 */ + MX8MP_IOMUXC_SD1_DATA2__USDHC1_DATA2 0x1d0 /* SDIO_D2 */ + MX8MP_IOMUXC_SD1_DATA3__USDHC1_DATA3 0x1d0 /* SDIO_D3 */ + >; + }; + + pinctrl_wlbt: wlbtgrp { + fsl,pins = < + MX8MP_IOMUXC_SPDIF_EXT_CLK__GPIO5_IO05 0x106 /* WAKE_DEV */ + MX8MP_IOMUXC_SD1_DATA5__GPIO2_IO07 0x106 /* PDn */ + MX8MP_IOMUXC_SD1_DATA7__GPIO2_IO09 0x106 /* WAKE_HOST */ + >; + }; +}; + +&uart3 { + assigned-clocks = <&clk IMX8MP_CLK_UART3>; + assigned-clock-parents = <&clk IMX8MP_SYS_PLL1_80M>; + pinctrl-0 = <&pinctrl_uart3>; + pinctrl-names = "default"; + uart-has-rtscts; + status = "okay"; + + bluetooth { + compatible = "nxp,88w8987-bt"; + vcc-supply = <®_vcc_3v3_sw>; + }; +}; + +&usdhc1 { + bus-width = <4>; + keep-power-in-suspend; + max-frequency = <50000000>; + mmc-pwrseq = <&usdhc1_pwrseq>; + non-removable; + pinctrl-0 = <&pinctrl_usdhc1>, <&pinctrl_wlbt>; + pinctrl-names = "default"; + vmmc-supply = <®_vcc_3v3_sw>; + wakeup-source; + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-toradex-smarc.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-toradex-smarc.dtsi index 0348da3..eb8b9db 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-toradex-smarc.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-toradex-smarc.dtsi
@@ -323,7 +323,7 @@ &gpio3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lvds_dsi_sel>; gpio-line-names = "ETH_0_INT#", /* 0 */ - "SLEEP#", + "SMARC_SLEEP#", "", "", "",
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpqs-mb-smarc-2-lvds0-tm070jvhg33.dtso b/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpqs-mb-smarc-2-lvds0-tm070jvhg33.dtso index 2cf1de8..9ce0744 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpqs-mb-smarc-2-lvds0-tm070jvhg33.dtso +++ b/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpqs-mb-smarc-2-lvds0-tm070jvhg33.dtso
@@ -12,7 +12,7 @@ &backlight_lvds0 { status = "okay"; }; -&panel_lvds0{ +&panel_lvds0 { compatible = "tianma,tm070jvhg33"; status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpqs-mb-smarc-2-lvds1-tm070jvhg33.dtso b/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpqs-mb-smarc-2-lvds1-tm070jvhg33.dtso index cbad0cf..24f5f93 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpqs-mb-smarc-2-lvds1-tm070jvhg33.dtso +++ b/arch/arm64/boot/dts/freescale/imx8mp-tqma8mpqs-mb-smarc-2-lvds1-tm070jvhg33.dtso
@@ -12,7 +12,7 @@ &backlight_lvds1 { status = "okay"; }; -&panel_lvds1{ +&panel_lvds1 { compatible = "tianma,tm070jvhg33"; status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-tx8p-ml81-moduline-display-106.dts b/arch/arm64/boot/dts/freescale/imx8mp-tx8p-ml81-moduline-display-106.dts index 87b20b8..206992f 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-tx8p-ml81-moduline-display-106.dts +++ b/arch/arm64/boot/dts/freescale/imx8mp-tx8p-ml81-moduline-display-106.dts
@@ -11,7 +11,6 @@ / { compatible = "gocontroll,moduline-display-106", "karo,tx8p-ml81", "fsl,imx8mp"; chassis-type = "embedded"; - hardware = "Moduline Display V1.06"; model = "GOcontroll Moduline Display baseboard"; aliases {
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin-ivy.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin-ivy.dtsi index db1b4ee..bf021e8 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-verdin-ivy.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-ivy.dtsi
@@ -333,8 +333,8 @@ &gpio3 { "", "", "", - "DIG_1", /* SODIMM 56 */ - "DIG_2", /* SODIMM 58 */ + "DIGI_1", /* SODIMM 56 */ + "DIGI_2", /* SODIMM 58 */ "REL1", /* SODIMM 60 */ "REL2", /* SODIMM 62 */ "", /* 10 */
diff --git a/arch/arm64/boot/dts/freescale/imx8mp-verdin-yavia.dtsi b/arch/arm64/boot/dts/freescale/imx8mp-verdin-yavia.dtsi index f3d28e2..2a90f31 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp-verdin-yavia.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp-verdin-yavia.dtsi
@@ -117,6 +117,11 @@ &flexcan1 { status = "okay"; }; +&gpio3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpios_ext_yavia>; +}; + &gpio4 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_ctrl_sleep_moci>; @@ -266,7 +271,7 @@ MX8MP_IOMUXC_NAND_DATA03__GPIO3_IO09 0x106 /* SODIMM 62 */ pinctrl_gpios_ext_yavia: gpiosextyaviagrp { fsl,pins = < - MX8MP_IOMUXC_NAND_CE1_B__GPIO3_IO02 0x106 /* SODIMM 64 */ + MX8MP_IOMUXC_NAND_READY_B__GPIO3_IO16 0x106 /* SODIMM 64 */ MX8MP_IOMUXC_NAND_DQS__GPIO3_IO14 0x106 /* SODIMM 66 */ >; };
diff --git a/arch/arm64/boot/dts/freescale/imx8mp.dtsi b/arch/arm64/boot/dts/freescale/imx8mp.dtsi index 9cf9f6f..bec64cb 100644 --- a/arch/arm64/boot/dts/freescale/imx8mp.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mp.dtsi
@@ -1437,7 +1437,7 @@ aips5: bus@30df0000 { #access-controller-cells = <3>; ranges = <0x30c00000 0x30c00000 0x400000>; - spba-bus@30c00000 { + spba5: spba-bus@30c00000 { compatible = "fsl,spba-bus", "simple-bus"; reg = <0x30c00000 0x100000>; #address-cells = <1>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts index 5ea0470..fc0303e 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-evk.dts
@@ -299,6 +299,9 @@ vref_reg: vrefddr { vgen1_reg: vgen1 { regulator-min-microvolt = <800000>; regulator-max-microvolt = <1550000>; + regulator-state-mem { + regulator-off-in-suspend; + }; }; vgen2_reg: vgen2 { @@ -328,6 +331,9 @@ vgen5_reg: vgen5 { vgen6_reg: vgen6 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <3300000>; + regulator-state-mem { + regulator-off-in-suspend; + }; }; }; };
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts b/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts index 0c3f1b2..a82af92 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5-devkit.dts
@@ -119,7 +119,7 @@ regulator-state-mem { }; }; - reg_22v4_p: regulator-22v4-p { + reg_22v4_p: regulator-22v4-p { compatible = "regulator-fixed"; regulator-name = "22v4_P"; regulator-min-microvolt = <22400000>; @@ -507,7 +507,7 @@ &i2c3 { pinctrl-0 = <&pinctrl_i2c3>; status = "okay"; - magnetometer@1e { + magnetometer@1e { compatible = "st,lsm9ds1-magn"; reg = <0x1e>; pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi index f5d529c5..ad7c0e7 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
@@ -1025,7 +1025,7 @@ &i2c2 { sda-gpios = <&gpio5 17 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; status = "okay"; - magnetometer: magnetometer@1e { + magnetometer: magnetometer@1e { compatible = "st,lsm9ds1-magn"; reg = <0x1e>; pinctrl-names = "default"; @@ -1060,7 +1060,7 @@ proximity: prox@60 { interrupts = <7 IRQ_TYPE_LEVEL_LOW>; }; - accel_gyro: accel-gyro@6a { + accel_gyro: accel-gyro@6a { compatible = "st,lsm9ds1-imu"; reg = <0x6a>; vdd-supply = <®_vdd_sen>;
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts b/arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts index 767819c..b91509b 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts +++ b/arch/arm64/boot/dts/freescale/imx8mq-nitrogen.dts
@@ -230,7 +230,7 @@ i2c@0 { hdmi-bridge@48 { compatible = "lontium,lt8912b"; - reg = <0x48> ; + reg = <0x48>; reset-gpios = <&max7323 0 GPIO_ACTIVE_LOW>; ports {
diff --git a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi index c7bbba4..a272c1b 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mq-zii-ultra.dtsi
@@ -99,7 +99,7 @@ reg_arm: regulator-arm { regulator-max-microvolt = <1000000>; gpios = <&gpio3 16 GPIO_ACTIVE_HIGH>; states = <1000000 0x1 - 900000 0x0>; + 900000 0x0>; regulator-always-on; }; @@ -295,7 +295,7 @@ ucs1002: charger@32 { reg = <0x32>; interrupt-parent = <&gpio3>; interrupts = <17 IRQ_TYPE_EDGE_BOTH>, - <18 IRQ_TYPE_EDGE_FALLING>; + <18 IRQ_TYPE_EDGE_FALLING>; interrupt-names = "a_det", "alert"; }; @@ -549,9 +549,9 @@ &pcie0 { pinctrl-0 = <&pinctrl_pcie0>; reset-gpio = <&gpio1 3 GPIO_ACTIVE_LOW>; clocks = <&clk IMX8MQ_CLK_PCIE1_ROOT>, - <&pcie0_refclk>, - <&clk IMX8MQ_CLK_PCIE1_PHY>, - <&clk IMX8MQ_CLK_PCIE1_AUX>; + <&pcie0_refclk>, + <&clk IMX8MQ_CLK_PCIE1_PHY>, + <&clk IMX8MQ_CLK_PCIE1_AUX>; vph-supply = <&vgen5_reg>; status = "okay"; }; @@ -561,9 +561,9 @@ &pcie1 { pinctrl-0 = <&pinctrl_pcie1>; reset-gpio = <&gpio1 6 GPIO_ACTIVE_LOW>; clocks = <&clk IMX8MQ_CLK_PCIE2_ROOT>, - <&pcie1_refclk>, - <&clk IMX8MQ_CLK_PCIE2_PHY>, - <&clk IMX8MQ_CLK_PCIE2_AUX>; + <&pcie1_refclk>, + <&clk IMX8MQ_CLK_PCIE2_PHY>, + <&clk IMX8MQ_CLK_PCIE2_AUX>; vph-supply = <&vgen5_reg>; status = "okay"; };
diff --git a/arch/arm64/boot/dts/freescale/imx8mq.dtsi b/arch/arm64/boot/dts/freescale/imx8mq.dtsi index d75710c..5545b5b 100644 --- a/arch/arm64/boot/dts/freescale/imx8mq.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8mq.dtsi
@@ -363,9 +363,9 @@ vpu-crit { timer { compatible = "arm,armv8-timer"; interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, /* Physical Secure */ - <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, /* Physical Non-Secure */ - <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, /* Virtual */ - <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; /* Hypervisor */ + <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, /* Physical Non-Secure */ + <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, /* Virtual */ + <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; /* Hypervisor */ interrupt-parent = <&gic>; arm,no-tick-in-suspend; }; @@ -531,8 +531,8 @@ sai1: sai@30010000 { reg = <0x30010000 0x10000>; interrupts = <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_SAI1_IPG>, - <&clk IMX8MQ_CLK_SAI1_ROOT>, - <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>; + <&clk IMX8MQ_CLK_SAI1_ROOT>, + <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>; clock-names = "bus", "mclk1", "mclk2", "mclk3"; dmas = <&sdma2 8 24 0>, <&sdma1 9 24 0>; dma-names = "rx", "tx"; @@ -545,8 +545,8 @@ sai6: sai@30030000 { reg = <0x30030000 0x10000>; interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_SAI6_IPG>, - <&clk IMX8MQ_CLK_SAI6_ROOT>, - <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>; + <&clk IMX8MQ_CLK_SAI6_ROOT>, + <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>; clock-names = "bus", "mclk1", "mclk2", "mclk3"; dmas = <&sdma2 4 24 0>, <&sdma2 5 24 0>; dma-names = "rx", "tx"; @@ -559,8 +559,8 @@ sai5: sai@30040000 { reg = <0x30040000 0x10000>; interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_SAI5_IPG>, - <&clk IMX8MQ_CLK_SAI5_ROOT>, - <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>; + <&clk IMX8MQ_CLK_SAI5_ROOT>, + <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>; clock-names = "bus", "mclk1", "mclk2", "mclk3"; dmas = <&sdma2 2 24 0>, <&sdma2 3 24 0>; dma-names = "rx", "tx"; @@ -573,8 +573,8 @@ sai4: sai@30050000 { reg = <0x30050000 0x10000>; interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_SAI4_IPG>, - <&clk IMX8MQ_CLK_SAI4_ROOT>, - <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>; + <&clk IMX8MQ_CLK_SAI4_ROOT>, + <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>; clock-names = "bus", "mclk1", "mclk2", "mclk3"; dmas = <&sdma2 0 24 0>, <&sdma2 1 24 0>; dma-names = "rx", "tx"; @@ -585,7 +585,7 @@ gpio1: gpio@30200000 { compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio"; reg = <0x30200000 0x10000>; interrupts = <GIC_SPI 64 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_GPIO1_ROOT>; gpio-controller; #gpio-cells = <2>; @@ -598,7 +598,7 @@ gpio2: gpio@30210000 { compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio"; reg = <0x30210000 0x10000>; interrupts = <GIC_SPI 66 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 67 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_GPIO2_ROOT>; gpio-controller; #gpio-cells = <2>; @@ -611,7 +611,7 @@ gpio3: gpio@30220000 { compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio"; reg = <0x30220000 0x10000>; interrupts = <GIC_SPI 68 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 69 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_GPIO3_ROOT>; gpio-controller; #gpio-cells = <2>; @@ -624,7 +624,7 @@ gpio4: gpio@30230000 { compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio"; reg = <0x30230000 0x10000>; interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_GPIO4_ROOT>; gpio-controller; #gpio-cells = <2>; @@ -637,7 +637,7 @@ gpio5: gpio@30240000 { compatible = "fsl,imx8mq-gpio", "fsl,imx35-gpio"; reg = <0x30240000 0x10000>; interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_GPIO5_ROOT>; gpio-controller; #gpio-cells = <2>; @@ -845,14 +845,14 @@ clk: clock-controller@30380000 { compatible = "fsl,imx8mq-ccm"; reg = <0x30380000 0x10000>; interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>; #clock-cells = <1>; clocks = <&ckil>, <&osc_25m>, <&osc_27m>, - <&clk_ext1>, <&clk_ext2>, - <&clk_ext3>, <&clk_ext4>; + <&clk_ext1>, <&clk_ext2>, + <&clk_ext3>, <&clk_ext4>; clock-names = "ckil", "osc_25m", "osc_27m", - "clk_ext1", "clk_ext2", - "clk_ext3", "clk_ext4"; + "clk_ext1", "clk_ext2", + "clk_ext3", "clk_ext4"; assigned-clocks = <&clk IMX8MQ_CLK_A53_SRC>, <&clk IMX8MQ_CLK_A53_CORE>, <&clk IMX8MQ_CLK_NOC>, @@ -940,9 +940,9 @@ pgc_gpu: power-domain@5 { #power-domain-cells = <0>; reg = <IMX8M_POWER_DOMAIN_GPU>; clocks = <&clk IMX8MQ_CLK_GPU_ROOT>, - <&clk IMX8MQ_CLK_GPU_SHADER_DIV>, + <&clk IMX8MQ_CLK_GPU_SHADER_DIV>, <&clk IMX8MQ_CLK_GPU_AXI>, - <&clk IMX8MQ_CLK_GPU_AHB>; + <&clk IMX8MQ_CLK_GPU_AHB>; }; pgc_vpu: power-domain@6 { @@ -1000,7 +1000,7 @@ pwm1: pwm@30660000 { reg = <0x30660000 0x10000>; interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_PWM1_ROOT>, - <&clk IMX8MQ_CLK_PWM1_ROOT>; + <&clk IMX8MQ_CLK_PWM1_ROOT>; clock-names = "ipg", "per"; #pwm-cells = <3>; status = "disabled"; @@ -1011,7 +1011,7 @@ pwm2: pwm@30670000 { reg = <0x30670000 0x10000>; interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_PWM2_ROOT>, - <&clk IMX8MQ_CLK_PWM2_ROOT>; + <&clk IMX8MQ_CLK_PWM2_ROOT>; clock-names = "ipg", "per"; #pwm-cells = <3>; status = "disabled"; @@ -1022,7 +1022,7 @@ pwm3: pwm@30680000 { reg = <0x30680000 0x10000>; interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_PWM3_ROOT>, - <&clk IMX8MQ_CLK_PWM3_ROOT>; + <&clk IMX8MQ_CLK_PWM3_ROOT>; clock-names = "ipg", "per"; #pwm-cells = <3>; status = "disabled"; @@ -1033,7 +1033,7 @@ pwm4: pwm@30690000 { reg = <0x30690000 0x10000>; interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_PWM4_ROOT>, - <&clk IMX8MQ_CLK_PWM4_ROOT>; + <&clk IMX8MQ_CLK_PWM4_ROOT>; clock-names = "ipg", "per"; #pwm-cells = <3>; status = "disabled"; @@ -1124,11 +1124,11 @@ ecspi3: spi@30840000 { uart1: serial@30860000 { compatible = "fsl,imx8mq-uart", - "fsl,imx6q-uart"; + "fsl,imx6q-uart"; reg = <0x30860000 0x10000>; interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_UART1_ROOT>, - <&clk IMX8MQ_CLK_UART1_ROOT>; + <&clk IMX8MQ_CLK_UART1_ROOT>; clock-names = "ipg", "per"; dmas = <&sdma1 22 4 0>, <&sdma1 23 4 0>; dma-names = "rx", "tx"; @@ -1137,11 +1137,11 @@ uart1: serial@30860000 { uart3: serial@30880000 { compatible = "fsl,imx8mq-uart", - "fsl,imx6q-uart"; + "fsl,imx6q-uart"; reg = <0x30880000 0x10000>; interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_UART3_ROOT>, - <&clk IMX8MQ_CLK_UART3_ROOT>; + <&clk IMX8MQ_CLK_UART3_ROOT>; clock-names = "ipg", "per"; dmas = <&sdma1 26 4 0>, <&sdma1 27 4 0>; dma-names = "rx", "tx"; @@ -1150,11 +1150,11 @@ uart3: serial@30880000 { uart2: serial@30890000 { compatible = "fsl,imx8mq-uart", - "fsl,imx6q-uart"; + "fsl,imx6q-uart"; reg = <0x30890000 0x10000>; interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_UART2_ROOT>, - <&clk IMX8MQ_CLK_UART2_ROOT>; + <&clk IMX8MQ_CLK_UART2_ROOT>; clock-names = "ipg", "per"; dmas = <&sdma1 24 4 0>, <&sdma1 25 4 0>; dma-names = "rx", "tx"; @@ -1205,8 +1205,8 @@ sai3: sai@308c0000 { reg = <0x308c0000 0x10000>; interrupts = <GIC_SPI 50 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_SAI3_IPG>, - <&clk IMX8MQ_CLK_SAI3_ROOT>, - <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>; + <&clk IMX8MQ_CLK_SAI3_ROOT>, + <&clk IMX8MQ_CLK_DUMMY>, <&clk IMX8MQ_CLK_DUMMY>; clock-names = "bus", "mclk1", "mclk2", "mclk3"; dmas = <&sdma1 12 24 0>, <&sdma1 13 24 0>; dma-names = "rx", "tx"; @@ -1356,11 +1356,11 @@ i2c4: i2c@30a50000 { uart4: serial@30a60000 { compatible = "fsl,imx8mq-uart", - "fsl,imx6q-uart"; + "fsl,imx6q-uart"; reg = <0x30a60000 0x10000>; interrupts = <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_UART4_ROOT>, - <&clk IMX8MQ_CLK_UART4_ROOT>; + <&clk IMX8MQ_CLK_UART4_ROOT>; clock-names = "ipg", "per"; dmas = <&sdma1 28 4 0>, <&sdma1 29 4 0>; dma-names = "rx", "tx"; @@ -1481,12 +1481,12 @@ mu: mailbox@30aa0000 { usdhc1: mmc@30b40000 { compatible = "fsl,imx8mq-usdhc", - "fsl,imx7d-usdhc"; + "fsl,imx7d-usdhc"; reg = <0x30b40000 0x10000>; interrupts = <GIC_SPI 22 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_IPG_ROOT>, - <&clk IMX8MQ_CLK_NAND_USDHC_BUS>, - <&clk IMX8MQ_CLK_USDHC1_ROOT>; + <&clk IMX8MQ_CLK_NAND_USDHC_BUS>, + <&clk IMX8MQ_CLK_USDHC1_ROOT>; clock-names = "ipg", "ahb", "per"; fsl,tuning-start-tap = <20>; fsl,tuning-step = <2>; @@ -1496,12 +1496,12 @@ usdhc1: mmc@30b40000 { usdhc2: mmc@30b50000 { compatible = "fsl,imx8mq-usdhc", - "fsl,imx7d-usdhc"; + "fsl,imx7d-usdhc"; reg = <0x30b50000 0x10000>; interrupts = <GIC_SPI 23 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_IPG_ROOT>, - <&clk IMX8MQ_CLK_NAND_USDHC_BUS>, - <&clk IMX8MQ_CLK_USDHC2_ROOT>; + <&clk IMX8MQ_CLK_NAND_USDHC_BUS>, + <&clk IMX8MQ_CLK_USDHC2_ROOT>; clock-names = "ipg", "ahb", "per"; fsl,tuning-start-tap = <20>; fsl,tuning-step = <2>; @@ -1538,16 +1538,16 @@ fec1: ethernet@30be0000 { compatible = "fsl,imx8mq-fec", "fsl,imx6sx-fec"; reg = <0x30be0000 0x10000>; interrupts = <GIC_SPI 118 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 119 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_ENET1_ROOT>, - <&clk IMX8MQ_CLK_ENET1_ROOT>, - <&clk IMX8MQ_CLK_ENET_TIMER>, - <&clk IMX8MQ_CLK_ENET_REF>, - <&clk IMX8MQ_CLK_ENET_PHY_REF>; + <&clk IMX8MQ_CLK_ENET1_ROOT>, + <&clk IMX8MQ_CLK_ENET_TIMER>, + <&clk IMX8MQ_CLK_ENET_REF>, + <&clk IMX8MQ_CLK_ENET_PHY_REF>; clock-names = "ipg", "ahb", "ptp", - "enet_clk_ref", "enet_out"; + "enet_clk_ref", "enet_out"; assigned-clocks = <&clk IMX8MQ_CLK_ENET_AXI>, <&clk IMX8MQ_CLK_ENET_TIMER>, <&clk IMX8MQ_CLK_ENET_REF>, @@ -1639,23 +1639,23 @@ gpu: gpu@38000000 { reg = <0x38000000 0x40000>; interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>; clocks = <&clk IMX8MQ_CLK_GPU_ROOT>, - <&clk IMX8MQ_CLK_GPU_SHADER_DIV>, - <&clk IMX8MQ_CLK_GPU_AXI>, - <&clk IMX8MQ_CLK_GPU_AHB>; + <&clk IMX8MQ_CLK_GPU_SHADER_DIV>, + <&clk IMX8MQ_CLK_GPU_AXI>, + <&clk IMX8MQ_CLK_GPU_AHB>; clock-names = "core", "shader", "bus", "reg"; #cooling-cells = <2>; assigned-clocks = <&clk IMX8MQ_CLK_GPU_CORE_SRC>, - <&clk IMX8MQ_CLK_GPU_SHADER_SRC>, - <&clk IMX8MQ_CLK_GPU_AXI>, - <&clk IMX8MQ_CLK_GPU_AHB>, - <&clk IMX8MQ_GPU_PLL_BYPASS>; + <&clk IMX8MQ_CLK_GPU_SHADER_SRC>, + <&clk IMX8MQ_CLK_GPU_AXI>, + <&clk IMX8MQ_CLK_GPU_AHB>, + <&clk IMX8MQ_GPU_PLL_BYPASS>; assigned-clock-parents = <&clk IMX8MQ_GPU_PLL_OUT>, - <&clk IMX8MQ_GPU_PLL_OUT>, - <&clk IMX8MQ_GPU_PLL_OUT>, - <&clk IMX8MQ_GPU_PLL_OUT>, - <&clk IMX8MQ_GPU_PLL>; + <&clk IMX8MQ_GPU_PLL_OUT>, + <&clk IMX8MQ_GPU_PLL_OUT>, + <&clk IMX8MQ_GPU_PLL_OUT>, + <&clk IMX8MQ_GPU_PLL>; assigned-clock-rates = <800000000>, <800000000>, - <800000000>, <400000000>, <0>; + <800000000>, <400000000>, <0>; power-domains = <&pgc_gpu>; }; @@ -1663,13 +1663,13 @@ usb_dwc3_0: usb@38100000 { compatible = "fsl,imx8mq-dwc3", "snps,dwc3"; reg = <0x38100000 0x10000>; clocks = <&clk IMX8MQ_CLK_USB1_CTRL_ROOT>, - <&clk IMX8MQ_CLK_USB_CORE_REF>, + <&clk IMX8MQ_CLK_USB_CORE_REF>, <&clk IMX8MQ_CLK_32K>; clock-names = "bus_early", "ref", "suspend"; assigned-clocks = <&clk IMX8MQ_CLK_USB_BUS>, - <&clk IMX8MQ_CLK_USB_CORE_REF>; + <&clk IMX8MQ_CLK_USB_CORE_REF>; assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_500M>, - <&clk IMX8MQ_SYS1_PLL_100M>; + <&clk IMX8MQ_SYS1_PLL_100M>; assigned-clock-rates = <500000000>, <100000000>; interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; phys = <&usb3_phy0>, <&usb3_phy0>; @@ -1695,13 +1695,13 @@ usb_dwc3_1: usb@38200000 { compatible = "fsl,imx8mq-dwc3", "snps,dwc3"; reg = <0x38200000 0x10000>; clocks = <&clk IMX8MQ_CLK_USB2_CTRL_ROOT>, - <&clk IMX8MQ_CLK_USB_CORE_REF>, + <&clk IMX8MQ_CLK_USB_CORE_REF>, <&clk IMX8MQ_CLK_32K>; clock-names = "bus_early", "ref", "suspend"; assigned-clocks = <&clk IMX8MQ_CLK_USB_BUS>, - <&clk IMX8MQ_CLK_USB_CORE_REF>; + <&clk IMX8MQ_CLK_USB_CORE_REF>; assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_500M>, - <&clk IMX8MQ_SYS1_PLL_100M>; + <&clk IMX8MQ_SYS1_PLL_100M>; assigned-clock-rates = <500000000>, <100000000>; interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; phys = <&usb3_phy1>, <&usb3_phy1>; @@ -1767,9 +1767,9 @@ pcie0: pcie@33800000 { #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 0x7>; interrupt-map = <0 0 0 1 &gic GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 2 &gic GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 3 &gic GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 4 &gic GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>; + <0 0 0 2 &gic GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>; fsl,max-link-speed = <2>; linux,pci-domain = <0>; clocks = <&clk IMX8MQ_CLK_PCIE1_ROOT>, @@ -1779,17 +1779,17 @@ pcie0: pcie@33800000 { clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux"; power-domains = <&pgc_pcie>; resets = <&src IMX8MQ_RESET_PCIEPHY>, - <&src IMX8MQ_RESET_PCIE_CTRL_APPS_EN>, - <&src IMX8MQ_RESET_PCIE_CTRL_APPS_TURNOFF>; + <&src IMX8MQ_RESET_PCIE_CTRL_APPS_EN>, + <&src IMX8MQ_RESET_PCIE_CTRL_APPS_TURNOFF>; reset-names = "pciephy", "apps", "turnoff"; assigned-clocks = <&clk IMX8MQ_CLK_PCIE1_CTRL>, - <&clk IMX8MQ_CLK_PCIE1_PHY>, - <&clk IMX8MQ_CLK_PCIE1_AUX>; + <&clk IMX8MQ_CLK_PCIE1_PHY>, + <&clk IMX8MQ_CLK_PCIE1_AUX>; assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_250M>, - <&clk IMX8MQ_SYS2_PLL_100M>, - <&clk IMX8MQ_SYS1_PLL_80M>; + <&clk IMX8MQ_SYS2_PLL_100M>, + <&clk IMX8MQ_SYS1_PLL_80M>; assigned-clock-rates = <250000000>, <100000000>, - <10000000>; + <10000000>; status = "disabled"; pcie0_port0: pcie@0 { @@ -1868,17 +1868,17 @@ pcie1: pcie@33c00000 { clock-names = "pcie", "pcie_bus", "pcie_phy", "pcie_aux"; power-domains = <&pgc_pcie>; resets = <&src IMX8MQ_RESET_PCIEPHY2>, - <&src IMX8MQ_RESET_PCIE2_CTRL_APPS_EN>, - <&src IMX8MQ_RESET_PCIE2_CTRL_APPS_TURNOFF>; + <&src IMX8MQ_RESET_PCIE2_CTRL_APPS_EN>, + <&src IMX8MQ_RESET_PCIE2_CTRL_APPS_TURNOFF>; reset-names = "pciephy", "apps", "turnoff"; assigned-clocks = <&clk IMX8MQ_CLK_PCIE2_CTRL>, - <&clk IMX8MQ_CLK_PCIE2_PHY>, - <&clk IMX8MQ_CLK_PCIE2_AUX>; + <&clk IMX8MQ_CLK_PCIE2_PHY>, + <&clk IMX8MQ_CLK_PCIE2_AUX>; assigned-clock-parents = <&clk IMX8MQ_SYS2_PLL_250M>, - <&clk IMX8MQ_SYS2_PLL_100M>, - <&clk IMX8MQ_SYS1_PLL_80M>; + <&clk IMX8MQ_SYS2_PLL_100M>, + <&clk IMX8MQ_SYS1_PLL_80M>; assigned-clock-rates = <250000000>, <100000000>, - <10000000>; + <10000000>; status = "disabled"; pcie1_port0: pcie@0 {
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts index 9e49ac3..1afa65b 100644 --- a/arch/arm64/boot/dts/freescale/imx8qm-mek.dts +++ b/arch/arm64/boot/dts/freescale/imx8qm-mek.dts
@@ -44,57 +44,57 @@ reserved-memory { #size-cells = <2>; ranges; - vdev0vring0: memory@90000000 { + vdev0vring0: vdev0vring0@90000000 { reg = <0 0x90000000 0 0x8000>; no-map; }; - vdev0vring1: memory@90008000 { + vdev0vring1: vdev0vring1@90008000 { reg = <0 0x90008000 0 0x8000>; no-map; }; - vdev1vring0: memory@90010000 { + vdev1vring0: vdev1vring0@90010000 { reg = <0 0x90010000 0 0x8000>; no-map; }; - vdev1vring1: memory@90018000 { + vdev1vring1: vdev1vring1@90018000 { reg = <0 0x90018000 0 0x8000>; no-map; }; - rsc_table0: memory@900ff000 { + rsc_table0: rsc-table@900ff000 { reg = <0 0x900ff000 0 0x1000>; no-map; }; - vdev2vring0: memory@90100000 { + vdev2vring0: vdev2vring0@90100000 { reg = <0 0x90100000 0 0x8000>; no-map; }; - vdev2vring1: memory@90108000 { + vdev2vring1: vdev2vring1@90108000 { reg = <0 0x90108000 0 0x8000>; no-map; }; - vdev3vring0: memory@90110000 { + vdev3vring0: vdev3vring0@90110000 { reg = <0 0x90110000 0 0x8000>; no-map; }; - vdev3vring1: memory@90118000 { + vdev3vring1: vdev3vring1@90118000 { reg = <0 0x90118000 0 0x8000>; no-map; }; - rsc_table1: memory@901ff000 { + rsc_table1: rsc-table@901ff000 { reg = <0 0x901ff000 0 0x1000>; no-map; }; - vdevbuffer: memory@90400000 { + vdev0buffer: vdev0buffer@90400000 { compatible = "shared-dma-pool"; reg = <0 0x90400000 0 0x100000>; no-map; @@ -105,17 +105,17 @@ dsp_reserved: memory@92400000 { no-map; }; - dsp_vdev0vring0: memory@942f0000 { + dsp_vdev0vring0: vdev0vring0@942f0000 { reg = <0 0x942f0000 0 0x8000>; no-map; }; - dsp_vdev0vring1: memory@942f8000 { + dsp_vdev0vring1: vdev0vring1@942f8000 { reg = <0 0x942f8000 0 0x8000>; no-map; }; - dsp_vdev0buffer: memory@94300000 { + dsp_vdev0buffer: vdev0buffer@94300000 { compatible = "shared-dma-pool"; reg = <0 0x94300000 0 0x100000>; no-map; @@ -456,7 +456,7 @@ imx8qm-cm4-0 { mboxes = <&lsio_mu5 0 1 &lsio_mu5 1 1 &lsio_mu5 3 1>; - memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, + memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, <&vdev1vring0>, <&vdev1vring1>, <&rsc_table0>; power-domains = <&pd IMX_SC_R_M4_0_PID0>, <&pd IMX_SC_R_M4_0_MU_1A>; @@ -471,7 +471,7 @@ imx8qm-cm4-1 { mboxes = <&lsio_mu6 0 1 &lsio_mu6 1 1 &lsio_mu6 3 1>; - memory-region = <&vdevbuffer>, <&vdev2vring0>, <&vdev2vring1>, + memory-region = <&vdev0buffer>, <&vdev2vring0>, <&vdev2vring1>, <&vdev3vring0>, <&vdev3vring1>, <&rsc_table1>; power-domains = <&pd IMX_SC_R_M4_1_PID0>, <&pd IMX_SC_R_M4_1_MU_1A>;
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi index ccf9f51..f25f62d 100644 --- a/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8qm-ss-conn.dtsi
@@ -4,6 +4,41 @@ * Dong Aisheng <aisheng.dong@nxp.com> */ +&{/} { + usbphynop2: usbphynop2 { + compatible = "usb-nop-xceiv"; + clocks = <&usb2_lpcg IMX_LPCG_CLK_7>; + clock-names = "main_clk"; + #phy-cells = <0>; + power-domains = <&pd IMX_SC_R_USB_1_PHY>; + status = "disabled"; + }; +}; + +&conn_subsys { + usbh1: usb@5b0e0000 { + compatible = "fsl,imx7ulp-usb", "fsl,imx6ul-usb", "fsl,imx27-usb"; + reg = <0x5b0e0000 0x200>; + interrupt-parent = <&gic>; + interrupts = <GIC_SPI 268 IRQ_TYPE_LEVEL_HIGH>; + phy_type = "hsic"; + dr_mode = "host"; + clocks = <&usb2_lpcg IMX_LPCG_CLK_6>; + ahb-burst-config = <0x0>; + tx-burst-size-dword = <0x10>; + rx-burst-size-dword = <0x10>; + power-domains = <&pd IMX_SC_R_USB_1>; + fsl,usbphy = <&usbphynop2>; + fsl,usbmisc = <&usbmisc2 0>; + }; + + usbmisc2: usbmisc@5b0e0200 { + compatible = "fsl,imx7ulp-usbmisc", "fsl,imx7d-usbmisc", "fsl,imx6q-usbmisc"; + #index-cells = <1>; + reg = <0x5b0e0200 0x200>; + }; +}; + &usbphy1 { compatible = "fsl,imx8qm-usbphy", "fsl,imx7ulp-usbphy"; }; @@ -32,3 +67,7 @@ &usdhc3 { compatible = "fsl,imx8qm-usdhc", "fsl,imx8qxp-usdhc", "fsl,imx7d-usdhc"; iommus = <&smmu 0x11 0x7f80>; }; + +&usbotg3_cdns3 { + iommus = <&smmu 0x4 0x7f80>; +};
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-var-som-symphony.dts b/arch/arm64/boot/dts/freescale/imx8qm-var-som-symphony.dts index ec55b86..4528627 100644 --- a/arch/arm64/boot/dts/freescale/imx8qm-var-som-symphony.dts +++ b/arch/arm64/boot/dts/freescale/imx8qm-var-som-symphony.dts
@@ -303,7 +303,7 @@ usb3-signal-route-hog { }; }; -&pciea{ +&pciea { phys = <&hsio_phy 0 PHY_TYPE_PCIE 0>; phy-names = "pcie-phy"; status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx8qm-var-som.dtsi b/arch/arm64/boot/dts/freescale/imx8qm-var-som.dtsi index b11da10..a443511 100644 --- a/arch/arm64/boot/dts/freescale/imx8qm-var-som.dtsi +++ b/arch/arm64/boot/dts/freescale/imx8qm-var-som.dtsi
@@ -275,15 +275,15 @@ &lpuart1 { status = "okay"; }; -&mu_m0{ +&mu_m0 { status = "okay"; }; -&mu1_m0{ +&mu1_m0 { status = "okay"; }; -&mu2_m0{ +&mu2_m0 { status = "okay"; };
diff --git a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts index 857a6e5..eb994f3 100644 --- a/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts +++ b/arch/arm64/boot/dts/freescale/imx8qxp-mek.dts
@@ -27,7 +27,7 @@ imx8x_cm4: imx8x-cm4 { mboxes = <&lsio_mu5 0 1 &lsio_mu5 1 1 &lsio_mu5 3 1>; - memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, + memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>; power-domains = <&pd IMX_SC_R_M4_0_PID0>, <&pd IMX_SC_R_M4_0_MU_1A>; @@ -242,48 +242,48 @@ reserved-memory { #size-cells = <2>; ranges; - vdev0vring0: memory@90000000 { + vdev0vring0: vdev0vring0@90000000 { reg = <0 0x90000000 0 0x8000>; no-map; }; - vdev0vring1: memory@90008000 { + vdev0vring1: vdev0vring1@90008000 { reg = <0 0x90008000 0 0x8000>; no-map; }; - vdev1vring0: memory@90010000 { + vdev1vring0: vdev1vring0@90010000 { reg = <0 0x90010000 0 0x8000>; no-map; }; - vdev1vring1: memory@90018000 { + vdev1vring1: vdev1vring1@90018000 { reg = <0 0x90018000 0 0x8000>; no-map; }; - rsc_table: memory@900ff000 { + rsc_table: rsc-table@900ff000 { reg = <0 0x900ff000 0 0x1000>; no-map; }; - vdevbuffer: memory@90400000 { + vdev0buffer: vdev0buffer@90400000 { compatible = "shared-dma-pool"; reg = <0 0x90400000 0 0x100000>; no-map; }; - dsp_vdev0vring0: memory@942f0000 { + dsp_vdev0vring0: vdev0vring0@942f0000 { reg = <0 0x942f0000 0 0x8000>; no-map; }; - dsp_vdev0vring1: memory@942f8000 { + dsp_vdev0vring1: vdev0vring1@942f8000 { reg = <0 0x942f8000 0 0x8000>; no-map; }; - dsp_vdev0buffer: memory@94300000 { + dsp_vdev0buffer: vdev0buffer@94300000 { compatible = "shared-dma-pool"; reg = <0 0x94300000 0 0x100000>; no-map;
diff --git a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts index 4b92583..4e19847 100644 --- a/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx8ulp-evk.dts
@@ -80,7 +80,7 @@ vdev1vring1: vdev1vring1@aff18000 { no-map; }; - vdevbuffer: vdevbuffer@a8400000 { + vdev0buffer: vdev0buffer@a8400000 { compatible = "shared-dma-pool"; reg = <0 0xa8400000 0 0x100000>; no-map; @@ -139,7 +139,7 @@ &cm33 { mboxes = <&mu 0 1>, <&mu 1 1>, <&mu 3 1>; - memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, + memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>; status = "okay"; };
diff --git a/arch/arm64/boot/dts/freescale/imx9-mqs.dtso b/arch/arm64/boot/dts/freescale/imx9-mqs.dtso new file mode 100644 index 0000000..bdb2512 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx9-mqs.dtso
@@ -0,0 +1,57 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 NXP + */ + +/dts-v1/; +/plugin/; + +&{/} { + sound-mqs { + compatible = "audio-graph-card2"; + aux-devs = <&_mqs1>; + label = "mqs-audio"; + links = <&sai1_port1>; + routing = "MQS AMP INL", "MQS_L", + "MQS AMP INR", "MQS_R"; + }; +}; + +&mqs1_conflict_card { + status = "disabled"; +}; + +&mqs1_conflict_dev { + status = "disabled"; +}; + +&mqs1 { + status = "okay"; + + port { + mqs1_endpoint: endpoint { + remote-endpoint = <&sai1_endpoint1>; + }; + }; +}; + +&sai1 { + ports { + #address-cells = <1>; + #size-cells = <0>; + + sai1_port1: port@1 { + reg = <1>; + playback-only; + + sai1_endpoint1: endpoint { + dai-format = "left_j"; + bitclock-master; + frame-master; + mclk-fs = <512>; + system-clock-direction-out; + remote-endpoint = <&mqs1_endpoint>; + }; + }; + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx91-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx91-11x11-evk.dts index 5716feb..66466ce 100644 --- a/arch/arm64/boot/dts/freescale/imx91-11x11-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx91-11x11-evk.dts
@@ -25,6 +25,7 @@ aliases { mmc1 = &usdhc2; mmc2 = &usdhc3; rtc0 = &bbnsm_rtc; + rtc1 = &pcf2131; serial0 = &lpuart1; serial1 = &lpuart2; serial2 = &lpuart3; @@ -32,6 +33,12 @@ aliases { serial4 = &lpuart5; }; + amp_mqs1: audio-amplifier { + compatible = "simple-audio-amplifier"; + sound-name-prefix = "MQS AMP"; + VCC-supply = <®_3p3v>; + }; + bt_sco_codec: bt-sco-codec { compatible = "linux,bt-sco"; #sound-dai-cells = <1>; @@ -41,6 +48,32 @@ chosen { stdout-path = &lpuart1; }; + pdm_mqs1_mux: mux-controller-0 { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + #mux-state-cells = <1>; + mux-gpios = <&adp5585 2 GPIO_ACTIVE_HIGH>; + }; + + pinctrl-gpiomux { + compatible = "pinctrl-multiplexer"; + + mqs1_fun: mqs1-grp { + mux-states = <&pdm_mqs1_mux 1>; + }; + + pdm_fun: pdm-grp { + mux-states = <&pdm_mqs1_mux 0>; + }; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "+V3.3_SW"; + }; + reg_vref_1v8: regulator-adc-vref { compatible = "regulator-fixed"; regulator-max-microvolt = <1800000>; @@ -126,7 +159,7 @@ sound-wm8962 { "IN1R", "AMIC"; }; - sound-bt-sco { + mqs1_conflict_card: sound-bt-sco { compatible = "simple-audio-card"; simple-audio-card,name = "bt-sco-audio"; simple-audio-card,format = "dsp_a"; @@ -482,9 +515,9 @@ bluetooth { }; }; -&micfil { +mqs1_conflict_dev: &micfil { pinctrl-names = "default", "sleep"; - pinctrl-0 = <&pinctrl_pdm>; + pinctrl-0 = <&pinctrl_pdm>, <&pdm_fun>; pinctrl-1 = <&pinctrl_pdm_sleep>; assigned-clocks = <&clk IMX93_CLK_PDM>; assigned-clock-parents = <&clk IMX93_CLK_AUDIO_PLL>; @@ -492,10 +525,19 @@ &micfil { status = "okay"; }; +&mqs1 { + pinctrl-0 = <&pinctrl_mqs1>, <&mqs1_fun>; + pinctrl-names = "default"; +}; + &sai1 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&pinctrl_sai1>; pinctrl-1 = <&pinctrl_sai1_sleep>; + clocks = <&clk IMX93_CLK_SAI1_IPG>, <&clk IMX93_CLK_DUMMY>, + <&clk IMX93_CLK_SAI1_GATE>, <&clk IMX93_CLK_DUMMY>, + <&clk IMX93_CLK_DUMMY>, <&clk IMX93_CLK_AUDIO_PLL>; + clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k"; assigned-clocks = <&clk IMX93_CLK_SAI1>; assigned-clock-parents = <&clk IMX93_CLK_AUDIO_PLL>; assigned-clock-rates = <12288000>; @@ -701,6 +743,13 @@ MX91_PAD_I2C2_SDA__LPI2C2_SDA 0x40000b9e >; }; + pinctrl_mqs1: mqs1grp { + fsl,pins = < + MX91_PAD_PDM_CLK__MQS1_LEFT 0x31e + MX91_PAD_PDM_BIT_STREAM0__MQS1_RIGHT 0x31e + >; + }; + pinctrl_pdm: pdmgrp { fsl,pins = < MX91_PAD_PDM_CLK__PDM_CLK 0x31e
diff --git a/arch/arm64/boot/dts/freescale/imx91-11x11-frdm-s.dts b/arch/arm64/boot/dts/freescale/imx91-11x11-frdm-s.dts index 62dc1de..c6019d7 100644 --- a/arch/arm64/boot/dts/freescale/imx91-11x11-frdm-s.dts +++ b/arch/arm64/boot/dts/freescale/imx91-11x11-frdm-s.dts
@@ -672,8 +672,6 @@ &media_blk_ctrl { }; &mqs1 { - clocks = <&clk IMX93_CLK_MQS1_GATE>; - clock-names = "mclk"; pinctrl-0 = <&pinctrl_mqs1>; pinctrl-names = "default"; status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx91-11x11-frdm.dts b/arch/arm64/boot/dts/freescale/imx91-11x11-frdm.dts index c255615..6144fa6 100644 --- a/arch/arm64/boot/dts/freescale/imx91-11x11-frdm.dts +++ b/arch/arm64/boot/dts/freescale/imx91-11x11-frdm.dts
@@ -468,8 +468,6 @@ bluetooth { }; &mqs1 { - clocks = <&clk IMX93_CLK_MQS1_GATE>; - clock-names = "mclk"; pinctrl-0 = <&pinctrl_mqs1>; pinctrl-names = "default"; status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx91-9x9-qsb-tianma-tm050rdh03.dtso b/arch/arm64/boot/dts/freescale/imx91-9x9-qsb-tianma-tm050rdh03.dtso new file mode 100644 index 0000000..01c22f9 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx91-9x9-qsb-tianma-tm050rdh03.dtso
@@ -0,0 +1,104 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 NXP + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/pwm/pwm.h> +#include "imx91-pinfunc.h" + +&{/} { + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&tpm1 3 40000 PWM_POLARITY_INVERTED>; /* 25KHz PWM */ + brightness-levels = <0 100>; + num-interpolated-steps = <100>; + default-brightness-level = <80>; + power-supply = <®_exp_5v>; + }; + + panel { + compatible = "tianma,tm050rdh03"; + backlight = <&backlight>; + enable-gpios = <&pcal6524 8 GPIO_ACTIVE_HIGH>; + power-supply = <®_exp_3v3>; + + port { + panel_in: endpoint { + remote-endpoint = <&dpi_to_panel>; + }; + }; + }; +}; + +&dpi_bridge { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lcdif>, <&gpio_fun>, <&sai3_tx_fun>, <&sai3_enable>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + dpi_to_panel: endpoint { + remote-endpoint = <&panel_in>; + bus-width = <18>; + }; + }; + }; +}; + +&iomuxc { + pinctrl_lcdif: lcdifgrp { + fsl,pins = < + MX91_PAD_GPIO_IO00__MEDIAMIX_DISP_CLK 0x31e + MX91_PAD_GPIO_IO01__MEDIAMIX_DISP_DE 0x31e + MX91_PAD_GPIO_IO02__MEDIAMIX_DISP_VSYNC 0x31e + MX91_PAD_GPIO_IO03__MEDIAMIX_DISP_HSYNC 0x31e + MX91_PAD_GPIO_IO04__MEDIAMIX_DISP_DATA0 0x31e + MX91_PAD_GPIO_IO05__MEDIAMIX_DISP_DATA1 0x31e + MX91_PAD_GPIO_IO06__MEDIAMIX_DISP_DATA2 0x31e + MX91_PAD_GPIO_IO07__MEDIAMIX_DISP_DATA3 0x31e + MX91_PAD_GPIO_IO08__MEDIAMIX_DISP_DATA4 0x31e + MX91_PAD_GPIO_IO09__MEDIAMIX_DISP_DATA5 0x31e + MX91_PAD_GPIO_IO10__MEDIAMIX_DISP_DATA6 0x31e + MX91_PAD_GPIO_IO11__MEDIAMIX_DISP_DATA7 0x31e + MX91_PAD_GPIO_IO12__MEDIAMIX_DISP_DATA8 0x31e + MX91_PAD_GPIO_IO13__MEDIAMIX_DISP_DATA9 0x31e + MX91_PAD_GPIO_IO14__MEDIAMIX_DISP_DATA10 0x31e + MX91_PAD_GPIO_IO15__MEDIAMIX_DISP_DATA11 0x31e + MX91_PAD_GPIO_IO16__MEDIAMIX_DISP_DATA12 0x31e + MX91_PAD_GPIO_IO17__MEDIAMIX_DISP_DATA13 0x31e + MX91_PAD_GPIO_IO18__MEDIAMIX_DISP_DATA14 0x31e + MX91_PAD_GPIO_IO19__MEDIAMIX_DISP_DATA15 0x31e + MX91_PAD_GPIO_IO20__MEDIAMIX_DISP_DATA16 0x31e + MX91_PAD_GPIO_IO21__MEDIAMIX_DISP_DATA17 0x31e + >; + }; + + pinctrl_tpm1_ch3: tpm1ch3grp { + fsl,pins = < + MX91_PAD_UART2_TXD__TPM1_CH3 0x31e + >; + }; +}; + +&lcdif { + status = "okay"; +}; + +&media_blk_ctrl { + status = "okay"; +}; + +&tpm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_tpm1_ch3>; + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx91-9x9-qsb.dts b/arch/arm64/boot/dts/freescale/imx91-9x9-qsb.dts index 044b37f..b7f0e39 100644 --- a/arch/arm64/boot/dts/freescale/imx91-9x9-qsb.dts +++ b/arch/arm64/boot/dts/freescale/imx91-9x9-qsb.dts
@@ -23,6 +23,7 @@ aliases { mmc0 = &usdhc1; mmc1 = &usdhc2; rtc0 = &bbnsm_rtc; + rtc1 = &pcf2131; serial0 = &lpuart1; }; @@ -75,6 +76,27 @@ sai1_en_mux: mux-controller-2 { mux-gpios = <&pcal6524 9 GPIO_ACTIVE_HIGH>; }; + exp_mux: mux-controller-3 { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + #mux-state-cells = <1>; + mux-gpios = <&pcal6524 22 GPIO_ACTIVE_HIGH>; + }; + + sai3_tx_rx_mux: mux-controller-4 { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + #mux-state-cells = <1>; + mux-gpios = <&pcal6524 14 GPIO_ACTIVE_HIGH>; + }; + + sai3_en_mux: mux-controller-5 { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + #mux-state-cells = <1>; + mux-gpios = <&pcal6524 23 GPIO_ACTIVE_HIGH>; + }; + pinctrl-gpiomux { compatible = "pinctrl-multiplexer"; @@ -82,6 +104,10 @@ can_fun: can-grp { mux-states = <&can_mux 1>; }; + gpio_fun: exp-grp { + mux-states = <&exp_mux 0>; + }; + m2_fun: m2-grp { mux-states = <&sai1_mux 1>; }; @@ -101,6 +127,32 @@ sai1_enable: sai1-enable-grp { sai1_fun: sai1-grp { mux-states = <&sai1_mux 0>; }; + + sai3_enable: sai3-enable-grp { + mux-states = <&sai3_en_mux 0>; + }; + + sai3_tx_fun: sai3-tx-grp { + mux-states = <&sai3_tx_rx_mux 0>; + }; + }; + + reg_exp_3v3: regulator-exp-3v3 { + compatible = "regulator-fixed"; + regulator-name = "EXP_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&pcal6524 21 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_exp_5v: regulator-exp-5v { + compatible = "regulator-fixed"; + regulator-name = "EXP_5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&pcal6524 4 GPIO_ACTIVE_HIGH>; + enable-active-high; }; reg_vref_1v8: regulator-adc-vref {
diff --git a/arch/arm64/boot/dts/freescale/imx91-lino-verdin-dahlia.dts b/arch/arm64/boot/dts/freescale/imx91-lino-verdin-dahlia.dts new file mode 100644 index 0000000..eb3a8cd --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx91-lino-verdin-dahlia.dts
@@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Lino iMX91 SoM on Lino-Verdin Adapter / Dahlia carrier board + * + * https://www.toradex.com/computer-on-modules/lino-arm-family/nxp-imx91 + * https://www.toradex.com/products/carrier-board/dahlia-carrier-board-kit + */ + +/dts-v1/; + +#include "imx91.dtsi" +#include "imx91-lino.dtsi" +#include "imx93-imx91-lino-verdin-common.dtsi" +#include "imx93-imx91-lino-verdin-dahlia-common.dtsi" + +/ { + model = "Toradex Lino iMX91 on Verdin Adapter plus Dahlia Board"; + compatible = "toradex,lino-imx91-verdin-dahlia", + "toradex,lino-imx91-verdin", + "toradex,lino-imx91", + "fsl,imx91"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx91-lino-verdin-dev.dts b/arch/arm64/boot/dts/freescale/imx91-lino-verdin-dev.dts new file mode 100644 index 0000000..a988897 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx91-lino-verdin-dev.dts
@@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Lino iMX91 SoM on Lino-Verdin Adapter / Development carrier board + * + * https://www.toradex.com/computer-on-modules/lino-arm-family/nxp-imx91 + * https://www.toradex.com/products/carrier-board/verdin-development-board-kit + */ + +/dts-v1/; + +#include "imx91.dtsi" +#include "imx91-lino.dtsi" +#include "imx93-imx91-lino-verdin-common.dtsi" +#include "imx93-imx91-lino-verdin-dev-common.dtsi" + +/ { + model = "Toradex Lino iMX91 on Verdin Adapter plus Development Board"; + compatible = "toradex,lino-imx91-verdin-dev", + "toradex,lino-imx91-verdin", + "toradex,lino-imx91", + "fsl,imx91"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx91-lino.dtsi b/arch/arm64/boot/dts/freescale/imx91-lino.dtsi new file mode 100644 index 0000000..99d9569 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx91-lino.dtsi
@@ -0,0 +1,305 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Lino iMX91 SoM + * + * https://www.toradex.com/computer-on-modules/lino-arm-family/nxp-imx91 + */ + +#include "imx91-pinfunc.h" +#include "imx93-imx91-lino-common.dtsi" + +&iomuxc { + /* Lino CAN_1 */ + pinctrl_can1: can1grp { + fsl,pins = <MX91_PAD_PDM_BIT_STREAM0__CAN1_RX 0x139e>, /* Lino P12 */ + <MX91_PAD_PDM_CLK__CAN1_TX 0x139e>; /* Lino P10 */ + }; + + /* Lino CAN_2 */ + pinctrl_can2: can2grp { + fsl,pins = <MX91_PAD_GPIO_IO25__CAN2_TX 0x139e>, /* Lino S28 */ + <MX91_PAD_GPIO_IO27__CAN2_RX 0x139e>; /* Lino S30 */ + }; + + /* Lino ETH_1 RGMII */ + pinctrl_eth1: eqosgrp { + fsl,pins = <MX91_PAD_ENET1_RD0__ENET_QOS_RGMII_RD0 0x1fe>, /* Lino P77 */ + <MX91_PAD_ENET1_RD1__ENET_QOS_RGMII_RD1 0x1fe>, /* Lino P79 */ + <MX91_PAD_ENET1_RD2__ENET_QOS_RGMII_RD2 0x1fe>, /* Lino P81 */ + <MX91_PAD_ENET1_RD3__ENET_QOS_RGMII_RD3 0x1fe>, /* Lino P83 */ + <MX91_PAD_ENET1_RXC__ENET_QOS_RGMII_RXC 0x1fe>, /* Lino P73 */ + <MX91_PAD_ENET1_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x1fe>, /* Lino P75 */ + <MX91_PAD_ENET1_TD0__ENET_QOS_RGMII_TD0 0x1fe>, /* Lino P97 */ + <MX91_PAD_ENET1_TD1__ENET1_RGMII_TD1 0x1fe>, /* Lino P95 */ + <MX91_PAD_ENET1_TD2__ENET_QOS_RGMII_TD2 0x1fe>, /* Lino P93 */ + <MX91_PAD_ENET1_TD3__ENET_QOS_RGMII_TD3 0x1fe>, /* Lino P91 */ + <MX91_PAD_ENET1_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x1fe>, /* Lino P89 */ + <MX91_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1fe>; /* Lino P85 */ + }; + + /* Lino ETH MDIO */ + pinctrl_mdio: eqosmdiogrp { + fsl,pins = <MX91_PAD_ENET1_MDC__ENET1_MDC 0x1fe>, /* Lino P69 */ + <MX91_PAD_ENET1_MDIO__ENET_QOS_MDIO 0x1fe>; /* Lino P67 */ + }; + + /* Lino ETH_2 RGMII */ + pinctrl_eth2: fecgrp { + fsl,pins = <MX91_PAD_ENET2_RD0__ENET2_RGMII_RD0 0x1fe>, /* Lino S77 */ + <MX91_PAD_ENET2_RD1__ENET2_RGMII_RD1 0x1fe>, /* Lino S79 */ + <MX91_PAD_ENET2_RD2__ENET2_RGMII_RD2 0x1fe>, /* Lino S81 */ + <MX91_PAD_ENET2_RD3__ENET2_RGMII_RD3 0x1fe>, /* Lino S83 */ + <MX91_PAD_ENET2_RXC__ENET2_RGMII_RXC 0x1fe>, /* Lino S71 */ + <MX91_PAD_ENET2_RX_CTL__ENET2_RGMII_RX_CTL 0x1fe>, /* Lino S73 */ + <MX91_PAD_ENET2_TD0__ENET2_RGMII_TD0 0x1fe>, /* Lino S99 */ + <MX91_PAD_ENET2_TD1__ENET2_RGMII_TD1 0x1fe>, /* Lino S97 */ + <MX91_PAD_ENET2_TD2__ENET2_RGMII_TD2 0x1fe>, /* Lino S93 */ + <MX91_PAD_ENET2_TD3__ENET2_RGMII_TD3 0x1fe>, /* Lino S91 */ + <MX91_PAD_ENET2_TXC__ENET2_RGMII_TXC 0x1fe>, /* Lino S87 */ + <MX91_PAD_ENET2_TX_CTL__ENET2_RGMII_TX_CTL 0x1fe>; /* Lino S89 */ + }; + + /* Lino GPIO_11 */ + pinctrl_gpio_11: gpio1io10grp { + fsl,pins = <MX91_PAD_PDM_BIT_STREAM1__GPIO1_IO10 0x139e>; /* Lino P65 */ + }; + + /* Lino SPI_2_CS as GPIO */ + pinctrl_spi2_cs0_gpio: gpio1io11grp { + fsl,pins = <MX91_PAD_SAI1_TXFS__GPIO1_IO11 0x139e>; /* Lino S18 */ + }; + + /* Lino GPIO_1 */ + pinctrl_gpio1: gpio2io0grp { + fsl,pins = <MX91_PAD_GPIO_IO00__GPIO2_IO0 0x139e>; /* Lino P30 */ + }; + + /* Lino GPIO_2 */ + pinctrl_gpio2: gpio2io1grp { + fsl,pins = <MX91_PAD_GPIO_IO01__GPIO2_IO1 0x139e>; /* Lino P32 */ + }; + + /* Lino SPI_1_CS as GPIO */ + pinctrl_spi1_cs0_gpio: gpio2io12grp { + fsl,pins = <MX91_PAD_GPIO_IO12__GPIO2_IO12 0x139e>; /* Lino P58 */ + }; + + /* Lino GPIO_3 */ + pinctrl_gpio3: gpio2io17grp { + fsl,pins = <MX91_PAD_GPIO_IO17__GPIO2_IO17 0x139e>; /* Lino P34 */ + }; + + /* Lino GPIO_4 */ + pinctrl_gpio4: gpio2io22grp { + fsl,pins = <MX91_PAD_GPIO_IO22__GPIO2_IO22 0x139e>; /* Lino P36 */ + }; + + /* Lino PWM_3 as GPIO */ + pinctrl_pwm3_gpio: gpio2io23grp { + fsl,pins = <MX91_PAD_GPIO_IO23__GPIO2_IO23 0x139e>; /* Lino P5 */ + }; + + /* Lino GPIO_5 */ + pinctrl_gpio5: gpio2io24grp { + fsl,pins = <MX91_PAD_GPIO_IO24__GPIO2_IO24 0x139e>; /* Lino P38 */ + }; + + /* Lino GPIO_6 */ + pinctrl_gpio6: gpio3io26grp { + fsl,pins = <MX91_PAD_CCM_CLKO1__GPIO3_IO26 0x139e>; /* Lino P40 */ + }; + + /* Lino GPIO_7 */ + pinctrl_gpio7: gpio3io27grp { + fsl,pins = <MX91_PAD_CCM_CLKO2__GPIO3_IO27 0x139e>; /* Lino P42 */ + }; + + /* Lino GPIO_9 */ + pinctrl_gpio9: gpio4io14grp { + fsl,pins = <MX91_PAD_ENET2_MDC__GPIO4_IO14 0x139e>; /* Lino P46 */ + }; + + /* Lino GPIO_10 */ + pinctrl_gpio10: gpio4io15grp { + fsl,pins = <MX91_PAD_ENET2_MDIO__GPIO4_IO15 0x139e>; /* Lino P48 */ + }; + + /* Lino GPIO_8 */ + pinctrl_gpio8: gpio4io28grp { + fsl,pins = <MX91_PAD_CCM_CLKO3__GPIO4_IO28 0x139e>; /* Lino P44 */ + }; + + /* On-module GPIO_EXP_INT# */ + pinctrl_gpio_exp_int: gpio4io29grp { + fsl,pins = <MX91_PAD_CCM_CLKO4__GPIO4_IO29 0x139e>; /* GPIO_EXP_INT# */ + }; + + /* Lino I2C_1 as GPIO */ + pinctrl_i2c1_gpio: lpi2c1gpiogrp { + fsl,pins = <MX91_PAD_I2C1_SCL__GPIO1_IO0 0x40000b9e>, /* Lino P18 */ + <MX91_PAD_I2C1_SDA__GPIO1_IO1 0x40000b9e>; /* Lino P16 */ + }; + + /* Lino I2C_1 */ + pinctrl_i2c1: lpi2c1grp { + fsl,pins = <MX91_PAD_I2C1_SCL__LPI2C1_SCL 0x40000b9e>, /* Lino P18 */ + <MX91_PAD_I2C1_SDA__LPI2C1_SDA 0x40000b9e>; /* Lino P16 */ + }; + + /* On-module PMIC I2C as GPIO */ + pinctrl_pmic_i2c_gpio: lpi2c2gpiogrp { + fsl,pins = <MX91_PAD_I2C2_SCL__GPIO1_IO2 0x40000b9e>, /* PMIC_I2C_SCL */ + <MX91_PAD_I2C2_SDA__GPIO1_IO3 0x40000b9e>; /* PMIC_I2C_SDA */ + }; + + /* On-module PMIC I2C */ + pinctrl_pmic_i2c: lpi2c2grp { + fsl,pins = <MX91_PAD_I2C2_SCL__LPI2C2_SCL 0x40000b9e>, /* PMIC_I2C_SCL */ + <MX91_PAD_I2C2_SDA__LPI2C2_SDA 0x40000b9e>; /* PMIC_I2C_SDA */ + }; + + /* Lino I2C_2 as GPIO */ + pinctrl_i2c2_gpio: lpi2c3gpiogrp { + fsl,pins = <MX91_PAD_GPIO_IO28__GPIO2_IO28 0x40000b9e>, /* Lino P20 */ + <MX91_PAD_GPIO_IO29__GPIO2_IO29 0x40000b9e>; /* Lino P22 */ + }; + + /* Lino I2C_2 */ + pinctrl_i2c2: lpi2c3grp { + fsl,pins = <MX91_PAD_GPIO_IO28__LPI2C3_SDA 0x40000b9e>, /* Lino P20 */ + <MX91_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e>; /* Lino P22 */ + }; + + /* Lino I2C_3 as GPIO */ + pinctrl_i2c3_gpio: lpi2c4gpiogrp { + fsl,pins = <MX91_PAD_GPIO_IO02__GPIO2_IO2 0x40000b9e>, /* Lino P24 */ + <MX91_PAD_GPIO_IO03__GPIO2_IO3 0x40000b9e>; /* Lino P26 */ + }; + + /* Lino I2C_3 */ + pinctrl_i2c3: lpi2c4grp { + fsl,pins = <MX91_PAD_GPIO_IO02__LPI2C4_SDA 0x40000b9e>, /* Lino P24 */ + <MX91_PAD_GPIO_IO03__LPI2C4_SCL 0x40000b9e>; /* Lino P26 */ + }; + + /* Lino SPI_2 */ + pinctrl_spi2: lpspi1grp { + fsl,pins = <MX91_PAD_SAI1_TXD0__LPSPI1_SCK 0x139e>, /* Lino S20 */ + <MX91_PAD_SAI1_RXD0__LPSPI1_SOUT 0x139e>, /* Lino S22 */ + <MX91_PAD_SAI1_TXC__LPSPI1_SIN 0x139e>; /* Lino S24 */ + }; + + /* Lino SPI_1 */ + pinctrl_spi1: lpspi8grp { + fsl,pins = <MX91_PAD_GPIO_IO13__LPSPI8_SIN 0x139e>, /* Lino P54 */ + <MX91_PAD_GPIO_IO14__LPSPI8_SOUT 0x139e>, /* Lino P56 */ + <MX91_PAD_GPIO_IO15__LPSPI8_SCK 0x139e>; /* Lino P52 */ + }; + + /* Lino UART_3 */ + pinctrl_uart3: lpuart1grp { + fsl,pins = <MX91_PAD_UART1_RXD__LPUART1_RX 0x39e>, /* Lino P17 */ + <MX91_PAD_UART1_TXD__LPUART1_TX 0x39e>; /* Lino P19 */ + }; + + /* Lino UART_4 */ + pinctrl_uart4: lpuart2grp { + fsl,pins = <MX91_PAD_UART2_RXD__LPUART2_RX 0x39e>, /* Lino P23 */ + <MX91_PAD_UART2_TXD__LPUART2_TX 0x39e>; /* Lino P25 */ + }; + + /* Lino UART_1 */ + pinctrl_uart1: lpuart6grp { + fsl,pins = <MX91_PAD_GPIO_IO04__LPUART6_TX 0x39e>, /* Lino P11 */ + <MX91_PAD_GPIO_IO05__LPUART6_RX 0x39e>, /* Lino P9 */ + <MX91_PAD_GPIO_IO06__LPUART6_CTS_B 0x39e>, /* Lino P8 */ + <MX91_PAD_GPIO_IO07__LPUART6_RTS_B 0x39e>; /* Lino P6 */ + }; + + /* Lino UART_2 */ + pinctrl_uart2: lpuart7grp { + fsl,pins = <MX91_PAD_GPIO_IO08__LPUART7_TX 0x39e>, /* Lino P15 */ + <MX91_PAD_GPIO_IO09__LPUART7_RX 0x39e>, /* Lino P13 */ + <MX91_PAD_GPIO_IO10__LPUART7_CTS_B 0x39e>, /* Lino S7 */ + <MX91_PAD_GPIO_IO11__LPUART7_RTS_B 0x39e>; /* Lino S5 */ + }; + + /* Lino I2S_1 */ + pinctrl_i2s1: sai3grp { + fsl,pins = <MX91_PAD_GPIO_IO16__SAI3_TX_BCLK 0x139e>, /* Lino S94 */ + <MX91_PAD_GPIO_IO19__SAI3_TX_DATA0 0x139e>, /* Lino S98 */ + <MX91_PAD_GPIO_IO20__SAI3_RX_DATA0 0x139e>, /* Lino S100 */ + <MX91_PAD_GPIO_IO26__SAI3_TX_SYNC 0x139e>; /* Lino S96 */ + }; + + /* Lino PWM_1 */ + pinctrl_pwm1: tpm4ch1grp { + fsl,pins = <MX91_PAD_GPIO_IO21__TPM4_CH1 0x139e>; /* Lino P1 */ + }; + + /* Lino PWM_2 */ + pinctrl_pwm2: tpm5ch2grp { + fsl,pins = <MX91_PAD_GPIO_IO18__TPM5_CH2 0x139e>; /* Lino P3 */ + }; + + /* Lino PWM_3 */ + pinctrl_pwm3: tpm6ch1grp { + fsl,pins = <MX91_PAD_GPIO_IO23__TPM6_CH1 0x139e>; /* Lino P5 */ + }; + + /* On-module eMMC */ + pinctrl_emmc: usdhc1grp { + fsl,pins = <MX91_PAD_SD1_CLK__USDHC1_CLK 0x5fe>, /* eMMC_CLK */ + <MX91_PAD_SD1_CMD__USDHC1_CMD 0x400013fe>, /* eMMC_CMD */ + <MX91_PAD_SD1_DATA0__USDHC1_DATA0 0x400013fe>, /* eMMC_DATA0 */ + <MX91_PAD_SD1_DATA1__USDHC1_DATA1 0x400013fe>, /* eMMC_DATA1 */ + <MX91_PAD_SD1_DATA2__USDHC1_DATA2 0x400013fe>, /* eMMC_DATA2 */ + <MX91_PAD_SD1_DATA3__USDHC1_DATA3 0x400013fe>, /* eMMC_DATA3 */ + <MX91_PAD_SD1_DATA4__USDHC1_DATA4 0x400013fe>, /* eMMC_DATA4 */ + <MX91_PAD_SD1_DATA5__USDHC1_DATA5 0x400013fe>, /* eMMC_DATA5 */ + <MX91_PAD_SD1_DATA6__USDHC1_DATA6 0x400013fe>, /* eMMC_DATA6 */ + <MX91_PAD_SD1_DATA7__USDHC1_DATA7 0x400013fe>, /* eMMC_DATA7 */ + <MX91_PAD_SD1_STROBE__USDHC1_STROBE 0x1580>; /* eMMC_STROBE */ + }; + + /* Lino SD_1_CD# */ + pinctrl_sd1_cd: usdhc2cdgrp { + fsl,pins = <MX91_PAD_SD2_CD_B__GPIO3_IO0 0x139e>; /* Lino P78 */ + }; + + /* Lino SD_1 */ + pinctrl_sd1: usdhc2grp { + fsl,pins = <MX91_PAD_SD2_CLK__USDHC2_CLK 0x5fe>, /* Lino P68 */ + <MX91_PAD_SD2_CMD__USDHC2_CMD 0x400013fe>, /* Lino P66 */ + <MX91_PAD_SD2_DATA0__USDHC2_DATA0 0x400013fe>, /* Lino P74 */ + <MX91_PAD_SD2_DATA1__USDHC2_DATA1 0x400013fe>, /* Lino P76 */ + <MX91_PAD_SD2_DATA2__USDHC2_DATA2 0x400013fe>, /* Lino P60 */ + <MX91_PAD_SD2_DATA3__USDHC2_DATA3 0x400013fe>; /* Lino P64 */ + }; + + /* Lino SD_1_PWR_EN */ + pinctrl_sd1_pwr_en: usdhc2pwrgrp { + fsl,pins = <MX91_PAD_SD2_RESET_B__GPIO3_IO7 0x139e>; /* Lino P72 */ + }; + + /* On-module PMIC_SD_2_VSEL */ + pinctrl_sd1_vsel: usdhc2vselgrp { + fsl,pins = <MX91_PAD_SD2_VSELECT__GPIO3_IO19 0x51e>; /* PMIC_SD_2_VSEL */ + }; + + /* Lino SD_2 */ + pinctrl_sd2: usdhc3grp { + fsl,pins = <MX91_PAD_SD3_CLK__USDHC3_CLK 0x5fe>, /* Lino S10 */ + <MX91_PAD_SD3_CMD__USDHC3_CMD 0x400013fe>, /* Lino S8 */ + <MX91_PAD_SD3_DATA0__USDHC3_DATA0 0x400013fe>, /* Lino S12 */ + <MX91_PAD_SD3_DATA1__USDHC3_DATA1 0x400013fe>, /* Lino S16 */ + <MX91_PAD_SD3_DATA2__USDHC3_DATA2 0x400013fe>, /* Lino S2 */ + <MX91_PAD_SD3_DATA3__USDHC3_DATA3 0x400013fe>; /* Lino S4 */ + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = <MX91_PAD_WDOG_ANY__WDOG1_WDOG_ANY 0x31e>; /* PMIC_WDOG_B */ + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx91-toradex-osm-dev.dts b/arch/arm64/boot/dts/freescale/imx91-toradex-osm-dev.dts new file mode 100644 index 0000000..ec5e701 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx91-toradex-osm-dev.dts
@@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Toradex OSM iMX91 SoM on OSM Development carrier board + * + * https://www.toradex.com/computer-on-modules/osm-arm-family/nxp-imx91 + * https://www.toradex.com/products/carrier-board/osm-development-board + */ + +/dts-v1/; + +#include "imx91.dtsi" +#include "imx91-toradex-osm.dtsi" +#include "imx93-imx91-toradex-osm-dev-common.dtsi" + +/ { + model = "Toradex OSM iMX91 on OSM Development Board"; + compatible = "toradex,osm-imx91-dev", + "toradex,osm-imx91", + "fsl,imx91"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx91-toradex-osm.dtsi b/arch/arm64/boot/dts/freescale/imx91-toradex-osm.dtsi new file mode 100644 index 0000000..9d99093 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx91-toradex-osm.dtsi
@@ -0,0 +1,303 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Toradex OSM iMX91 SoM + * + * https://www.toradex.com/computer-on-modules/osm-arm-family/nxp-imx91 + */ + +#include "imx91-pinfunc.h" +#include "imx93-imx91-toradex-osm-common.dtsi" + +&iomuxc { + /* OSM CAN_A */ + pinctrl_can_a: can1grp { + fsl,pins = <MX91_PAD_PDM_BIT_STREAM0__CAN1_RX 0x139e>, /* OSM AB17 */ + <MX91_PAD_PDM_CLK__CAN1_TX 0x139e>; /* OSM AC17 */ + }; + + /* OSM CAN_B */ + pinctrl_can_b: can2grp { + fsl,pins = <MX91_PAD_GPIO_IO25__CAN2_TX 0x139e>, /* OSM AC19 */ + <MX91_PAD_GPIO_IO27__CAN2_RX 0x139e>; /* OSM AB19 */ + }; + + /* OSM CAM_MCK */ + pinctrl_cam_mck: ccmclk1grp { + fsl,pins = <MX91_PAD_CCM_CLKO1__CCMSRCGPCMIX_CLKO1 0x51e>; /* OSM C2 */ + }; + + /* OSM ETH_A RGMII */ + pinctrl_eth_a: eqosgrp { + fsl,pins = <MX91_PAD_ENET1_RD0__ENET_QOS_RGMII_RD0 0x1fe>, /* OSM K15 */ + <MX91_PAD_ENET1_RD1__ENET_QOS_RGMII_RD1 0x1fe>, /* OSM L15 */ + <MX91_PAD_ENET1_RD2__ENET_QOS_RGMII_RD2 0x1fe>, /* OSM N15 */ + <MX91_PAD_ENET1_RD3__ENET_QOS_RGMII_RD3 0x1fe>, /* OSM P15 */ + <MX91_PAD_ENET1_RXC__ENET_QOS_RGMII_RXC 0x1fe>, /* OSM R15 */ + <MX91_PAD_ENET1_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x1fe>, /* OSM M15 */ + <MX91_PAD_ENET1_TD0__ENET_QOS_RGMII_TD0 0x1fe>, /* OSM H15 */ + <MX91_PAD_ENET1_TD1__ENET1_RGMII_TD1 0x1fe>, /* OSM G15 */ + <MX91_PAD_ENET1_TD2__ENET_QOS_RGMII_TD2 0x1fe>, /* OSM H16 */ + <MX91_PAD_ENET1_TD3__ENET_QOS_RGMII_TD3 0x1fe>, /* OSM G16 */ + <MX91_PAD_ENET1_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x1fe>, /* OSM J15 */ + <MX91_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1fe>; /* OSM K16 */ + }; + + /* OSM ETH_MDIO */ + pinctrl_mdio: eqosmdiogrp { + fsl,pins = <MX91_PAD_ENET1_MDC__ENET1_MDC 0x1fe>, /* OSM T16 */ + <MX91_PAD_ENET1_MDIO__ENET_QOS_MDIO 0x1fe>; /* OSM T15 */ + }; + + /* OSM ETH_B RGMII */ + pinctrl_eth_b: fecgrp { + fsl,pins = <MX91_PAD_ENET2_RD0__ENET2_RGMII_RD0 0x1fe>, /* OSM J1 */ + <MX91_PAD_ENET2_RD1__ENET2_RGMII_RD1 0x1fe>, /* OSM K1 */ + <MX91_PAD_ENET2_RD2__ENET2_RGMII_RD2 0x1fe>, /* OSM M1 */ + <MX91_PAD_ENET2_RD3__ENET2_RGMII_RD3 0x1fe>, /* OSM N1 */ + <MX91_PAD_ENET2_RXC__ENET2_RGMII_RXC 0x1fe>, /* OSM P1 */ + <MX91_PAD_ENET2_RX_CTL__ENET2_RGMII_RX_CTL 0x1fe>, /* OSM L1 */ + <MX91_PAD_ENET2_TD0__ENET2_RGMII_TD0 0x1fe>, /* OSM G1 */ + <MX91_PAD_ENET2_TD1__ENET2_RGMII_TD1 0x1fe>, /* OSM F1 */ + <MX91_PAD_ENET2_TD2__ENET2_RGMII_TD2 0x1fe>, /* OSM G2 */ + <MX91_PAD_ENET2_TD3__ENET2_RGMII_TD3 0x1fe>, /* OSM F2 */ + <MX91_PAD_ENET2_TXC__ENET2_RGMII_TXC 0x1fe>, /* OSM H1 */ + <MX91_PAD_ENET2_TX_CTL__ENET2_RGMII_TX_CTL 0x1fe>; /* OSM J2 */ + }; + + /* OSM SPI_B_CS as GPIO */ + pinctrl_spi_b_cs0_gpio: gpio1io11grp { + fsl,pins = <MX91_PAD_SAI1_TXFS__GPIO1_IO11 0x139e>; /* OSM AA23 */ + }; + + /* OSM GPIO_A_0 */ + pinctrl_gpio_a0: gpio2io0grp { + fsl,pins = <MX91_PAD_GPIO_IO00__GPIO2_IO0 0x139e>; /* OSM D17 */ + }; + + /* OSM GPIO_A_1 */ + pinctrl_gpio_a1: gpio2io1grp { + fsl,pins = <MX91_PAD_GPIO_IO01__GPIO2_IO1 0x139e>; /* OSM E17 */ + }; + + /* OSM GPIO_A_2 */ + pinctrl_gpio_a2: gpio2io2grp { + fsl,pins = <MX91_PAD_GPIO_IO02__GPIO2_IO2 0x139e>; /* OSM F17 */ + }; + + /* OSM GPIO_A_3 */ + pinctrl_gpio_a3: gpio2io3grp { + fsl,pins = <MX91_PAD_GPIO_IO03__GPIO2_IO3 0x139e>; /* OSM G17 */ + }; + + /* OSM SPI_A_CS0 as GPIO */ + pinctrl_spi_a_cs0_gpio: gpio2io12grp { + fsl,pins = <MX91_PAD_GPIO_IO12__GPIO2_IO12 0x139e>; /* OSM Y15 */ + }; + + /* OSM PWM_0 as GPIO */ + pinctrl_pwm0_gpio: gpio2io21grp { + fsl,pins = <MX91_PAD_GPIO_IO21__GPIO2_IO21 0x139e>; /* OSM E18 */ + }; + + /* OSM GPIO_A_4 */ + pinctrl_gpio_a4: gpio2io22grp { + fsl,pins = <MX91_PAD_GPIO_IO22__GPIO2_IO22 0x139e>; /* OSM H17 */ + }; + + /* OSM GPIO_A_5 */ + pinctrl_gpio_a5: gpio2io24grp { + fsl,pins = <MX91_PAD_GPIO_IO24__GPIO2_IO24 0x139e>; /* OSM J17 */ + }; + + /* On-module CTRL_INT# */ + pinctrl_ctrl_int: gpio3io27grp { + fsl,pins = <MX91_PAD_CCM_CLKO2__GPIO3_IO27 0x139e>; /* CTRL_INT# */ + }; + + /* OSM GPIO_A_6 */ + pinctrl_gpio_a6: gpio4io14grp { + fsl,pins = <MX91_PAD_ENET2_MDC__GPIO4_IO14 0x139e>; /* OSM K17 */ + }; + + /* OSM GPIO_A_7 */ + pinctrl_gpio_a7: gpio4io15grp { + fsl,pins = <MX91_PAD_ENET2_MDIO__GPIO4_IO15 0x139e>; /* OSM L17 */ + }; + + /* OSM I2C_B as GPIO */ + pinctrl_i2c_b_gpio: lpi2c1gpiogrp { + fsl,pins = <MX91_PAD_I2C1_SCL__GPIO1_IO0 0x40000b9e>, /* OSM AA20 */ + <MX91_PAD_I2C1_SDA__GPIO1_IO1 0x40000b9e>; /* OSM AA21 */ + }; + + /* OSM I2C_B */ + pinctrl_i2c_b: lpi2c1grp { + fsl,pins = <MX91_PAD_I2C1_SCL__LPI2C1_SCL 0x40000b9e>, /* OSM AA20 */ + <MX91_PAD_I2C1_SDA__LPI2C1_SDA 0x40000b9e>; /* OSM AA21 */ + }; + + /* On-module PMIC I2C as GPIO */ + pinctrl_pmic_i2c_gpio: lpi2c2gpiogrp { + fsl,pins = <MX91_PAD_I2C2_SCL__GPIO1_IO2 0x40000b9e>, /* PMIC_I2C_SCL */ + <MX91_PAD_I2C2_SDA__GPIO1_IO3 0x40000b9e>; /* PMIC_I2C_SDA */ + }; + + /* On-module PMIC I2C */ + pinctrl_pmic_i2c: lpi2c2grp { + fsl,pins = <MX91_PAD_I2C2_SCL__LPI2C2_SCL 0x40000b9e>, /* PMIC_I2C_SCL */ + <MX91_PAD_I2C2_SDA__LPI2C2_SDA 0x40000b9e>; /* PMIC_I2C_SDA */ + }; + + /* OSM I2C_A as GPIO */ + pinctrl_i2c_a_gpio: lpi2c3gpiogrp { + fsl,pins = <MX91_PAD_GPIO_IO28__GPIO2_IO28 0x40000b9e>, /* OSM AA16 */ + <MX91_PAD_GPIO_IO29__GPIO2_IO29 0x40000b9e>; /* OSM AA15 */ + }; + + /* OSM I2C_A */ + pinctrl_i2c_a: lpi2c3grp { + fsl,pins = <MX91_PAD_GPIO_IO28__LPI2C3_SDA 0x40000b9e>, /* OSM AA16 */ + <MX91_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e>; /* OSM AA15 */ + }; + + /* OSM SPI_B */ + pinctrl_spi_b: lpspi1grp { + fsl,pins = <MX91_PAD_SAI1_TXC__LPSPI1_SIN 0x139e>, /* OSM Y22 */ + <MX91_PAD_SAI1_TXD0__LPSPI1_SCK 0x139e>, /* OSM Y21 */ + <MX91_PAD_SAI1_RXD0__LPSPI1_SOUT 0x139e>; /* OSM Y23 */ + }; + + /* OSM SPI_A */ + pinctrl_spi_a: lpspi8grp { + fsl,pins = <MX91_PAD_GPIO_IO13__LPSPI8_SIN 0x139e>, /* OSM U15 */ + <MX91_PAD_GPIO_IO14__LPSPI8_SOUT 0x139e>, /* OSM V15 */ + <MX91_PAD_GPIO_IO15__LPSPI8_SCK 0x139e>; /* OSM U16 */ + }; + + /* OSM UART_CON */ + pinctrl_uart_con: lpuart1grp { + fsl,pins = <MX91_PAD_UART1_RXD__LPUART1_RX 0x39e>, /* OSM D22 */ + <MX91_PAD_UART1_TXD__LPUART1_TX 0x39e>; /* OSM D23 */ + }; + + /* OSM UART_C */ + pinctrl_uart_c: lpuart2grp { + fsl,pins = <MX91_PAD_UART2_RXD__LPUART2_RX 0x39e>, /* OSM A22 */ + <MX91_PAD_UART2_TXD__LPUART2_TX 0x39e>; /* OSM B23 */ + }; + + /* OSM UART_A */ + pinctrl_uart_a: lpuart6grp { + fsl,pins = <MX91_PAD_GPIO_IO04__LPUART6_TX 0x39e>, /* OSM B13 */ + <MX91_PAD_GPIO_IO05__LPUART6_RX 0x39e>, /* OSM A14 */ + <MX91_PAD_GPIO_IO06__LPUART6_CTS_B 0x39e>, /* OSM C14 */ + <MX91_PAD_GPIO_IO07__LPUART6_RTS_B 0x39e>; /* OSM C13 */ + }; + + /* OSM UART_B */ + pinctrl_uart_b: lpuart7grp { + fsl,pins = <MX91_PAD_GPIO_IO08__LPUART7_TX 0x39e>, /* OSM D13 */ + <MX91_PAD_GPIO_IO09__LPUART7_RX 0x39e>, /* OSM D14 */ + <MX91_PAD_GPIO_IO10__LPUART7_CTS_B 0x39e>, /* OSM D16 */ + <MX91_PAD_GPIO_IO11__LPUART7_RTS_B 0x39e>; /* OSM D15 */ + }; + + /* OSM I2S_A */ + pinctrl_i2s_a: sai3grp { + fsl,pins = <MX91_PAD_GPIO_IO16__SAI3_TX_BCLK 0x139e>, /* OSM W20 */ + <MX91_PAD_GPIO_IO19__SAI3_TX_DATA0 0x139e>, /* OSM W21 */ + <MX91_PAD_GPIO_IO20__SAI3_RX_DATA0 0x139e>, /* OSM V21 */ + <MX91_PAD_GPIO_IO26__SAI3_TX_SYNC 0x139e>; /* OSM W18 */ + }; + + /* OSM I2S_MCLK */ + pinctrl_i2s_a_mclk: sai3mclkgrp { + fsl,pins = <MX91_PAD_GPIO_IO17__SAI3_MCLK 0x31e>; /* OSM V18 */ + }; + + /* OSM PWM_0 */ + pinctrl_pwm0: tpm4ch1grp { + fsl,pins = <MX91_PAD_GPIO_IO21__TPM4_CH1 0x139e>; /* OSM E18 */ + }; + + /* OSM PWM_1 */ + pinctrl_pwm1: tpm5ch2grp { + fsl,pins = <MX91_PAD_GPIO_IO18__TPM5_CH2 0x139e>; /* OSM F18 */ + }; + + /* OSM PWM_2 */ + pinctrl_pwm2: tpm6ch1grp { + fsl,pins = <MX91_PAD_GPIO_IO23__TPM6_CH1 0x139e>; /* OSM G18 */ + }; + + /* OSM USB_A_EN */ + pinctrl_usb_a_en: usb1engrp { + fsl,pins = <MX91_PAD_CCM_CLKO3__GPIO4_IO28 0x139e>; /* OSM AC16 */ + }; + + /* OSM USB_A_OC# */ + pinctrl_usb_a_oc: usb1ocgrp { + fsl,pins = <MX91_PAD_CCM_CLKO4__GPIO4_IO29 0x139e>; /* OSM AC15 */ + }; + + /* OSM USB_B_EN */ + pinctrl_usb_b_en: usb2engrp { + fsl,pins = <MX91_PAD_PDM_BIT_STREAM1__GPIO1_IO10 0x139e>; /* OSM AC20 */ + }; + + /* On-module eMMC */ + pinctrl_emmc: usdhc1grp { + fsl,pins = <MX91_PAD_SD1_CLK__USDHC1_CLK 0x5fe>, /* eMMC_CLK */ + <MX91_PAD_SD1_CMD__USDHC1_CMD 0x400013fe>, /* eMMC_CMD */ + <MX91_PAD_SD1_DATA0__USDHC1_DATA0 0x400013fe>, /* eMMC_DATA0 */ + <MX91_PAD_SD1_DATA1__USDHC1_DATA1 0x400013fe>, /* eMMC_DATA1 */ + <MX91_PAD_SD1_DATA2__USDHC1_DATA2 0x400013fe>, /* eMMC_DATA2 */ + <MX91_PAD_SD1_DATA3__USDHC1_DATA3 0x400013fe>, /* eMMC_DATA3 */ + <MX91_PAD_SD1_DATA4__USDHC1_DATA4 0x400013fe>, /* eMMC_DATA4 */ + <MX91_PAD_SD1_DATA5__USDHC1_DATA5 0x400013fe>, /* eMMC_DATA5 */ + <MX91_PAD_SD1_DATA6__USDHC1_DATA6 0x400013fe>, /* eMMC_DATA6 */ + <MX91_PAD_SD1_DATA7__USDHC1_DATA7 0x400013fe>, /* eMMC_DATA7 */ + <MX91_PAD_SD1_STROBE__USDHC1_STROBE 0x1580>; /* eMMC_STROBE */ + }; + + /* OSM SDIO_A_CD# */ + pinctrl_sdio_a_cd: usdhc2cdgrp { + fsl,pins = <MX91_PAD_SD2_CD_B__GPIO3_IO0 0x139e>; /* OSM J21 */ + }; + + /* OSM SDIO_A */ + pinctrl_sdio_a: usdhc2grp { + fsl,pins = <MX91_PAD_SD2_CLK__USDHC2_CLK 0x5fe>, /* OSM F21 */ + <MX91_PAD_SD2_CMD__USDHC2_CMD 0x400013fe>, /* OSM E20 */ + <MX91_PAD_SD2_DATA0__USDHC2_DATA0 0x400013fe>, /* OSM G20 */ + <MX91_PAD_SD2_DATA1__USDHC2_DATA1 0x400013fe>, /* OSM G21 */ + <MX91_PAD_SD2_DATA2__USDHC2_DATA2 0x400013fe>, /* OSM H20 */ + <MX91_PAD_SD2_DATA3__USDHC2_DATA3 0x400013fe>; /* OSM H21 */ + }; + + /* OSM SDIO_A_PWR_EN */ + pinctrl_sdio_a_pwr_en: usdhc2pwrgrp { + fsl,pins = <MX91_PAD_SD2_RESET_B__GPIO3_IO7 0x139e>; /* OSM D21 */ + }; + + /* On-module PMIC_SD_2_VSEL */ + pinctrl_sdio_a_vsel: usdhc2vselgrp { + fsl,pins = <MX91_PAD_SD2_VSELECT__GPIO3_IO19 0x51e>; /* PMIC_SD_2_VSEL */ + }; + + /* OSM SDIO_B */ + pinctrl_sdio_b: usdhc3grp { + fsl,pins = <MX91_PAD_SD3_CLK__USDHC3_CLK 0x5fe>, /* OSM K20 */ + <MX91_PAD_SD3_CMD__USDHC3_CMD 0x400013fe>, /* OSM K21 */ + <MX91_PAD_SD3_DATA0__USDHC3_DATA0 0x400013fe>, /* OSM L20 */ + <MX91_PAD_SD3_DATA1__USDHC3_DATA1 0x400013fe>, /* OSM L21 */ + <MX91_PAD_SD3_DATA2__USDHC3_DATA2 0x400013fe>, /* OSM M21 */ + <MX91_PAD_SD3_DATA3__USDHC3_DATA3 0x400013fe>; /* OSM N20 */ + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = <MX91_PAD_WDOG_ANY__WDOG1_WDOG_ANY 0x31e>; /* PMIC_WDOG_B */ + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx91.dtsi b/arch/arm64/boot/dts/freescale/imx91.dtsi index d63569b..a7355f5 100644 --- a/arch/arm64/boot/dts/freescale/imx91.dtsi +++ b/arch/arm64/boot/dts/freescale/imx91.dtsi
@@ -62,6 +62,10 @@ &ddr_pmu { compatible = "fsl,imx91-ddr-pmu", "fsl,imx93-ddr-pmu"; }; +&dpi_bridge { + compatible = "nxp,imx91-pdfc"; +}; + &eqos { clocks = <&clk IMX91_CLK_ENET1_QOS_TSN_GATE>, <&clk IMX91_CLK_ENET1_QOS_TSN_GATE>, @@ -116,6 +120,13 @@ &media_blk_ctrl { <&clk IMX93_CLK_MIPI_CSI_GATE>; clock-names = "apb", "axi", "nic", "disp", "cam", "lcdif", "isi", "csi"; + assigned-clocks = <&clk IMX93_CLK_MEDIA_AXI>, + <&clk IMX93_CLK_MEDIA_APB>, + <&clk IMX93_CLK_MEDIA_DISP_PIX>; + assigned-clock-parents = <&clk IMX93_CLK_SYS_PLL_PFD0>, + <&clk IMX93_CLK_SYS_PLL_PFD0_DIV2>, + <&clk IMX93_CLK_VIDEO_PLL>; + assigned-clock-rates = <333330000>, <125000000>; }; &ocotp {
diff --git a/arch/arm64/boot/dts/freescale/imx91_93_common.dtsi b/arch/arm64/boot/dts/freescale/imx91_93_common.dtsi index a1a7e6a..a68ffd0 100644 --- a/arch/arm64/boot/dts/freescale/imx91_93_common.dtsi +++ b/arch/arm64/boot/dts/freescale/imx91_93_common.dtsi
@@ -100,13 +100,19 @@ gic: interrupt-controller@48000000 { mqs1: mqs1 { compatible = "fsl,imx93-mqs"; + clocks = <&clk IMX93_CLK_MQS1_GATE>; + clock-names = "mclk"; gpr = <&aonmix_ns_gpr>; + #sound-dai-cells = <0>; status = "disabled"; }; mqs2: mqs2 { compatible = "fsl,imx93-mqs"; + clocks = <&clk IMX93_CLK_MQS2_GATE>; + clock-names = "mclk"; gpr = <&wakeupmix_gpr>; + #sound-dai-cells = <0>; status = "disabled"; };
diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk-common.dtsi b/arch/arm64/boot/dts/freescale/imx93-11x11-evk-common.dtsi index f48e794..164b5c1 100644 --- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk-common.dtsi +++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk-common.dtsi
@@ -18,6 +18,7 @@ aliases { mmc0 = &usdhc1; mmc1 = &usdhc2; rtc0 = &bbnsm_rtc; + rtc1 = &pcf2131; serial0 = &lpuart1; serial1 = &lpuart2; serial2 = &lpuart3; @@ -67,7 +68,7 @@ rsc_table: rsc-table@2021e000 { no-map; }; - vdevbuffer: vdevbuffer@a4020000 { + vdev0buffer: vdev0buffer@a4020000 { compatible = "shared-dma-pool"; reg = <0 0xa4020000 0 0x100000>; no-map; @@ -170,7 +171,7 @@ &cm33 { mboxes = <&mu1 0 1>, <&mu1 1 1>, <&mu1 3 1>; - memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, + memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>; status = "okay"; };
diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts index c6db9c8..d331209 100644 --- a/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx93-11x11-evk.dts
@@ -16,6 +16,38 @@ aliases { mmc2 = &usdhc3; }; + amp_mqs1: audio-amplifier { + compatible = "simple-audio-amplifier"; + sound-name-prefix = "MQS AMP"; + VCC-supply = <®_3p3v>; + }; + + pdm_mqs1_mux: mux-controller-0 { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + #mux-state-cells = <1>; + mux-gpios = <&adp5585 2 GPIO_ACTIVE_HIGH>; + }; + + pinctrl-gpiomux { + compatible = "pinctrl-multiplexer"; + + mqs1_fun: mqs1-grp { + mux-states = <&pdm_mqs1_mux 1>; + }; + + pdm_fun: pdm-grp { + mux-states = <&pdm_mqs1_mux 0>; + }; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "+V3.3_SW"; + }; + reg_m2_pwr: regulator-m2-pwr { compatible = "regulator-fixed"; regulator-name = "M.2-power"; @@ -52,7 +84,7 @@ bt_sco_codec: bt-sco-codec { #sound-dai-cells = <1>; }; - sound-bt-sco { + mqs1_conflict_card: sound-bt-sco { compatible = "simple-audio-card"; simple-audio-card,name = "bt-sco-audio"; simple-audio-card,format = "dsp_a"; @@ -86,9 +118,9 @@ cpu { }; }; -&micfil { +mqs1_conflict_dev: &micfil { pinctrl-names = "default", "sleep"; - pinctrl-0 = <&pinctrl_pdm>; + pinctrl-0 = <&pinctrl_pdm>, <&pdm_fun>; pinctrl-1 = <&pinctrl_pdm_sleep>; assigned-clocks = <&clk IMX93_CLK_PDM>; assigned-clock-parents = <&clk IMX93_CLK_AUDIO_PLL>; @@ -96,6 +128,11 @@ &micfil { status = "okay"; }; +&mqs1 { + pinctrl-0 = <&pinctrl_mqs1>, <&mqs1_fun>; + pinctrl-names = "default"; +}; + &pcal6524 { m2-pcm-level-shifter-hog { gpio-hog; @@ -108,6 +145,10 @@ &sai1 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&pinctrl_sai1>; pinctrl-1 = <&pinctrl_sai1_sleep>; + clocks = <&clk IMX93_CLK_SAI1_IPG>, <&clk IMX93_CLK_DUMMY>, + <&clk IMX93_CLK_SAI1_GATE>, <&clk IMX93_CLK_DUMMY>, + <&clk IMX93_CLK_DUMMY>, <&clk IMX93_CLK_AUDIO_PLL>; + clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k"; assigned-clocks = <&clk IMX93_CLK_SAI1>; assigned-clock-parents = <&clk IMX93_CLK_AUDIO_PLL>; assigned-clock-rates = <12288000>; @@ -131,6 +172,13 @@ &usdhc3 { }; &iomuxc { + pinctrl_mqs1: mqs1grp { + fsl,pins = < + MX93_PAD_PDM_CLK__MQS1_LEFT 0x31e + MX93_PAD_PDM_BIT_STREAM0__MQS1_RIGHT 0x31e + >; + }; + pinctrl_pdm: pdmgrp { fsl,pins = < MX93_PAD_PDM_CLK__PDM_CLK 0x31e
diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-frdm-common.dtsi b/arch/arm64/boot/dts/freescale/imx93-11x11-frdm-common.dtsi new file mode 100644 index 0000000..33ed26a --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93-11x11-frdm-common.dtsi
@@ -0,0 +1,681 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +#include <dt-bindings/usb/pd.h> + +/ { + aliases { + can0 = &flexcan2; + ethernet0 = &fec; + ethernet1 = &eqos; + i2c0 = &lpi2c1; + i2c1 = &lpi2c2; + i2c2 = &lpi2c3; + mmc0 = &usdhc1; /* EMMC */ + mmc1 = &usdhc2; /* uSD */ + rtc0 = &pcf2131; + rtc1 = &bbnsm_rtc; + serial0 = &lpuart1; + serial4 = &lpuart5; + }; + + chosen { + stdout-path = &lpuart1; + }; + + flexcan2_phy: can-phy { + compatible = "nxp,tja1051"; + #phy-cells = <0>; + max-bitrate = <5000000>; + silent-gpios = <&pcal6524 23 GPIO_ACTIVE_HIGH>; + }; + + gpio-keys { + compatible = "gpio-keys"; + + button-k2 { + label = "Button K2"; + linux,code = <BTN_1>; + gpios = <&pcal6524 5 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + interrupt-parent = <&pcal6524>; + interrupts = <5 IRQ_TYPE_EDGE_FALLING>; + }; + + button-k3 { + label = "Button K3"; + linux,code = <BTN_2>; + gpios = <&pcal6524 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + interrupt-parent = <&pcal6524>; + interrupts = <6 IRQ_TYPE_EDGE_FALLING>; + }; + }; + + reg_usdhc2_vmmc: regulator-usdhc2 { + compatible = "regulator-fixed"; + off-on-delay-us = <12000>; + pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>; + pinctrl-names = "default"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "VSD_3V3"; + vin-supply = <&buck4>; + gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reserved-memory { + ranges; + #address-cells = <2>; + #size-cells = <2>; + + linux,cma { + compatible = "shared-dma-pool"; + alloc-ranges = <0 0x80000000 0 0x30000000>; + reusable; + size = <0 0x10000000>; + linux,cma-default; + }; + + rsc_table: rsc-table@2021e000 { + reg = <0 0x2021e000 0 0x1000>; + no-map; + }; + + vdev0vring0: vdev0vring0@a4000000 { + reg = <0 0xa4000000 0 0x8000>; + no-map; + }; + + vdev0vring1: vdev0vring1@a4008000 { + reg = <0 0xa4008000 0 0x8000>; + no-map; + }; + + vdev1vring0: vdev1vring0@a4010000 { + reg = <0 0xa4010000 0 0x8000>; + no-map; + }; + + vdev1vring1: vdev1vring1@a4018000 { + reg = <0 0xa4018000 0 0x8000>; + no-map; + }; + + vdev0buffer: vdev0buffer@a4020000 { + compatible = "shared-dma-pool"; + reg = <0 0xa4020000 0 0x100000>; + no-map; + }; + }; +}; + +&adc1 { + vref-supply = <&buck5>; + status = "okay"; +}; + +&mu1 { + status = "okay"; +}; + +&cm33 { + mboxes = <&mu1 0 1>, + <&mu1 1 1>, + <&mu1 3 1>; + mbox-names = "tx", "rx", "rxdb"; + memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, + <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>; + status = "okay"; +}; + +&eqos { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pinctrl_eqos>; + pinctrl-1 = <&pinctrl_eqos_sleep>; + phy-handle = <ðphy1>; + phy-mode = "rgmii-id"; + status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <5000000>; + + ethphy1: ethernet-phy@1 { + reg = <1>; + reset-assert-us = <10000>; + reset-deassert-us = <80000>; + reset-gpios = <&pcal6524 15 GPIO_ACTIVE_LOW>; + realtek,clkout-disable; + }; + }; +}; + +&fec { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pinctrl_fec>; + pinctrl-1 = <&pinctrl_fec_sleep>; + phy-mode = "rgmii-id"; + phy-handle = <ðphy2>; + fsl,magic-packet; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + clock-frequency = <5000000>; + + ethphy2: ethernet-phy@2 { + reg = <2>; + reset-assert-us = <10000>; + reset-deassert-us = <80000>; + reset-gpios = <&pcal6524 16 GPIO_ACTIVE_LOW>; + realtek,clkout-disable; + }; + }; +}; + +&flexcan2 { + phys = <&flexcan2_phy>; + pinctrl-0 = <&pinctrl_flexcan2>; + pinctrl-1 = <&pinctrl_flexcan2_sleep>; + pinctrl-names = "default", "sleep"; + status = "okay"; +}; + +&lpi2c1 { + clock-frequency = <400000>; + pinctrl-0 = <&pinctrl_lpi2c1>; + pinctrl-names = "default"; + status = "okay"; +}; + +&lpi2c2 { + clock-frequency = <400000>; + pinctrl-0 = <&pinctrl_lpi2c2>; + pinctrl-names = "default"; + status = "okay"; + + pcal6524: gpio@22 { + compatible = "nxp,pcal6524"; + reg = <0x22>; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&gpio3>; + interrupts = <27 IRQ_TYPE_LEVEL_LOW>; + #gpio-cells = <2>; + gpio-controller; + pinctrl-0 = <&pinctrl_pcal6524>; + pinctrl-names = "default"; + /* does not boot with supplier set, because it is the bucks interrupt parent */ + /* vcc-supply = <&buck4>; */ + }; + + pmic@25 { + compatible = "nxp,pca9451a"; + reg = <0x25>; + interrupt-parent = <&pcal6524>; + interrupts = <11 IRQ_TYPE_EDGE_FALLING>; + + regulators { + + buck1: BUCK1 { + regulator-name = "VDD_SOC_0V8"; + regulator-min-microvolt = <610000>; + regulator-max-microvolt = <950000>; + regulator-always-on; + regulator-boot-on; + regulator-ramp-delay = <3125>; + }; + + buck2: BUCK2 { + regulator-name = "LPD4_x_VDDQ_0V6"; + regulator-min-microvolt = <600000>; + regulator-max-microvolt = <670000>; + regulator-always-on; + regulator-boot-on; + regulator-ramp-delay = <3125>; + }; + + buck4: BUCK4 { + regulator-name = "VDD_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + buck5: BUCK5 { + regulator-name = "VDD_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + buck6: BUCK6 { + regulator-name = "LPD4_x_VDD2_1V1"; + regulator-min-microvolt = <1060000>; + regulator-max-microvolt = <1140000>; + regulator-always-on; + regulator-boot-on; + }; + + ldo1: LDO1 { + regulator-name = "NVCC_BBSM_1V8"; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <1980000>; + regulator-always-on; + regulator-boot-on; + }; + + ldo4: LDO4 { + regulator-name = "VDD_ANA_0V8"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <840000>; + regulator-always-on; + regulator-boot-on; + }; + + ldo5: LDO5 { + regulator-name = "NVCC_SD"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + }; + }; + + eeprom: eeprom@50 { + compatible = "atmel,24c256"; + reg = <0x50>; + pagesize = <64>; + vcc-supply = <&buck4>; + }; +}; + +&lpi2c3 { + clock-frequency = <400000>; + pinctrl-0 = <&pinctrl_lpi2c3>; + pinctrl-names = "default"; + status = "okay"; + + ptn5110: tcpc@50 { + compatible = "nxp,ptn5110", "tcpci"; + reg = <0x50>; + interrupt-parent = <&gpio3>; + interrupts = <27 IRQ_TYPE_LEVEL_LOW>; + + typec1_con: connector { + compatible = "usb-c-connector"; + data-role = "dual"; + label = "USB-C"; + op-sink-microwatt = <15000000>; + power-role = "dual"; + self-powered; + sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM) + PDO_VAR(5000, 20000, 3000)>; + source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>; + try-power-role = "sink"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + typec1_dr_sw: endpoint { + remote-endpoint = <&usb1_drd_sw>; + }; + }; + }; + }; + }; + + pcf2131: rtc@53 { + compatible = "nxp,pcf2131"; + reg = <0x53>; + interrupt-parent = <&pcal6524>; + interrupts = <1 IRQ_TYPE_EDGE_FALLING>; + }; +}; + +&lpuart1 { /* console */ + pinctrl-0 = <&pinctrl_uart1>; + pinctrl-names = "default"; + status = "okay"; +}; + +&lpuart5 { + pinctrl-0 = <&pinctrl_uart5>; + pinctrl-names = "default"; + status = "okay"; + + uart-has-rtscts; + + bluetooth: bluetooth { + compatible = "nxp,88w8987-bt"; + }; +}; + +&usbotg1 { + adp-disable; + disable-over-current; + dr_mode = "otg"; + hnp-disable; + srp-disable; + usb-role-switch; + samsung,picophy-dc-vol-level-adjust = <7>; + samsung,picophy-pre-emp-curr-control = <3>; + status = "okay"; + + port { + usb1_drd_sw: endpoint { + remote-endpoint = <&typec1_dr_sw>; + }; + }; +}; + +&usbotg2 { + disable-over-current; + dr_mode = "host"; + samsung,picophy-dc-vol-level-adjust = <7>; + samsung,picophy-pre-emp-curr-control = <3>; + status = "okay"; +}; + +&usdhc1 { + bus-width = <8>; + non-removable; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + vmmc-supply = <&buck4>; + status = "okay"; +}; + +&usdhc2 { + bus-width = <4>; + cd-gpios = <&gpio3 00 GPIO_ACTIVE_LOW>; + no-mmc; + no-sdio; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; + pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_gpio_sleep>; + pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; + vmmc-supply = <®_usdhc2_vmmc>; + status = "okay"; +}; + +&wdog3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + status = "okay"; +}; + +&iomuxc { + + pinctrl_eqos: eqosgrp { + fsl,pins = < + MX93_PAD_ENET1_MDC__ENET_QOS_MDC 0x57e + MX93_PAD_ENET1_MDIO__ENET_QOS_MDIO 0x57e + MX93_PAD_ENET1_RD0__ENET_QOS_RGMII_RD0 0x57e + MX93_PAD_ENET1_RD1__ENET_QOS_RGMII_RD1 0x57e + MX93_PAD_ENET1_RD2__ENET_QOS_RGMII_RD2 0x57e + MX93_PAD_ENET1_RD3__ENET_QOS_RGMII_RD3 0x57e + MX93_PAD_ENET1_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x58e + MX93_PAD_ENET1_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x57e + MX93_PAD_ENET1_TD0__ENET_QOS_RGMII_TD0 0x57e + MX93_PAD_ENET1_TD1__ENET_QOS_RGMII_TD1 0x57e + MX93_PAD_ENET1_TD2__ENET_QOS_RGMII_TD2 0x57e + MX93_PAD_ENET1_TD3__ENET_QOS_RGMII_TD3 0x57e + MX93_PAD_ENET1_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x58e + MX93_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x57e + >; + }; + + pinctrl_eqos_sleep: eqossleepgrp { + fsl,pins = < + MX93_PAD_ENET1_MDC__GPIO4_IO00 0x31e + MX93_PAD_ENET1_MDIO__GPIO4_IO01 0x31e + MX93_PAD_ENET1_RD0__GPIO4_IO10 0x31e + MX93_PAD_ENET1_RD1__GPIO4_IO11 0x31e + MX93_PAD_ENET1_RD2__GPIO4_IO12 0x31e + MX93_PAD_ENET1_RD3__GPIO4_IO13 0x31e + MX93_PAD_ENET1_RXC__GPIO4_IO09 0x31e + MX93_PAD_ENET1_RX_CTL__GPIO4_IO08 0x31e + MX93_PAD_ENET1_TD0__GPIO4_IO05 0x31e + MX93_PAD_ENET1_TD1__GPIO4_IO04 0x31e + MX93_PAD_ENET1_TD2__GPIO4_IO03 0x31e + MX93_PAD_ENET1_TD3__GPIO4_IO02 0x31e + MX93_PAD_ENET1_TXC__GPIO4_IO07 0x31e + MX93_PAD_ENET1_TX_CTL__GPIO4_IO06 0x31e + >; + }; + + pinctrl_fec: fecgrp { + fsl,pins = < + MX93_PAD_ENET2_MDC__ENET1_MDC 0x57e + MX93_PAD_ENET2_MDIO__ENET1_MDIO 0x57e + MX93_PAD_ENET2_RD0__ENET1_RGMII_RD0 0x57e + MX93_PAD_ENET2_RD1__ENET1_RGMII_RD1 0x57e + MX93_PAD_ENET2_RD2__ENET1_RGMII_RD2 0x57e + MX93_PAD_ENET2_RD3__ENET1_RGMII_RD3 0x57e + MX93_PAD_ENET2_RXC__ENET1_RGMII_RXC 0x58e + MX93_PAD_ENET2_RX_CTL__ENET1_RGMII_RX_CTL 0x57e + MX93_PAD_ENET2_TD0__ENET1_RGMII_TD0 0x57e + MX93_PAD_ENET2_TD1__ENET1_RGMII_TD1 0x57e + MX93_PAD_ENET2_TD2__ENET1_RGMII_TD2 0x57e + MX93_PAD_ENET2_TD3__ENET1_RGMII_TD3 0x57e + MX93_PAD_ENET2_TXC__ENET1_RGMII_TXC 0x58e + MX93_PAD_ENET2_TX_CTL__ENET1_RGMII_TX_CTL 0x57e + >; + }; + + pinctrl_fec_sleep: fecsleepgrp { + fsl,pins = < + MX93_PAD_ENET2_MDC__GPIO4_IO14 0x51e + MX93_PAD_ENET2_MDIO__GPIO4_IO15 0x51e + MX93_PAD_ENET2_RD0__GPIO4_IO24 0x51e + MX93_PAD_ENET2_RD1__GPIO4_IO25 0x51e + MX93_PAD_ENET2_RD2__GPIO4_IO26 0x51e + MX93_PAD_ENET2_RD3__GPIO4_IO27 0x51e + MX93_PAD_ENET2_RXC__GPIO4_IO23 0x51e + MX93_PAD_ENET2_RX_CTL__GPIO4_IO22 0x51e + MX93_PAD_ENET2_TD0__GPIO4_IO19 0x51e + MX93_PAD_ENET2_TD1__GPIO4_IO18 0x51e + MX93_PAD_ENET2_TD2__GPIO4_IO17 0x51e + MX93_PAD_ENET2_TD3__GPIO4_IO16 0x51e + MX93_PAD_ENET2_TXC__GPIO4_IO21 0x51e + MX93_PAD_ENET2_TX_CTL__GPIO4_IO20 0x51e + >; + }; + + pinctrl_flexcan2: flexcan2grp { + fsl,pins = < + MX93_PAD_GPIO_IO25__CAN2_TX 0x139e + MX93_PAD_GPIO_IO27__CAN2_RX 0x139e + >; + }; + + pinctrl_flexcan2_sleep: flexcan2sleepgrp { + fsl,pins = < + MX93_PAD_GPIO_IO25__GPIO2_IO25 0x31e + MX93_PAD_GPIO_IO27__GPIO2_IO27 0x31e + >; + }; + + pinctrl_lpi2c1: lpi2c1grp { + fsl,pins = < + MX93_PAD_I2C1_SCL__LPI2C1_SCL 0x40000b9e + MX93_PAD_I2C1_SDA__LPI2C1_SDA 0x40000b9e + >; + }; + + pinctrl_lpi2c2: lpi2c2grp { + fsl,pins = < + MX93_PAD_I2C2_SCL__LPI2C2_SCL 0x40000b9e + MX93_PAD_I2C2_SDA__LPI2C2_SDA 0x40000b9e + >; + }; + + pinctrl_lpi2c3: lpi2c3grp { + fsl,pins = < + MX93_PAD_GPIO_IO28__LPI2C3_SDA 0x40000b9e + MX93_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e + >; + }; + + pinctrl_pcal6524: pcal6524grp { + fsl,pins = < + MX93_PAD_CCM_CLKO2__GPIO3_IO27 0x31e + >; + }; + + pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { + fsl,pins = < + MX93_PAD_SD2_RESET_B__GPIO3_IO07 0x31e + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + MX93_PAD_UART1_RXD__LPUART1_RX 0x31e + MX93_PAD_UART1_TXD__LPUART1_TX 0x31e + >; + }; + + pinctrl_uart5: uart5grp { + fsl,pins = < + MX93_PAD_DAP_TDO_TRACESWO__LPUART5_TX 0x31e + MX93_PAD_DAP_TDI__LPUART5_RX 0x31e + MX93_PAD_DAP_TMS_SWDIO__LPUART5_RTS_B 0x31e + MX93_PAD_DAP_TCLK_SWCLK__LPUART5_CTS_B 0x31e + >; + }; + + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + MX93_PAD_SD1_CLK__USDHC1_CLK 0x1582 + MX93_PAD_SD1_CMD__USDHC1_CMD 0x40001382 + MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x40001382 + MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x40001382 + MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x40001382 + MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x40001382 + MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x40001382 + MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x40001382 + MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x40001382 + MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x40001382 + MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x1582 + >; + }; + + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { + fsl,pins = < + MX93_PAD_SD1_CLK__USDHC1_CLK 0x158e + MX93_PAD_SD1_CMD__USDHC1_CMD 0x4000138e + MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x4000138e + MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x4000138e + MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x4000138e + MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x4000138e + MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x4000138e + MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x4000138e + MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x4000138e + MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x4000138e + MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x158e + >; + }; + + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { + fsl,pins = < + MX93_PAD_SD1_CLK__USDHC1_CLK 0x15fe + MX93_PAD_SD1_CMD__USDHC1_CMD 0x400013fe + MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x400013fe + MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x400013fe + MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x400013fe + MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x400013fe + MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x400013fe + MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x400013fe + MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x400013fe + MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x400013fe + MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x15fe + >; + }; + + pinctrl_usdhc2_gpio: usdhc2gpiogrp { + fsl,pins = < + MX93_PAD_SD2_CD_B__GPIO3_IO00 0x31e + >; + }; + + pinctrl_usdhc2_gpio_sleep: usdhc2gpiosleepgrp { + fsl,pins = < + MX93_PAD_SD2_CD_B__GPIO3_IO00 0x51e + >; + }; + + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + MX93_PAD_SD2_CLK__USDHC2_CLK 0x1582 + MX93_PAD_SD2_CMD__USDHC2_CMD 0x40001382 + MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x40001382 + MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x40001382 + MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x40001382 + MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x40001382 + MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e + >; + }; + + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { + fsl,pins = < + MX93_PAD_SD2_CLK__USDHC2_CLK 0x158e + MX93_PAD_SD2_CMD__USDHC2_CMD 0x4000138e + MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x4000138e + MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x4000138e + MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x4000138e + MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x4000138e + MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e + >; + }; + + /* need to config the SION for data and cmd pad, refer to ERR052021 */ + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { + fsl,pins = < + MX93_PAD_SD2_CLK__USDHC2_CLK 0x15fe + MX93_PAD_SD2_CMD__USDHC2_CMD 0x400013fe + MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x400013fe + MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x400013fe + MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x400013fe + MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x400013fe + MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e + >; + }; + + pinctrl_usdhc2_sleep: usdhc2-sleepgrp { + fsl,pins = < + MX93_PAD_SD2_CLK__GPIO3_IO01 0x51e + MX93_PAD_SD2_CMD__GPIO3_IO02 0x51e + MX93_PAD_SD2_DATA0__GPIO3_IO03 0x51e + MX93_PAD_SD2_DATA1__GPIO3_IO04 0x51e + MX93_PAD_SD2_DATA2__GPIO3_IO05 0x51e + MX93_PAD_SD2_DATA3__GPIO3_IO06 0x51e + MX93_PAD_SD2_VSELECT__GPIO3_IO19 0x51e + >; + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = < + MX93_PAD_WDOG_ANY__WDOG1_WDOG_ANY 0x31e + >; + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts b/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts index bd14ba2..6e8351d 100644 --- a/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts +++ b/arch/arm64/boot/dts/freescale/imx93-11x11-frdm.dts
@@ -1,71 +1,14 @@ // SPDX-License-Identifier: (GPL-2.0+ OR MIT) + /dts-v1/; -#include <dt-bindings/usb/pd.h> #include "imx93.dtsi" +#include "imx93-11x11-frdm-common.dtsi" / { compatible = "fsl,imx93-11x11-frdm", "fsl,imx93"; model = "NXP i.MX93 11X11 FRDM board"; - aliases { - can0 = &flexcan2; - ethernet0 = &fec; - ethernet1 = &eqos; - i2c0 = &lpi2c1; - i2c1 = &lpi2c2; - i2c2 = &lpi2c3; - mmc0 = &usdhc1; /* EMMC */ - mmc1 = &usdhc2; /* uSD */ - rtc0 = &pcf2131; - serial0 = &lpuart1; - serial4 = &lpuart5; - }; - - chosen { - stdout-path = &lpuart1; - }; - - flexcan2_phy: can-phy { - compatible = "nxp,tja1051"; - #phy-cells = <0>; - max-bitrate = <5000000>; - silent-gpios = <&pcal6524 23 GPIO_ACTIVE_HIGH>; - }; - - gpio-keys { - compatible = "gpio-keys"; - - button-k2 { - label = "Button K2"; - linux,code = <BTN_1>; - gpios = <&pcal6524 5 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; - interrupt-parent = <&pcal6524>; - interrupts = <5 IRQ_TYPE_EDGE_FALLING>; - }; - - button-k3 { - label = "Button K3"; - linux,code = <BTN_2>; - gpios = <&pcal6524 6 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; - interrupt-parent = <&pcal6524>; - interrupts = <6 IRQ_TYPE_EDGE_FALLING>; - }; - }; - - reg_usdhc2_vmmc: regulator-usdhc2 { - compatible = "regulator-fixed"; - off-on-delay-us = <12000>; - pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>; - pinctrl-names = "default"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-name = "VSD_3V3"; - vin-supply = <&buck4>; - gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; - reg_usdhc3_vmmc: regulator-usdhc3 { compatible = "regulator-fixed"; regulator-name = "VPCIe_3V3"; @@ -76,51 +19,6 @@ reg_usdhc3_vmmc: regulator-usdhc3 { enable-active-high; }; - reserved-memory { - ranges; - #address-cells = <2>; - #size-cells = <2>; - - linux,cma { - compatible = "shared-dma-pool"; - alloc-ranges = <0 0x80000000 0 0x30000000>; - reusable; - size = <0 0x10000000>; - linux,cma-default; - }; - - rsc_table: rsc-table@2021e000 { - reg = <0 0x2021e000 0 0x1000>; - no-map; - }; - - vdev0vring0: vdev0vring0@a4000000 { - reg = <0 0xa4000000 0 0x8000>; - no-map; - }; - - vdev0vring1: vdev0vring1@a4008000 { - reg = <0 0xa4008000 0 0x8000>; - no-map; - }; - - vdev1vring0: vdev1vring0@a4010000 { - reg = <0 0xa4010000 0 0x8000>; - no-map; - }; - - vdev1vring1: vdev1vring1@a4018000 { - reg = <0 0xa4018000 0 0x8000>; - no-map; - }; - - vdevbuffer: vdevbuffer@a4020000 { - compatible = "shared-dma-pool"; - reg = <0 0xa4020000 0 0x100000>; - no-map; - }; - }; - sound-mqs { compatible = "fsl,imx-audio-mqs"; model = "mqs-audio"; @@ -134,274 +32,26 @@ usdhc3_pwrseq: mmc-pwrseq { }; }; -&adc1 { - vref-supply = <&buck5>; - status = "okay"; -}; - -&mu1 { - status = "okay"; -}; - -&cm33 { - mboxes = <&mu1 0 1>, - <&mu1 1 1>, - <&mu1 3 1>; - mbox-names = "tx", "rx", "rxdb"; - memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, - <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>; - status = "okay"; -}; - -&eqos { - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&pinctrl_eqos>; - pinctrl-1 = <&pinctrl_eqos_sleep>; - phy-handle = <ðphy1>; - phy-mode = "rgmii-id"; - status = "okay"; - - mdio { - compatible = "snps,dwmac-mdio"; - #address-cells = <1>; - #size-cells = <0>; - clock-frequency = <5000000>; - - ethphy1: ethernet-phy@1 { - reg = <1>; - reset-assert-us = <10000>; - reset-deassert-us = <80000>; - reset-gpios = <&pcal6524 15 GPIO_ACTIVE_LOW>; - realtek,clkout-disable; - }; - }; -}; - -&fec { - pinctrl-names = "default", "sleep"; - pinctrl-0 = <&pinctrl_fec>; - pinctrl-1 = <&pinctrl_fec_sleep>; - phy-mode = "rgmii-id"; - phy-handle = <ðphy2>; - fsl,magic-packet; - status = "okay"; - - mdio { - #address-cells = <1>; - #size-cells = <0>; - clock-frequency = <5000000>; - - ethphy2: ethernet-phy@2 { - reg = <2>; - reset-assert-us = <10000>; - reset-deassert-us = <80000>; - reset-gpios = <&pcal6524 16 GPIO_ACTIVE_LOW>; - realtek,clkout-disable; - }; - }; -}; - -&flexcan2 { - phys = <&flexcan2_phy>; - pinctrl-0 = <&pinctrl_flexcan2>; - pinctrl-1 = <&pinctrl_flexcan2_sleep>; - pinctrl-names = "default", "sleep"; - status = "okay"; +&bluetooth { + device-wakeup-gpios = <&pcal6408 3 GPIO_ACTIVE_HIGH>; + reset-gpios = <&pcal6524 19 GPIO_ACTIVE_LOW>; + vcc-supply = <®_usdhc3_vmmc>; }; &lpi2c1 { - clock-frequency = <400000>; - pinctrl-0 = <&pinctrl_lpi2c1>; - pinctrl-names = "default"; - status = "okay"; - pcal6408: gpio@20 { compatible = "nxp,pcal6408"; reg = <0x20>; #gpio-cells = <2>; gpio-controller; reset-gpios = <&pcal6524 20 GPIO_ACTIVE_LOW>; - }; -}; - -&lpi2c2 { - clock-frequency = <400000>; - pinctrl-0 = <&pinctrl_lpi2c2>; - pinctrl-names = "default"; - status = "okay"; - - pcal6524: gpio@22 { - compatible = "nxp,pcal6524"; - reg = <0x22>; - #interrupt-cells = <2>; - interrupt-controller; - interrupt-parent = <&gpio3>; - interrupts = <27 IRQ_TYPE_LEVEL_LOW>; - #gpio-cells = <2>; - gpio-controller; - pinctrl-0 = <&pinctrl_pcal6524>; - pinctrl-names = "default"; - /* does not boot with supplier set, because it is the bucks interrupt parent */ - /* vcc-supply = <&buck4>; */ - }; - - pmic@25 { - compatible = "nxp,pca9451a"; - reg = <0x25>; - interrupt-parent = <&pcal6524>; - interrupts = <11 IRQ_TYPE_EDGE_FALLING>; - - regulators { - - buck1: BUCK1 { - regulator-name = "VDD_SOC_0V8"; - regulator-min-microvolt = <610000>; - regulator-max-microvolt = <950000>; - regulator-always-on; - regulator-boot-on; - regulator-ramp-delay = <3125>; - }; - - buck2: BUCK2 { - regulator-name = "LPD4_x_VDDQ_0V6"; - regulator-min-microvolt = <600000>; - regulator-max-microvolt = <670000>; - regulator-always-on; - regulator-boot-on; - regulator-ramp-delay = <3125>; - }; - - buck4: BUCK4 { - regulator-name = "VDD_3V3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - regulator-boot-on; - }; - - buck5: BUCK5 { - regulator-name = "VDD_1V8"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-always-on; - regulator-boot-on; - }; - - buck6: BUCK6 { - regulator-name = "LPD4_x_VDD2_1V1"; - regulator-min-microvolt = <1060000>; - regulator-max-microvolt = <1140000>; - regulator-always-on; - regulator-boot-on; - }; - - ldo1: LDO1 { - regulator-name = "NVCC_BBSM_1V8"; - regulator-min-microvolt = <1620000>; - regulator-max-microvolt = <1980000>; - regulator-always-on; - regulator-boot-on; - }; - - ldo4: LDO4 { - regulator-name = "VDD_ANA_0V8"; - regulator-min-microvolt = <800000>; - regulator-max-microvolt = <840000>; - regulator-always-on; - regulator-boot-on; - }; - - ldo5: LDO5 { - regulator-name = "NVCC_SD"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - regulator-boot-on; - }; - }; - }; - - eeprom: eeprom@50 { - compatible = "atmel,24c256"; - reg = <0x50>; - pagesize = <64>; - vcc-supply = <&buck4>; - }; -}; - -&lpi2c3 { - clock-frequency = <400000>; - pinctrl-0 = <&pinctrl_lpi2c3>; - pinctrl-names = "default"; - status = "okay"; - - ptn5110: tcpc@50 { - compatible = "nxp,ptn5110", "tcpci"; - reg = <0x50>; - interrupt-parent = <&gpio3>; - interrupts = <27 IRQ_TYPE_LEVEL_LOW>; - - typec1_con: connector { - compatible = "usb-c-connector"; - data-role = "dual"; - label = "USB-C"; - op-sink-microwatt = <15000000>; - power-role = "dual"; - self-powered; - sink-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM) - PDO_VAR(5000, 20000, 3000)>; - source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>; - try-power-role = "sink"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - typec1_dr_sw: endpoint { - remote-endpoint = <&usb1_drd_sw>; - }; - }; - }; - }; - }; - - pcf2131: rtc@53 { - compatible = "nxp,pcf2131"; - reg = <0x53>; - interrupt-parent = <&pcal6524>; - interrupts = <1 IRQ_TYPE_EDGE_FALLING>; - }; -}; - -&lpuart1 { /* console */ - pinctrl-0 = <&pinctrl_uart1>; - pinctrl-names = "default"; - status = "okay"; -}; - -&lpuart5 { - pinctrl-0 = <&pinctrl_uart5>; - pinctrl-names = "default"; - status = "okay"; - - uart-has-rtscts; - - bluetooth { - compatible = "nxp,88w8987-bt"; - device-wakeup-gpios = <&pcal6408 3 GPIO_ACTIVE_HIGH>; - reset-gpios = <&pcal6524 19 GPIO_ACTIVE_LOW>; - vcc-supply = <®_usdhc3_vmmc>; + vcc-supply = <&buck5>; }; }; &mqs1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_mqs1>; - clocks = <&clk IMX93_CLK_MQS1_GATE>; - clock-names = "mclk"; status = "okay"; }; @@ -418,57 +68,6 @@ &sai1 { status = "okay"; }; -&usbotg1 { - adp-disable; - disable-over-current; - dr_mode = "otg"; - hnp-disable; - srp-disable; - usb-role-switch; - samsung,picophy-dc-vol-level-adjust = <7>; - samsung,picophy-pre-emp-curr-control = <3>; - status = "okay"; - - port { - usb1_drd_sw: endpoint { - remote-endpoint = <&typec1_dr_sw>; - }; - }; -}; - -&usbotg2 { - disable-over-current; - dr_mode = "host"; - samsung,picophy-dc-vol-level-adjust = <7>; - samsung,picophy-pre-emp-curr-control = <3>; - status = "okay"; -}; - -&usdhc1 { - bus-width = <8>; - non-removable; - pinctrl-0 = <&pinctrl_usdhc1>; - pinctrl-1 = <&pinctrl_usdhc1_100mhz>; - pinctrl-2 = <&pinctrl_usdhc1_200mhz>; - pinctrl-names = "default", "state_100mhz", "state_200mhz"; - vmmc-supply = <&buck4>; - status = "okay"; -}; - -&usdhc2 { - bus-width = <4>; - cd-gpios = <&gpio3 00 GPIO_ACTIVE_LOW>; - no-mmc; - no-sdio; - pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; - pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; - pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; - pinctrl-3 = <&pinctrl_usdhc2_sleep>, <&pinctrl_usdhc2_gpio_sleep>; - pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; - vmmc-supply = <®_usdhc2_vmmc>; - status = "okay"; -}; - &usdhc3 { bus-width = <4>; keep-power-in-suspend; @@ -483,126 +82,7 @@ &usdhc3 { status = "okay"; }; -&wdog3 { - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_wdog>; - fsl,ext-reset-output; - status = "okay"; -}; - &iomuxc { - - pinctrl_eqos: eqosgrp { - fsl,pins = < - MX93_PAD_ENET1_MDC__ENET_QOS_MDC 0x57e - MX93_PAD_ENET1_MDIO__ENET_QOS_MDIO 0x57e - MX93_PAD_ENET1_RD0__ENET_QOS_RGMII_RD0 0x57e - MX93_PAD_ENET1_RD1__ENET_QOS_RGMII_RD1 0x57e - MX93_PAD_ENET1_RD2__ENET_QOS_RGMII_RD2 0x57e - MX93_PAD_ENET1_RD3__ENET_QOS_RGMII_RD3 0x57e - MX93_PAD_ENET1_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x58e - MX93_PAD_ENET1_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x57e - MX93_PAD_ENET1_TD0__ENET_QOS_RGMII_TD0 0x57e - MX93_PAD_ENET1_TD1__ENET_QOS_RGMII_TD1 0x57e - MX93_PAD_ENET1_TD2__ENET_QOS_RGMII_TD2 0x57e - MX93_PAD_ENET1_TD3__ENET_QOS_RGMII_TD3 0x57e - MX93_PAD_ENET1_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x58e - MX93_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x57e - >; - }; - - pinctrl_eqos_sleep: eqossleepgrp { - fsl,pins = < - MX93_PAD_ENET1_MDC__GPIO4_IO00 0x31e - MX93_PAD_ENET1_MDIO__GPIO4_IO01 0x31e - MX93_PAD_ENET1_RD0__GPIO4_IO10 0x31e - MX93_PAD_ENET1_RD1__GPIO4_IO11 0x31e - MX93_PAD_ENET1_RD2__GPIO4_IO12 0x31e - MX93_PAD_ENET1_RD3__GPIO4_IO13 0x31e - MX93_PAD_ENET1_RXC__GPIO4_IO09 0x31e - MX93_PAD_ENET1_RX_CTL__GPIO4_IO08 0x31e - MX93_PAD_ENET1_TD0__GPIO4_IO05 0x31e - MX93_PAD_ENET1_TD1__GPIO4_IO04 0x31e - MX93_PAD_ENET1_TD2__GPIO4_IO03 0x31e - MX93_PAD_ENET1_TD3__GPIO4_IO02 0x31e - MX93_PAD_ENET1_TXC__GPIO4_IO07 0x31e - MX93_PAD_ENET1_TX_CTL__GPIO4_IO06 0x31e - >; - }; - - pinctrl_fec: fecgrp { - fsl,pins = < - MX93_PAD_ENET2_MDC__ENET1_MDC 0x57e - MX93_PAD_ENET2_MDIO__ENET1_MDIO 0x57e - MX93_PAD_ENET2_RD0__ENET1_RGMII_RD0 0x57e - MX93_PAD_ENET2_RD1__ENET1_RGMII_RD1 0x57e - MX93_PAD_ENET2_RD2__ENET1_RGMII_RD2 0x57e - MX93_PAD_ENET2_RD3__ENET1_RGMII_RD3 0x57e - MX93_PAD_ENET2_RXC__ENET1_RGMII_RXC 0x58e - MX93_PAD_ENET2_RX_CTL__ENET1_RGMII_RX_CTL 0x57e - MX93_PAD_ENET2_TD0__ENET1_RGMII_TD0 0x57e - MX93_PAD_ENET2_TD1__ENET1_RGMII_TD1 0x57e - MX93_PAD_ENET2_TD2__ENET1_RGMII_TD2 0x57e - MX93_PAD_ENET2_TD3__ENET1_RGMII_TD3 0x57e - MX93_PAD_ENET2_TXC__ENET1_RGMII_TXC 0x58e - MX93_PAD_ENET2_TX_CTL__ENET1_RGMII_TX_CTL 0x57e - >; - }; - - pinctrl_fec_sleep: fecsleepgrp { - fsl,pins = < - MX93_PAD_ENET2_MDC__GPIO4_IO14 0x51e - MX93_PAD_ENET2_MDIO__GPIO4_IO15 0x51e - MX93_PAD_ENET2_RD0__GPIO4_IO24 0x51e - MX93_PAD_ENET2_RD1__GPIO4_IO25 0x51e - MX93_PAD_ENET2_RD2__GPIO4_IO26 0x51e - MX93_PAD_ENET2_RD3__GPIO4_IO27 0x51e - MX93_PAD_ENET2_RXC__GPIO4_IO23 0x51e - MX93_PAD_ENET2_RX_CTL__GPIO4_IO22 0x51e - MX93_PAD_ENET2_TD0__GPIO4_IO19 0x51e - MX93_PAD_ENET2_TD1__GPIO4_IO18 0x51e - MX93_PAD_ENET2_TD2__GPIO4_IO17 0x51e - MX93_PAD_ENET2_TD3__GPIO4_IO16 0x51e - MX93_PAD_ENET2_TXC__GPIO4_IO21 0x51e - MX93_PAD_ENET2_TX_CTL__GPIO4_IO20 0x51e - >; - }; - - pinctrl_flexcan2: flexcan2grp { - fsl,pins = < - MX93_PAD_GPIO_IO25__CAN2_TX 0x139e - MX93_PAD_GPIO_IO27__CAN2_RX 0x139e - >; - }; - - pinctrl_flexcan2_sleep: flexcan2sleepgrp { - fsl,pins = < - MX93_PAD_GPIO_IO25__GPIO2_IO25 0x31e - MX93_PAD_GPIO_IO27__GPIO2_IO27 0x31e - >; - }; - - pinctrl_lpi2c1: lpi2c1grp { - fsl,pins = < - MX93_PAD_I2C1_SCL__LPI2C1_SCL 0x40000b9e - MX93_PAD_I2C1_SDA__LPI2C1_SDA 0x40000b9e - >; - }; - - pinctrl_lpi2c2: lpi2c2grp { - fsl,pins = < - MX93_PAD_I2C2_SCL__LPI2C2_SCL 0x40000b9e - MX93_PAD_I2C2_SDA__LPI2C2_SDA 0x40000b9e - >; - }; - - pinctrl_lpi2c3: lpi2c3grp { - fsl,pins = < - MX93_PAD_GPIO_IO28__LPI2C3_SDA 0x40000b9e - MX93_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e - >; - }; - pinctrl_mqs1: mqs1grp { fsl,pins = < MX93_PAD_PDM_CLK__MQS1_LEFT 0x31e @@ -610,149 +90,7 @@ MX93_PAD_PDM_BIT_STREAM0__MQS1_RIGHT 0x31e >; }; - pinctrl_pcal6524: pcal6524grp { - fsl,pins = < - MX93_PAD_CCM_CLKO2__GPIO3_IO27 0x31e - >; - }; - - pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { - fsl,pins = < - MX93_PAD_SD2_RESET_B__GPIO3_IO07 0x31e - >; - }; - - pinctrl_uart1: uart1grp { - fsl,pins = < - MX93_PAD_UART1_RXD__LPUART1_RX 0x31e - MX93_PAD_UART1_TXD__LPUART1_TX 0x31e - >; - }; - - pinctrl_uart5: uart5grp { - fsl,pins = < - MX93_PAD_DAP_TDO_TRACESWO__LPUART5_TX 0x31e - MX93_PAD_DAP_TDI__LPUART5_RX 0x31e - MX93_PAD_DAP_TMS_SWDIO__LPUART5_RTS_B 0x31e - MX93_PAD_DAP_TCLK_SWCLK__LPUART5_CTS_B 0x31e - >; - }; - /* need to config the SION for data and cmd pad, refer to ERR052021 */ - pinctrl_usdhc1: usdhc1grp { - fsl,pins = < - MX93_PAD_SD1_CLK__USDHC1_CLK 0x1582 - MX93_PAD_SD1_CMD__USDHC1_CMD 0x40001382 - MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x40001382 - MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x40001382 - MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x40001382 - MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x40001382 - MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x40001382 - MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x40001382 - MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x40001382 - MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x40001382 - MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x1582 - >; - }; - - /* need to config the SION for data and cmd pad, refer to ERR052021 */ - pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { - fsl,pins = < - MX93_PAD_SD1_CLK__USDHC1_CLK 0x158e - MX93_PAD_SD1_CMD__USDHC1_CMD 0x4000138e - MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x4000138e - MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x4000138e - MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x4000138e - MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x4000138e - MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x4000138e - MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x4000138e - MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x4000138e - MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x4000138e - MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x158e - >; - }; - - /* need to config the SION for data and cmd pad, refer to ERR052021 */ - pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { - fsl,pins = < - MX93_PAD_SD1_CLK__USDHC1_CLK 0x15fe - MX93_PAD_SD1_CMD__USDHC1_CMD 0x400013fe - MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x400013fe - MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x400013fe - MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x400013fe - MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x400013fe - MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x400013fe - MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x400013fe - MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x400013fe - MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x400013fe - MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x15fe - >; - }; - - pinctrl_usdhc2_gpio: usdhc2gpiogrp { - fsl,pins = < - MX93_PAD_SD2_CD_B__GPIO3_IO00 0x31e - >; - }; - - pinctrl_usdhc2_gpio_sleep: usdhc2gpiosleepgrp { - fsl,pins = < - MX93_PAD_SD2_CD_B__GPIO3_IO00 0x51e - >; - }; - - /* need to config the SION for data and cmd pad, refer to ERR052021 */ - pinctrl_usdhc2: usdhc2grp { - fsl,pins = < - MX93_PAD_SD2_CLK__USDHC2_CLK 0x1582 - MX93_PAD_SD2_CMD__USDHC2_CMD 0x40001382 - MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x40001382 - MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x40001382 - MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x40001382 - MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x40001382 - MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e - >; - }; - - /* need to config the SION for data and cmd pad, refer to ERR052021 */ - pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { - fsl,pins = < - MX93_PAD_SD2_CLK__USDHC2_CLK 0x158e - MX93_PAD_SD2_CMD__USDHC2_CMD 0x4000138e - MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x4000138e - MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x4000138e - MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x4000138e - MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x4000138e - MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e - >; - }; - - /* need to config the SION for data and cmd pad, refer to ERR052021 */ - pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { - fsl,pins = < - MX93_PAD_SD2_CLK__USDHC2_CLK 0x15fe - MX93_PAD_SD2_CMD__USDHC2_CMD 0x400013fe - MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x400013fe - MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x400013fe - MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x400013fe - MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x400013fe - MX93_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e - >; - }; - - pinctrl_usdhc2_sleep: usdhc2-sleepgrp { - fsl,pins = < - MX93_PAD_SD2_CLK__GPIO3_IO01 0x51e - MX93_PAD_SD2_CMD__GPIO3_IO02 0x51e - MX93_PAD_SD2_DATA0__GPIO3_IO03 0x51e - MX93_PAD_SD2_DATA1__GPIO3_IO04 0x51e - MX93_PAD_SD2_DATA2__GPIO3_IO05 0x51e - MX93_PAD_SD2_DATA3__GPIO3_IO06 0x51e - MX93_PAD_SD2_VSELECT__GPIO3_IO19 0x51e - >; - }; - - /* need to config the SION for data and cmd pad, refer to ERR052021 */ pinctrl_usdhc3: usdhc3grp { fsl,pins = < MX93_PAD_SD3_CLK__USDHC3_CLK 0x1582 @@ -798,10 +136,4 @@ MX93_PAD_SD3_DATA2__GPIO3_IO24 0x31e MX93_PAD_SD3_DATA3__GPIO3_IO25 0x31e >; }; - - pinctrl_wdog: wdoggrp { - fsl,pins = < - MX93_PAD_WDOG_ANY__WDOG1_WDOG_ANY 0x31e - >; - }; };
diff --git a/arch/arm64/boot/dts/freescale/imx93-14x14-evk.dts b/arch/arm64/boot/dts/freescale/imx93-14x14-evk.dts index ec78c03..1081881 100644 --- a/arch/arm64/boot/dts/freescale/imx93-14x14-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx93-14x14-evk.dts
@@ -28,6 +28,13 @@ aliases { serial4 = &lpuart5; }; + amp_mqs1: audio-amplifier { + compatible = "simple-audio-amplifier"; + enable-gpios = <&pcal6524_2 1 GPIO_ACTIVE_HIGH>; + sound-name-prefix = "MQS AMP"; + VCC-supply = <®_5v>; + }; + bt_sco_codec: bt-sco-codec { compatible = "linux,bt-sco"; #sound-dai-cells = <1>; @@ -37,6 +44,25 @@ chosen { stdout-path = &lpuart1; }; + can1_mqs1_mux: mux-controller-0 { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + #mux-state-cells = <1>; + mux-gpios = <&pcal6524_2 2 GPIO_ACTIVE_HIGH>; + }; + + pinctrl-gpiomux { + compatible = "pinctrl-multiplexer"; + + can1_fun: can1-grp { + mux-states = <&can1_mqs1_mux 0>; + }; + + mqs1_fun: mqs1-grp { + mux-states = <&can1_mqs1_mux 1>; + }; + }; + reserved-memory { #address-cells = <2>; #size-cells = <2>; @@ -75,13 +101,20 @@ rsc_table: rsc-table@2021e000 { no-map; }; - vdevbuffer: vdevbuffer@a4020000 { + vdev0buffer: vdev0buffer@a4020000 { compatible = "shared-dma-pool"; reg = <0 0xa4020000 0 0x100000>; no-map; }; }; + reg_5v: regulator-5v { + compatible = "regulator-fixed"; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + regulator-name = "+V5_SW"; + }; + reg_can1_stby: regulator-can1-stby { compatible = "regulator-fixed"; regulator-name = "can1-stby"; @@ -174,7 +207,7 @@ reg_vref_1v8: regulator-adc-vref { regulator-max-microvolt = <1800000>; }; - sound-bt-sco { + mqs1_conflict_card: sound-bt-sco { compatible = "simple-audio-card"; simple-audio-card,name = "bt-sco-audio"; simple-audio-card,format = "dsp_a"; @@ -222,7 +255,7 @@ &cm33 { mboxes = <&mu1 0 1>, <&mu1 1 1>, <&mu1 3 1>; - memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, + memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>; status = "okay"; }; @@ -252,9 +285,9 @@ ethphy2: ethernet-phy@2 { }; }; -&flexcan1 { +mqs1_conflict_dev: &flexcan1 { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_flexcan1>; + pinctrl-0 = <&pinctrl_flexcan1>, <&can1_fun>; xceiver-supply = <®_can1_stby>; status = "okay"; }; @@ -412,6 +445,11 @@ bluetooth { }; }; +&mqs1 { + pinctrl-0 = <&pinctrl_mqs1>, <&mqs1_fun>; + pinctrl-names = "default"; +}; + &mu1 { status = "okay"; }; @@ -423,6 +461,10 @@ &mu2 { &sai1 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_sai1>; + clocks = <&clk IMX93_CLK_SAI1_IPG>, <&clk IMX93_CLK_DUMMY>, + <&clk IMX93_CLK_SAI1_GATE>, <&clk IMX93_CLK_DUMMY>, + <&clk IMX93_CLK_DUMMY>, <&clk IMX93_CLK_AUDIO_PLL>; + clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k"; assigned-clocks = <&clk IMX93_CLK_SAI1>; assigned-clock-parents = <&clk IMX93_CLK_AUDIO_PLL>; assigned-clock-rates = <12288000>; @@ -540,6 +582,13 @@ MX93_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e >; }; + pinctrl_mqs1: mqs1grp { + fsl,pins = < + MX93_PAD_PDM_CLK__MQS1_LEFT 0x31e + MX93_PAD_PDM_BIT_STREAM0__MQS1_RIGHT 0x31e + >; + }; + pinctrl_pcal6524: pcal6524grp { fsl,pins = < MX93_PAD_CCM_CLKO2__GPIO3_IO27 0x31e
diff --git a/arch/arm64/boot/dts/freescale/imx93-9x9-qsb.dts b/arch/arm64/boot/dts/freescale/imx93-9x9-qsb.dts index 01c11c5..3be5bf4 100644 --- a/arch/arm64/boot/dts/freescale/imx93-9x9-qsb.dts +++ b/arch/arm64/boot/dts/freescale/imx93-9x9-qsb.dts
@@ -28,6 +28,7 @@ aliases { mmc0 = &usdhc1; mmc1 = &usdhc2; rtc0 = &bbnsm_rtc; + rtc1 = &pcf2131; serial0 = &lpuart1; serial1 = &lpuart2; serial2 = &lpuart3; @@ -76,7 +77,7 @@ rsc_table: rsc-table@2021e000 { no-map; }; - vdevbuffer: vdevbuffer@a4020000 { + vdev0buffer: vdev0buffer@a4020000 { compatible = "shared-dma-pool"; reg = <0 0xa4020000 0 0x100000>; no-map; @@ -212,7 +213,7 @@ &cm33 { mboxes = <&mu1 0 1>, <&mu1 1 1>, <&mu1 3 1>; - memory-region = <&vdevbuffer>, <&vdev0vring0>, <&vdev0vring1>, + memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>; status = "okay"; }; @@ -306,7 +307,7 @@ typec1_dr_sw: endpoint { }; }; - rtc@53 { + pcf2131: rtc@53 { compatible = "nxp,pcf2131"; reg = <0x53>; interrupt-parent = <&pcal6524>;
diff --git a/arch/arm64/boot/dts/freescale/imx93-imx91-lino-common.dtsi b/arch/arm64/boot/dts/freescale/imx93-imx91-lino-common.dtsi new file mode 100644 index 0000000..f8f13f7 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93-imx91-lino-common.dtsi
@@ -0,0 +1,536 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Lino iMX93/iMX91 SoM + * + * https://www.toradex.com/computer-on-modules/lino-arm-family/nxp-imx93 + * https://www.toradex.com/computer-on-modules/lino-arm-family/nxp-imx91 + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + aliases { + can0 = &flexcan1; + can1 = &flexcan2; + eeprom0 = &som_eeprom; + ethernet0 = &eqos; + ethernet1 = &fec; + i2c0 = &lpi2c2; + i2c1 = &lpi2c1; + i2c2 = &lpi2c3; + i2c3 = &lpi2c4; + mmc0 = &usdhc1; + mmc1 = &usdhc2; + mmc2 = &usdhc3; + serial0 = &lpuart6; + serial1 = &lpuart7; + serial2 = &lpuart1; + serial3 = &lpuart2; + usb0 = &usbotg1; + usb1 = &usbotg2; + }; + + chosen { + stdout-path = &lpuart1; + }; + + /* Lino SD_1 Power Supply */ + reg_sd1_vmmc: regulator-sdhci2-vmmc { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sd1_pwr_en>; + /* Lino SD_1_PWR_EN (Lino P72) */ + gpios = <&gpio3 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + off-on-delay-us = <100000>; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "+V3.3_SD"; + startup-delay-us = <20000>; + }; + + reg_sd1_vqmmc: regulator-sdhci2-vqmmc { + compatible = "regulator-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sd1_vsel>; + /* PMIC_SD_2_VSEL */ + gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + regulator-name = "LDO1-VSEL-SD (PMIC)"; + states = <1800000 0x1>, + <3300000 0x0>; + vin-supply = <®_sd_3v3_1v8>; + }; + + reg_usb1_vbus: regulator-usb1-vbus { + compatible = "regulator-fixed"; + /* Lino USB_1_EN (P27) */ + gpios = <&som_gpio_expander 0 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + regulator-name = "USB_1_EN"; + startup-delay-us = <20000>; + }; + + reg_usb2_vbus: regulator-usb2-vbus { + compatible = "regulator-fixed"; + /* Lino USB_2_EN (P61) */ + gpios = <&som_gpio_expander 1 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + regulator-name = "USB_2_EN"; + startup-delay-us = <20000>; + }; +}; + +/* Lino ADC_1, ADC_2, ADC_3 and ADC_4 */ +&adc1 { + vref-supply = <®_1v8>; +}; + +/* Lino ETH_1 */ +&eqos { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mdio>, <&pinctrl_eth1>; + + mdio: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; +}; + +/* Lino ETH_2 */ +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_eth2>; +}; + +/* Lino CAN_1 */ +&flexcan1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can1>; +}; + +/* Lino CAN_2 */ +&flexcan2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can2>; +}; + +&gpio1 { + gpio-line-names = + "LINO_P18", + "LINO_P16", + "PMIC_I2C_SCL", + "PMIC_I2C_SDA", + "", + "", + "", + "", + "", + "", + "LINO_P65", /* 10 */ + "LINO_S18", + "LINO_S24", + "LINO_S20", + "LINO_S22", + ""; +}; + +&gpio2 { + gpio-line-names = + "LINO_P30", + "LINO_P32", + "LINO_P24", + "LINO_P26", + "", + "", + "", + "", + "", + "", + "", /* 10 */ + "", + "LINO_P58", + "", + "", + "", + "", + "LINO_P34", + "", + "", + "", /* 20 */ + "", + "LINO_P36", + "", + "LINO_P38", + "", + "", + "", + "LINO_P20", + "LINO_P22"; +}; + +&gpio3 { + gpio-line-names = + "LINO_P78", + "", + "", + "", + "", + "", + "", + "LINO_P72", + "", + "", + "", /* 10 */ + "", + "", + "", + "", + "", + "", + "", + "", + "PMIC_SD_2_VSEL", + "", /* 20 */ + "", + "", + "", + "", + "", + "LINO_P40", + "LINO_P42", + "", + "", + "", /* 30 */ + ""; +}; + +&gpio4 { + gpio-line-names = + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", /* 10 */ + "", + "", + "", + "LINO_P46", + "LINO_P48", + "", + "", + "", + "", + "", /* 20 */ + "", + "", + "", + "", + "", + "", + "", + "LINO_P44", + "GPIO_EXP_INT#"; +}; + +/* Lino I2C_1 */ +&lpi2c1 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c1>; + pinctrl-1 = <&pinctrl_i2c1_gpio>; + clock-frequency = <100000>; + scl-gpios = <&gpio1 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + single-master; +}; + +/* On-module I2C - PMIC_I2C */ +&lpi2c2 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_pmic_i2c>; + pinctrl-1 = <&pinctrl_pmic_i2c_gpio>; + clock-frequency = <400000>; + scl-gpios = <&gpio1 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio1 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + single-master; + + status = "okay"; + + som_gpio_expander: gpio@21 { + compatible = "nxp,pcal6408"; + reg = <0x21>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_exp_int>; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&gpio4>; + interrupts = <29 IRQ_TYPE_LEVEL_LOW>; + #gpio-cells = <2>; + gpio-controller; + gpio-line-names = + "Lino_P27", /* Lino USB_1_EN */ + "Lino_P61", /* Lino USB_2_EN */ + "TPM_SPI_CS#", + "Lino_P29", /* Lino USB_1_OC# */ + "Lino_P63", /* Lino USB_2_OC# */ + "PMIC_INT#", + "TPM_IRQ#", + "Lino_S66"; + }; + + pmic@32 { + compatible = "nxp,pf9453"; + reg = <0x32>; + interrupt-parent = <&som_gpio_expander>; + interrupts = <5 IRQ_TYPE_EDGE_FALLING>; + + regulators { + BUCK1 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1100000>; + regulator-min-microvolt = <1100000>; + regulator-name = "+V1.1_DDR (PMIC BUCK1)"; + }; + + reg_vdd_soc: BUCK2 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <950000>; + regulator-min-microvolt = <612500>; + regulator-name = "+VDD_SOC (PMIC BUCK2)"; + regulator-ramp-delay = <12500>; + }; + + reg_1v8: BUCK3 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "+V1.8 / +V1.8_ANA (PMIC BUCK3)"; + }; + + reg_3v3: BUCK4 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "+V3.3 (PMIC BUCK4)"; + }; + + reg_sd_3v3_1v8: LDO1 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + regulator-name = "+V3.3_1.8_SD (PMIC LDO1)"; + }; + + LDO2 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <800000>; + regulator-min-microvolt = <800000>; + regulator-name = "+V0.8_ANA (PMIC LDO2)"; + }; + + LDO-SNVS { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "+V1.8_BBSM (PMIC LDO-SNVS)"; + }; + }; + }; + + temperature-sensor@48 { + compatible = "ti,tmp1075"; + reg = <0x48>; + }; + + som_eeprom: eeprom@50 { + compatible = "st,24c02", "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +/* Lino I2C_2 */ +&lpi2c3 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c2>; + pinctrl-1 = <&pinctrl_i2c2_gpio>; + clock-frequency = <100000>; + scl-gpios = <&gpio2 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio2 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + single-master; +}; + +/* Lino I2C_3 */ +&lpi2c4 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c3>; + pinctrl-1 = <&pinctrl_i2c3_gpio>; + clock-frequency = <100000>; + scl-gpios = <&gpio2 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio2 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + single-master; +}; + +/* Lino SPI_2 */ +&lpspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi2>, <&pinctrl_spi2_cs0_gpio>; + cs-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>, <&som_gpio_expander 2 GPIO_ACTIVE_LOW>; + + status = "okay"; + + tpm@1 { + compatible = "infineon,slb9670", "tcg,tpm_tis-spi"; + reg = <1>; + interrupt-parent = <&som_gpio_expander>; + interrupts = <6 IRQ_TYPE_EDGE_FALLING>; + spi-max-frequency = <18500000>; + }; +}; + +/* Lino SPI_1 */ +&lpspi8 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi1>, <&pinctrl_spi1_cs0_gpio>; + cs-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; +}; + +/* Lino UART_3, used as the Linux Console */ +&lpuart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart3>; +}; + +/* Lino UART_4 */ +&lpuart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart4>; +}; + +/* Lino UART_1 */ +&lpuart6 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + uart-has-rtscts; +}; + +/* Lino UART_2 */ +&lpuart7 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart2>; + uart-has-rtscts; +}; + +/* Lino I2S_1 */ +&sai3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2s1>; + assigned-clocks = <&clk IMX93_CLK_SAI3>; + assigned-clock-parents = <&clk IMX93_CLK_AUDIO_PLL>; + assigned-clock-rates = <24576000>; +}; + +/* Lino PWM_1 */ +&tpm4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm1>; +}; + +/* Lino PWM_2 */ +&tpm5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm2>; +}; + +/* Lino PWM_3 */ +&tpm6 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm3>; +}; + +/* Lino USB_1 */ +&usbotg1 { + dr_mode = "otg"; + adp-disable; + hnp-disable; + srp-disable; + usb-role-switch; + disable-over-current; + role-switch-default-mode = "peripheral"; + samsung,picophy-dc-vol-level-adjust = <7>; + samsung,picophy-pre-emp-curr-control = <3>; +}; + +/* Lino USB_2 */ +&usbotg2 { + disable-over-current; + dr_mode = "host"; + vbus-supply = <®_usb2_vbus>; + samsung,picophy-dc-vol-level-adjust = <7>; + samsung,picophy-pre-emp-curr-control = <3>; +}; + +/* On-module eMMC */ +&usdhc1 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_emmc>; + pinctrl-1 = <&pinctrl_emmc>; + pinctrl-2 = <&pinctrl_emmc>; + no-sd; + no-sdio; + non-removable; + + status = "okay"; +}; + +/* Lino SD_1 */ +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_sd1>, <&pinctrl_sd1_cd>; + pinctrl-1 = <&pinctrl_sd1>, <&pinctrl_sd1_cd>; + pinctrl-2 = <&pinctrl_sd1>, <&pinctrl_sd1_cd>; + cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; + disable-wp; + vmmc-supply = <®_sd1_vmmc>; + vqmmc-supply = <®_sd1_vqmmc>; +}; + +/* Lino SD_2 */ +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_sd2>; + pinctrl-1 = <&pinctrl_sd2>; + pinctrl-2 = <&pinctrl_sd2>; +}; + +&wdog3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx93-imx91-lino-verdin-common.dtsi b/arch/arm64/boot/dts/freescale/imx93-imx91-lino-verdin-common.dtsi new file mode 100644 index 0000000..0023e76 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93-imx91-lino-verdin-common.dtsi
@@ -0,0 +1,175 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Lino iMX93/iMX91 SoM on Lino-Verdin Adapter + * + * https://www.toradex.com/computer-on-modules/verdin-arm-family + * https://www.toradex.com/computer-on-modules/lino-arm-family/nxp-imx93 + * https://www.toradex.com/computer-on-modules/lino-arm-family/nxp-imx91 + */ + +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/net/ti-dp83867.h> + +/ { + verdin_i2s1_mclk: clock-24576000 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24576000>; + }; + + verdin_csi1_mclk: clock-25000000 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + }; + + connector { + compatible = "gpio-usb-b-connector", "usb-b-connector"; + id-gpios = <&adapter_gpio_expander 1 GPIO_ACTIVE_HIGH>; + self-powered; + type = "micro"; + vbus-supply = <®_usb1_vbus>; + + port { + usb_1_connector: endpoint { + remote-endpoint = <&usb1_drd_sw>; + }; + }; + }; + + verdin_gpio_keys: gpio-keys { + compatible = "gpio-keys"; + + status = "disabled"; + + key-wakeup { + debounce-interval = <10>; + /* Verdin CTRL_WAKE1_MICO# (SODIMM 252) */ + gpios = <&adapter_gpio_expander 2 GPIO_ACTIVE_LOW>; + label = "Wake-Up"; + wakeup-source; + linux,code = <KEY_WAKEUP>; + }; + }; +}; + +/* Lino ETH_1 */ +&eqos { + phy-handle = <ðphy1>; + phy-mode = "rgmii-id"; +}; + +/* Lino I2C_1 */ +&lpi2c1 { + status = "okay"; + + i2c-mux@70 { + compatible = "nxp,pca9543"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + verdin_i2c_1: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + adapter_i2c: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + + adapter_gpio_expander: gpio@21 { + compatible = "nxp,pcal6416"; + reg = <0x21>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_11>; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&gpio1>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; + #gpio-cells = <2>; + gpio-controller; + gpio-line-names = + "SODIMM_244", /* Verdin PCIE_1_RESET# */ + "SODIMM_161", /* Verdin USB_1_ID */ + "SODIMM_252", /* Verdin CTRL_WAKE1_MICO# */ + "ETH_1_INT#", + "CTRL_EN_WIFI", + "", + "", + "", + "SODIMM_42", /* Verdin I2S_2_BCLK */ + "SODIMM_48", /* Verdin I2S_2_D_IN */ + "SODIMM_46", /* Verdin I2S_2_D_OUT */ + "SODIMM_44", /* Verdin I2S_2_SYNC */ + "SODIMM_64", /* Verdin QSPI_1_CS2# */ + "SODIMM_66", /* Verdin QSPI_1_DQS */ + "SODIMM_60", /* Verdin QSPI_1_IO2 */ + "SODIMM_62"; /* Verdin QSPI_1_IO3 */ + + verdin_pcie_1_reset_hog: pcie-1-reset-hog { + gpio-hog; + /* Verdin PCIE_1_RESET# (SODIMM 244) */ + gpios = <0 GPIO_ACTIVE_LOW>; + line-name = "PCIE_1_RESET#"; + output-low; + + status = "disabled"; + }; + }; + + /* Current measurement into module VCC */ + hwmon@40 { + compatible = "ti,ina219"; + reg = <0x40>; + shunt-resistor = <10000>; + }; + }; + }; +}; + +/* Lino UART_1 */ +&lpuart6 { + status = "okay"; + + bluetooth { + compatible = "nxp,88w8987-bt"; + fw-init-baudrate = <3000000>; + }; +}; + +/* Lino Ethernet MDIO */ +&mdio { + status = "okay"; + + ethphy1: ethernet-phy@1 { + reg = <1>; + interrupt-parent = <&adapter_gpio_expander>; + interrupts = <3 IRQ_TYPE_EDGE_FALLING>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>; + ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>; + }; +}; + +/* Lino USB_1 */ +&usbotg1 { + port { + usb1_drd_sw: endpoint { + remote-endpoint = <&usb_1_connector>; + }; + }; +}; + +/* Lino SD_2 */ +&usdhc3 { + keep-power-in-suspend; + non-removable; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx93-imx91-lino-verdin-dahlia-common.dtsi b/arch/arm64/boot/dts/freescale/imx93-imx91-lino-verdin-dahlia-common.dtsi new file mode 100644 index 0000000..5f61362 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93-imx91-lino-verdin-dahlia-common.dtsi
@@ -0,0 +1,198 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Lino iMX93/iMX91 SoM on Lino-Verdin Adapter / Dahlia carrier board + * + * https://www.toradex.com/computer-on-modules/lino-arm-family/nxp-imx91 + * https://www.toradex.com/computer-on-modules/lino-arm-family/nxp-imx93 + * https://www.toradex.com/products/carrier-board/dahlia-carrier-board-kit + */ + +/ { + aliases { + eeprom1 = &carrier_eeprom; + }; + + reg_1v8_sw: regulator-1v8-sw { + compatible = "regulator-fixed"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "On-carrier +V1.8_SW"; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,bitclock-master = <&codec_dai>; + simple-audio-card,format = "i2s"; + simple-audio-card,frame-master = <&codec_dai>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "verdin-wm8904"; + simple-audio-card,routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "IN2L", "Line In Jack", + "IN2R", "Line In Jack", + "Microphone Jack", "MICBIAS", + "IN1L", "Microphone Jack"; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Headphone", "Headphone Jack", + "Line", "Line In Jack"; + + codec_dai: simple-audio-card,codec { + sound-dai = <&wm8904_1a>; + }; + + simple-audio-card,cpu { + sound-dai = <&sai3>; + }; + }; +}; + +/* Lino ADC_1, ADC_2, ADC_3 and ADC_4 */ +&adc1 { + status = "okay"; +}; + +&gpio2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>, <&pinctrl_gpio3>, + <&pinctrl_gpio4>, <&pinctrl_gpio5>; +}; + +&gpio3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio6>, <&pinctrl_gpio7>; +}; + +&gpio4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio8>, <&pinctrl_gpio9>, <&pinctrl_gpio10>; +}; + +/* Lino ETH_1 */ +&eqos { + status = "okay"; +}; + +/* Lino CAN_1 */ +&flexcan1 { + status = "okay"; +}; + +/* Lino CAN_2 */ +&flexcan2 { + status = "okay"; +}; + +/* Lino I2C_2 */ +&lpi2c3 { + status = "okay"; +}; + +/* Lino I2C_3 */ +&lpi2c4 { + status = "okay"; +}; + +/* Lino SPI_1 */ +&lpspi8 { + status = "okay"; +}; + +/* Lino UART_3, used as the Linux Console */ +&lpuart1 { + status = "okay"; +}; + +/* Lino UART_4 */ +&lpuart2 { + status = "okay"; +}; + +/* Lino UART_2 */ +&lpuart7 { + status = "okay"; +}; + +/* Lino I2S_1 */ +&sai3 { + status = "okay"; +}; + +/* Lino PWM_1 */ +&tpm4 { + status = "okay"; +}; + +/* Lino PWM_2 */ +&tpm5 { + status = "okay"; +}; + +/* Lino PWM_3 */ +&tpm6 { + status = "okay"; +}; + +/* Lino USB_1 */ +&usbotg1 { + status = "okay"; +}; + +/* Lino USB_2 */ +&usbotg2 { + status = "okay"; +}; + +/* Lino SD_1 */ +&usdhc2 { + status = "okay"; +}; + +/* Verdin CTRL_WAKE1_MICO# */ +&verdin_gpio_keys { + status = "okay"; +}; + +/* Verdin I2C_1 */ +&verdin_i2c_1 { + status = "okay"; + + wm8904_1a: audio-codec@1a { + compatible = "wlf,wm8904"; + reg = <0x1a>; + clock-names = "mclk"; + clocks = <&verdin_i2s1_mclk>; + #sound-dai-cells = <0>; + AVDD-supply = <®_1v8_sw>; + CPVDD-supply = <®_1v8_sw>; + DBVDD-supply = <®_1v8_sw>; + DCVDD-supply = <®_1v8_sw>; + MICVDD-supply = <®_1v8_sw>; + }; + + /* Current measurement into module VCC */ + hwmon@40 { + compatible = "ti,ina219"; + reg = <0x40>; + shunt-resistor = <10000>; + }; + + temperature-sensor@4f { + compatible = "ti,tmp75c"; + reg = <0x4f>; + }; + + carrier_eeprom: eeprom@57 { + compatible = "st,24c02", "atmel,24c02"; + reg = <0x57>; + pagesize = <16>; + }; +}; + +/* Verdin PCIE_1_RESET# */ +&verdin_pcie_1_reset_hog { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx93-imx91-lino-verdin-dev-common.dtsi b/arch/arm64/boot/dts/freescale/imx93-imx91-lino-verdin-dev-common.dtsi new file mode 100644 index 0000000..1664b38 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93-imx91-lino-verdin-dev-common.dtsi
@@ -0,0 +1,216 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Lino iMX93/iMX91 SoM on Lino-Verdin Adapter / Development carrier board + * + * https://www.toradex.com/computer-on-modules/lino-arm-family/nxp-imx91 + * https://www.toradex.com/computer-on-modules/lino-arm-family/nxp-imx93 + * https://www.toradex.com/products/carrier-board/verdin-development-board-kit + */ + +/ { + aliases { + eeprom1 = &carrier_eeprom; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,bitclock-master = <&codec_dai>; + simple-audio-card,format = "i2s"; + simple-audio-card,frame-master = <&codec_dai>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "verdin-nau8822"; + simple-audio-card,routing = + "Headphones", "LHP", + "Headphones", "RHP", + "Speaker", "LSPK", + "Speaker", "RSPK", + "Line Out", "AUXOUT1", + "Line Out", "AUXOUT2", + "LAUX", "Line In", + "RAUX", "Line In", + "LMICP", "Mic In", + "RMICP", "Mic In"; + simple-audio-card,widgets = + "Headphones", "Headphones", + "Line Out", "Line Out", + "Speaker", "Speaker", + "Microphone", "Mic In", + "Line", "Line In"; + + codec_dai: simple-audio-card,codec { + sound-dai = <&nau8822_1a>; + }; + + simple-audio-card,cpu { + sound-dai = <&sai3>; + }; + }; +}; + +/* Lino ADC_1, ADC_2, ADC_3 and ADC_4 */ +&adc1 { + status = "okay"; +}; + +&gpio2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio1>, <&pinctrl_gpio2>, <&pinctrl_gpio3>, + <&pinctrl_gpio4>, <&pinctrl_gpio5>; +}; + +&gpio3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio6>, <&pinctrl_gpio7>; +}; + +&gpio4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio8>, <&pinctrl_gpio9>, <&pinctrl_gpio10>; +}; + +/* Lino ETH_1 */ +&eqos { + status = "okay"; +}; + +/* Lino ETH_2 */ +&fec { + phy-handle = <ðphy2>; + phy-mode = "rgmii-id"; + + status = "okay"; +}; + +/* Lino CAN_1 */ +&flexcan1 { + status = "okay"; +}; + +/* Lino CAN_2 */ +&flexcan2 { + status = "okay"; +}; + +/* Lino I2C_2 */ +&lpi2c3 { + status = "okay"; +}; + +/* Lino I2C_3 */ +&lpi2c4 { + status = "okay"; +}; + +/* Lino SPI_1 */ +&lpspi8 { + status = "okay"; +}; + +/* Lino UART_3, used as the Linux Console */ +&lpuart1 { + status = "okay"; +}; + +/* Lino UART_4 */ +&lpuart2 { + status = "okay"; +}; + +/* Lino UART_2 */ +&lpuart7 { + status = "okay"; +}; + +/* Lino Ethernet MDIO */ +&mdio { + ethphy2: ethernet-phy@7 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <7>; + micrel,led-mode = <0>; + }; +}; + +/* Lino I2S_1 */ +&sai3 { + status = "okay"; +}; + +/* Lino PWM_1 */ +&tpm4 { + status = "okay"; +}; + +/* Lino PWM_2 */ +&tpm5 { + status = "okay"; +}; + +/* Lino PWM_3 */ +&tpm6 { + status = "okay"; +}; + +/* Lino USB_1 */ +&usbotg1 { + status = "okay"; +}; + +/* Lino USB_2 */ +&usbotg2 { + status = "okay"; +}; + +/* Lino SD_1 */ +&usdhc2 { + status = "okay"; +}; + +/* Verdin CTRL_WAKE1_MICO# */ +&verdin_gpio_keys { + status = "okay"; +}; + +/* Verdin I2C_1 */ +&verdin_i2c_1 { + status = "okay"; + + nau8822_1a: audio-codec@1a { + compatible = "nuvoton,nau8822"; + reg = <0x1a>; + clock-names = "mclk"; + clocks = <&verdin_i2s1_mclk>; + #sound-dai-cells = <0>; + }; + + carrier_gpio_expander: gpio@21 { + compatible = "nxp,pcal6416"; + reg = <0x21>; + #gpio-cells = <2>; + gpio-controller; + }; + + /* Current measurement into module VCC */ + hwmon@40 { + compatible = "ti,ina219"; + reg = <0x40>; + shunt-resistor = <10000>; + }; + + temperature-sensor@4f { + compatible = "ti,tmp75c"; + reg = <0x4f>; + }; + + carrier_eeprom: eeprom@57 { + compatible = "st,24c02", "atmel,24c02"; + reg = <0x57>; + pagesize = <16>; + }; +}; + +/* Verdin PCIE_1_RESET# */ +&verdin_pcie_1_reset_hog { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx93-imx91-toradex-osm-common.dtsi b/arch/arm64/boot/dts/freescale/imx93-imx91-toradex-osm-common.dtsi new file mode 100644 index 0000000..8b0131d --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93-imx91-toradex-osm-common.dtsi
@@ -0,0 +1,526 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Toradex OSM iMX93/iMX91 SoM + * + * https://www.toradex.com/computer-on-modules/osm-arm-family/nxp-imx93 + * https://www.toradex.com/computer-on-modules/osm-arm-family/nxp-imx91 + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + aliases { + can0 = &flexcan1; + can1 = &flexcan2; + eeprom0 = &som_eeprom; + ethernet0 = &eqos; + ethernet1 = &fec; + i2c0 = &lpi2c2; + i2c1 = &lpi2c3; + i2c2 = &lpi2c1; + mmc0 = &usdhc1; + mmc1 = &usdhc2; + mmc2 = &usdhc3; + rtc0 = &rtc_i2c; + rtc1 = &bbnsm_rtc; + serial0 = &lpuart1; + serial1 = &lpuart6; + serial2 = &lpuart7; + serial3 = &lpuart2; + usb0 = &usbotg1; + usb1 = &usbotg2; + }; + + chosen { + stdout-path = &lpuart1; + }; + + reg_sdio_a_vmmc: regulator-sdhci2-vmmc { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdio_a_pwr_en>; + /* OSM SDIO_A_PWR_EN (OSM D21) */ + gpios = <&gpio3 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + off-on-delay-us = <100000>; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "SDIO_A_PWR_EN"; + startup-delay-us = <20000>; + }; + + reg_sdio_a_vqmmc: regulator-sdhci2-vqmmc { + compatible = "regulator-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdio_a_vsel>; + /* PMIC_SD_2_VSEL */ + gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + regulator-name = "LDO1-VSEL-SD (PMIC)"; + states = <1800000 0x1>, + <3300000 0x0>; + vin-supply = <®_sd_3v3_1v8>; + }; + + reg_usb_b_vbus: regulator-usb2-vbus { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb_b_en>; + /* OSM USB_B_EN (OSM AC20) */ + gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + regulator-name = "USB_B_EN"; + startup-delay-us = <20000>; + }; +}; + +/* OSM ADC_0, ADC_1 */ +&adc1 { + vref-supply = <®_1v8>; +}; + +/* OSM ETH_A */ +&eqos { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mdio>, <&pinctrl_eth_a>; + + mdio: mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; +}; + +/* OSM ETH_B */ +&fec { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_eth_b>; +}; + +/* OSM CAN_A */ +&flexcan1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can_a>; +}; + +/* OSM CAN_B */ +&flexcan2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can_b>; +}; + +&gpio1 { + gpio-line-names = + "OSM_AA20", + "OSM_AA21", + "PMIC_I2C_SCL", + "PMIC_I2C_SDA", + "", + "", + "", + "", + "", + "", + "OSM_AC20", /* 10 */ + "OSM_AA23", + "", + "", + "", + ""; +}; + +&gpio2 { + gpio-line-names = + "OSM_D17", + "OSM_E17", + "OSM_F17", + "OSM_G17", + "", + "", + "", + "", + "", + "", + "", /* 10 */ + "", + "OSM_Y15", + "", + "", + "", + "", + "", + "", + "", + "", /* 20 */ + "", + "OSM_H17", + "", + "OSM_J17", + "", + "", + "", + "OSM_AA16", + "OSM_AA15"; +}; + +&gpio3 { + gpio-line-names = + "OSM_J21", + "", + "", + "", + "", + "", + "", + "OSM_D21", + "", + "", + "", /* 10 */ + "", + "", + "", + "", + "", + "", + "", + "", + "PMIC_SD_2_VSEL", + "", /* 20 */ + "", + "", + "", + "", + "", + "", + "CTRL_INT#", + "", + "", + "", /* 30 */ + ""; +}; + +&gpio4 { + gpio-line-names = + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", /* 10 */ + "", + "", + "", + "OSM_K17", + "OSM_L17", + "", + "", + "", + "", + "", /* 20 */ + "", + "", + "", + "", + "", + "", + "", + "OSM_AC16", + "OSM_AC15"; +}; + +/* OSM I2C_B */ +&lpi2c1 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c_b>; + pinctrl-1 = <&pinctrl_i2c_b_gpio>; + clock-frequency = <100000>; + scl-gpios = <&gpio1 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + single-master; + + status = "okay"; + + rtc_i2c: rtc@32 { + compatible = "epson,rx8130"; + reg = <0x32>; + }; +}; + +/* On-module I2C - PMIC_I2C */ +&lpi2c2 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_pmic_i2c>, <&pinctrl_ctrl_int>; + pinctrl-1 = <&pinctrl_pmic_i2c_gpio>, <&pinctrl_ctrl_int>; + clock-frequency = <400000>; + scl-gpios = <&gpio1 2 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio1 3 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + single-master; + + status = "okay"; + + som_gpio_expander: gpio@21 { + compatible = "nxp,pcal6416"; + reg = <0x21>; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&gpio3>; + interrupts = <27 IRQ_TYPE_LEVEL_LOW>; + #gpio-cells = <2>; + gpio-controller; + gpio-line-names = + "OSM_D19", /* OSM GPIO_B_0 */ + "OSM_E19", /* OSM GPIO_B_1 */ + "OSM_F19", /* OSM GPIO_B_2 */ + "OSM_G19", /* OSM GPIO_B_3 */ + "OSM_H19", /* OSM GPIO_B_4 */ + "OSM_J19", /* OSM GPIO_B_5 */ + "OSM_K19", /* OSM GPIO_B_6 */ + "OSM_L19", /* OSM GPIO_B_7 */ + "OSM_D3", /* OSM GPIO_C_0 */ + "OSM_D4", /* OSM GPIO_C_1 */ + "OSM_E3", /* OSM GPIO_C_2/CAM_B_PWR */ + "OSM_E4", /* OSM GPIO_C_3/CAM_B_RST# */ + "OSM_F3", /* OSM GPIO_C_4/DISP_VDD_EN */ + "OSM_F4", /* OSM GPIO_C_5/DISP_BL_EN */ + "OSM_G3", /* OSM GPIO_C_6/CAM_A_PWR */ + "OSM_G4"; /* OSM GPIO_C_7/CAM_A_RST# */ + }; + + tpm@2e { + compatible = "st,st33ktpm2xi2c", "tcg,tpm-tis-i2c"; + reg = <0x2e>; + }; + + pmic@32 { + compatible = "nxp,pf9453"; + reg = <0x32>; + interrupt-parent = <&gpio3>; + interrupts = <27 IRQ_TYPE_LEVEL_LOW>; + + regulators { + BUCK1 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1100000>; + regulator-min-microvolt = <1100000>; + regulator-name = "+V1.1_DDR (PMIC BUCK1)"; + }; + + reg_vdd_soc: BUCK2 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <950000>; + regulator-min-microvolt = <612500>; + regulator-name = "+VDD_SOC (PMIC BUCK2)"; + regulator-ramp-delay = <12500>; + }; + + reg_1v8: BUCK3 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "+V1.8 / +V1.8_ANA (PMIC BUCK3)"; + }; + + reg_3v3: BUCK4 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "+V3.3 (PMIC BUCK4)"; + }; + + reg_sd_3v3_1v8: LDO1 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + regulator-name = "+V3.3_1.8_SD (PMIC LDO1)"; + }; + + LDO2 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <800000>; + regulator-min-microvolt = <800000>; + regulator-name = "+V0.8_ANA (PMIC LDO2)"; + }; + + LDO-SNVS { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "+V1.8_BBSM (PMIC LDO-SNVS)"; + }; + }; + }; + + temperature-sensor@48 { + compatible = "ti,tmp1075"; + reg = <0x48>; + }; + + som_eeprom: eeprom@50 { + compatible = "st,24c02", "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +/* OSM I2C_A */ +&lpi2c3 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c_a>; + pinctrl-1 = <&pinctrl_i2c_a_gpio>; + clock-frequency = <100000>; + scl-gpios = <&gpio2 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio2 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + single-master; +}; + +/* OSM SPI_B */ +&lpspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi_b>, <&pinctrl_spi_b_cs0_gpio>; + cs-gpios = <&gpio1 11 GPIO_ACTIVE_LOW>; +}; + +/* OSM SPI_A */ +&lpspi8 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi_a>, <&pinctrl_spi_a_cs0_gpio>; + cs-gpios = <&gpio2 12 GPIO_ACTIVE_LOW>; +}; + +/* OSM UART_CON, used as the Linux Console */ +&lpuart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart_con>; +}; + +/* OSM UART_C */ +&lpuart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart_c>; +}; + +/* OSM UART_A */ +&lpuart6 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart_a>; + uart-has-rtscts; +}; + +/* OSM UART_B */ +&lpuart7 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart_b>; + uart-has-rtscts; +}; + +/* OSM I2S_A */ +&sai3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2s_a>; + assigned-clocks = <&clk IMX93_CLK_SAI3>; + assigned-clock-parents = <&clk IMX93_CLK_AUDIO_PLL>; + assigned-clock-rates = <12288000>; + fsl,sai-mclk-direction-output; +}; + +/* OSM PWM_0 */ +&tpm4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm0>; +}; + +/* OSM PWM_1 */ +&tpm5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm1>; +}; + +/* OSM PWM_2 */ +&tpm6 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm2>; +}; + +/* OSM USB_A */ +&usbotg1 { + dr_mode = "otg"; + adp-disable; + hnp-disable; + srp-disable; + usb-role-switch; + disable-over-current; + role-switch-default-mode = "peripheral"; + samsung,picophy-dc-vol-level-adjust = <7>; + samsung,picophy-pre-emp-curr-control = <3>; +}; + +/* OSM USB_B */ +&usbotg2 { + disable-over-current; + dr_mode = "host"; + vbus-supply = <®_usb_b_vbus>; + samsung,picophy-dc-vol-level-adjust = <7>; + samsung,picophy-pre-emp-curr-control = <3>; +}; + +/* On-module eMMC */ +&usdhc1 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_emmc>; + pinctrl-1 = <&pinctrl_emmc>; + pinctrl-2 = <&pinctrl_emmc>; + no-sd; + no-sdio; + non-removable; + + status = "okay"; +}; + +/* OSM SDIO_A */ +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_sdio_a>, <&pinctrl_sdio_a_cd>; + pinctrl-1 = <&pinctrl_sdio_a>, <&pinctrl_sdio_a_cd>; + pinctrl-2 = <&pinctrl_sdio_a>, <&pinctrl_sdio_a_cd>; + cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; + disable-wp; + vmmc-supply = <®_sdio_a_vmmc>; + vqmmc-supply = <®_sdio_a_vqmmc>; +}; + +/* OSM SDIO_B */ +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_sdio_b>; + pinctrl-1 = <&pinctrl_sdio_b>; + pinctrl-2 = <&pinctrl_sdio_b>; + disable-wp; +}; + +&wdog3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_wdog>; + fsl,ext-reset-output; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx93-imx91-toradex-osm-dev-common.dtsi b/arch/arm64/boot/dts/freescale/imx93-imx91-toradex-osm-dev-common.dtsi new file mode 100644 index 0000000..566671b --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93-imx91-toradex-osm-dev-common.dtsi
@@ -0,0 +1,324 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Toradex OSM iMX93/iMX91 SoM on OSM Development carrier board + * + * https://www.toradex.com/computer-on-modules/osm-arm-family/nxp-imx93 + * https://www.toradex.com/computer-on-modules/osm-arm-family/nxp-imx91 + * https://www.toradex.com/products/carrier-board/osm-development-board + */ + +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/net/ti-dp83867.h> +#include <dt-bindings/usb/pd.h> + +/ { + aliases { + eeprom1 = &carrier_eeprom; + }; + + reg_carrier_1p8v: regulator-carrier-1p8v { + compatible = "regulator-fixed"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "On-carrier V1.8_SW"; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,bitclock-master = <&codec_dai>; + simple-audio-card,format = "i2s"; + simple-audio-card,frame-master = <&codec_dai>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "verdin-wm8904"; + simple-audio-card,routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "IN2L", "Line In Jack", + "IN2R", "Line In Jack", + "Microphone Jack", "MICBIAS", + "IN1L", "Microphone Jack"; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Headphone", "Headphone Jack", + "Line", "Line In Jack"; + + codec_dai: simple-audio-card,codec { + sound-dai = <&wm8904_1a>; + }; + + simple-audio-card,cpu { + sound-dai = <&sai3>; + }; + }; +}; + +/* OSM ADC_0, ADC_1 */ +&adc1 { + status = "okay"; +}; + +/* OSM ETH_A */ +&eqos { + phy-handle = <ðphy_a>; + phy-mode = "rgmii-id"; + + status = "okay"; +}; + +/* OSM ETH_B */ +&fec { + phy-handle = <ðphy_b>; + phy-mode = "rgmii-id"; + + status = "okay"; +}; + +/* OSM CAN_A */ +&flexcan1 { + status = "okay"; +}; + +/* OSM CAN_B */ +&flexcan2 { + status = "okay"; +}; + +&gpio2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_a1>, <&pinctrl_gpio_a2>, <&pinctrl_gpio_a3>, + <&pinctrl_gpio_a4>, <&pinctrl_gpio_a5>; +}; + +&gpio4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_a6>; +}; + +/* OSM I2C_B */ +&lpi2c1 { + i2c-mux@70 { + compatible = "nxp,pca9548"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + i2c_csi: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c_lvds: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + + /* I2C on DSI connector pin #4 and #6 */ + i2c_dsi_1: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; + + /* I2C on DSI connector pin #52 and #54 */ + i2c_dsi_2: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; + +/* OSM I2C_A */ +&lpi2c3 { + status = "okay"; + + wm8904_1a: audio-codec@1a { + compatible = "wlf,wm8904"; + reg = <0x1a>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2s_a_mclk>; + clocks = <&clk IMX93_CLK_SAI3>; + clock-names = "mclk"; + #sound-dai-cells = <0>; + AVDD-supply = <®_carrier_1p8v>; + CPVDD-supply = <®_carrier_1p8v>; + DBVDD-supply = <®_carrier_1p8v>; + DCVDD-supply = <®_carrier_1p8v>; + MICVDD-supply = <®_carrier_1p8v>; + }; + + gpio@20 { + compatible = "nxp,pcal6408"; + reg = <0x20>; + #gpio-cells = <2>; + gpio-controller; + gpio-line-names = + "PWR_CTRL_CAN_A", /* 0 */ + "PWR_CTRL_CAN_B", + "PWR_CTRL_USB-HUB", + "LVDS_MUX_CTRL", + "USB_MUX_CTRL", + "I2CA_IOEXP_P5", + "I2CA_IOEXP_P6", + "I2CA_IOEXP_P7"; + + lvds_mux_ctrl: lvds-mux-ctrl-hog { + gpio-hog; + gpios = <3 GPIO_ACTIVE_HIGH>; + line-name = "LVDS_MUX_CTRL"; + output-high; + }; + + usb_mux_ctrl: usb-mux-ctrl-hog { + gpio-hog; + gpios = <4 GPIO_ACTIVE_HIGH>; + line-name = "USB_MUX_CTRL"; + output-low; + }; + }; + + hwmon@40 { + compatible = "ti,ina219"; + reg = <0x40>; + shunt-resistor = <10000>; + }; + + temperature-sensor@4f { + compatible = "ti,tmp1075"; + reg = <0x4f>; + }; + + tcpc@52 { + compatible = "nxp,ptn5110", "tcpci"; + reg = <0x52>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_a0>; + interrupt-parent = <&gpio2>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + + connector { + compatible = "usb-c-connector"; + label = "USB_A"; + data-role = "dual"; + power-role = "dual"; + try-power-role = "sink"; + self-powered; + source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>; + sink-pdos = <PDO_FIXED(5000, 0, PDO_FIXED_USB_COMM)>; + op-sink-microwatt = <0>; + + port { + usb_c_a_conn_hs: endpoint { + remote-endpoint = <&usb_a_hs>; + }; + }; + }; + }; + + carrier_eeprom: eeprom@57 { + compatible = "st,24c02", "atmel,24c02"; + reg = <0x57>; + pagesize = <16>; + }; +}; + +/* OSM SPI_B */ +&lpspi1 { + status = "okay"; +}; + +/* OSM SPI_A */ +&lpspi8 { + status = "okay"; +}; + +/* OSM UART_CON, used as the Linux Console */ +&lpuart1 { + status = "okay"; +}; + +/* OSM UART_C */ +&lpuart2 { + status = "okay"; +}; + +/* OSM UART_A */ +&lpuart6 { + status = "okay"; +}; + +/* OSM UART_B */ +&lpuart7 { + status = "okay"; +}; + +/* OSM ETH_MDIO */ +&mdio { + status = "okay"; + + ethphy_a: ethernet-phy@2 { + reg = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_a7>; + interrupt-parent = <&gpio4>; + interrupts = <15 IRQ_TYPE_LEVEL_LOW>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>; + ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>; + }; + + ethphy_b: ethernet-phy@3 { + reg = <3>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>; + ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>; + }; +}; + +/* OSM I2S_A */ +&sai3 { + status = "okay"; +}; + +/* OSM PWM_0 */ +&tpm4 { + status = "okay"; +}; + +/* OSM PWM_1 */ +&tpm5 { + status = "okay"; +}; + +/* OSM PWM_2 */ +&tpm6 { + status = "okay"; +}; + +/* OSM USB_A */ +&usbotg1 { + status = "okay"; + + port { + usb_a_hs: endpoint { + remote-endpoint = <&usb_c_a_conn_hs>; + }; + }; +}; + +/* OSM USB_B */ +&usbotg2 { + status = "okay"; +}; + +/* OSM SDIO_A */ +&usdhc2 { + status = "okay"; +}; + +/* OSM SDIO_B */ +&usdhc3 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx93-kontron-bl-osm-s.dts b/arch/arm64/boot/dts/freescale/imx93-kontron-bl-osm-s.dts index 4620c07..0277640 100644 --- a/arch/arm64/boot/dts/freescale/imx93-kontron-bl-osm-s.dts +++ b/arch/arm64/boot/dts/freescale/imx93-kontron-bl-osm-s.dts
@@ -158,12 +158,8 @@ &tpm6 { }; &usbotg1 { - adp-disable; - hnp-disable; - srp-disable; disable-over-current; - dr_mode = "otg"; - usb-role-switch; + dr_mode = "peripheral"; status = "okay"; };
diff --git a/arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi b/arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi index f881912..36548d9 100644 --- a/arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi +++ b/arch/arm64/boot/dts/freescale/imx93-kontron-osm-s.dtsi
@@ -34,29 +34,6 @@ reg_usdhc2_vcc: regulator-usdhc2-vcc { regulator-max-microvolt = <3300000>; regulator-name = "VCC_SDIO_A"; }; - - reg_vdd_carrier: regulator-vdd-carrier { - compatible = "regulator-fixed"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_reg_vdd_carrier>; - gpio = <&gpio4 29 GPIO_ACTIVE_HIGH>; - enable-active-high; - regulator-always-on; - regulator-boot-on; - regulator-name = "VDD_CARRIER"; - - regulator-state-standby { - regulator-on-in-suspend; - }; - - regulator-state-mem { - regulator-off-in-suspend; - }; - - regulator-state-disk { - regulator-off-in-suspend; - }; - }; }; &flexcan1 { /* OSM-S CAN_A */ @@ -113,7 +90,7 @@ &gpio4 { "ETH_A_TXD3", "ETH_A_TXD2", "ETH_A_TXD1", "ETH_A_TXD0", "ETH_A_TX_EN", "ETH_A_TX_CLK", "ETH_A_RX_CTL", "ETH_A_RX_CLK", "ETH_A_RXD0", "ETH_A_RXD1", "ETH_A_RXD2", "ETH_A_RXD3", - "GPIO_B_0", "CARRIER_PWR_EN"; + "GPIO_B_0", "GPIO_B_2"; }; &lpi2c1 { @@ -385,6 +362,7 @@ MX93_PAD_CCM_CLKO2__GPIO3_IO27 0x31e /* GPIO_A_7 */ pinctrl_gpio4: gpio4grp { fsl,pins = < MX93_PAD_CCM_CLKO3__GPIO4_IO28 0x31e /* GPIO_B_0 */ + MX93_PAD_CCM_CLKO4__GPIO4_IO29 0x31e /* GPIO_B_2 */ >; }; @@ -465,12 +443,6 @@ MX93_PAD_SD2_RESET_B__GPIO3_IO07 0x31e /* SDIO_A_PWR_EN */ >; }; - pinctrl_reg_vdd_carrier: regvddcarriergrp { - fsl,pins = < - MX93_PAD_CCM_CLKO4__GPIO4_IO29 0x31e /* CARRIER_PWR_EN */ - >; - }; - pinctrl_rtc: rtcgrp { fsl,pins = < MX93_PAD_SD2_VSELECT__GPIO3_IO19 0x31e
diff --git a/arch/arm64/boot/dts/freescale/imx93-lino-verdin-dahlia.dts b/arch/arm64/boot/dts/freescale/imx93-lino-verdin-dahlia.dts new file mode 100644 index 0000000..c708a2e --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93-lino-verdin-dahlia.dts
@@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Lino iMX93 SoM on Lino-Verdin Adapter / Dahlia carrier board + * + * https://www.toradex.com/computer-on-modules/lino-arm-family/nxp-imx93 + * https://www.toradex.com/products/carrier-board/dahlia-carrier-board-kit + */ + +/dts-v1/; + +#include "imx93.dtsi" +#include "imx93-lino.dtsi" +#include "imx93-imx91-lino-verdin-common.dtsi" +#include "imx93-imx91-lino-verdin-dahlia-common.dtsi" + +/ { + model = "Toradex Lino iMX93 on Verdin Adapter plus Dahlia Board"; + compatible = "toradex,lino-imx93-verdin-dahlia", + "toradex,lino-imx93-verdin", + "toradex,lino-imx93", + "fsl,imx93"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx93-lino-verdin-dev.dts b/arch/arm64/boot/dts/freescale/imx93-lino-verdin-dev.dts new file mode 100644 index 0000000..a79553d --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93-lino-verdin-dev.dts
@@ -0,0 +1,24 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Lino iMX93 SoM on Lino-Verdin Adapter / Development carrier board + * + * https://www.toradex.com/computer-on-modules/lino-arm-family/nxp-imx93 + * https://www.toradex.com/products/carrier-board/verdin-development-board-kit + */ + +/dts-v1/; + +#include "imx93.dtsi" +#include "imx93-lino.dtsi" +#include "imx93-imx91-lino-verdin-common.dtsi" +#include "imx93-imx91-lino-verdin-dev-common.dtsi" + +/ { + model = "Toradex Lino iMX93 on Verdin Adapter plus Development Board"; + compatible = "toradex,lino-imx93-verdin-dev", + "toradex,lino-imx93-verdin", + "toradex,lino-imx93", + "fsl,imx93"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx93-lino.dtsi b/arch/arm64/boot/dts/freescale/imx93-lino.dtsi new file mode 100644 index 0000000..cab7f34 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93-lino.dtsi
@@ -0,0 +1,359 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Lino iMX93 SoM + * + * https://www.toradex.com/computer-on-modules/lino-arm-family/nxp-imx93 + */ + +#include "imx93-pinfunc.h" +#include "imx93-imx91-lino-common.dtsi" + +/ { + reserved-memory { + ranges; + #address-cells = <2>; + #size-cells = <2>; + + rsc_table: rsc-table@2021e000 { + reg = <0 0x2021e000 0 0x1000>; + no-map; + }; + + vdev0vring0: vdev0vring0@a4000000 { + reg = <0 0xa4000000 0 0x8000>; + no-map; + }; + + vdev0vring1: vdev0vring1@a4008000 { + reg = <0 0xa4008000 0 0x8000>; + no-map; + }; + + vdev1vring0: vdev1vring0@a4010000 { + reg = <0 0xa4010000 0 0x8000>; + no-map; + }; + + vdev1vring1: vdev1vring1@a4018000 { + reg = <0 0xa4018000 0 0x8000>; + no-map; + }; + + vdev0buffer: vdev0buffer@a4020000 { + compatible = "shared-dma-pool"; + reg = <0 0xa4020000 0 0x100000>; + no-map; + }; + }; +}; + +&cm33 { + mbox-names = "tx", "rx", "rxdb"; + mboxes = <&mu1 0 1>, + <&mu1 1 1>, + <&mu1 3 1>; + memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, + <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>; + + status = "okay"; +}; + +&mu1 { + status = "okay"; +}; + +&iomuxc { + /* Lino CAN_1 */ + pinctrl_can1: can1grp { + fsl,pins = <MX93_PAD_PDM_BIT_STREAM0__CAN1_RX 0x139e>, /* Lino P12 */ + <MX93_PAD_PDM_CLK__CAN1_TX 0x139e>; /* Lino P10 */ + }; + + /* Lino CAN_2 */ + pinctrl_can2: can2grp { + fsl,pins = <MX93_PAD_GPIO_IO25__CAN2_TX 0x139e>, /* Lino S28 */ + <MX93_PAD_GPIO_IO27__CAN2_RX 0x139e>; /* Lino S30 */ + }; + + /* Lino ETH_1 RGMII */ + pinctrl_eth1: eqosgrp { + fsl,pins = <MX93_PAD_ENET1_RD0__ENET_QOS_RGMII_RD0 0x1fe>, /* Lino P77 */ + <MX93_PAD_ENET1_RD1__ENET_QOS_RGMII_RD1 0x1fe>, /* Lino P79 */ + <MX93_PAD_ENET1_RD2__ENET_QOS_RGMII_RD2 0x1fe>, /* Lino P81 */ + <MX93_PAD_ENET1_RD3__ENET_QOS_RGMII_RD3 0x1fe>, /* Lino P83 */ + <MX93_PAD_ENET1_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x1fe>, /* Lino P73 */ + <MX93_PAD_ENET1_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x1fe>, /* Lino P75 */ + <MX93_PAD_ENET1_TD0__ENET_QOS_RGMII_TD0 0x1fe>, /* Lino P97 */ + <MX93_PAD_ENET1_TD1__ENET_QOS_RGMII_TD1 0x1fe>, /* Lino P95 */ + <MX93_PAD_ENET1_TD2__ENET_QOS_RGMII_TD2 0x1fe>, /* Lino P93 */ + <MX93_PAD_ENET1_TD3__ENET_QOS_RGMII_TD3 0x1fe>, /* Lino P91 */ + <MX93_PAD_ENET1_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x1fe>, /* Lino P89 */ + <MX93_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1fe>; /* Lino P85 */ + }; + + /* Lino ETH MDIO */ + pinctrl_mdio: eqosmdiogrp { + fsl,pins = <MX93_PAD_ENET1_MDC__ENET_QOS_MDC 0x1fe>, /* Lino P69 */ + <MX93_PAD_ENET1_MDIO__ENET_QOS_MDIO 0x1fe>; /* Lino P67 */ + }; + + /* Lino ETH_2 RGMII */ + pinctrl_eth2: fecgrp { + fsl,pins = <MX93_PAD_ENET2_RD0__ENET1_RGMII_RD0 0x1fe>, /* Lino S77 */ + <MX93_PAD_ENET2_RD1__ENET1_RGMII_RD1 0x1fe>, /* Lino S79 */ + <MX93_PAD_ENET2_RD2__ENET1_RGMII_RD2 0x1fe>, /* Lino S81 */ + <MX93_PAD_ENET2_RD3__ENET1_RGMII_RD3 0x1fe>, /* Lino S83 */ + <MX93_PAD_ENET2_RXC__ENET1_RGMII_RXC 0x1fe>, /* Lino S71 */ + <MX93_PAD_ENET2_RX_CTL__ENET1_RGMII_RX_CTL 0x1fe>, /* Lino S73 */ + <MX93_PAD_ENET2_TD0__ENET1_RGMII_TD0 0x1fe>, /* Lino S99 */ + <MX93_PAD_ENET2_TD1__ENET1_RGMII_TD1 0x1fe>, /* Lino S97 */ + <MX93_PAD_ENET2_TD2__ENET1_RGMII_TD2 0x1fe>, /* Lino S93 */ + <MX93_PAD_ENET2_TD3__ENET1_RGMII_TD3 0x1fe>, /* Lino S91 */ + <MX93_PAD_ENET2_TXC__ENET1_RGMII_TXC 0x1fe>, /* Lino S87 */ + <MX93_PAD_ENET2_TX_CTL__ENET1_RGMII_TX_CTL 0x1fe>; /* Lino S89 */ + }; + + /* Lino GPIO_11 */ + pinctrl_gpio_11: gpio1io10grp { + fsl,pins = <MX93_PAD_PDM_BIT_STREAM1__GPIO1_IO10 0x139e>; /* Lino P65 */ + }; + + /* Lino SPI_2_CS as GPIO */ + pinctrl_spi2_cs0_gpio: gpio1io11grp { + fsl,pins = <MX93_PAD_SAI1_TXFS__GPIO1_IO11 0x139e>; /* Lino S18 */ + }; + + /* Lino GPIO_1 */ + pinctrl_gpio1: gpio2io0grp { + fsl,pins = <MX93_PAD_GPIO_IO00__GPIO2_IO00 0x139e>; /* Lino P30 */ + }; + + /* Lino GPIO_2 */ + pinctrl_gpio2: gpio2io1grp { + fsl,pins = <MX93_PAD_GPIO_IO01__GPIO2_IO01 0x139e>; /* Lino P32 */ + }; + + /* Lino SPI_1_CS as GPIO */ + pinctrl_spi1_cs0_gpio: gpio2io12grp { + fsl,pins = <MX93_PAD_GPIO_IO12__GPIO2_IO12 0x139e>; /* Lino P58 */ + }; + + /* Lino GPIO_3 */ + pinctrl_gpio3: gpio2io17grp { + fsl,pins = <MX93_PAD_GPIO_IO17__GPIO2_IO17 0x139e>; /* Lino P34 */ + }; + + /* Lino GPIO_4 */ + pinctrl_gpio4: gpio2io22grp { + fsl,pins = <MX93_PAD_GPIO_IO22__GPIO2_IO22 0x139e>; /* Lino P36 */ + }; + + /* Lino PWM_3 as GPIO */ + pinctrl_pwm3_gpio: gpio2io23grp { + fsl,pins = <MX93_PAD_GPIO_IO23__GPIO2_IO23 0x139e>; /* Lino P5 */ + }; + + /* Lino GPIO_5 */ + pinctrl_gpio5: gpio2io24grp { + fsl,pins = <MX93_PAD_GPIO_IO24__GPIO2_IO24 0x139e>; /* Lino P38 */ + }; + + /* Lino GPIO_6 */ + pinctrl_gpio6: gpio3io26grp { + fsl,pins = <MX93_PAD_CCM_CLKO1__GPIO3_IO26 0x139e>; /* Lino P40 */ + }; + + /* Lino GPIO_7 */ + pinctrl_gpio7: gpio3io27grp { + fsl,pins = <MX93_PAD_CCM_CLKO2__GPIO3_IO27 0x139e>; /* Lino P42 */ + }; + + /* Lino GPIO_9 */ + pinctrl_gpio9: gpio4io14grp { + fsl,pins = <MX93_PAD_ENET2_MDC__GPIO4_IO14 0x139e>; /* Lino P46 */ + }; + + /* Lino GPIO_10 */ + pinctrl_gpio10: gpio4io15grp { + fsl,pins = <MX93_PAD_ENET2_MDIO__GPIO4_IO15 0x139e>; /* Lino P48 */ + }; + + /* Lino GPIO_8 */ + pinctrl_gpio8: gpio4io28grp { + fsl,pins = <MX93_PAD_CCM_CLKO3__GPIO4_IO28 0x139e>; /* Lino P44 */ + }; + + /* On-module GPIO_EXP_INT# */ + pinctrl_gpio_exp_int: gpio4io29grp { + fsl,pins = <MX93_PAD_CCM_CLKO4__GPIO4_IO29 0x139e>; /* GPIO_EXP_INT# */ + }; + + /* Lino I2C_1 as GPIO */ + pinctrl_i2c1_gpio: lpi2c1gpiogrp { + fsl,pins = <MX93_PAD_I2C1_SCL__GPIO1_IO00 0x40000b9e>, /* Lino P18 */ + <MX93_PAD_I2C1_SDA__GPIO1_IO01 0x40000b9e>; /* Lino P16 */ + }; + + /* Lino I2C_1 */ + pinctrl_i2c1: lpi2c1grp { + fsl,pins = <MX93_PAD_I2C1_SCL__LPI2C1_SCL 0x40000b9e>, /* Lino P18 */ + <MX93_PAD_I2C1_SDA__LPI2C1_SDA 0x40000b9e>; /* Lino P16 */ + }; + + /* On-module PMIC I2C as GPIO */ + pinctrl_pmic_i2c_gpio: lpi2c2gpiogrp { + fsl,pins = <MX93_PAD_I2C2_SCL__GPIO1_IO02 0x40000b9e>, /* PMIC_I2C_SCL */ + <MX93_PAD_I2C2_SDA__GPIO1_IO03 0x40000b9e>; /* PMIC_I2C_SDA */ + }; + + /* On-module PMIC I2C */ + pinctrl_pmic_i2c: lpi2c2grp { + fsl,pins = <MX93_PAD_I2C2_SCL__LPI2C2_SCL 0x40000b9e>, /* PMIC_I2C_SCL */ + <MX93_PAD_I2C2_SDA__LPI2C2_SDA 0x40000b9e>; /* PMIC_I2C_SDA */ + }; + + /* Lino I2C_2 as GPIO */ + pinctrl_i2c2_gpio: lpi2c3gpiogrp { + fsl,pins = <MX93_PAD_GPIO_IO28__GPIO2_IO28 0x40000b9e>, /* Lino P20 */ + <MX93_PAD_GPIO_IO29__GPIO2_IO29 0x40000b9e>; /* Lino P22 */ + }; + + /* Lino I2C_2 */ + pinctrl_i2c2: lpi2c3grp { + fsl,pins = <MX93_PAD_GPIO_IO28__LPI2C3_SDA 0x40000b9e>, /* Lino P20 */ + <MX93_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e>; /* Lino P22 */ + }; + + /* Lino I2C_3 as GPIO */ + pinctrl_i2c3_gpio: lpi2c4gpiogrp { + fsl,pins = <MX93_PAD_GPIO_IO02__GPIO2_IO02 0x40000b9e>, /* Lino P24 */ + <MX93_PAD_GPIO_IO03__GPIO2_IO03 0x40000b9e>; /* Lino P26 */ + }; + + /* Lino I2C_3 */ + pinctrl_i2c3: lpi2c4grp { + fsl,pins = <MX93_PAD_GPIO_IO02__LPI2C4_SDA 0x40000b9e>, /* Lino P24 */ + <MX93_PAD_GPIO_IO03__LPI2C4_SCL 0x40000b9e>; /* Lino P26 */ + }; + + /* Lino SPI_2 */ + pinctrl_spi2: lpspi1grp { + fsl,pins = <MX93_PAD_SAI1_TXD0__LPSPI1_SCK 0x139e>, /* Lino S20 */ + <MX93_PAD_SAI1_RXD0__LPSPI1_SOUT 0x139e>, /* Lino S22 */ + <MX93_PAD_SAI1_TXC__LPSPI1_SIN 0x139e>; /* Lino S24 */ + }; + + /* Lino SPI_1 */ + pinctrl_spi1: lpspi8grp { + fsl,pins = <MX93_PAD_GPIO_IO13__LPSPI8_SIN 0x139e>, /* Lino P54 */ + <MX93_PAD_GPIO_IO14__LPSPI8_SOUT 0x139e>, /* Lino P56 */ + <MX93_PAD_GPIO_IO15__LPSPI8_SCK 0x139e>; /* Lino P52 */ + }; + + /* Lino UART_3 */ + pinctrl_uart3: lpuart1grp { + fsl,pins = <MX93_PAD_UART1_RXD__LPUART1_RX 0x39e>, /* Lino P17 */ + <MX93_PAD_UART1_TXD__LPUART1_TX 0x39e>; /* Lino P19 */ + }; + + /* Lino UART_4 */ + pinctrl_uart4: lpuart2grp { + fsl,pins = <MX93_PAD_UART2_RXD__LPUART2_RX 0x39e>, /* Lino P23 */ + <MX93_PAD_UART2_TXD__LPUART2_TX 0x39e>; /* Lino P25 */ + }; + + /* Lino UART_1 */ + pinctrl_uart1: lpuart6grp { + fsl,pins = <MX93_PAD_GPIO_IO04__LPUART6_TX 0x39e>, /* Lino P11 */ + <MX93_PAD_GPIO_IO05__LPUART6_RX 0x39e>, /* Lino P9 */ + <MX93_PAD_GPIO_IO06__LPUART6_CTS_B 0x39e>, /* Lino P8 */ + <MX93_PAD_GPIO_IO07__LPUART6_RTS_B 0x39e>; /* Lino P6 */ + }; + + /* Lino UART_2 */ + pinctrl_uart2: lpuart7grp { + fsl,pins = <MX93_PAD_GPIO_IO08__LPUART7_TX 0x39e>, /* Lino P15 */ + <MX93_PAD_GPIO_IO09__LPUART7_RX 0x39e>, /* Lino P13 */ + <MX93_PAD_GPIO_IO10__LPUART7_CTS_B 0x39e>, /* Lino S7 */ + <MX93_PAD_GPIO_IO11__LPUART7_RTS_B 0x39e>; /* Lino S5 */ + }; + + /* Lino I2S_1 */ + pinctrl_i2s1: sai3grp { + fsl,pins = <MX93_PAD_GPIO_IO16__SAI3_TX_BCLK 0x139e>, /* Lino S94 */ + <MX93_PAD_GPIO_IO19__SAI3_TX_DATA00 0x139e>, /* Lino S98 */ + <MX93_PAD_GPIO_IO20__SAI3_RX_DATA00 0x139e>, /* Lino S100 */ + <MX93_PAD_GPIO_IO26__SAI3_TX_SYNC 0x139e>; /* Lino S96 */ + }; + + /* Lino PWM_1 */ + pinctrl_pwm1: tpm4ch1grp { + fsl,pins = <MX93_PAD_GPIO_IO21__TPM4_CH1 0x139e>; /* Lino P1 */ + }; + + /* Lino PWM_2 */ + pinctrl_pwm2: tpm5ch2grp { + fsl,pins = <MX93_PAD_GPIO_IO18__TPM5_CH2 0x139e>; /* Lino P3 */ + }; + + /* Lino PWM_3 */ + pinctrl_pwm3: tpm6ch1grp { + fsl,pins = <MX93_PAD_GPIO_IO23__TPM6_CH1 0x139e>; /* Lino P5 */ + }; + + /* On-module eMMC */ + pinctrl_emmc: usdhc1grp { + fsl,pins = <MX93_PAD_SD1_CLK__USDHC1_CLK 0x5fe>, /* eMMC_CLK */ + <MX93_PAD_SD1_CMD__USDHC1_CMD 0x400013fe>, /* eMMC_CMD */ + <MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x400013fe>, /* eMMC_DATA0 */ + <MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x400013fe>, /* eMMC_DATA1 */ + <MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x400013fe>, /* eMMC_DATA2 */ + <MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x400013fe>, /* eMMC_DATA3 */ + <MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x400013fe>, /* eMMC_DATA4 */ + <MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x400013fe>, /* eMMC_DATA5 */ + <MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x400013fe>, /* eMMC_DATA6 */ + <MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x400013fe>, /* eMMC_DATA7 */ + <MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x1580>; /* eMMC_STROBE */ + }; + + /* Lino SD_1_CD# */ + pinctrl_sd1_cd: usdhc2cdgrp { + fsl,pins = <MX93_PAD_SD2_CD_B__GPIO3_IO00 0x139e>; /* Lino P78 */ + }; + + /* Lino SD_1 */ + pinctrl_sd1: usdhc2grp { + fsl,pins = <MX93_PAD_SD2_CLK__USDHC2_CLK 0x5fe>, /* Lino P68 */ + <MX93_PAD_SD2_CMD__USDHC2_CMD 0x400013fe>, /* Lino P66 */ + <MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x400013fe>, /* Lino P74 */ + <MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x400013fe>, /* Lino P76 */ + <MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x400013fe>, /* Lino P60 */ + <MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x400013fe>; /* Lino P64 */ + }; + + /* Lino SD_1_PWR_EN */ + pinctrl_sd1_pwr_en: usdhc2pwrgrp { + fsl,pins = <MX93_PAD_SD2_RESET_B__GPIO3_IO07 0x139e>; /* Lino P72 */ + }; + + /* On-module PMIC_SD_2_VSEL */ + pinctrl_sd1_vsel: usdhc2vselgrp { + fsl,pins = <MX93_PAD_SD2_VSELECT__GPIO3_IO19 0x51e>; /* PMIC_SD_2_VSEL */ + }; + + /* Lino SD_2 */ + pinctrl_sd2: usdhc3grp { + fsl,pins = <MX93_PAD_SD3_CLK__USDHC3_CLK 0x5fe>, /* Lino S10 */ + <MX93_PAD_SD3_CMD__USDHC3_CMD 0x400013fe>, /* Lino S8 */ + <MX93_PAD_SD3_DATA0__USDHC3_DATA0 0x400013fe>, /* Lino S12 */ + <MX93_PAD_SD3_DATA1__USDHC3_DATA1 0x400013fe>, /* Lino S16 */ + <MX93_PAD_SD3_DATA2__USDHC3_DATA2 0x400013fe>, /* Lino S2 */ + <MX93_PAD_SD3_DATA3__USDHC3_DATA3 0x400013fe>; /* Lino S4 */ + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = <MX93_PAD_WDOG_ANY__WDOG1_WDOG_ANY 0x31e>; /* PMIC_WDOG_B */ + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx93-toradex-osm-dev.dts b/arch/arm64/boot/dts/freescale/imx93-toradex-osm-dev.dts new file mode 100644 index 0000000..a6cc2ae --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93-toradex-osm-dev.dts
@@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Toradex OSM iMX93 SoM on OSM Development carrier board + * + * https://www.toradex.com/computer-on-modules/osm-arm-family/nxp-imx93 + * https://www.toradex.com/products/carrier-board/osm-development-board + */ + +/dts-v1/; + +#include "imx93.dtsi" +#include "imx93-toradex-osm.dtsi" +#include "imx93-imx91-toradex-osm-dev-common.dtsi" + +/ { + model = "Toradex OSM iMX93 on OSM Development Board"; + compatible = "toradex,osm-imx93-dev", + "toradex,osm-imx93", + "fsl,imx93"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx93-toradex-osm.dtsi b/arch/arm64/boot/dts/freescale/imx93-toradex-osm.dtsi new file mode 100644 index 0000000..ea5e605 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93-toradex-osm.dtsi
@@ -0,0 +1,357 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Toradex OSM iMX93 SoM + * + * https://www.toradex.com/computer-on-modules/osm-arm-family/nxp-imx93 + */ + +#include "imx93-pinfunc.h" +#include "imx93-imx91-toradex-osm-common.dtsi" + +/ { + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + rsc_table: rsc-table@2021e000 { + reg = <0 0x2021e000 0 0x1000>; + no-map; + }; + + vdev0vring0: vdev0vring0@a4000000 { + reg = <0 0xa4000000 0 0x8000>; + no-map; + }; + + vdev0vring1: vdev0vring1@a4008000 { + reg = <0 0xa4008000 0 0x8000>; + no-map; + }; + + vdev1vring0: vdev1vring0@a4010000 { + reg = <0 0xa4010000 0 0x8000>; + no-map; + }; + + vdev1vring1: vdev1vring1@a4018000 { + reg = <0 0xa4018000 0 0x8000>; + no-map; + }; + + vdev0buffer: vdev0buffer@a4020000 { + compatible = "shared-dma-pool"; + reg = <0 0xa4020000 0 0x100000>; + no-map; + }; + }; +}; + +&cm33 { + mbox-names = "tx", "rx", "rxdb"; + mboxes = <&mu1 0 1>, + <&mu1 1 1>, + <&mu1 3 1>; + memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, + <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>; + + status = "okay"; +}; + +&mu1 { + status = "okay"; +}; + +&iomuxc { + /* OSM CAN_A */ + pinctrl_can_a: can1grp { + fsl,pins = <MX93_PAD_PDM_BIT_STREAM0__CAN1_RX 0x139e>, /* OSM AB17 */ + <MX93_PAD_PDM_CLK__CAN1_TX 0x139e>; /* OSM AC17 */ + }; + + /* OSM CAN_B */ + pinctrl_can_b: can2grp { + fsl,pins = <MX93_PAD_GPIO_IO25__CAN2_TX 0x139e>, /* OSM AC19 */ + <MX93_PAD_GPIO_IO27__CAN2_RX 0x139e>; /* OSM AB19 */ + }; + + /* OSM CAM_MCK */ + pinctrl_cam_mck: ccmclk1grp { + fsl,pins = <MX93_PAD_CCM_CLKO1__CCMSRCGPCMIX_CLKO1 0x51e>; /* OSM C2 */ + }; + + /* OSM ETH_A RGMII */ + pinctrl_eth_a: eqosgrp { + fsl,pins = <MX93_PAD_ENET1_RD0__ENET_QOS_RGMII_RD0 0x1fe>, /* OSM K15 */ + <MX93_PAD_ENET1_RD1__ENET_QOS_RGMII_RD1 0x1fe>, /* OSM L15 */ + <MX93_PAD_ENET1_RD2__ENET_QOS_RGMII_RD2 0x1fe>, /* OSM N15 */ + <MX93_PAD_ENET1_RD3__ENET_QOS_RGMII_RD3 0x1fe>, /* OSM P15 */ + <MX93_PAD_ENET1_RXC__CCM_ENET_QOS_CLOCK_GENERATE_RX_CLK 0x1fe>, /* OSM R15 */ + <MX93_PAD_ENET1_RX_CTL__ENET_QOS_RGMII_RX_CTL 0x1fe>, /* OSM M15 */ + <MX93_PAD_ENET1_TD0__ENET_QOS_RGMII_TD0 0x1fe>, /* OSM H15 */ + <MX93_PAD_ENET1_TD1__ENET_QOS_RGMII_TD1 0x1fe>, /* OSM G15 */ + <MX93_PAD_ENET1_TD2__ENET_QOS_RGMII_TD2 0x1fe>, /* OSM H16 */ + <MX93_PAD_ENET1_TD3__ENET_QOS_RGMII_TD3 0x1fe>, /* OSM G16 */ + <MX93_PAD_ENET1_TXC__CCM_ENET_QOS_CLOCK_GENERATE_TX_CLK 0x1fe>, /* OSM J15 */ + <MX93_PAD_ENET1_TX_CTL__ENET_QOS_RGMII_TX_CTL 0x1fe>; /* OSM K16 */ + }; + + /* OSM ETH_MDIO */ + pinctrl_mdio: eqosmdiogrp { + fsl,pins = <MX93_PAD_ENET1_MDC__ENET_QOS_MDC 0x1fe>, /* OSM T16 */ + <MX93_PAD_ENET1_MDIO__ENET_QOS_MDIO 0x1fe>; /* OSM T15 */ + }; + + /* OSM ETH_B RGMII */ + pinctrl_eth_b: fecgrp { + fsl,pins = <MX93_PAD_ENET2_RD0__ENET1_RGMII_RD0 0x1fe>, /* OSM J1 */ + <MX93_PAD_ENET2_RD1__ENET1_RGMII_RD1 0x1fe>, /* OSM K1 */ + <MX93_PAD_ENET2_RD2__ENET1_RGMII_RD2 0x1fe>, /* OSM M1 */ + <MX93_PAD_ENET2_RD3__ENET1_RGMII_RD3 0x1fe>, /* OSM N1 */ + <MX93_PAD_ENET2_RXC__ENET1_RGMII_RXC 0x1fe>, /* OSM P1 */ + <MX93_PAD_ENET2_RX_CTL__ENET1_RGMII_RX_CTL 0x1fe>, /* OSM L1 */ + <MX93_PAD_ENET2_TD0__ENET1_RGMII_TD0 0x1fe>, /* OSM G1 */ + <MX93_PAD_ENET2_TD1__ENET1_RGMII_TD1 0x1fe>, /* OSM F1 */ + <MX93_PAD_ENET2_TD2__ENET1_RGMII_TD2 0x1fe>, /* OSM G2 */ + <MX93_PAD_ENET2_TD3__ENET1_RGMII_TD3 0x1fe>, /* OSM F2 */ + <MX93_PAD_ENET2_TXC__ENET1_RGMII_TXC 0x1fe>, /* OSM H1 */ + <MX93_PAD_ENET2_TX_CTL__ENET1_RGMII_TX_CTL 0x1fe>; /* OSM J2 */ + }; + + /* OSM SPI_B_CS as GPIO */ + pinctrl_spi_b_cs0_gpio: gpio1io11grp { + fsl,pins = <MX93_PAD_SAI1_TXFS__GPIO1_IO11 0x139e>; /* OSM AA23 */ + }; + + /* OSM GPIO_A_0 */ + pinctrl_gpio_a0: gpio2io0grp { + fsl,pins = <MX93_PAD_GPIO_IO00__GPIO2_IO00 0x139e>; /* OSM D17 */ + }; + + /* OSM GPIO_A_1 */ + pinctrl_gpio_a1: gpio2io1grp { + fsl,pins = <MX93_PAD_GPIO_IO01__GPIO2_IO01 0x139e>; /* OSM E17 */ + }; + + /* OSM GPIO_A_2 */ + pinctrl_gpio_a2: gpio2io2grp { + fsl,pins = <MX93_PAD_GPIO_IO02__GPIO2_IO02 0x139e>; /* OSM F17 */ + }; + + /* OSM GPIO_A_3 */ + pinctrl_gpio_a3: gpio2io3grp { + fsl,pins = <MX93_PAD_GPIO_IO03__GPIO2_IO03 0x139e>; /* OSM G17 */ + }; + + /* OSM SPI_A_CS0 as GPIO */ + pinctrl_spi_a_cs0_gpio: gpio2io12grp { + fsl,pins = <MX93_PAD_GPIO_IO12__GPIO2_IO12 0x139e>; /* OSM Y15 */ + }; + + /* OSM PWM_0 as GPIO */ + pinctrl_pwm0_gpio: gpio2io21grp { + fsl,pins = <MX93_PAD_GPIO_IO21__GPIO2_IO21 0x139e>; /* OSM E18 */ + }; + + /* OSM GPIO_A_4 */ + pinctrl_gpio_a4: gpio2io22grp { + fsl,pins = <MX93_PAD_GPIO_IO22__GPIO2_IO22 0x139e>; /* OSM H17 */ + }; + + /* OSM GPIO_A_5 */ + pinctrl_gpio_a5: gpio2io24grp { + fsl,pins = <MX93_PAD_GPIO_IO24__GPIO2_IO24 0x139e>; /* OSM J17 */ + }; + + /* On-module CTRL_INT# */ + pinctrl_ctrl_int: gpio3io27grp { + fsl,pins = <MX93_PAD_CCM_CLKO2__GPIO3_IO27 0x139e>; /* CTRL_INT# */ + }; + + /* OSM GPIO_A_6 */ + pinctrl_gpio_a6: gpio4io14grp { + fsl,pins = <MX93_PAD_ENET2_MDC__GPIO4_IO14 0x139e>; /* OSM K17 */ + }; + + /* OSM GPIO_A_7 */ + pinctrl_gpio_a7: gpio4io15grp { + fsl,pins = <MX93_PAD_ENET2_MDIO__GPIO4_IO15 0x139e>; /* OSM L17 */ + }; + + /* OSM I2C_B as GPIO */ + pinctrl_i2c_b_gpio: lpi2c1gpiogrp { + fsl,pins = <MX93_PAD_I2C1_SCL__GPIO1_IO00 0x40000b9e>, /* OSM AA20 */ + <MX93_PAD_I2C1_SDA__GPIO1_IO01 0x40000b9e>; /* OSM AA21 */ + }; + + /* OSM I2C_B */ + pinctrl_i2c_b: lpi2c1grp { + fsl,pins = <MX93_PAD_I2C1_SCL__LPI2C1_SCL 0x40000b9e>, /* OSM AA20 */ + <MX93_PAD_I2C1_SDA__LPI2C1_SDA 0x40000b9e>; /* OSM AA21 */ + }; + + /* On-module PMIC I2C as GPIO */ + pinctrl_pmic_i2c_gpio: lpi2c2gpiogrp { + fsl,pins = <MX93_PAD_I2C2_SCL__GPIO1_IO02 0x40000b9e>, /* PMIC_I2C_SCL */ + <MX93_PAD_I2C2_SDA__GPIO1_IO03 0x40000b9e>; /* PMIC_I2C_SDA */ + }; + + /* On-module PMIC I2C */ + pinctrl_pmic_i2c: lpi2c2grp { + fsl,pins = <MX93_PAD_I2C2_SCL__LPI2C2_SCL 0x40000b9e>, /* PMIC_I2C_SCL */ + <MX93_PAD_I2C2_SDA__LPI2C2_SDA 0x40000b9e>; /* PMIC_I2C_SDA */ + }; + + /* OSM I2C_A as GPIO */ + pinctrl_i2c_a_gpio: lpi2c3gpiogrp { + fsl,pins = <MX93_PAD_GPIO_IO28__GPIO2_IO28 0x40000b9e>, /* OSM AA16 */ + <MX93_PAD_GPIO_IO29__GPIO2_IO29 0x40000b9e>; /* OSM AA15 */ + }; + + /* OSM I2C_A */ + pinctrl_i2c_a: lpi2c3grp { + fsl,pins = <MX93_PAD_GPIO_IO28__LPI2C3_SDA 0x40000b9e>, /* OSM AA16 */ + <MX93_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e>; /* OSM AA15 */ + }; + + /* OSM SPI_B */ + pinctrl_spi_b: lpspi1grp { + fsl,pins = <MX93_PAD_SAI1_TXC__LPSPI1_SIN 0x139e>, /* OSM Y22 */ + <MX93_PAD_SAI1_TXD0__LPSPI1_SCK 0x139e>, /* OSM Y21 */ + <MX93_PAD_SAI1_RXD0__LPSPI1_SOUT 0x139e>; /* OSM Y23 */ + }; + + /* OSM SPI_A */ + pinctrl_spi_a: lpspi8grp { + fsl,pins = <MX93_PAD_GPIO_IO13__LPSPI8_SIN 0x139e>, /* OSM U15 */ + <MX93_PAD_GPIO_IO14__LPSPI8_SOUT 0x139e>, /* OSM V15 */ + <MX93_PAD_GPIO_IO15__LPSPI8_SCK 0x139e>; /* OSM U16 */ + }; + + /* OSM UART_CON */ + pinctrl_uart_con: lpuart1grp { + fsl,pins = <MX93_PAD_UART1_RXD__LPUART1_RX 0x39e>, /* OSM D22 */ + <MX93_PAD_UART1_TXD__LPUART1_TX 0x39e>; /* OSM D23 */ + }; + + /* OSM UART_C */ + pinctrl_uart_c: lpuart2grp { + fsl,pins = <MX93_PAD_UART2_RXD__LPUART2_RX 0x39e>, /* OSM A22 */ + <MX93_PAD_UART2_TXD__LPUART2_TX 0x39e>; /* OSM B23 */ + }; + + /* OSM UART_A */ + pinctrl_uart_a: lpuart6grp { + fsl,pins = <MX93_PAD_GPIO_IO04__LPUART6_TX 0x39e>, /* OSM B13 */ + <MX93_PAD_GPIO_IO05__LPUART6_RX 0x39e>, /* OSM A14 */ + <MX93_PAD_GPIO_IO06__LPUART6_CTS_B 0x39e>, /* OSM C14 */ + <MX93_PAD_GPIO_IO07__LPUART6_RTS_B 0x39e>; /* OSM C13 */ + }; + + /* OSM UART_B */ + pinctrl_uart_b: lpuart7grp { + fsl,pins = <MX93_PAD_GPIO_IO08__LPUART7_TX 0x39e>, /* OSM D13 */ + <MX93_PAD_GPIO_IO09__LPUART7_RX 0x39e>, /* OSM D14 */ + <MX93_PAD_GPIO_IO10__LPUART7_CTS_B 0x39e>, /* OSM D16 */ + <MX93_PAD_GPIO_IO11__LPUART7_RTS_B 0x39e>; /* OSM D15 */ + }; + + /* OSM I2S_A */ + pinctrl_i2s_a: sai3grp { + fsl,pins = <MX93_PAD_GPIO_IO16__SAI3_TX_BCLK 0x139e>, /* OSM W20 */ + <MX93_PAD_GPIO_IO19__SAI3_TX_DATA00 0x139e>, /* OSM W21 */ + <MX93_PAD_GPIO_IO20__SAI3_RX_DATA00 0x139e>, /* OSM V21 */ + <MX93_PAD_GPIO_IO26__SAI3_TX_SYNC 0x139e>; /* OSM W18 */ + }; + + /* OSM I2S_MCLK */ + pinctrl_i2s_a_mclk: sai3mclkgrp { + fsl,pins = <MX93_PAD_GPIO_IO17__SAI3_MCLK 0x31e>; /* OSM V18 */ + }; + + /* OSM PWM_0 */ + pinctrl_pwm0: tpm4ch1grp { + fsl,pins = <MX93_PAD_GPIO_IO21__TPM4_CH1 0x139e>; /* OSM E18 */ + }; + + /* OSM PWM_1 */ + pinctrl_pwm1: tpm5ch2grp { + fsl,pins = <MX93_PAD_GPIO_IO18__TPM5_CH2 0x139e>; /* OSM F18 */ + }; + + /* OSM PWM_2 */ + pinctrl_pwm2: tpm6ch1grp { + fsl,pins = <MX93_PAD_GPIO_IO23__TPM6_CH1 0x139e>; /* OSM G18 */ + }; + + /* OSM USB_A_EN */ + pinctrl_usb_a_en: usb1engrp { + fsl,pins = <MX93_PAD_CCM_CLKO3__GPIO4_IO28 0x139e>; /* OSM AC16 */ + }; + + /* OSM USB_A_OC# */ + pinctrl_usb_a_oc: usb1ocgrp { + fsl,pins = <MX93_PAD_CCM_CLKO4__GPIO4_IO29 0x139e>; /* OSM AC15 */ + }; + + /* OSM USB_B_EN */ + pinctrl_usb_b_en: usb2engrp { + fsl,pins = <MX93_PAD_PDM_BIT_STREAM1__GPIO1_IO10 0x139e>; /* OSM AC20 */ + }; + + /* On-module eMMC */ + pinctrl_emmc: usdhc1grp { + fsl,pins = <MX93_PAD_SD1_CLK__USDHC1_CLK 0x5fe>, /* eMMC_CLK */ + <MX93_PAD_SD1_CMD__USDHC1_CMD 0x400013fe>, /* eMMC_CMD */ + <MX93_PAD_SD1_DATA0__USDHC1_DATA0 0x400013fe>, /* eMMC_DATA0 */ + <MX93_PAD_SD1_DATA1__USDHC1_DATA1 0x400013fe>, /* eMMC_DATA1 */ + <MX93_PAD_SD1_DATA2__USDHC1_DATA2 0x400013fe>, /* eMMC_DATA2 */ + <MX93_PAD_SD1_DATA3__USDHC1_DATA3 0x400013fe>, /* eMMC_DATA3 */ + <MX93_PAD_SD1_DATA4__USDHC1_DATA4 0x400013fe>, /* eMMC_DATA4 */ + <MX93_PAD_SD1_DATA5__USDHC1_DATA5 0x400013fe>, /* eMMC_DATA5 */ + <MX93_PAD_SD1_DATA6__USDHC1_DATA6 0x400013fe>, /* eMMC_DATA6 */ + <MX93_PAD_SD1_DATA7__USDHC1_DATA7 0x400013fe>, /* eMMC_DATA7 */ + <MX93_PAD_SD1_STROBE__USDHC1_STROBE 0x1580>; /* eMMC_STROBE */ + }; + + /* OSM SDIO_A_CD# */ + pinctrl_sdio_a_cd: usdhc2cdgrp { + fsl,pins = <MX93_PAD_SD2_CD_B__GPIO3_IO00 0x139e>; /* OSM J21 */ + }; + + /* OSM SDIO_A */ + pinctrl_sdio_a: usdhc2grp { + fsl,pins = <MX93_PAD_SD2_CLK__USDHC2_CLK 0x5fe>, /* OSM F21 */ + <MX93_PAD_SD2_CMD__USDHC2_CMD 0x400013fe>, /* OSM E20 */ + <MX93_PAD_SD2_DATA0__USDHC2_DATA0 0x400013fe>, /* OSM G20 */ + <MX93_PAD_SD2_DATA1__USDHC2_DATA1 0x400013fe>, /* OSM G21 */ + <MX93_PAD_SD2_DATA2__USDHC2_DATA2 0x400013fe>, /* OSM H20 */ + <MX93_PAD_SD2_DATA3__USDHC2_DATA3 0x400013fe>; /* OSM H21 */ + }; + + /* OSM SDIO_A_PWR_EN */ + pinctrl_sdio_a_pwr_en: usdhc2pwrgrp { + fsl,pins = <MX93_PAD_SD2_RESET_B__GPIO3_IO07 0x139e>; /* OSM D21 */ + }; + + /* On-module PMIC_SD_2_VSEL */ + pinctrl_sdio_a_vsel: usdhc2vselgrp { + fsl,pins = <MX93_PAD_SD2_VSELECT__GPIO3_IO19 0x51e>; /* PMIC_SD_2_VSEL */ + }; + + /* OSM SDIO_B */ + pinctrl_sdio_b: usdhc3grp { + fsl,pins = <MX93_PAD_SD3_CLK__USDHC3_CLK 0x5fe>, /* OSM K20 */ + <MX93_PAD_SD3_CMD__USDHC3_CMD 0x400013fe>, /* OSM K21 */ + <MX93_PAD_SD3_DATA0__USDHC3_DATA0 0x400013fe>, /* OSM L20 */ + <MX93_PAD_SD3_DATA1__USDHC3_DATA1 0x400013fe>, /* OSM L21 */ + <MX93_PAD_SD3_DATA2__USDHC3_DATA2 0x400013fe>, /* OSM M21 */ + <MX93_PAD_SD3_DATA3__USDHC3_DATA3 0x400013fe>; /* OSM N20 */ + }; + + pinctrl_wdog: wdoggrp { + fsl,pins = <MX93_PAD_WDOG_ANY__WDOG1_WDOG_ANY 0x31e>; /* PMIC_WDOG_B */ + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx93w-frdm.dts b/arch/arm64/boot/dts/freescale/imx93w-frdm.dts new file mode 100644 index 0000000..766e942 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx93w-frdm.dts
@@ -0,0 +1,23 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 NXP + */ + +/dts-v1/; + +#include "imx93w.dtsi" +#include "imx93-11x11-frdm-common.dtsi" + +/ { + model = "NXP i.MX93W FRDM board"; + compatible = "fsl,imx93-wireless-frdm", "fsl,imx93"; +}; + +&iomuxc { + pinctrl_lpi2c3: lpi2c3grp { + fsl,pins = < + MX93_PAD_GPIO_IO00__LPI2C3_SDA 0x40000b9e + MX93_PAD_GPIO_IO01__LPI2C3_SCL 0x40000b9e + >; + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx94.dtsi b/arch/arm64/boot/dts/freescale/imx94.dtsi index 34833e6..020aa1da 100644 --- a/arch/arm64/boot/dts/freescale/imx94.dtsi +++ b/arch/arm64/boot/dts/freescale/imx94.dtsi
@@ -131,6 +131,9 @@ scmi_misc: protocol@84 { mqs1: mqs1 { compatible = "fsl,imx943-aonmix-mqs"; + clocks = <&scmi_clk IMX94_CLK_SAI1>; + clock-names = "mclk"; + #sound-dai-cells = <0>; status = "disabled"; }; @@ -1379,7 +1382,7 @@ pcie0: pcie@4c300000 { <0 0x4c340000 0 0x4000>; reg-names = "dbi", "config", "atu", "app"; ranges = <0x43000000 0x9 0x00000000 0x9 0x00000000 0x0 0xe0000000>, - <0x82000000 0x0 0xe0000000 0x9 0xe0000000 0x0 0x10000000>, + <0x82000000 0x0 0x10000000 0x9 0xe0000000 0x0 0x10000000>, <0x81000000 0x0 0x00000000 0x9 0xf0000000 0x0 0x00100000>; #address-cells = <3>; #size-cells = <2>;
diff --git a/arch/arm64/boot/dts/freescale/imx943-evk-sdwifi.dtso b/arch/arm64/boot/dts/freescale/imx943-evk-sdwifi.dtso index 59cc1c2..b95304f 100644 --- a/arch/arm64/boot/dts/freescale/imx943-evk-sdwifi.dtso +++ b/arch/arm64/boot/dts/freescale/imx943-evk-sdwifi.dtso
@@ -6,10 +6,35 @@ /dts-v1/; /plugin/; +#include <dt-bindings/gpio/gpio.h> + +&{/} { + reg_usdhc3_vmmc: regulator-usdhc3 { + compatible = "regulator-fixed"; + regulator-name = "WLAN_EN"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <®_m2_pwr>; + gpio = <&pcal6416_i2c3_u46 5 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&lpuart6 { + bluetooth { + compatible = "nxp,88w8987-bt"; + }; +}; + +&m2_connector { + status = "disabled"; +}; + &pcie0 { status = "disabled"; }; &usdhc3 { + vmmc-supply = <®_usdhc3_vmmc>; status = "okay"; };
diff --git a/arch/arm64/boot/dts/freescale/imx943-evk.dts b/arch/arm64/boot/dts/freescale/imx943-evk.dts index 64660f9..39e819c 100644 --- a/arch/arm64/boot/dts/freescale/imx943-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx943-evk.dts
@@ -33,11 +33,51 @@ aliases { serial5 = &lpuart6; }; + amp_mqs1: audio-amplifier { + compatible = "simple-audio-amplifier"; + sound-name-prefix = "MQS AMP"; + VCC-supply = <®_3p3v>; + }; + bt_sco_codec: bt-sco-codec { compatible = "linux,bt-sco"; #sound-dai-cells = <1>; }; + can1_pdm_mux: mux-controller-0 { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + #mux-state-cells = <1>; + mux-gpios = <&pcal6416_i2c6_u44 12 GPIO_ACTIVE_HIGH>; + }; + + mqs1_mic_mux: mux-controller-1 { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + #mux-state-cells = <1>; + mux-gpios = <&pcal6416_i2c3_u171 11 GPIO_ACTIVE_HIGH>; + }; + + pinctrl-gpiomux { + compatible = "pinctrl-multiplexer"; + + can1_fun: can1-grp { + mux-states = <&can1_pdm_mux 1>; + }; + + mic_fun: mic-grp { + mux-states = <&mqs1_mic_mux 0>; + }; + + mqs1_fun: mqs1-grp { + mux-states = <&mqs1_mic_mux 1>; + }; + + pdm_fun: pdm-grp { + mux-states = <&can1_pdm_mux 0>; + }; + }; + flexcan2_phy: can-phy0 { compatible = "nxp,tjr1443"; #phy-cells = <0>; @@ -77,6 +117,44 @@ dmic: dmic { #sound-dai-cells = <0>; }; + m2_connector: m2-connector { + compatible = "pcie-m2-e-connector"; + vpcie3v3-supply = <®_m2_pwr>; + w-disable1-gpios = <&pcal6416_i2c3_u46 5 GPIO_ACTIVE_LOW>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + m2_e_pcie_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&pcie0_port0_ep>; + }; + }; + + port@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + m2_e_uart_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&lpuart6_ep>; + }; + }; + }; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "+V3.3_SW"; + }; + reg_m2_pwr: regulator-m2-pwr { compatible = "regulator-fixed"; regulator-name = "M.2-power"; @@ -102,16 +180,6 @@ reg_slot_pwr: regulator-slot-pwr { enable-active-high; }; - reg_m2_wlan: regulator-wlan { - compatible = "regulator-fixed"; - regulator-name = "WLAN_EN"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - vin-supply = <®_m2_pwr>; - gpio = <&pcal6416_i2c3_u46 5 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; - reg_usdhc2_vmmc: regulator-usdhc2 { compatible = "regulator-fixed"; off-on-delay-us = <12000>; @@ -307,7 +375,7 @@ cpu { }; }; - sound-wm8962 { + mqs1_conflict_card: sound-wm8962 { compatible = "fsl,imx-audio-wm8962"; audio-codec = <&wm8962>; audio-cpu = <&sai1>; @@ -535,12 +603,6 @@ audio-pwren-hog { gpio-hog; output-high; }; - - mqs-mic-sel-hog { - gpios = <11 GPIO_ACTIVE_HIGH>; - gpio-hog; - output-low; - }; }; }; @@ -651,13 +713,6 @@ pcal6416_i2c6_u44: gpio@20 { #gpio-cells = <2>; gpio-controller; - /* pdm selection */ - can-pdm-sel-hog { - gpios = <12 GPIO_ACTIVE_HIGH>; - gpio-hog; - output-low; - }; - sai3-sel-hog { gpios = <11 GPIO_ACTIVE_HIGH>; gpio-hog; @@ -694,12 +749,14 @@ &lpuart6 { pinctrl-names = "default"; status = "okay"; - bluetooth { - compatible = "nxp,88w8987-bt"; + port { + lpuart6_ep: endpoint { + remote-endpoint = <&m2_e_uart_ep>; + }; }; }; -&micfil { +mqs1_conflict_dev: &micfil { assigned-clocks = <&scmi_clk IMX94_CLK_AUDIOPLL1_VCO>, <&scmi_clk IMX94_CLK_AUDIOPLL2_VCO>, <&scmi_clk IMX94_CLK_AUDIOPLL1>, @@ -710,11 +767,16 @@ &micfil { assigned-clock-rates = <3932160000>, <3612672000>, <393216000>, <361267200>, <49152000>; - pinctrl-0 = <&pinctrl_pdm>; + pinctrl-0 = <&pinctrl_pdm>, <&mic_fun>, <&pdm_fun>; pinctrl-names = "default"; status = "okay"; }; +&mqs1 { + pinctrl-0 = <&pinctrl_mqs1>, <&mqs1_fun>, <&pdm_fun>; + pinctrl-names = "default"; +}; + &mu11 { status = "okay"; }; @@ -761,6 +823,11 @@ &netc_timer1 { }; &sai1 { + clocks = <&scmi_clk IMX94_CLK_BUSAON>, <&dummy>, + <&scmi_clk IMX94_CLK_SAI1>, <&dummy>, + <&dummy>, <&scmi_clk IMX94_CLK_AUDIOPLL1>, + <&scmi_clk IMX94_CLK_AUDIOPLL2>; + clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k", "pll11k"; assigned-clocks = <&scmi_clk IMX94_CLK_AUDIOPLL1_VCO>, <&scmi_clk IMX94_CLK_AUDIOPLL2_VCO>, <&scmi_clk IMX94_CLK_AUDIOPLL1>, @@ -883,6 +950,13 @@ IMX94_PAD_GPIO_IO28__LPI2C6_SCL 0x40000b9e >; }; + pinctrl_mqs1: mqs1grp { + fsl,pins = < + IMX94_PAD_PDM_CLK__MQS1_LEFT 0x31e + IMX94_PAD_PDM_BIT_STREAM0__MQS1_RIGHT 0x31e + >; + }; + pinctrl_pcie0: pcie0grp { fsl,pins = < IMX94_PAD_GPIO_IO20__PCIE1_CLKREQ_B 0x4000031e @@ -1175,7 +1249,12 @@ &pcie0 { &pcie0_port0 { reset-gpios = <&pcal6416_i2c3_u46 3 GPIO_ACTIVE_LOW>; - vpcie3v3aux-supply = <®_m2_wlan>; + + port { + pcie0_port0_ep: endpoint { + remote-endpoint = <&m2_e_pcie_ep>; + }; + }; }; &pcie0_ep { @@ -1288,7 +1367,6 @@ &usdhc3 { pinctrl-1 = <&pinctrl_usdhc3>; pinctrl-names = "default", "sleep"; bus-width = <4>; - vmmc-supply = <®_m2_wlan>; mmc-pwrseq = <&usdhc3_pwrseq>; keep-power-in-suspend; non-removable;
diff --git a/arch/arm64/boot/dts/freescale/imx943.dtsi b/arch/arm64/boot/dts/freescale/imx943.dtsi index 01152fd0..a564488 100644 --- a/arch/arm64/boot/dts/freescale/imx943.dtsi +++ b/arch/arm64/boot/dts/freescale/imx943.dtsi
@@ -219,7 +219,7 @@ pcie1: pcie@4c380000 { <0 0x4c3c0000 0 0x4000>; reg-names = "dbi", "config", "atu", "app"; ranges = <0x43000000 0xa 0x00000000 0xa 0x00000000 0x0 0xe0000000>, - <0x82000000 0x0 0xe0000000 0xa 0xe0000000 0x0 0x10000000>, + <0x82000000 0x0 0x10000000 0xa 0xe0000000 0x0 0x10000000>, <0x81000000 0x0 0x00000000 0xa 0xf0000000 0x0 0x00100000>; #address-cells = <3>; #size-cells = <2>;
diff --git a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts index 6aedcbb..1ca6850 100644 --- a/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx95-15x15-evk.dts
@@ -48,6 +48,12 @@ aliases { serial4 = &lpuart5; }; + amp_mqs1: audio-amplifier { + compatible = "simple-audio-amplifier"; + sound-name-prefix = "MQS AMP"; + VCC-supply = <®_3p3v>; + }; + bt_sco_codec: bt-sco-codec { compatible = "linux,bt-sco"; #sound-dai-cells = <1>; @@ -114,6 +120,25 @@ flexcan2_phy: can-phy { silent-gpios = <&pcal6524 14 GPIO_ACTIVE_HIGH>; }; + pdm_mqs1_mux: mux-controller-0 { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + #mux-state-cells = <1>; + mux-gpios = <&pcal6524 20 GPIO_ACTIVE_HIGH>; + }; + + pinctrl-gpiomux { + compatible = "pinctrl-multiplexer"; + + pdm_fun: pdm-grp { + mux-states = <&pdm_mqs1_mux 0>; + }; + + mqs1_fun: mqs1-grp { + mux-states = <&pdm_mqs1_mux 1>; + }; + }; + reg_m2_pwr: regulator-m2-pwr { compatible = "regulator-fixed"; regulator-max-microvolt = <3300000>; @@ -220,7 +245,7 @@ vpu_boot: vpu-boot@a0000000 { }; }; - sound-bt-sco { + mqs1_conflict_card: sound-bt-sco { compatible = "simple-audio-card"; simple-audio-card,bitclock-inversion; simple-audio-card,bitclock-master = <&btcpu>; @@ -479,7 +504,7 @@ bluetooth { }; }; -&micfil { +mqs1_conflict_dev: &micfil { assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>, <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>, <&scmi_clk IMX95_CLK_AUDIOPLL1>, @@ -488,11 +513,16 @@ &micfil { assigned-clock-parents = <0>, <0>, <0>, <0>, <&scmi_clk IMX95_CLK_AUDIOPLL1>; assigned-clock-rates = <3932160000>, <3612672000>, <393216000>, <361267200>, <49152000>; #sound-dai-cells = <0>; - pinctrl-0 = <&pinctrl_pdm>; + pinctrl-0 = <&pinctrl_pdm>, <&pdm_fun>; pinctrl-names = "default"; status = "okay"; }; +&mqs1 { + pinctrl-0 = <&pinctrl_mqs1>, <&mqs1_fun>; + pinctrl-names = "default"; +}; + &mu7 { status = "okay"; }; @@ -573,6 +603,11 @@ &pcie0_port0 { }; &sai1 { + clocks = <&scmi_clk IMX95_CLK_BUSAON>, <&dummy>, + <&scmi_clk IMX95_CLK_SAI1>, <&dummy>, + <&dummy>, <&scmi_clk IMX95_CLK_AUDIOPLL1>, + <&scmi_clk IMX95_CLK_AUDIOPLL2>; + clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k", "pll11k"; assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>, <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>, <&scmi_clk IMX95_CLK_AUDIOPLL1>, @@ -651,6 +686,13 @@ IMX95_PAD_GPIO_IO27__CAN2_RX 0x39e >; }; + pinctrl_mqs1: mqs1grp { + fsl,pins = < + IMX95_PAD_PDM_CLK__AONMIX_TOP_MQS1_LEFT 0x31e + IMX95_PAD_PDM_BIT_STREAM0__AONMIX_TOP_MQS1_RIGHT 0x31e + >; + }; + pinctrl_hp: hpgrp { fsl,pins = < IMX95_PAD_GPIO_IO21__GPIO2_IO_BIT21 0x31e
diff --git a/arch/arm64/boot/dts/freescale/imx95-15x15-frdm.dts b/arch/arm64/boot/dts/freescale/imx95-15x15-frdm.dts index 0f43e3b..f82e149 100644 --- a/arch/arm64/boot/dts/freescale/imx95-15x15-frdm.dts +++ b/arch/arm64/boot/dts/freescale/imx95-15x15-frdm.dts
@@ -56,7 +56,7 @@ dmic: dmic { num-channels = <2>; }; - flexcan2_phy: can-phy { + flexcan2_phy: can-phy0 { compatible = "nxp,tja1051"; #phy-cells = <0>; max-bitrate = <5000000>; @@ -67,7 +67,7 @@ flexcan2_phy: can-phy { silent-gpios = <&pcal6524 7 GPIO_ACTIVE_HIGH>; }; - flexcan5_phy: can-phy { + flexcan5_phy: can-phy1 { compatible = "nxp,tja1051"; #phy-cells = <0>; max-bitrate = <5000000>; @@ -140,6 +140,7 @@ reg_usdhc2_vmmc: regulator-usdhc2 { regulator-name = "VDD_SD2_3V3"; gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>; enable-active-high; + bootph-pre-ram; }; reg_usdhc3_vmmc: regulator-usdhc3 { @@ -188,33 +189,33 @@ linux_cma: linux,cma { linux,cma-default; }; - vdev0vring0: memory@88000000 { + vdev0vring0: vdev0vring0@88000000 { reg = <0 0x88000000 0 0x8000>; no-map; }; - vdev0vring1: memory@88008000 { + vdev0vring1: vdev0vring1@88008000 { reg = <0 0x88008000 0 0x8000>; no-map; }; - vdev1vring0: memory@88010000 { + vdev1vring0: vdev1vring0@88010000 { reg = <0 0x88010000 0 0x8000>; no-map; }; - vdev1vring1: memory@88018000 { + vdev1vring1: vdev1vring1@88018000 { reg = <0 0x88018000 0 0x8000>; no-map; }; - vdevbuffer: memory@88020000 { + vdev0buffer: vdev0buffer@88020000 { compatible = "shared-dma-pool"; reg = <0 0x88020000 0 0x100000>; no-map; }; - rsc_table: memory@88220000 { + rsc_table: rsc-table@88220000 { reg = <0 0x88220000 0 0x1000>; no-map; }; @@ -445,6 +446,7 @@ led_backlight1: led@1 { &lpuart1 { pinctrl-0 = <&pinctrl_uart1>; pinctrl-names = "default"; + bootph-pre-ram; status = "okay"; }; @@ -480,8 +482,6 @@ &mu7 { }; &mqs1 { - clocks = <&scmi_clk IMX95_CLK_SAI1>; - clock-names = "mclk"; pinctrl-0 = <&pinctrl_mqs1>; pinctrl-names = "default"; status = "okay"; @@ -549,12 +549,15 @@ &netcmix_blk_ctrl { &pcie0 { pinctrl-0 = <&pinctrl_pcie0>; pinctrl-names = "default"; - reset-gpio = <&gpio5 13 GPIO_ACTIVE_LOW>; supports-clkreq; - vpcie-supply = <®_m2_mkey_pwr>; status = "okay"; }; +&pcie0_port0 { + reset-gpios = <&gpio5 13 GPIO_ACTIVE_LOW>; + vpcie3v3-supply = <®_m2_mkey_pwr>; +}; + &sai1 { clocks = <&scmi_clk IMX95_CLK_BUSAON>, <&dummy>, <&scmi_clk IMX95_CLK_SAI1>, <&dummy>, @@ -721,6 +724,7 @@ pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { fsl,pins = < IMX95_PAD_SD2_RESET_B__GPIO3_IO_BIT7 0x31e >; + bootph-pre-ram; }; pinctrl_uart1: uart1grp { @@ -728,6 +732,7 @@ pinctrl_uart1: uart1grp { IMX95_PAD_UART1_RXD__AONMIX_TOP_LPUART1_RX 0x31e IMX95_PAD_UART1_TXD__AONMIX_TOP_LPUART1_TX 0x31e >; + bootph-pre-ram; }; pinctrl_uart5: uart5grp { @@ -753,6 +758,7 @@ IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x138e IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x138e IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x158e >; + bootph-pre-ram; }; pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { @@ -769,6 +775,7 @@ IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x138e IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x138e IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x158e >; + bootph-pre-ram; }; pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { @@ -785,12 +792,14 @@ IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x13fe IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x13fe IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x15fe >; + bootph-pre-ram; }; pinctrl_usdhc2_gpio: usdhc2gpiogrp { fsl,pins = < IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0 0x31e >; + bootph-pre-ram; }; pinctrl_usdhc2: usdhc2grp { @@ -803,6 +812,7 @@ IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x138e IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x138e IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e >; + bootph-pre-ram; }; pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { @@ -815,6 +825,7 @@ IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x138e IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x138e IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e >; + bootph-pre-ram; }; pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { @@ -827,6 +838,7 @@ IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x138e IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x138e IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e >; + bootph-pre-ram; }; pinctrl_usdhc3: usdhc3grp { @@ -1001,6 +1013,7 @@ &usdhc1 { pinctrl-3 = <&pinctrl_usdhc1>; pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; fsl,tuning-step = <1>; + bootph-pre-ram; status = "okay"; }; @@ -1014,6 +1027,7 @@ &usdhc2 { pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; vmmc-supply = <®_usdhc2_vmmc>; fsl,tuning-step = <1>; + bootph-pre-ram; status = "okay"; };
diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts index 814da90..47ed0ef 100644 --- a/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx95-19x19-evk.dts
@@ -57,6 +57,37 @@ memory@80000000 { reg = <0x0 0x80000000 0 0x80000000>; }; + m2-connector { + compatible = "pcie-m2-e-connector"; + vpcie3v3-supply = <®_m2_pwr>; + w-disable1-gpios = <&i2c7_pcal6524 6 GPIO_ACTIVE_LOW>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + #address-cells = <1>; + #size-cells = <0>; + reg = <0>; + m2_e_pcie_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&pcie0_port0_ep>; + }; + }; + + port@3 { + #address-cells = <1>; + #size-cells = <0>; + reg = <3>; + m2_e_uart_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&lpuart5_ep>; + }; + }; + }; + }; + fan0: pwm-fan { compatible = "pwm-fan"; #cooling-cells = <2>; @@ -181,16 +212,6 @@ reg_m2_pwr: regulator-m2-pwr { startup-delay-us = <5000>; }; - reg_pcie0: regulator-pcie { - compatible = "regulator-fixed"; - regulator-name = "PCIE_WLAN_EN"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - vin-supply = <®_m2_pwr>; - gpio = <&i2c7_pcal6524 6 GPIO_ACTIVE_HIGH>; - enable-active-high; - }; - reg_slot_pwr: regulator-slot-pwr { compatible = "regulator-fixed"; regulator-name = "PCIe slot-power"; @@ -523,8 +544,10 @@ &lpuart5 { pinctrl-0 = <&pinctrl_uart5>; status = "okay"; - bluetooth { - compatible = "nxp,88w8987-bt"; + port { + lpuart5_ep: endpoint { + remote-endpoint = <&m2_e_uart_ep>; + }; }; }; @@ -601,8 +624,12 @@ &pcie0_ep { &pcie0_port0 { reset-gpios = <&i2c7_pcal6524 5 GPIO_ACTIVE_LOW>; - vpcie3v3-supply = <®_pcie0>; - vpcie3v3aux-supply = <®_pcie0>; + + port { + pcie0_port0_ep: endpoint { + remote-endpoint = <&m2_e_pcie_ep>; + }; + }; }; &pcie1 {
diff --git a/arch/arm64/boot/dts/freescale/imx95-19x19-frdm-pro.dts b/arch/arm64/boot/dts/freescale/imx95-19x19-frdm-pro.dts index b87a26b..1f62d72 100644 --- a/arch/arm64/boot/dts/freescale/imx95-19x19-frdm-pro.dts +++ b/arch/arm64/boot/dts/freescale/imx95-19x19-frdm-pro.dts
@@ -450,8 +450,6 @@ &micfil { }; &mqs1 { - clocks = <&scmi_clk IMX95_CLK_SAI1>; - clock-names = "mclk"; pinctrl-0 = <&pinctrl_mqs1>; pinctrl-names = "default"; status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx95-aquila-clover.dts b/arch/arm64/boot/dts/freescale/imx95-aquila-clover.dts index fd93043..07bf532 100644 --- a/arch/arm64/boot/dts/freescale/imx95-aquila-clover.dts +++ b/arch/arm64/boot/dts/freescale/imx95-aquila-clover.dts
@@ -67,6 +67,15 @@ &enetc_port0 { status = "okay"; }; +/* Aquila ETH_2_XGMII */ +&enetc_port2 { + phy-handle = <ðphy2>; + phy-mode = "sgmii"; + managed = "in-band-status"; + + status = "okay"; +}; + /* Aquila CAN_1 */ &flexcan1 { status = "okay"; @@ -188,6 +197,11 @@ &lpi2c5 { status = "okay"; }; +/* Aquila I2C_3_DSI1 */ +&lpi2c8 { + status = "okay"; +}; + /* Aquila SPI_1 */ &lpspi6 { pinctrl-names = "default"; @@ -227,6 +241,15 @@ &lpuart7 { status = "okay"; }; +/* Aquila ETH_2_XGMII_MDIO, shared between all ethernet ports */ +&netc_emdio { + ethphy2: ethernet-phy@4 { + reg = <4>; + interrupt-parent = <&som_gpio_expander_1>; + interrupts = <8 IRQ_TYPE_EDGE_FALLING>; + }; +}; + /* Aquila PCIE_1 */ &pcie0 { status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx95-aquila-dev.dts b/arch/arm64/boot/dts/freescale/imx95-aquila-dev.dts index 3df1770..7698ef4 100644 --- a/arch/arm64/boot/dts/freescale/imx95-aquila-dev.dts +++ b/arch/arm64/boot/dts/freescale/imx95-aquila-dev.dts
@@ -104,6 +104,15 @@ &enetc_port0 { status = "okay"; }; +/* Aquila ETH_2_XGMII */ +&enetc_port2 { + phy-handle = <ðphy2>; + phy-mode = "sgmii"; + managed = "in-band-status"; + + status = "okay"; +}; + /* Aquila CAN_1 */ &flexcan1 { status = "okay"; @@ -326,6 +335,15 @@ &lpuart7 { status = "okay"; }; +/* Aquila ETH_2_XGMII_MDIO, shared between all ethernet ports */ +&netc_emdio { + ethphy2: ethernet-phy@4 { + reg = <4>; + interrupt-parent = <&som_gpio_expander_1>; + interrupts = <8 IRQ_TYPE_EDGE_FALLING>; + }; +}; + /* Aquila PCIE_1 */ &pcie0 { status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx95-aquila.dtsi b/arch/arm64/boot/dts/freescale/imx95-aquila.dtsi index 69dc962..c5f4cf0 100644 --- a/arch/arm64/boot/dts/freescale/imx95-aquila.dtsi +++ b/arch/arm64/boot/dts/freescale/imx95-aquila.dtsi
@@ -16,6 +16,7 @@ aliases { can3 = &flexcan4; eeprom0 = &som_eeprom; ethernet0 = &enetc_port0; + ethernet1 = &enetc_port2; i2c0 = &lpi2c3; i2c1 = &lpi2c2; i2c2 = &i3c2; @@ -209,6 +210,12 @@ &enetc_port0 { phy-mode = "rgmii-id"; }; +/* Aquila ETH_2_XGMII */ +&enetc_port2 { + clocks = <&clk_serdes_eth_ref>; + clock-names = "ref"; +}; + /* Aquila CAN_1 */ &flexcan1 { pinctrl-names = "default"; @@ -406,10 +413,10 @@ som_gpio_expander_1: gpio@21 { #gpio-cells = <2>; gpio-controller; gpio-line-names = - "AQUILA_C1", /* 0 */ - "AQUILA_C2", - "AQUILA_C3", - "AQUILA_C4", + "AQUILA_C01", /* 0 */ + "AQUILA_C02", + "AQUILA_C03", + "AQUILA_C04", "AQUILA_C36", "AQUILA_B74", "AQUILA_B75",
diff --git a/arch/arm64/boot/dts/freescale/imx95-navq.dts b/arch/arm64/boot/dts/freescale/imx95-navq.dts new file mode 100644 index 0000000..7860c11 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx95-navq.dts
@@ -0,0 +1,228 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 NXP + */ + +/dts-v1/; + +#include "imx95.dtsi" + +/ { + model = "NXP MR-NAVQ95"; + compatible = "fsl,imx95-navq", "fsl,imx95"; + + aliases { + ethernet0 = &enetc_port0; + mmc0 = &usdhc1; + mmc1 = &usdhc2; + serial0 = &lpuart1; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@80000000 { + device_type = "memory"; + /* actual size filled in by the bootloader */ + reg = <0x0 0x80000000 0 0x80000000>; + }; + + reg_usdhc2_vmmc: regulator-usdhc2 { + compatible = "regulator-fixed"; + bootph-pre-ram; + enable-active-high; + gpios = <&gpio3 7 GPIO_ACTIVE_HIGH>; + off-on-delay-us = <12000>; + pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>; + pinctrl-names = "default"; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "VDD_SD2_3V3"; + }; +}; + +&edma1 { + /* owned by M7 */ + status = "reserved"; +}; + +&edma2 { + /* channels 30-63 owned by M7 */ + dma-channels = <30>; +}; + +&enetc_port0 { + phy-handle = <ðphy0>; + phy-mode = "rgmii-id"; + pinctrl-0 = <&pinctrl_enetc0>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&lpi2c3 { + clock-frequency = <400000>; + pinctrl-0 = <&pinctrl_lpi2c3>; + pinctrl-names = "default"; + + status = "okay"; + + i2c3_gpio_expander_21: gpio-expander@21 { + compatible = "nxp,pcal6408"; + reg = <0x21>; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&gpio4>; + interrupts = <27 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&pinctrl_i2c3_gpio_expander_21>; + pinctrl-names = "default"; + }; +}; + +&lpuart1 { + bootph-pre-ram; + pinctrl-0 = <&pinctrl_uart1>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&netc_blk_ctrl { + status = "okay"; +}; + +&netc_emdio { + pinctrl-0 = <&pinctrl_emdio>; + pinctrl-names = "default"; + + status = "okay"; + + ethphy0: ethernet-phy@1 { + compatible = "ethernet-phy-id001c.c916"; + reg = <1>; + reset-assert-us = <10000>; + reset-deassert-us = <80000>; + reset-gpios = <&i2c3_gpio_expander_21 1 GPIO_ACTIVE_LOW>; + realtek,clkout-disable; + }; +}; + +&scmi_iomuxc { + pinctrl_emdio: emdiogrp { + fsl,pins = <IMX95_PAD_ENET2_MDC__NETCMIX_TOP_NETC_MDC 0x57e>, + <IMX95_PAD_ENET2_MDIO__NETCMIX_TOP_NETC_MDIO 0x97e>; + }; + + pinctrl_enetc0: enetc0grp { + fsl,pins = <IMX95_PAD_ENET1_TD3__NETCMIX_TOP_ETH0_RGMII_TD3 0x57e>, + <IMX95_PAD_ENET1_TD2__NETCMIX_TOP_ETH0_RGMII_TD2 0x57e>, + <IMX95_PAD_ENET1_TD1__NETCMIX_TOP_ETH0_RGMII_TD1 0x57e>, + <IMX95_PAD_ENET1_TD0__NETCMIX_TOP_ETH0_RGMII_TD0 0x57e>, + <IMX95_PAD_ENET1_TX_CTL__NETCMIX_TOP_ETH0_RGMII_TX_CTL 0x57e>, + <IMX95_PAD_ENET1_TXC__NETCMIX_TOP_ETH0_RGMII_TX_CLK 0x58e>, + <IMX95_PAD_ENET1_RX_CTL__NETCMIX_TOP_ETH0_RGMII_RX_CTL 0x57e>, + <IMX95_PAD_ENET1_RXC__NETCMIX_TOP_ETH0_RGMII_RX_CLK 0x58e>, + <IMX95_PAD_ENET1_RD0__NETCMIX_TOP_ETH0_RGMII_RD0 0x57e>, + <IMX95_PAD_ENET1_RD1__NETCMIX_TOP_ETH0_RGMII_RD1 0x57e>, + <IMX95_PAD_ENET1_RD2__NETCMIX_TOP_ETH0_RGMII_RD2 0x57e>, + <IMX95_PAD_ENET1_RD3__NETCMIX_TOP_ETH0_RGMII_RD3 0x57e>; + }; + + pinctrl_i2c3_gpio_expander_21: i2c3gpioexpander21grp { + fsl,pins = <IMX95_PAD_ENET2_RD3__GPIO4_IO_BIT27 0x31e>; + }; + + pinctrl_lpi2c3: lpi2c3grp { + fsl,pins = <IMX95_PAD_GPIO_IO28__LPI2C3_SDA 0x40000b9e>, + <IMX95_PAD_GPIO_IO29__LPI2C3_SCL 0x40000b9e>; + }; + + pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { + bootph-pre-ram; + fsl,pins = <IMX95_PAD_SD2_RESET_B__GPIO3_IO_BIT7 0x31e>; + }; + + pinctrl_uart1: uart1grp { + bootph-pre-ram; + fsl,pins = <IMX95_PAD_UART1_RXD__AONMIX_TOP_LPUART1_RX 0x31e>, + <IMX95_PAD_UART1_TXD__AONMIX_TOP_LPUART1_TX 0x31e>; + }; + + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { + bootph-pre-ram; + fsl,pins = <IMX95_PAD_SD1_CLK__USDHC1_CLK 0x15fe>, + <IMX95_PAD_SD1_CMD__USDHC1_CMD 0x13fe>, + <IMX95_PAD_SD1_DATA0__USDHC1_DATA0 0x13fe>, + <IMX95_PAD_SD1_DATA1__USDHC1_DATA1 0x13fe>, + <IMX95_PAD_SD1_DATA2__USDHC1_DATA2 0x13fe>, + <IMX95_PAD_SD1_DATA3__USDHC1_DATA3 0x13fe>, + <IMX95_PAD_SD1_DATA4__USDHC1_DATA4 0x13fe>, + <IMX95_PAD_SD1_DATA5__USDHC1_DATA5 0x13fe>, + <IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x13fe>, + <IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x13fe>, + <IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x15fe>; + }; + + pinctrl_usdhc1: usdhc1grp { + bootph-pre-ram; + fsl,pins = <IMX95_PAD_SD1_CLK__USDHC1_CLK 0x158e>, + <IMX95_PAD_SD1_CMD__USDHC1_CMD 0x138e>, + <IMX95_PAD_SD1_DATA0__USDHC1_DATA0 0x138e>, + <IMX95_PAD_SD1_DATA1__USDHC1_DATA1 0x138e>, + <IMX95_PAD_SD1_DATA2__USDHC1_DATA2 0x138e>, + <IMX95_PAD_SD1_DATA3__USDHC1_DATA3 0x138e>, + <IMX95_PAD_SD1_DATA4__USDHC1_DATA4 0x138e>, + <IMX95_PAD_SD1_DATA5__USDHC1_DATA5 0x138e>, + <IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x138e>, + <IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x138e>, + <IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x158e>; + }; + + pinctrl_usdhc2_gpio: usdhc2gpiogrp { + bootph-pre-ram; + fsl,pins = <IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0 0x31e>; + }; + + pinctrl_usdhc2: usdhc2grp { + bootph-pre-ram; + fsl,pins = <IMX95_PAD_SD2_CLK__USDHC2_CLK 0x158e>, + <IMX95_PAD_SD2_CMD__USDHC2_CMD 0x138e>, + <IMX95_PAD_SD2_DATA0__USDHC2_DATA0 0x138e>, + <IMX95_PAD_SD2_DATA1__USDHC2_DATA1 0x138e>, + <IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x138e>, + <IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x138e>, + <IMX95_PAD_SD2_VSELECT__USDHC2_VSELECT 0x51e>; + }; +}; + +&usdhc1 { + bootph-pre-ram; + bus-width = <8>; + no-sd; + no-sdio; + non-removable; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + pinctrl-3 = <&pinctrl_usdhc1>; + pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; + + status = "okay"; +}; + +&usdhc2 { + bootph-pre-ram; + bus-width = <4>; + cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-1 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-2 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-3 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; + vmmc-supply = <®_usdhc2_vmmc>; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx95-toradex-osm-dev.dts b/arch/arm64/boot/dts/freescale/imx95-toradex-osm-dev.dts new file mode 100644 index 0000000..b3d54be --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx95-toradex-osm-dev.dts
@@ -0,0 +1,404 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * https://www.toradex.com/computer-on-modules/osm-arm-family/nxp-imx95 + * https://www.toradex.com/products/carrier-board/osm-development-board + */ + +/dts-v1/; + +#include <dt-bindings/net/ti-dp83867.h> +#include <dt-bindings/pwm/pwm.h> +#include <dt-bindings/usb/pd.h> +#include "imx95-toradex-osm.dtsi" + +/ { + model = "Toradex OSM iMX95 on OSM Development Board"; + compatible = "toradex,osm-imx95-dev", + "toradex,osm-imx95", + "fsl,imx95"; + + aliases { + eeprom1 = &carrier_eeprom; + }; + + reg_carrier_1p8v: regulator-carrier-1p8v { + compatible = "regulator-fixed"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "On-carrier 1V8"; + }; + + sfp: sfp { + compatible = "sff,sfp"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_b0>, <&pinctrl_gpio_b1>, + <&pinctrl_gpio_b2>, <&pinctrl_gpio_b3>; + i2c-bus = <&i2c_mux_carrier_sfp>; + los-gpios = <&gpio1 10 GPIO_ACTIVE_HIGH>; + maximum-power-milliwatt = <3000>; + mod-def0-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; + rate-select0-gpios = <&som_gpio_expander_0 4 GPIO_ACTIVE_HIGH>; + rate-select1-gpios = <&som_gpio_expander_1 3 GPIO_ACTIVE_HIGH>; + tx-disable-gpios = <&gpio5 11 GPIO_ACTIVE_HIGH>; + tx-fault-gpios = <&gpio5 8 GPIO_ACTIVE_HIGH>; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,bitclock-master = <&codec_dai>; + simple-audio-card,format = "i2s"; + simple-audio-card,frame-master = <&codec_dai>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "verdin-wm8904"; + simple-audio-card,routing = + "Headphone Jack", "HPOUTL", + "Headphone Jack", "HPOUTR", + "IN2L", "Line In Jack", + "IN2R", "Line In Jack", + "Microphone Jack", "MICBIAS", + "IN1L", "Microphone Jack"; + simple-audio-card,widgets = + "Microphone", "Microphone Jack", + "Headphone", "Headphone Jack", + "Line", "Line In Jack"; + + codec_dai: simple-audio-card,codec { + clocks = <&scmi_clk IMX95_CLK_SAI3>; + sound-dai = <&wm8904_1a>; + }; + + simple-audio-card,cpu { + sound-dai = <&sai3>; + }; + }; +}; + +/* OSM ADC_0, ADC_1 */ +&adc1 { + status = "okay"; +}; + +/* OSM ETH_A */ +&enetc_port0 { + phy-handle = <ðphy_a>; + phy-mode = "rgmii-id"; + + status = "okay"; +}; + +/* OSM ETH_B */ +&enetc_port1 { + phy-handle = <ðphy_b>; + phy-mode = "rgmii-id"; + + status = "okay"; +}; + +/* OSM ETH_C */ +&enetc_port2 { + managed = "in-band-status"; + phy-mode = "10gbase-r"; + sfp = <&sfp>; + + status = "okay"; +}; + +/* OSM CAN_A */ +&flexcan2 { + status = "okay"; +}; + +/* OSM CAN_B */ +&flexcan3 { + status = "okay"; +}; + +&gpio5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_a1>, <&pinctrl_gpio_a2>, <&pinctrl_gpio_a3>, + <&pinctrl_gpio_a4>, <&pinctrl_gpio_a5>, <&pinctrl_gpio_a6>; +}; + +/* OSM I2C_A */ +&lpi2c1 { + status = "okay"; + + fan_controller: fan-controller@19 { + compatible = "ti,amc6821"; + reg = <0x19>; + #pwm-cells = <2>; + + fan { + cooling-levels = <255>; + pwms = <&fan_controller 40000 PWM_POLARITY_INVERTED>; + }; + }; + + wm8904_1a: audio-codec@1a { + compatible = "wlf,wm8904"; + reg = <0x1a>; + clocks = <&scmi_clk IMX95_CLK_SAI3>; + clock-names = "mclk"; + #sound-dai-cells = <0>; + AVDD-supply = <®_carrier_1p8v>; + CPVDD-supply = <®_carrier_1p8v>; + DBVDD-supply = <®_carrier_1p8v>; + DCVDD-supply = <®_carrier_1p8v>; + MICVDD-supply = <®_carrier_1p8v>; + }; + + gpio@20 { + compatible = "nxp,pcal6408"; + reg = <0x20>; + #gpio-cells = <2>; + gpio-controller; + gpio-line-names = + "PWR_CTRL_CAN_A", /* 0 */ + "PWR_CTRL_CAN_B", + "PWR_CTRL_USB-HUB", + "LVDS_MUX_CTRL", + "USB_MUX_CTRL", + "I2CA_IOEXP_P5", + "I2CA_IOEXP_P6", + "I2CA_IOEXP_P7"; + + lvds_mux_ctrl: lvds-mux-ctrl-hog { + gpio-hog; + gpios = <3 GPIO_ACTIVE_HIGH>; + line-name = "LVDS_MUX_CTRL"; + output-low; + }; + + usb_mux_ctrl: usb-mux-ctrl-hog { + gpio-hog; + gpios = <4 GPIO_ACTIVE_HIGH>; + line-name = "USB_MUX_CTRL"; + output-high; + }; + }; + + power-monitor@40 { + compatible = "ti,ina219"; + reg = <0x40>; + shunt-resistor = <10000>; + }; + + temperature-sensor@4f { + compatible = "ti,tmp1075"; + reg = <0x4f>; + }; + + tcpc@52 { + compatible = "nxp,ptn5110", "tcpci"; + reg = <0x52>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_a0>; + interrupt-parent = <&gpio5>; + interrupts = <0 IRQ_TYPE_LEVEL_LOW>; + + connector { + compatible = "usb-c-connector"; + data-role = "dual"; + label = "USB_A"; + op-sink-microwatt = <0>; + power-role = "dual"; + try-power-role = "sink"; + self-powered; + sink-pdos = <PDO_FIXED(5000, 0, PDO_FIXED_USB_COMM)>; + source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>; + + port { + usb_c_a_conn_hs: endpoint { + remote-endpoint = <&usb_a_hs>; + }; + }; + }; + }; + + carrier_eeprom: eeprom@57 { + compatible = "st,24c02", "atmel,24c02"; + reg = <0x57>; + pagesize = <16>; + }; +}; + +/* OSM I2C_B */ +&lpi2c5 { + status = "okay"; + + i2c-mux@70 { + compatible = "nxp,pca9548"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + + i2c_mux_carrier_cam_a: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c_mux_carrier_lvds: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + + /* I2C on DSI connector pin #4 and #6 */ + i2c_mux_carrier_dsi_1: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + }; + + /* I2C on DSI connector pin #52 and #54 */ + i2c_mux_carrier_dsi_2: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c_mux_carrier_cam_b: i2c@4 { + reg = <4>; + #address-cells = <1>; + #size-cells = <0>; + }; + + i2c_mux_carrier_sfp: i2c@5 { + reg = <5>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; +}; + +/* OSM SPI_A */ +&lpspi4 { + status = "okay"; +}; + +/* OSM UART_CON, used as the Linux Console */ +&lpuart1 { + status = "okay"; +}; + +/* OSM UART_D */ +&lpuart2 { + status = "okay"; +}; + +/* OSM UART_C */ +&lpuart3 { + status = "okay"; +}; + +/* OSM UART_B */ +&lpuart5 { + status = "okay"; +}; + +/* OSM UART_A */ +&lpuart6 { + status = "okay"; +}; + +&netc_blk_ctrl { + status = "okay"; +}; + +/* OSM MDIO, shared between all ethernet ports */ +&netc_emdio { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_mdio>; + + status = "okay"; + + ethphy_a: ethernet-phy@2 { + reg = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_a7>; + interrupt-parent = <&gpio1>; + interrupts = <11 IRQ_TYPE_LEVEL_LOW>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>; + ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>; + }; + + ethphy_b: ethernet-phy@3 { + reg = <3>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>; + ti,tx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>; + }; +}; + +&netc_timer { + status = "okay"; +}; + +&netcmix_blk_ctrl { + status = "okay"; +}; + +&pcie0 { + status = "okay"; +}; + +&pcie1 { + status = "okay"; +}; + +/* OSM I2S_A */ +&sai3 { + status = "okay"; +}; + +/* OSM PWM_0 */ +&tpm3 { + status = "okay"; +}; + +/* OSM PWM_1 */ +&tpm4 { + status = "okay"; +}; + +/* OSM PWM_2 */ +&tpm5 { + status = "okay"; +}; + +/* OSM PWM_3 */ +&tpm6 { + status = "okay"; +}; + +/* OSM USB_A */ +&usb2 { + status = "okay"; + + port { + usb_a_hs: endpoint { + remote-endpoint = <&usb_c_a_conn_hs>; + }; + }; +}; + +/* OSM USB_C */ +&usb3 { + status = "okay"; +}; + +&usb3_phy { + status = "okay"; +}; + +/* OSM SDIO_A */ +&usdhc2 { + status = "okay"; +}; + +/* OSM SDIO_B */ +&usdhc3 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx95-toradex-osm.dtsi b/arch/arm64/boot/dts/freescale/imx95-toradex-osm.dtsi new file mode 100644 index 0000000..8eb7ea4 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx95-toradex-osm.dtsi
@@ -0,0 +1,1032 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (c) Toradex + * + * Toradex OSM iMX95 SoM + * + * https://www.toradex.com/computer-on-modules/osm-arm-family/nxp-imx95 + */ + +#include "imx95.dtsi" + +/ { + aliases { + can0 = &flexcan2; + can1 = &flexcan3; + eeprom0 = &som_eeprom; + ethernet0 = &enetc_port0; + ethernet1 = &enetc_port1; + ethernet2 = &enetc_port2; + i2c0 = &lpi2c3; + i2c1 = &lpi2c1; + i2c2 = &lpi2c5; + mmc0 = &usdhc1; + mmc1 = &usdhc2; + mmc2 = &usdhc3; + rtc0 = &rtc_i2c; + rtc1 = &scmi_bbm; + serial0 = &lpuart1; + serial1 = &lpuart6; + serial2 = &lpuart5; + serial3 = &lpuart3; + serial4 = &lpuart2; + usb0 = &usb2; + usb1 = &usb3; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + clk_serdes_eth_ref: clock-eth-ref { + compatible = "gpio-gate-clock"; + #clock-cells = <0>; + /* CTRL_ETH_REF_CLK_STBY# */ + enable-gpios = <&som_gpio_expander_0 13 GPIO_ACTIVE_HIGH>; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "On-module +V1.8"; + }; + + reg_usb_a_vbus: regulator-usb-a-vbus { + compatible = "regulator-fixed"; + /* OSM USB_A_EN (OSM_AC16) */ + gpios = <&som_gpio_expander_0 0 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-name = "USB_A_EN"; + }; + + reg_usb_c_vbus: regulator-usb-c-vbus { + compatible = "regulator-fixed"; + /* OSM USB_C_EN (OSM_C10) */ + gpios = <&som_gpio_expander_0 2 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-name = "USB_C_EN"; + }; + + reg_sdio_a_vmmc: regulator-usdhc2-vmmc { + compatible = "regulator-fixed"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdio_a_pwr_en>; + gpios = <&gpio3 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + off-on-delay-us = <100000>; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "SDIO_A_PWR_EN"; + startup-delay-us = <20000>; + }; + + reg_sdio_a_vqmmc: regulator-usdhc2-vqmmc { + compatible = "regulator-gpio"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sdio_a_vsel>; + gpios = <&gpio3 19 GPIO_ACTIVE_HIGH>; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + regulator-name = "PMIC_SDIO_A_VSEL"; + states = <1800000 0x1>, <3300000 0x0>; + }; + + remoteproc-cm7 { + compatible = "fsl,imx95-cm7"; + mbox-names = "tx", "rx", "rxdb"; + mboxes = <&mu7 0 1 &mu7 1 1 &mu7 3 1>; + memory-region = <&vdev0buffer>, <&vdev0vring0>, <&vdev0vring1>, + <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>, <&m7_reserved>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + linux_cma: linux,cma { + compatible = "shared-dma-pool"; + alloc-ranges = <0 0x80000000 0 0x7f000000>; + linux,cma-default; + reusable; + size = <0 0x3c000000>; + }; + + m7_reserved: memory@80000000 { + reg = <0 0x80000000 0 0x1000000>; + no-map; + }; + + vdev0vring0: vdev0vring0@88000000 { + reg = <0 0x88000000 0 0x8000>; + no-map; + }; + + vdev0vring1: vdev0vring1@88008000 { + reg = <0 0x88008000 0 0x8000>; + no-map; + }; + + vdev1vring0: vdev1vring0@88010000 { + reg = <0 0x88010000 0 0x8000>; + no-map; + }; + + vdev1vring1: vdev1vring1@88018000 { + reg = <0 0x88018000 0 0x8000>; + no-map; + }; + + vdev0buffer: vdev0buffer@88020000 { + compatible = "shared-dma-pool"; + reg = <0 0x88020000 0 0x100000>; + no-map; + }; + + rsc_table: rsc-table@88220000 { + reg = <0 0x88220000 0 0x1000>; + no-map; + }; + }; +}; + +/* OSM ADC_0, ADC_1 */ +&adc1 { + vref-supply = <®_1p8v>; +}; + +/* OSM ETH_A */ +&enetc_port0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_eth_a>; +}; + +/* OSM ETH_B */ +&enetc_port1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_eth_b>; +}; + +/* OSM ETH_C */ +&enetc_port2 { + clocks = <&clk_serdes_eth_ref>; + clock-names = "ref"; +}; + +/* OSM CAN_A */ +&flexcan2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can_a>; +}; + +/* OSM CAN_B */ +&flexcan3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_can_b>; +}; + +&gpio1 { + gpio-line-names = + "OSM_AA15", /* 0 */ + "OSM_AA16", + "", + "", + "", + "", + "", + "", + "OSM_F19", + "OSM_AA23", + "OSM_G19", /* 10 */ + "OSM_L17"; /* OSM GPIO_A_7/SPI_B_CS1# */ + + status = "okay"; +}; + +&gpio2 { + gpio-line-names = + "", /* 0 */ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", /* 10 */ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", /* 20 */ + "", + "OSM_AA21", + "OSM_AA20", + "", + "", + "", + "", + "I2C_SOM_SDA", + "I2C_SOM_SCL"; +}; + +&gpio3 { + gpio-line-names = + "OSM_J21", /* 0 */ + "", + "", + "", + "", + "", + "", + "OSM_D21", + "", + "", + "", /* 10 */ + "", + "", + "", + "", + "", + "", + "", + "", + "PMIC_SDIO_A_VSEL"; +}; + +&gpio4 { + gpio-line-names = + "", /* 0 */ + "", + "", + "", + "", + "", + "", + "", + "", + "", + "", /* 10 */ + "", + "", + "", + "CTRL_GPIO_EXP_INT#", + "OSM_T2"; +}; + +&gpio5 { + gpio-line-names = + "OSM_D17", /* OSM GPIO_A_0 */ + "OSM_E17", /* OSM GPIO_A_1 */ + "OSM_F17", /* OSM GPIO_A_2 */ + "OSM_G17", /* OSM GPIO_A_3 */ + "", + "", + "", + "", + "OSM_E19", + "OSM_H17", /* OSM GPIO_A_4 */ + "OSM_J17", /* OSM GPIO_A_5 */ + "OSM_D19", + "", + "OSM_K17", /* OSM GPIO_A_6/SPI_A_CS1# */ + "OSM_Y15"; +}; + +/* OSM I2C_A */ +&lpi2c1 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c_a>; + pinctrl-1 = <&pinctrl_i2c_a_gpio>; + clock-frequency = <100000>; + scl-gpios = <&gpio1 0 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio1 1 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; +}; + +/* I2C_SOM */ +&lpi2c3 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c_som>, <&pinctrl_ctrl_gpio_exp_int>; + pinctrl-1 = <&pinctrl_i2c_som_gpio>, <&pinctrl_ctrl_gpio_exp_int>; + clock-frequency = <400000>; + scl-gpios = <&gpio2 29 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio2 28 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + + status = "okay"; + + som_gpio_expander_0: gpio@20 { + compatible = "nxp,pcal6416"; + reg = <0x20>; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&gpio4>; + interrupts = <14 IRQ_TYPE_LEVEL_LOW>; + #gpio-cells = <2>; + gpio-controller; + gpio-line-names = + "OSM_AC16", /* 0 */ + "OSM_AC15", + "OSM_C10", + "OSM_C8", + "OSM_H19", /* OSM GPIO_B_4 */ + "OSM_J19", /* OSM GPIO_B_5 */ + "OSM_K19", /* OSM GPIO_B_6 */ + "OSM_L19", /* OSM GPIO_B_7 */ + "OSM_V2", + "OSM_L33", + "OSM_AN23", /* 10 */ + "OSM_AN14", + "USB_RECOVERY_CTRL#", + "CTRL_ETH_REF_CLK_STBY#", + "CTRL_DSI_EN/CSI_EN#", + "SPI_B_TPM_CS#"; + + /* + * Switch USB to default position: + * - SoC USB2 -> OSM USB_A + * - SoC USB1 -> OSM USB_C + * Reset configuration: + * - SoC USB1 -> OSM USB_A (USB recovery) + * - SoC USB2 not connected + */ + usb_recov_ctrl: usb-recov-ctrl-hog { + gpio-hog; + gpios = <12 GPIO_ACTIVE_HIGH>; + line-name = "USB_RECOVERY_CTRL#"; + output-high; + }; + }; + + som_gpio_expander_1: gpio@21 { + compatible = "nxp,pcal6416"; + reg = <0x21>; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&gpio4>; + interrupts = <14 IRQ_TYPE_LEVEL_LOW>; + #gpio-cells = <2>; + gpio-controller; + gpio-line-names = + "OSM_D3", /* OSM GPIO_C_0 */ + "OSM_D4", /* OSM GPIO_C_1 */ + "OSM_E3", /* OSM GPIO_C_2/CAM_B_PWR */ + "OSM_E4", /* OSM GPIO_C_3/CAM_B_RST# */ + "OSM_F3", /* OSM GPIO_C_4/DISP_VDD_EN */ + "OSM_F4", /* OSM GPIO_C_5/DISP_BL_EN */ + "OSM_G3", /* OSM GPIO_C_6/CAM_A_PWR */ + "OSM_G4", /* OSM GPIO_C_7/CAM_A_RST# */ + "OSM_U32", + "OSM_U33", + "OSM_V32", /* 10 */ + "OSM_V33", + "OSM_W32", + "OSM_W33", + "OSM_Y32", + "OSM_Y33"; + }; + + rtc_i2c: rtc@32 { + compatible = "epson,rx8130"; + reg = <0x32>; + }; + + temperature-sensor@48 { + compatible = "ti,tmp1075"; + reg = <0x48>; + }; + + som_eeprom: eeprom@50 { + compatible = "st,24c02", "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +/* OSM I2C_B */ +&lpi2c5 { + pinctrl-names = "default", "gpio"; + pinctrl-0 = <&pinctrl_i2c_b>; + pinctrl-1 = <&pinctrl_i2c_b_gpio>; + clock-frequency = <100000>; + scl-gpios = <&gpio2 23 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; + sda-gpios = <&gpio2 22 (GPIO_ACTIVE_HIGH | GPIO_OPEN_DRAIN)>; +}; + +/* OSM SPI_B */ +&lpspi1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi_b>, <&pinctrl_spi_b_cs0_gpio>; + cs-gpios = <&gpio1 9 GPIO_ACTIVE_LOW>, + <&som_gpio_expander_0 15 GPIO_ACTIVE_LOW>; + + status = "okay"; + + som_tpm: tpm@1 { + compatible = "infineon,slb9670", "tcg,tpm_tis-spi"; + reg = <0x1>; + /* + * Maximum TPM-supported speed is 18.5 MHz, limited to 12 MHz + * here as lpspi1's per-clock (twice the max speed) is 24 MHz + */ + spi-max-frequency = <12000000>; + }; +}; + +/* OSM SPI_A */ +&lpspi4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_spi_a>, <&pinctrl_spi_a_cs0_gpio>; + cs-gpios = <&gpio5 14 GPIO_ACTIVE_LOW>; +}; + +/* OSM UART_CON, used as the Linux Console */ +&lpuart1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart_con>; +}; + +/* OSM UART_D */ +&lpuart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart_d>; +}; + +/* OSM UART_C */ +&lpuart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart_c>; +}; + +/* OSM UART_B */ +&lpuart5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart_b>; + uart-has-rtscts; +}; + +/* OSM UART_A */ +&lpuart6 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart_a>; + uart-has-rtscts; +}; + +&mu7 { + status = "okay"; +}; + +/* OSM PCIE_A */ +&pcie0 { + /* PCIE_A_PERST# (OSM V2) */ + reset-gpios = <&som_gpio_expander_0 8 GPIO_ACTIVE_LOW>; +}; + +/* OSM PCIE_B */ +&pcie1 { + /* PCIE_B_PERST# (OSM L33) */ + reset-gpios = <&som_gpio_expander_0 9 GPIO_ACTIVE_LOW>; +}; + +/* OSM I2S_A */ +&sai3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2s_a>, <&pinctrl_i2s_mclk>; + assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>, + <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>, + <&scmi_clk IMX95_CLK_AUDIOPLL1>, + <&scmi_clk IMX95_CLK_AUDIOPLL2>, + <&scmi_clk IMX95_CLK_SAI3>; + assigned-clock-parents = <0>, <0>, <0>, <0>, + <&scmi_clk IMX95_CLK_AUDIOPLL1>; + assigned-clock-rates = <3932160000>, + <3612672000>, + <393216000>, + <361267200>, + <12288000>; + #sound-dai-cells = <0>; + fsl,sai-mclk-direction-output; +}; + +/* OSM I2S_B */ +&sai5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2s_b>; + assigned-clocks = <&scmi_clk IMX95_CLK_AUDIOPLL1_VCO>, + <&scmi_clk IMX95_CLK_AUDIOPLL2_VCO>, + <&scmi_clk IMX95_CLK_AUDIOPLL1>, + <&scmi_clk IMX95_CLK_AUDIOPLL2>, + <&scmi_clk IMX95_CLK_SAI5>; + assigned-clock-parents = <0>, <0>, <0>, <0>, + <&scmi_clk IMX95_CLK_AUDIOPLL1>; + assigned-clock-rates = <3932160000>, + <3612672000>, + <393216000>, + <361267200>, + <12288000>; + #sound-dai-cells = <0>; + fsl,sai-mclk-direction-output; +}; + +&scmi_bbm { + linux,code = <KEY_POWER>; +}; + +&thermal_zones { + /* PF09 Main PMIC */ + pf09-thermal { + polling-delay = <2000>; + polling-delay-passive = <250>; + thermal-sensors = <&scmi_sensor 2>; + + trips { + trip0 { + hysteresis = <2000>; + temperature = <155000>; + type = "critical"; + }; + }; + }; + + /* PF53 VDD_ARM PMIC */ + pf53-arm-thermal { + polling-delay = <2000>; + polling-delay-passive = <250>; + thermal-sensors = <&scmi_sensor 4>; + + trips { + trip0 { + hysteresis = <2000>; + temperature = <155000>; + type = "critical"; + }; + }; + }; + + /* PF53 VDD_SOC PMIC */ + pf53-soc-thermal { + polling-delay = <2000>; + polling-delay-passive = <250>; + thermal-sensors = <&scmi_sensor 3>; + + trips { + trip0 { + hysteresis = <2000>; + temperature = <155000>; + type = "critical"; + }; + }; + }; +}; + +/* OSM PWM_0 */ +&tpm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm0>; +}; + +/* OSM PWM_1 */ +&tpm4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm1>; +}; + +/* OSM PWM_2 */ +&tpm5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm2>; +}; + +/* OSM PWM_3 */ +&tpm6 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pwm3>; +}; + +/* OSM USB_A */ +&usb2 { + adp-disable; + disable-over-current; + dr_mode = "otg"; + hnp-disable; + srp-disable; + usb-role-switch; + vbus-supply = <®_usb_a_vbus>; +}; + +/* OSM USB_C */ +&usb3 { + fsl,disable-port-power-control; +}; + +&usb3_dwc3 { + dr_mode = "host"; +}; + +&usb3_phy { + vbus-supply = <®_usb_c_vbus>; +}; + +/* On-module eMMC */ +&usdhc1 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_emmc>; + pinctrl-1 = <&pinctrl_emmc>; + pinctrl-2 = <&pinctrl_emmc_200mhz>; + no-sd; + no-sdio; + non-removable; + + status = "okay"; +}; + +/* OSM SDIO_A */ +&usdhc2 { + pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; + pinctrl-0 = <&pinctrl_sdio_a>, <&pinctrl_sdio_a_cd>; + pinctrl-1 = <&pinctrl_sdio_a>, <&pinctrl_sdio_a_cd>; + pinctrl-2 = <&pinctrl_sdio_a_200mhz>, <&pinctrl_sdio_a_cd>; + pinctrl-3 = <&pinctrl_sdio_a_sleep>, <&pinctrl_sdio_a_cd>; + cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; + disable-wp; + vmmc-supply = <®_sdio_a_vmmc>; + vqmmc-supply = <®_sdio_a_vqmmc>; +}; + +/* OSM SDIO_B */ +&usdhc3 { + pinctrl-names = "default", "state_100mhz", "state_200mhz"; + pinctrl-0 = <&pinctrl_sdio_b>; + pinctrl-1 = <&pinctrl_sdio_b>; + pinctrl-2 = <&pinctrl_sdio_b_200mhz>; + disable-wp; +}; + +&wdog3 { + fsl,ext-reset-output; + + status = "okay"; +}; + +&scmi_iomuxc { + /* OSM MDIO, shared between all ethernet ports */ + pinctrl_mdio: emdiogrp { + fsl,pins = <IMX95_PAD_ENET1_MDC__NETCMIX_TOP_NETC_MDC 0x50e>, /* OSM T16 */ + <IMX95_PAD_ENET1_MDIO__NETCMIX_TOP_NETC_MDIO 0x90e>; /* OSM T15 */ + }; + + /* OSM ETH_A */ + pinctrl_eth_a: enetc0grp { + fsl,pins = <IMX95_PAD_ENET1_TX_CTL__NETCMIX_TOP_ETH0_RGMII_TX_CTL 0x57e>, /* OSM K16 */ + <IMX95_PAD_ENET1_TXC__NETCMIX_TOP_ETH0_RGMII_TX_CLK 0x58e>, /* OSM J15 */ + <IMX95_PAD_ENET1_TD0__NETCMIX_TOP_ETH0_RGMII_TD0 0x50e>, /* OSM H15 */ + <IMX95_PAD_ENET1_TD1__NETCMIX_TOP_ETH0_RGMII_TD1 0x50e>, /* OSM G15 */ + <IMX95_PAD_ENET1_TD2__NETCMIX_TOP_ETH0_RGMII_TD2 0x50e>, /* OSM H16 */ + <IMX95_PAD_ENET1_TD3__NETCMIX_TOP_ETH0_RGMII_TD3 0x50e>, /* OSM G16 */ + <IMX95_PAD_ENET1_RX_CTL__NETCMIX_TOP_ETH0_RGMII_RX_CTL 0x57e>, /* OSM M15 */ + <IMX95_PAD_ENET1_RXC__NETCMIX_TOP_ETH0_RGMII_RX_CLK 0x58e>, /* OSM R15 */ + <IMX95_PAD_ENET1_RD0__NETCMIX_TOP_ETH0_RGMII_RD0 0x57e>, /* OSM K15 */ + <IMX95_PAD_ENET1_RD1__NETCMIX_TOP_ETH0_RGMII_RD1 0x57e>, /* OSM L15 */ + <IMX95_PAD_ENET1_RD2__NETCMIX_TOP_ETH0_RGMII_RD2 0x57e>, /* OSM N15 */ + <IMX95_PAD_ENET1_RD3__NETCMIX_TOP_ETH0_RGMII_RD3 0x57e>; /* OSM P15 */ + }; + + /* OSM ETH_B */ + pinctrl_eth_b: enetc1grp { + fsl,pins = <IMX95_PAD_ENET2_TX_CTL__NETCMIX_TOP_ETH1_RGMII_TX_CTL 0x57e>, /* OSM J2 */ + <IMX95_PAD_ENET2_TXC__NETCMIX_TOP_ETH1_RGMII_TX_CLK 0x58e>, /* OSM H1 */ + <IMX95_PAD_ENET2_TD0__NETCMIX_TOP_ETH1_RGMII_TD0 0x50e>, /* OSM G1 */ + <IMX95_PAD_ENET2_TD1__NETCMIX_TOP_ETH1_RGMII_TD1 0x50e>, /* OSM F1 */ + <IMX95_PAD_ENET2_TD2__NETCMIX_TOP_ETH1_RGMII_TD2 0x50e>, /* OSM G2 */ + <IMX95_PAD_ENET2_TD3__NETCMIX_TOP_ETH1_RGMII_TD3 0x50e>, /* OSM F2 */ + <IMX95_PAD_ENET2_RX_CTL__NETCMIX_TOP_ETH1_RGMII_RX_CTL 0x57e>, /* OSM L1 */ + <IMX95_PAD_ENET2_RXC__NETCMIX_TOP_ETH1_RGMII_RX_CLK 0x58e>, /* OSM P1 */ + <IMX95_PAD_ENET2_RD0__NETCMIX_TOP_ETH1_RGMII_RD0 0x57e>, /* OSM J1 */ + <IMX95_PAD_ENET2_RD1__NETCMIX_TOP_ETH1_RGMII_RD1 0x57e>, /* OSM K1 */ + <IMX95_PAD_ENET2_RD2__NETCMIX_TOP_ETH1_RGMII_RD2 0x57e>, /* OSM M1 */ + <IMX95_PAD_ENET2_RD3__NETCMIX_TOP_ETH1_RGMII_RD3 0x57e>; /* OSM N1 */ + }; + + /* OSM CAN_A */ + pinctrl_can_a: flexcan2grp { + fsl,pins = <IMX95_PAD_GPIO_IO25__CAN2_TX 0x39e>, /* OSM AC17 */ + <IMX95_PAD_GPIO_IO27__CAN2_RX 0x39e>; /* OSM AB17 */ + }; + + /* OSM CAN_B */ + pinctrl_can_b: flexcan3grp { + fsl,pins = <IMX95_PAD_CCM_CLKO3__CAN3_TX 0x39e>, /* OSM AC19 */ + <IMX95_PAD_CCM_CLKO4__CAN3_RX 0x39e>; /* OSM AB19 */ + }; + + /* OSM GPIO_B_2 */ + pinctrl_gpio_b2: gpio1io8grp { + fsl,pins = <IMX95_PAD_PDM_CLK__AONMIX_TOP_GPIO1_IO_BIT8 0x31e>; /* OSM F19 */ + }; + + /* OSM SPI_B_CS0# */ + pinctrl_spi_b_cs0_gpio: gpio1io9grp { + fsl,pins = <IMX95_PAD_PDM_BIT_STREAM0__AONMIX_TOP_GPIO1_IO_BIT9 0x3fe>; /* OSM AA23 */ + }; + + /* OSM GPIO_B_3 */ + pinctrl_gpio_b3: gpio1io10grp { + fsl,pins = <IMX95_PAD_PDM_BIT_STREAM1__AONMIX_TOP_GPIO1_IO_BIT10 0x31e>; /* OSM G19 */ + }; + + /* OSM GPIO_A_7/SPI_B_CS1# */ + pinctrl_gpio_a7: gpio1io11grp { + fsl,pins = <IMX95_PAD_SAI1_TXFS__AONMIX_TOP_GPIO1_IO_BIT11 0x31e>; /* OSM L17 */ + }; + + /* OSM PWM_0 as GPIO */ + pinctrl_pwm0_gpio: gpio2io12grp { + fsl,pins = <IMX95_PAD_GPIO_IO12__GPIO2_IO_BIT12 0x31e>; /* OSM E18 */ + }; + + /* OSM GPIO_A_0 */ + pinctrl_gpio_a0: gpio5io0grp { + fsl,pins = <IMX95_PAD_XSPI1_DATA0__GPIO5_IO_BIT0 0x31e>; /* OSM D17 */ + }; + + /* OSM GPIO_A_1 */ + pinctrl_gpio_a1: gpio5io1grp { + fsl,pins = <IMX95_PAD_XSPI1_DATA1__GPIO5_IO_BIT1 0x31e>; /* OSM E17 */ + }; + + /* OSM GPIO_A_2 */ + pinctrl_gpio_a2: gpio5io2grp { + fsl,pins = <IMX95_PAD_XSPI1_DATA2__GPIO5_IO_BIT2 0x31e>; /* OSM F17 */ + }; + + /* OSM GPIO_A_3 */ + pinctrl_gpio_a3: gpio5io3grp { + fsl,pins = <IMX95_PAD_XSPI1_DATA3__GPIO5_IO_BIT3 0x31e>; /* OSM G17 */ + }; + + /* OSM GPIO_B_1 */ + pinctrl_gpio_b1: gpio5io8grp { + fsl,pins = <IMX95_PAD_XSPI1_DQS__GPIO5_IO_BIT8 0x31e>; /* OSM E19 */ + }; + + /* OSM GPIO_A_4 */ + pinctrl_gpio_a4: gpio5io9grp { + fsl,pins = <IMX95_PAD_XSPI1_SCLK__GPIO5_IO_BIT9 0x31e>; /* OSM H17 */ + }; + + /* OSM GPIO_A_5 */ + pinctrl_gpio_a5: gpio5io10grp { + fsl,pins = <IMX95_PAD_XSPI1_SS0_B__GPIO5_IO_BIT10 0x31e>; /* OSM J17 */ + }; + + /* OSM GPIO_B_0 */ + pinctrl_gpio_b0: gpio5io11grp { + fsl,pins = <IMX95_PAD_XSPI1_SS1_B__GPIO5_IO_BIT11 0x31e>; /* OSM D19 */ + }; + + /* OSM GPIO_A_6/SPI_A_CS1# */ + pinctrl_gpio_a6: gpio5io13grp { + fsl,pins = <IMX95_PAD_GPIO_IO33__GPIO5_IO_BIT13 0x31e>; /* OSM K17 */ + }; + + /* OSM SPI_A_CS0# */ + pinctrl_spi_a_cs0_gpio: gpio5io14grp { + fsl,pins = <IMX95_PAD_GPIO_IO34__GPIO5_IO_BIT14 0x3fe>; /* OSM Y15 */ + }; + + pinctrl_ctrl_gpio_exp_int: gpioexpintgrp { + fsl,pins = <IMX95_PAD_ENET2_MDC__GPIO4_IO_BIT14 0x31e>; /* CTRL_GPIO_EXP_INT# */ + }; + + /* OSM I2C_A as GPIOs */ + pinctrl_i2c_a_gpio: lpi2c1gpiogrp { + fsl,pins = <IMX95_PAD_I2C1_SDA__AONMIX_TOP_GPIO1_IO_BIT1 0x40000b9e>, /* OSM AA16 */ + <IMX95_PAD_I2C1_SCL__AONMIX_TOP_GPIO1_IO_BIT0 0x40000b9e>; /* OSM AA15 */ + }; + + /* OSM I2C_A */ + pinctrl_i2c_a: lpi2c1grp { + fsl,pins = <IMX95_PAD_I2C1_SDA__AONMIX_TOP_LPI2C1_SDA 0x40000b9e>, /* OSM AA16 */ + <IMX95_PAD_I2C1_SCL__AONMIX_TOP_LPI2C1_SCL 0x40000b9e>; /* OSM AA15 */ + }; + + /* I2C_SOM (On-module I2C) as GPIOs */ + pinctrl_i2c_som_gpio: lpi2c3gpiogrp { + fsl,pins = <IMX95_PAD_GPIO_IO28__GPIO2_IO_BIT28 0x40001b9e>, /* I2C_SOM_SDA */ + <IMX95_PAD_GPIO_IO29__GPIO2_IO_BIT29 0x40001b9e>; /* I2C_SOM_SCL */ + }; + + /* I2C_SOM (On-module I2C) */ + pinctrl_i2c_som: lpi2c3grp { + fsl,pins = <IMX95_PAD_GPIO_IO28__LPI2C3_SDA 0x40001b9e>, /* I2C_SOM_SDA */ + <IMX95_PAD_GPIO_IO29__LPI2C3_SCL 0x40001b9e>; /* I2C_SOM_SCL */ + }; + + /* OSM I2C_B as GPIOs */ + pinctrl_i2c_b_gpio: lpi2c5gpiogrp { + fsl,pins = <IMX95_PAD_GPIO_IO22__GPIO2_IO_BIT22 0x40001b9e>, /* OSM AA21 */ + <IMX95_PAD_GPIO_IO23__GPIO2_IO_BIT23 0x40001b9e>; /* OSM AA20 */ + }; + + /* OSM I2C_B */ + pinctrl_i2c_b: lpi2c5grp { + fsl,pins = <IMX95_PAD_GPIO_IO22__LPI2C5_SDA 0x40001b9e>, /* OSM AA21 */ + <IMX95_PAD_GPIO_IO23__LPI2C5_SCL 0x40001b9e>; /* OSM AA20 */ + }; + + /* OSM SPI_B */ + pinctrl_spi_b: lpspi1grp { + fsl,pins = <IMX95_PAD_SAI1_TXD0__AONMIX_TOP_LPSPI1_SCK 0x3fe>, /* OSM Y21 */ + <IMX95_PAD_SAI1_RXD0__AONMIX_TOP_LPSPI1_SOUT 0x3fe>, /* OSM Y23 */ + <IMX95_PAD_SAI1_TXC__AONMIX_TOP_LPSPI1_SIN 0x3fe>; /* OSM Y22 */ + }; + + /* OSM SPI_A */ + pinctrl_spi_a: lpspi4grp { + fsl,pins = <IMX95_PAD_GPIO_IO37__LPSPI4_SCK 0x3fe>, /* OSM U16 */ + <IMX95_PAD_GPIO_IO36__LPSPI4_SOUT 0x3fe>, /* OSM V15 */ + <IMX95_PAD_GPIO_IO35__LPSPI4_SIN 0x3fe>; /* OSM U15 */ + }; + + /* OSM UART_CON */ + pinctrl_uart_con: lpuart1grp { + fsl,pins = <IMX95_PAD_UART1_TXD__AONMIX_TOP_LPUART1_TX 0x31e>, /* OSM D23 */ + <IMX95_PAD_UART1_RXD__AONMIX_TOP_LPUART1_RX 0x31e>; /* OSM D22 */ + }; + + /* OSM UART_D */ + pinctrl_uart_d: lpuart2grp { + fsl,pins = <IMX95_PAD_UART2_TXD__AONMIX_TOP_LPUART2_TX 0x31e>, /* OSM C23 */ + <IMX95_PAD_UART2_RXD__AONMIX_TOP_LPUART2_RX 0x31e>; /* OSM C22 */ + }; + + /* OSM UART_C */ + pinctrl_uart_c: lpuart3grp { + fsl,pins = <IMX95_PAD_GPIO_IO14__LPUART3_TX 0x31e>, /* OSM B23 */ + <IMX95_PAD_GPIO_IO15__LPUART3_RX 0x31e>; /* OSM A22 */ + }; + + /* OSM UART_B */ + pinctrl_uart_b: lpuart5grp { + fsl,pins = <IMX95_PAD_GPIO_IO00__LPUART5_TX 0x31e>, /* OSM D13 */ + <IMX95_PAD_GPIO_IO01__LPUART5_RX 0x31e>, /* OSM D14 */ + <IMX95_PAD_GPIO_IO02__LPUART5_CTS_B 0x31e>, /* OSM D16 */ + <IMX95_PAD_GPIO_IO03__LPUART5_RTS_B 0x31e>; /* OSM D15 */ + }; + + /* OSM UART_A */ + pinctrl_uart_a: lpuart6grp { + fsl,pins = <IMX95_PAD_GPIO_IO04__LPUART6_TX 0x31e>, /* OSM B13 */ + <IMX95_PAD_GPIO_IO05__LPUART6_RX 0x31e>, /* OSM A14 */ + <IMX95_PAD_GPIO_IO06__LPUART6_CTS_B 0x31e>, /* OSM C14 */ + <IMX95_PAD_GPIO_IO07__LPUART6_RTS_B 0x31e>; /* OSM C13 */ + }; + + /* OSM PCIE_WAKE# */ + pinctrl_pcie_wake: pciewakegrp { + fsl,pins = <IMX95_PAD_ENET2_MDIO__GPIO4_IO_BIT15 0x31e>; /* OSM T2 */ + }; + + /* OSM I2S_A */ + pinctrl_i2s_a: sai3grp { + fsl,pins = <IMX95_PAD_GPIO_IO16__SAI3_TX_BCLK 0x11e>, /* OSM W20 */ + <IMX95_PAD_GPIO_IO20__SAI3_RX_DATA_BIT0 0x11e>, /* OSM V21 */ + <IMX95_PAD_GPIO_IO21__SAI3_TX_DATA_BIT0 0x11e>, /* OSM W21 */ + <IMX95_PAD_GPIO_IO26__SAI3_TX_SYNC 0x11e>; /* OSM W18 */ + }; + + /* OSM I2S_MCLK */ + pinctrl_i2s_mclk: sai3mclkgrp { + fsl,pins = <IMX95_PAD_GPIO_IO17__SAI3_MCLK 0x31e>; /* OSM V18 */ + }; + + /* OSM I2S_B */ + pinctrl_i2s_b: sai5grp { + fsl,pins = <IMX95_PAD_XSPI1_DATA6__SAI5_TX_BCLK 0x11e>, /* OSM T19 */ + <IMX95_PAD_XSPI1_DATA7__SAI5_RX_DATA_BIT0 0x11e>, /* OSM V19 */ + <IMX95_PAD_XSPI1_DATA4__SAI5_TX_DATA_BIT0 0x11e>, /* OSM W19 */ + <IMX95_PAD_XSPI1_DATA5__SAI5_TX_SYNC 0x11e>; /* OSM T18 */ + }; + + /* OSM PWM_0 */ + pinctrl_pwm0: tpm3ch2grp { + fsl,pins = <IMX95_PAD_GPIO_IO12__TPM3_CH2 0x51e>; /* OSM E18 */ + }; + + /* OSM PWM_1 */ + pinctrl_pwm1: tpm4ch2grp { + fsl,pins = <IMX95_PAD_GPIO_IO13__TPM4_CH2 0x51e>; /* OSM F18 */ + }; + + /* OSM PWM_2 */ + pinctrl_pwm2: tpm5ch2grp { + fsl,pins = <IMX95_PAD_GPIO_IO18__TPM5_CH2 0x51e>; /* OSM G18 */ + }; + + /* OSM PWM_3 */ + pinctrl_pwm3: tpm6ch2grp { + fsl,pins = <IMX95_PAD_GPIO_IO19__TPM6_CH2 0x51e>; /* OSM H18 */ + }; + + /* On-module eMMC (max 200MHz) */ + pinctrl_emmc_200mhz: usdhc1-200mhzgrp { + fsl,pins = <IMX95_PAD_SD1_CLK__USDHC1_CLK 0x15fe>, /* eMMC_CLK */ + <IMX95_PAD_SD1_CMD__USDHC1_CMD 0x13fe>, /* eMMC_CMD */ + <IMX95_PAD_SD1_DATA0__USDHC1_DATA0 0x13fe>, /* eMMC_DATA0 */ + <IMX95_PAD_SD1_DATA1__USDHC1_DATA1 0x13fe>, /* eMMC_DATA1 */ + <IMX95_PAD_SD1_DATA2__USDHC1_DATA2 0x13fe>, /* eMMC_DATA2 */ + <IMX95_PAD_SD1_DATA3__USDHC1_DATA3 0x13fe>, /* eMMC_DATA3 */ + <IMX95_PAD_SD1_DATA4__USDHC1_DATA4 0x13fe>, /* eMMC_DATA4 */ + <IMX95_PAD_SD1_DATA5__USDHC1_DATA5 0x13fe>, /* eMMC_DATA5 */ + <IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x13fe>, /* eMMC_DATA6 */ + <IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x13fe>, /* eMMC_DATA7 */ + <IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x15fe>; /* eMMC_STROBE */ + }; + + /* On-module eMMC (max 100MHz) */ + pinctrl_emmc: usdhc1grp { + fsl,pins = <IMX95_PAD_SD1_CLK__USDHC1_CLK 0x158e>, /* eMMC_CLK */ + <IMX95_PAD_SD1_CMD__USDHC1_CMD 0x138e>, /* eMMC_CMD */ + <IMX95_PAD_SD1_DATA0__USDHC1_DATA0 0x138e>, /* eMMC_DATA0 */ + <IMX95_PAD_SD1_DATA1__USDHC1_DATA1 0x138e>, /* eMMC_DATA1 */ + <IMX95_PAD_SD1_DATA2__USDHC1_DATA2 0x138e>, /* eMMC_DATA2 */ + <IMX95_PAD_SD1_DATA3__USDHC1_DATA3 0x138e>, /* eMMC_DATA3 */ + <IMX95_PAD_SD1_DATA4__USDHC1_DATA4 0x138e>, /* eMMC_DATA4 */ + <IMX95_PAD_SD1_DATA5__USDHC1_DATA5 0x138e>, /* eMMC_DATA5 */ + <IMX95_PAD_SD1_DATA6__USDHC1_DATA6 0x138e>, /* eMMC_DATA6 */ + <IMX95_PAD_SD1_DATA7__USDHC1_DATA7 0x138e>, /* eMMC_DATA7 */ + <IMX95_PAD_SD1_STROBE__USDHC1_STROBE 0x158e>; /* eMMC_STROBE */ + }; + + /* OSM SDIO_A (max 200MHz) */ + pinctrl_sdio_a_200mhz: usdhc2-200mhzgrp { + fsl,pins = <IMX95_PAD_SD2_CLK__USDHC2_CLK 0x15fe>, /* OSM F21 */ + <IMX95_PAD_SD2_CMD__USDHC2_CMD 0x13fe>, /* OSM E20 */ + <IMX95_PAD_SD2_DATA0__USDHC2_DATA0 0x13fe>, /* OSM G20 */ + <IMX95_PAD_SD2_DATA1__USDHC2_DATA1 0x13fe>, /* OSM G21 */ + <IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x13fe>, /* OSM H20 */ + <IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x13fe>; /* OSM H21 */ + }; + + /* OSM SDIO_A_CD# */ + pinctrl_sdio_a_cd: usdhc2-cdgrp { + fsl,pins = <IMX95_PAD_SD2_CD_B__GPIO3_IO_BIT0 0x1100>; /* OSM J21 */ + }; + + /* OSM SDIO_A_PWR_EN */ + pinctrl_sdio_a_pwr_en: usdhc2-pwrengrp { + fsl,pins = <IMX95_PAD_SD2_RESET_B__GPIO3_IO_BIT7 0x11e>; /* OSM D21 */ + }; + + /* OSM SDIO_A (sleep mode) */ + pinctrl_sdio_a_sleep: usdhc2-sleepgrp { + fsl,pins = <IMX95_PAD_SD2_CLK__USDHC2_CLK 0x400>, /* OSM F21 */ + <IMX95_PAD_SD2_CMD__USDHC2_CMD 0x400>, /* OSM E20 */ + <IMX95_PAD_SD2_DATA0__USDHC2_DATA0 0x400>, /* OSM G20 */ + <IMX95_PAD_SD2_DATA1__USDHC2_DATA1 0x400>, /* OSM G21 */ + <IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x400>, /* OSM H20 */ + <IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x400>; /* OSM H21 */ + }; + + /* PMIC_SDIO_A_VSEL */ + pinctrl_sdio_a_vsel: usdhc2-vselgrp { + fsl,pins = <IMX95_PAD_SD2_VSELECT__GPIO3_IO_BIT19 0x4>; /* PMIC_SDIO_A_VSEL */ + }; + + /* OSM SDIO_A (max 100MHz) */ + pinctrl_sdio_a: usdhc2grp { + fsl,pins = <IMX95_PAD_SD2_CLK__USDHC2_CLK 0x158e>, /* OSM F21 */ + <IMX95_PAD_SD2_CMD__USDHC2_CMD 0x138e>, /* OSM E20 */ + <IMX95_PAD_SD2_DATA0__USDHC2_DATA0 0x138e>, /* OSM G20 */ + <IMX95_PAD_SD2_DATA1__USDHC2_DATA1 0x138e>, /* OSM G21 */ + <IMX95_PAD_SD2_DATA2__USDHC2_DATA2 0x138e>, /* OSM H20 */ + <IMX95_PAD_SD2_DATA3__USDHC2_DATA3 0x138e>; /* OSM H21 */ + }; + + /* OSM SDIO_B (max 200MHz) */ + pinctrl_sdio_b_200mhz: usdhc3-200mhzgrp { + fsl,pins = <IMX95_PAD_SD3_CLK__USDHC3_CLK 0x15fe>, /* OSM K20 */ + <IMX95_PAD_SD3_CMD__USDHC3_CMD 0x13fe>, /* OSM K21 */ + <IMX95_PAD_SD3_DATA0__USDHC3_DATA0 0x13fe>, /* OSM L20 */ + <IMX95_PAD_SD3_DATA1__USDHC3_DATA1 0x13fe>, /* OSM L21 */ + <IMX95_PAD_SD3_DATA2__USDHC3_DATA2 0x13fe>, /* OSM M21 */ + <IMX95_PAD_SD3_DATA3__USDHC3_DATA3 0x13fe>; /* OSM N20 */ + }; + + /* OSM SDIO_B (max 100MHz) */ + pinctrl_sdio_b: usdhc3grp { + fsl,pins = <IMX95_PAD_SD3_CLK__USDHC3_CLK 0x158e>, /* OSM K20 */ + <IMX95_PAD_SD3_CMD__USDHC3_CMD 0x138e>, /* OSM K21 */ + <IMX95_PAD_SD3_DATA0__USDHC3_DATA0 0x138e>, /* OSM L20 */ + <IMX95_PAD_SD3_DATA1__USDHC3_DATA1 0x138e>, /* OSM L21 */ + <IMX95_PAD_SD3_DATA2__USDHC3_DATA2 0x138e>, /* OSM M21 */ + <IMX95_PAD_SD3_DATA3__USDHC3_DATA3 0x138e>; /* OSM N20 */ + }; +};
diff --git a/arch/arm64/boot/dts/freescale/imx95-toradex-smarc-dev.dts b/arch/arm64/boot/dts/freescale/imx95-toradex-smarc-dev.dts index 7437e52..ffe537c 100644 --- a/arch/arm64/boot/dts/freescale/imx95-toradex-smarc-dev.dts +++ b/arch/arm64/boot/dts/freescale/imx95-toradex-smarc-dev.dts
@@ -64,6 +64,14 @@ &enetc_port1 { status = "okay"; }; +/* SMARC SERDES_0 - ETH2 */ +&enetc_port2 { + phy-handle = <ðphy3>; + phy-mode = "sgmii"; + managed = "in-band-status"; + status = "okay"; +}; + /* SMARC CAN0 */ &flexcan1 { status = "okay";
diff --git a/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi b/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi index a6c5398..641573c 100644 --- a/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi +++ b/arch/arm64/boot/dts/freescale/imx95-toradex-smarc.dtsi
@@ -15,6 +15,7 @@ aliases { can1 = &flexcan2; ethernet0 = &enetc_port0; ethernet1 = &enetc_port1; + ethernet2 = &enetc_port2; mmc0 = &usdhc1; mmc1 = &usdhc2; mmc2 = &usdhc3; @@ -221,6 +222,12 @@ &enetc_port1 { phy-mode = "rgmii-id"; }; +/* SMARC SERDES_0 */ +&enetc_port2 { + clocks = <&clk_serdes_eth_ref>; + clock-names = "ref"; +}; + /* SMARC CAN0 */ &flexcan1 { pinctrl-names = "default"; @@ -839,6 +846,7 @@ &usdhc3 { keep-power-in-suspend; non-removable; vmmc-supply = <®_wifi_en>; + status = "okay"; }; &scmi_bbm {
diff --git a/arch/arm64/boot/dts/freescale/imx95-tqma9596sa-mb-smarc-2.dts b/arch/arm64/boot/dts/freescale/imx95-tqma9596sa-mb-smarc-2.dts index 97726ed..e376d3a 100644 --- a/arch/arm64/boot/dts/freescale/imx95-tqma9596sa-mb-smarc-2.dts +++ b/arch/arm64/boot/dts/freescale/imx95-tqma9596sa-mb-smarc-2.dts
@@ -243,6 +243,8 @@ &pcie1 { }; ®_sdvmmc { + startup-delay-us = <100>; + off-on-delay-us = <200000>; status = "okay"; };
diff --git a/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi b/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi index 456129f..6ed8107 100644 --- a/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi +++ b/arch/arm64/boot/dts/freescale/imx95-tqma9596sa.dtsi
@@ -458,6 +458,81 @@ &scmi_bbm { linux,code = <KEY_POWER>; }; +&thermal_zones { + pf09-thermal { + polling-delay = <2000>; + polling-delay-passive = <250>; + thermal-sensors = <&scmi_sensor 2>; + + trips { + pf09_alert: trip0 { + hysteresis = <2000>; + temperature = <140000>; + type = "passive"; + }; + + pf09_crit: trip1 { + hysteresis = <2000>; + temperature = <155000>; + type = "critical"; + }; + }; + }; + + pf53arm-thermal { + polling-delay = <2000>; + polling-delay-passive = <250>; + thermal-sensors = <&scmi_sensor 4>; + + cooling-maps { + map0 { + trip = <&pf5301_alert>; + cooling-device = + <&A55_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A55_1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A55_2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A55_3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A55_4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&A55_5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + + trips { + pf5301_alert: trip0 { + hysteresis = <2000>; + temperature = <140000>; + type = "passive"; + }; + + pf5301_crit: trip1 { + hysteresis = <2000>; + temperature = <155000>; + type = "critical"; + }; + }; + }; + + pf53soc-thermal { + polling-delay = <2000>; + polling-delay-passive = <250>; + thermal-sensors = <&scmi_sensor 3>; + + trips { + pf5302_alert: trip0 { + hysteresis = <2000>; + temperature = <140000>; + type = "passive"; + }; + + pf5302_crit: trip1 { + hysteresis = <2000>; + temperature = <155000>; + type = "critical"; + }; + }; + }; +}; + &tpm3 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_tpm3>;
diff --git a/arch/arm64/boot/dts/freescale/imx95-var-dart-sonata.dts b/arch/arm64/boot/dts/freescale/imx95-var-dart-sonata.dts index 3479abc..9344a0d 100644 --- a/arch/arm64/boot/dts/freescale/imx95-var-dart-sonata.dts +++ b/arch/arm64/boot/dts/freescale/imx95-var-dart-sonata.dts
@@ -336,7 +336,7 @@ &lpuart1 { status = "okay"; }; -/* Header (J12.4, J12.6) */ +/* Header (J6.4, J6.6) */ &lpuart8 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_uart8>;
diff --git a/arch/arm64/boot/dts/freescale/imx95.dtsi b/arch/arm64/boot/dts/freescale/imx95.dtsi index 38fc470..d20c249 100644 --- a/arch/arm64/boot/dts/freescale/imx95.dtsi +++ b/arch/arm64/boot/dts/freescale/imx95.dtsi
@@ -255,19 +255,16 @@ gpu_opp_table: opp-table { opp-500000000 { opp-hz = /bits/ 64 <500000000>; - opp-hz-real = /bits/ 64 <500000000>; opp-microvolt = <920000>; }; opp-800000000 { opp-hz = /bits/ 64 <800000000>; - opp-hz-real = /bits/ 64 <800000000>; opp-microvolt = <920000>; }; opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; - opp-hz-real = /bits/ 64 <1000000000>; opp-microvolt = <920000>; }; }; @@ -439,6 +436,9 @@ hugo_funnel_out_port0: endpoint { mqs1: mqs-1 { compatible = "fsl,imx95-aonmix-mqs"; + clocks = <&scmi_clk IMX95_CLK_SAI1>; + clock-names = "mclk"; + #sound-dai-cells = <0>; status = "disabled"; }; @@ -1458,7 +1458,7 @@ lpi2c1: i2c@44340000 { clock-names = "per", "ipg"; #address-cells = <1>; #size-cells = <0>; - dmas = <&edma1 12 0 0>, <&edma1 13 0 FSL_EDMA_RX> ; + dmas = <&edma1 12 0 0>, <&edma1 13 0 FSL_EDMA_RX>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -1472,7 +1472,7 @@ lpi2c2: i2c@44350000 { clock-names = "per", "ipg"; #address-cells = <1>; #size-cells = <0>; - dmas = <&edma1 14 0 0>, <&edma1 15 0 FSL_EDMA_RX> ; + dmas = <&edma1 14 0 0>, <&edma1 15 0 FSL_EDMA_RX>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -1486,7 +1486,7 @@ lpspi1: spi@44360000 { clocks = <&scmi_clk IMX95_CLK_LPSPI1>, <&scmi_clk IMX95_CLK_BUSAON>; clock-names = "per", "ipg"; - dmas = <&edma1 16 0 FSL_EDMA_RX>, <&edma1 17 0 0> ; + dmas = <&edma1 16 0 FSL_EDMA_RX>, <&edma1 17 0 0>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -1500,7 +1500,7 @@ lpspi2: spi@44370000 { clocks = <&scmi_clk IMX95_CLK_LPSPI2>, <&scmi_clk IMX95_CLK_BUSAON>; clock-names = "per", "ipg"; - dmas = <&edma1 18 0 FSL_EDMA_RX>, <&edma1 19 0 0> ; + dmas = <&edma1 18 0 FSL_EDMA_RX>, <&edma1 19 0 0>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -1948,7 +1948,7 @@ pcie0: pcie@4c300000 { <0 0x4c340000 0 0x4000>; reg-names = "dbi", "config", "atu", "app"; ranges = <0x43000000 0x9 0x00000000 0x9 0x00000000 0x0 0xe0000000>, - <0x82000000 0x0 0xe0000000 0x9 0xe0000000 0x0 0x10000000>, + <0x82000000 0x0 0x10000000 0x9 0xe0000000 0x0 0x10000000>, <0x81000000 0x0 0x00000000 0x9 0xf0000000 0x0 0x00100000>; #address-cells = <3>; #size-cells = <2>; @@ -2039,7 +2039,7 @@ pcie1: pcie@4c380000 { <0 0x4c3c0000 0 0x4000>; reg-names = "dbi", "config", "atu", "app"; ranges = <0x43000000 0xa 0x00000000 0xa 0x00000000 0x0 0xe0000000>, - <0x82000000 0x0 0xe0000000 0xa 0xe0000000 0x0 0x10000000>, + <0x82000000 0x0 0x10000000 0xa 0xe0000000 0x0 0x10000000>, <0x81000000 0x0 0x00000000 0xa 0xf0000000 0x0 0x00100000>; #address-cells = <3>; #size-cells = <2>;
diff --git a/arch/arm64/boot/dts/freescale/imx952-evk.dts b/arch/arm64/boot/dts/freescale/imx952-evk.dts index 2224b90..047dfde2 100644 --- a/arch/arm64/boot/dts/freescale/imx952-evk.dts +++ b/arch/arm64/boot/dts/freescale/imx952-evk.dts
@@ -43,6 +43,12 @@ aliases { spi6 = &lpspi7; }; + amp_mqs1: audio-amplifier { + compatible = "simple-audio-amplifier"; + sound-name-prefix = "MQS AMP"; + VCC-supply = <®_3p3v>; + }; + bt_sco_codec: audio-codec-bt-sco { #sound-dai-cells = <1>; compatible = "linux,bt-sco"; @@ -52,6 +58,40 @@ chosen { stdout-path = &lpuart1; }; + can1_pdm_mux: mux-controller-0 { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + #mux-state-cells = <1>; + mux-gpios = <&pcal6416 10 GPIO_ACTIVE_HIGH>; + }; + + mqs1_en_mux: mux-controller-1 { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + #mux-state-cells = <1>; + mux-gpios = <&pcal6416 15 GPIO_ACTIVE_HIGH>; + }; + + pinctrl-gpiomux { + compatible = "pinctrl-multiplexer"; + + can1_fun: can1-grp { + mux-states = <&can1_pdm_mux 1>; + }; + + mqs1_disable: mqs1-disable-grp { + mux-states = <&mqs1_en_mux 0>; + }; + + mqs1_enable: mqs1-enable-grp { + mux-states = <&mqs1_en_mux 1>; + }; + + pdm_fun: pdm-grp { + mux-states = <&can1_pdm_mux 0>; + }; + }; + dmic: dmic { compatible = "dmic-codec"; #sound-dai-cells = <0>; @@ -197,7 +237,7 @@ &mu7 1 1 <&vdev1vring0>, <&vdev1vring1>, <&rsc_table>, <&m7_reserved>; }; - sound-bt-sco { + mqs1_conflict_card: sound-bt-sco { compatible = "simple-audio-card"; simple-audio-card,bitclock-inversion; simple-audio-card,bitclock-master = <&btcpu>; @@ -284,7 +324,7 @@ &asrc2 { /* pin conflict with PDM */ &flexcan1 { pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_flexcan1>; + pinctrl-0 = <&pinctrl_flexcan1>, <&mqs1_disable>, <&can1_fun>; phys = <&flexcan1_phy>; status = "disabled"; }; @@ -387,18 +427,6 @@ pcal6416: gpio@21 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pcal6416>; vcc-supply = <®_3p3v>; - - pdm-can-sel-hog { - gpio-hog; - gpios = <10 GPIO_ACTIVE_HIGH>; - output-low; - }; - - mqs-en-hog { - gpio-hog; - gpios = <15 GPIO_ACTIVE_HIGH>; - output-low; - }; }; }; @@ -481,7 +509,7 @@ &lpspi7 { status = "okay"; }; -&micfil { +mqs1_conflict_dev: &micfil { assigned-clocks = <&scmi_clk IMX952_CLK_AUDIOPLL1_VCO>, <&scmi_clk IMX952_CLK_AUDIOPLL2_VCO>, <&scmi_clk IMX952_CLK_AUDIOPLL1>, @@ -491,17 +519,27 @@ &micfil { <&scmi_clk IMX952_CLK_AUDIOPLL1>; assigned-clock-rates = <3932160000>, <3612672000>, <393216000>, <361267200>, <49152000>; - pinctrl-0 = <&pinctrl_pdm>; + pinctrl-0 = <&pinctrl_pdm>, <&mqs1_disable>, <&pdm_fun>; pinctrl-1 = <&pinctrl_pdm_sleep>; pinctrl-names = "default", "sleep"; status = "okay"; }; +&mqs1 { + pinctrl-0 = <&pinctrl_mqs1>, <&mqs1_enable>; + pinctrl-names = "default"; +}; + &mu7 { status = "okay"; }; &sai1 { + clocks = <&scmi_clk IMX952_CLK_BUSAON>, <&clk_dummy>, + <&scmi_clk IMX952_CLK_SAI1>, <&clk_dummy>, + <&clk_dummy>, <&scmi_clk IMX952_CLK_AUDIOPLL1>, + <&scmi_clk IMX952_CLK_AUDIOPLL2>; + clock-names = "bus", "mclk0", "mclk1", "mclk2", "mclk3", "pll8k", "pll11k"; assigned-clocks = <&scmi_clk IMX952_CLK_AUDIOPLL1_VCO>, <&scmi_clk IMX952_CLK_AUDIOPLL2_VCO>, <&scmi_clk IMX952_CLK_AUDIOPLL1>, @@ -682,6 +720,13 @@ IMX952_PAD_GPIO_IO07__WAKEUPMIX_TOP_LPSPI7_SCK 0x39e >; }; + pinctrl_mqs1: mqs1grp { + fsl,pins = < + IMX952_PAD_PDM_CLK__AONMIX_TOP_MQS1_LEFT 0x31e + IMX952_PAD_PDM_BIT_STREAM0__AONMIX_TOP_MQS1_RIGHT 0x31e + >; + }; + pinctrl_pcal6416: pcal6416grp { fsl,pins = < IMX952_PAD_GPIO_IO10__WAKEUPMIX_TOP_GPIO2_IO_10 0x31e
diff --git a/arch/arm64/boot/dts/freescale/imx952-frdm.dts b/arch/arm64/boot/dts/freescale/imx952-frdm.dts new file mode 100644 index 0000000..0b9d74e --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx952-frdm.dts
@@ -0,0 +1,9 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 NXP + */ + +/dts-v1/; + +#include "imx952.dtsi" +#include "imx952-frdm.dtsi"
diff --git a/arch/arm64/boot/dts/freescale/imx952-frdm.dtsi b/arch/arm64/boot/dts/freescale/imx952-frdm.dtsi new file mode 100644 index 0000000..7785eb1 --- /dev/null +++ b/arch/arm64/boot/dts/freescale/imx952-frdm.dtsi
@@ -0,0 +1,726 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright 2026 NXP + */ + +#include <dt-bindings/usb/pd.h> + +#define BRD_SM_CTRL_SD3_WAKE 0x8000U /*!< PCAL6408A-0 */ +#define BRD_SM_CTRL_M2M_WAKE 0x8003U /*!< PCAL6408A-6 */ +#define BRD_SM_CTRL_BUTTON 0x8004U /*!< PCAL6408A-7 */ + +/ { + compatible = "fsl,imx952-frdm", "fsl,imx952"; + model = "NXP i.MX952 FRDM board"; + + aliases { + gpio0 = &gpio1; + gpio1 = &gpio2; + gpio2 = &gpio3; + gpio3 = &gpio4; + gpio4 = &gpio5; + i2c0 = &lpi2c1; + i2c1 = &lpi2c2; + i2c2 = &lpi2c3; + i2c3 = &lpi2c4; + i2c4 = &lpi2c5; + i2c5 = &lpi2c6; + i2c6 = &lpi2c7; + i2c7 = &lpi2c8; + mmc0 = &usdhc1; + mmc1 = &usdhc2; + serial0 = &lpuart1; + serial4 = &lpuart5; + spi2 = &lpspi3; + }; + + bt_sco_codec: audio-codec-bt-sco { + compatible = "linux,bt-sco"; + #sound-dai-cells = <1>; + }; + + chosen { + stdout-path = &lpuart1; + }; + + dmic: dmic { + compatible = "dmic-codec"; + #sound-dai-cells = <0>; + num-channels = <2>; + }; + + flexcan2_phy: can-phy0 { + compatible = "nxp,tja1051"; + #phy-cells = <0>; + max-bitrate = <8000000>; + silent-gpios = <&pcal6416 6 GPIO_ACTIVE_HIGH>; + }; + + flexcan3_phy: can-phy1 { + compatible = "nxp,tja1051"; + #phy-cells = <0>; + max-bitrate = <8000000>; + silent-gpios = <&pcal6416 6 GPIO_ACTIVE_HIGH>; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "+V1.8_SW"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "+V3.3_SW"; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + }; + + reg_5p0v: regulator-5p0v { + compatible = "regulator-fixed"; + regulator-name = "+V5.0_SW"; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + }; + + reg_vref_1v8: regulator-adc-vref { + compatible = "regulator-fixed"; + regulator-name = "vref_1v8"; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + }; + + reg_dummy: regulator-dummy { + compatible = "regulator-fixed"; + regulator-name = "dummy"; + }; + + reg_ext_12v: regulator-ext-12v { + compatible = "regulator-fixed"; + regulator-name = "VCCEXT_12V"; + regulator-max-microvolt = <12000000>; + regulator-min-microvolt = <12000000>; + vin-supply = <®_ext_5v>; + }; + + reg_ext_3v3: regulator-ext-3v3 { + compatible = "regulator-fixed"; + regulator-name = "VCCEXT_3V3"; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + gpio = <&pcal6416 13 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + }; + + reg_ext_5v: regulator-ext-5v { + compatible = "regulator-fixed"; + regulator-name = "VCCEXT_5V"; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + gpio = <&pcal6416 12 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + }; + + reg_m2_pwr: regulator-m2-pwr { + compatible = "regulator-fixed"; + regulator-name = "M.2-power"; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + gpio = <&pcal6416 11 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_usdhc2_vmmc: regulator-usdhc2 { + compatible = "regulator-fixed"; + regulator-name = "VDD_SD2_3V3"; + off-on-delay-us = <12000>; + pinctrl-0 = <&pinctrl_reg_usdhc2_vmmc>; + pinctrl-names = "default"; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + gpio = <&gpio3 7 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reg_usdhc3_vmmc: regulator-usdhc3 { + compatible = "regulator-fixed"; + regulator-name = "WLAN_EN"; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + vin-supply = <®_m2_pwr>; + gpio = <&pcal6416 9 GPIO_ACTIVE_HIGH>; + enable-active-high; + /* + * IW612 wifi chip needs more delay than other wifi chips to complete + * the host interface initialization after power up, otherwise the + * internal state of IW612 may be unstable, resulting in the failure of + * the SDIO3.0 switch voltage. + */ + startup-delay-us = <20000>; + }; + + reg_usb_vbus: regulator-vbus { + compatible = "regulator-fixed"; + regulator-name = "USB_VBUS"; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + gpio = <&pcal6416 15 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + reserved-memory { + ranges; + #address-cells = <2>; + #size-cells = <2>; + + linux_cma: linux,cma { + compatible = "shared-dma-pool"; + alloc-ranges = <0 0x80000000 0 0x7f000000>; + reusable; + size = <0 0x3c000000>; + linux,cma-default; + }; + }; + + sound-bt-sco { + compatible = "simple-audio-card"; + simple-audio-card,bitclock-inversion; + simple-audio-card,bitclock-master = <&btcpu>; + simple-audio-card,format = "dsp_a"; + simple-audio-card,frame-master = <&btcpu>; + simple-audio-card,name = "bt-sco-audio"; + + simple-audio-card,codec { + sound-dai = <&bt_sco_codec 1>; + }; + + btcpu: simple-audio-card,cpu { + dai-tdm-slot-num = <2>; + dai-tdm-slot-width = <16>; + sound-dai = <&sai5>; + }; + }; + + sound-micfil { + compatible = "fsl,imx-audio-card"; + model = "micfil-audio"; + + pri-dai-link { + format = "i2s"; + link-name = "micfil hifi"; + + codec { + sound-dai = <&dmic>; + }; + + cpu { + sound-dai = <&micfil>; + }; + }; + }; + + usdhc3_pwrseq: usdhc3-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&pcal6416 8 GPIO_ACTIVE_LOW>; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0 0x80000000>; + }; +}; + +&adc1 { + vref-supply = <®_vref_1v8>; + status = "okay"; +}; + +&asrc1 { + assigned-clocks = <&scmi_clk IMX952_CLK_AUDIOPLL1_VCO>, + <&scmi_clk IMX952_CLK_AUDIOPLL2_VCO>, + <&scmi_clk IMX952_CLK_AUDIOPLL1>, + <&scmi_clk IMX952_CLK_AUDIOPLL2>, + <&scmi_clk IMX952_CLK_ASRC1>; + assigned-clock-parents = <0>, <0>, <0>, <0>, + <&scmi_clk IMX952_CLK_AUDIOPLL1>; + assigned-clock-rates = <3932160000>, <3612672000>, + <393216000>, <361267200>, <49152000>; + fsl,asrc-rate = <48000>; + status = "okay"; +}; + +&asrc2 { + assigned-clocks = <&scmi_clk IMX952_CLK_AUDIOPLL1_VCO>, + <&scmi_clk IMX952_CLK_AUDIOPLL2_VCO>, + <&scmi_clk IMX952_CLK_AUDIOPLL1>, + <&scmi_clk IMX952_CLK_AUDIOPLL2>, + <&scmi_clk IMX952_CLK_ASRC2>; + assigned-clock-parents = <0>, <0>, <0>, <0>, + <&scmi_clk IMX952_CLK_AUDIOPLL1>; + assigned-clock-rates = <3932160000>, <3612672000>, + <393216000>, <361267200>, <49152000>; + fsl,asrc-rate = <48000>; + status = "okay"; +}; + +&flexcan2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan2>; + phys = <&flexcan2_phy>; + status = "okay"; +}; + +&flexcan3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_flexcan3>; + phys = <&flexcan3_phy>; + status = "okay"; +}; + +&lpi2c2 { + clock-frequency = <400000>; + pinctrl-0 = <&pinctrl_lpi2c2>; + pinctrl-names = "default"; + status = "okay"; + + pcal6416: gpio@20 { + compatible = "nxp,pcal6416"; + reg = <0x20>; + #interrupt-cells = <2>; + interrupt-controller; + interrupt-parent = <&gpio5>; + interrupts = <14 IRQ_TYPE_LEVEL_LOW>; + #gpio-cells = <2>; + gpio-controller; + pinctrl-0 = <&pinctrl_pcal6416>; + pinctrl-names = "default"; + vcc-supply = <®_3p3v>; + + /* When low, select CAN; When high, select gpio. */ + can-gpio-sel-hog { + gpios = <4 GPIO_ACTIVE_HIGH>; + gpio-hog; + output-low; + }; + }; +}; + +&lpi2c4 { + clock-frequency = <400000>; + pinctrl-0 = <&pinctrl_lpi2c4>; + pinctrl-names = "default"; + status = "okay"; + + ptn5110: tcpc@50 { + compatible = "nxp,ptn5110", "tcpci"; + reg = <0x50>; + interrupt-parent = <&gpio5>; + interrupts = <2 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&pinctrl_ptn5110>; + pinctrl-names = "default"; + + typec_con: connector { + compatible = "usb-c-connector"; + data-role = "dual"; + label = "USB-C"; + op-sink-microwatt = <0>; + power-role = "dual"; + self-powered; + sink-pdos = <PDO_FIXED(5000, 0, PDO_FIXED_USB_COMM)>; + source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>; + try-power-role = "sink"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + typec1_dr_sw: endpoint { + remote-endpoint = <&usb1_drd_sw>; + }; + }; + }; + }; + }; +}; + +&lpspi3 { + cs-gpios = <&gpio2 8 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&pinctrl_lpspi3>; + pinctrl-names = "default"; + status = "okay"; +}; + +&lpuart1 { + /* console */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart1>; + status = "okay"; +}; + +&lpuart5 { + /* BT */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_uart5>; + status = "okay"; + + bluetooth { + compatible = "nxp,88w8987-bt"; + }; +}; + +&micfil { + assigned-clocks = <&scmi_clk IMX952_CLK_AUDIOPLL1_VCO>, + <&scmi_clk IMX952_CLK_AUDIOPLL2_VCO>, + <&scmi_clk IMX952_CLK_AUDIOPLL1>, + <&scmi_clk IMX952_CLK_AUDIOPLL2>, + <&scmi_clk IMX952_CLK_PDM>; + assigned-clock-parents = <0>, <0>, <0>, <0>, + <&scmi_clk IMX952_CLK_AUDIOPLL1>; + assigned-clock-rates = <3932160000>, <3612672000>, + <393216000>, <361267200>, <49152000>; + pinctrl-0 = <&pinctrl_pdm>; + pinctrl-1 = <&pinctrl_pdm_sleep>; + pinctrl-names = "default", "sleep"; + status = "okay"; +}; + +&sai5 { + assigned-clocks = <&scmi_clk IMX952_CLK_AUDIOPLL1_VCO>, + <&scmi_clk IMX952_CLK_AUDIOPLL2_VCO>, + <&scmi_clk IMX952_CLK_AUDIOPLL1>, + <&scmi_clk IMX952_CLK_AUDIOPLL2>, + <&scmi_clk IMX952_CLK_SAI5>; + assigned-clock-parents = <0>, <0>, <0>, <0>, <&scmi_clk IMX952_CLK_AUDIOPLL1>; + assigned-clock-rates = <3932160000>, <3612672000>, <393216000>, <361267200>, <12288000>; + #sound-dai-cells = <0>; + pinctrl-0 = <&pinctrl_sai5>; + pinctrl-names = "default"; + fsl,sai-mclk-direction-output; + status = "okay"; +}; + +&scmi_iomuxc { + pinctrl_flexcan2: flexcan2grp { + fsl,pins = < + IMX952_PAD_GPIO_IO25__WAKEUPMIX_TOP_CAN2_TX 0x39e + IMX952_PAD_GPIO_IO27__WAKEUPMIX_TOP_CAN2_RX 0x39e + >; + }; + + pinctrl_flexcan3: flexcan3grp { + fsl,pins = < + IMX952_PAD_CCM_CLKO3__WAKEUPMIX_TOP_CAN3_TX 0x39e + IMX952_PAD_CCM_CLKO4__WAKEUPMIX_TOP_CAN3_RX 0x39e + >; + }; + + pinctrl_lpi2c2: lpi2c2grp { + fsl,pins = < + IMX952_PAD_I2C2_SCL__AONMIX_TOP_LPI2C2_SCL 0x40000b9e + IMX952_PAD_I2C2_SDA__AONMIX_TOP_LPI2C2_SDA 0x40000b9e + >; + }; + + pinctrl_lpi2c4: lpi2c4grp { + fsl,pins = < + IMX952_PAD_GPIO_IO30__WAKEUPMIX_TOP_LPI2C4_SDA 0x40000b9e + IMX952_PAD_GPIO_IO31__WAKEUPMIX_TOP_LPI2C4_SCL 0x40000b9e + >; + }; + + pinctrl_lpspi3: lpspi3grp { + fsl,pins = < + IMX952_PAD_GPIO_IO08__WAKEUPMIX_TOP_GPIO2_IO_8 0x39e + IMX952_PAD_GPIO_IO09__WAKEUPMIX_TOP_LPSPI3_SIN 0x39e + IMX952_PAD_GPIO_IO10__WAKEUPMIX_TOP_LPSPI3_SOUT 0x39e + IMX952_PAD_GPIO_IO11__WAKEUPMIX_TOP_LPSPI3_SCK 0x39e + >; + }; + + pinctrl_pcal6416: pcal6416grp { + fsl,pins = < + IMX952_PAD_GPIO_IO34__WAKEUPMIX_TOP_GPIO5_IO_14 0x31e + >; + }; + + pinctrl_pdm: pdmgrp { + fsl,pins = < + IMX952_PAD_PDM_CLK__AONMIX_TOP_PDM_CLK 0x31e + IMX952_PAD_PDM_BIT_STREAM0__AONMIX_TOP_PDM_BIT_STREAM_0 0x31e + >; + }; + + pinctrl_pdm_sleep: pdmsleepgrp { + fsl,pins = < + IMX952_PAD_PDM_CLK__AONMIX_TOP_GPIO1_IO_8 0x31e + IMX952_PAD_PDM_BIT_STREAM0__AONMIX_TOP_GPIO1_IO_9 0x31e + >; + }; + + pinctrl_ptn5110: ptn5110grp { + fsl,pins = < + IMX952_PAD_XSPI1_DATA2__WAKEUPMIX_TOP_GPIO5_IO_2 0x31e + >; + }; + + pinctrl_reg_usdhc2_vmmc: regusdhc2vmmcgrp { + fsl,pins = < + IMX952_PAD_SD2_RESET_B__WAKEUPMIX_TOP_GPIO3_IO_7 0x31e + >; + }; + + pinctrl_sai5: sai5grp { + fsl,pins = < + IMX952_PAD_XSPI1_DATA4__WAKEUPMIX_TOP_SAI5_TX_DATA_0 0x31e + IMX952_PAD_XSPI1_DATA5__WAKEUPMIX_TOP_SAI5_TX_SYNC 0x31e + IMX952_PAD_XSPI1_DATA6__WAKEUPMIX_TOP_SAI5_TX_BCLK 0x31e + IMX952_PAD_XSPI1_DATA7__WAKEUPMIX_TOP_SAI5_RX_DATA_0 0x31e + >; + }; + + pinctrl_tpm3: tpm3grp { + fsl,pins = < + IMX952_PAD_GPIO_IO04__WAKEUPMIX_TOP_TPM3_CH0 0x51e + IMX952_PAD_GPIO_IO12__WAKEUPMIX_TOP_TPM3_CH2 0x51e + >; + }; + + pinctrl_tpm4: tpm4grp { + fsl,pins = < + IMX952_PAD_GPIO_IO13__WAKEUPMIX_TOP_TPM4_CH2 0x51e + >; + }; + + pinctrl_uart1: uart1grp { + fsl,pins = < + IMX952_PAD_UART1_RXD__AONMIX_TOP_LPUART1_RX 0x31e + IMX952_PAD_UART1_TXD__AONMIX_TOP_LPUART1_TX 0x31e + >; + }; + + pinctrl_uart5: uart5grp { + fsl,pins = < + IMX952_PAD_DAP_TDO_TRACESWO__WAKEUPMIX_TOP_LPUART5_TX 0x31e + IMX952_PAD_DAP_TDI__WAKEUPMIX_TOP_LPUART5_RX 0x31e + IMX952_PAD_DAP_TMS_SWDIO__WAKEUPMIX_TOP_LPUART5_RTS_B 0x31e + IMX952_PAD_DAP_TCLK_SWCLK__WAKEUPMIX_TOP_LPUART5_CTS_B 0x31e + >; + }; + + pinctrl_usdhc1: usdhc1grp { + fsl,pins = < + IMX952_PAD_SD1_CLK__WAKEUPMIX_TOP_USDHC1_CLK 0x158e + IMX952_PAD_SD1_CMD__WAKEUPMIX_TOP_USDHC1_CMD 0x138e + IMX952_PAD_SD1_DATA0__WAKEUPMIX_TOP_USDHC1_DATA0 0x138e + IMX952_PAD_SD1_DATA1__WAKEUPMIX_TOP_USDHC1_DATA1 0x138e + IMX952_PAD_SD1_DATA2__WAKEUPMIX_TOP_USDHC1_DATA2 0x138e + IMX952_PAD_SD1_DATA3__WAKEUPMIX_TOP_USDHC1_DATA3 0x138e + IMX952_PAD_SD1_DATA4__WAKEUPMIX_TOP_USDHC1_DATA4 0x138e + IMX952_PAD_SD1_DATA5__WAKEUPMIX_TOP_USDHC1_DATA5 0x138e + IMX952_PAD_SD1_DATA6__WAKEUPMIX_TOP_USDHC1_DATA6 0x138e + IMX952_PAD_SD1_DATA7__WAKEUPMIX_TOP_USDHC1_DATA7 0x138e + IMX952_PAD_SD1_STROBE__WAKEUPMIX_TOP_USDHC1_STROBE 0x158e + >; + }; + + pinctrl_usdhc1_100mhz: usdhc1-100mhzgrp { + fsl,pins = < + IMX952_PAD_SD1_CLK__WAKEUPMIX_TOP_USDHC1_CLK 0x158e + IMX952_PAD_SD1_CMD__WAKEUPMIX_TOP_USDHC1_CMD 0x138e + IMX952_PAD_SD1_DATA0__WAKEUPMIX_TOP_USDHC1_DATA0 0x138e + IMX952_PAD_SD1_DATA1__WAKEUPMIX_TOP_USDHC1_DATA1 0x138e + IMX952_PAD_SD1_DATA2__WAKEUPMIX_TOP_USDHC1_DATA2 0x138e + IMX952_PAD_SD1_DATA3__WAKEUPMIX_TOP_USDHC1_DATA3 0x138e + IMX952_PAD_SD1_DATA4__WAKEUPMIX_TOP_USDHC1_DATA4 0x138e + IMX952_PAD_SD1_DATA5__WAKEUPMIX_TOP_USDHC1_DATA5 0x138e + IMX952_PAD_SD1_DATA6__WAKEUPMIX_TOP_USDHC1_DATA6 0x138e + IMX952_PAD_SD1_DATA7__WAKEUPMIX_TOP_USDHC1_DATA7 0x138e + IMX952_PAD_SD1_STROBE__WAKEUPMIX_TOP_USDHC1_STROBE 0x158e + >; + }; + + pinctrl_usdhc1_200mhz: usdhc1-200mhzgrp { + fsl,pins = < + IMX952_PAD_SD1_CLK__WAKEUPMIX_TOP_USDHC1_CLK 0x159e + IMX952_PAD_SD1_CMD__WAKEUPMIX_TOP_USDHC1_CMD 0x139e + IMX952_PAD_SD1_DATA0__WAKEUPMIX_TOP_USDHC1_DATA0 0x139e + IMX952_PAD_SD1_DATA1__WAKEUPMIX_TOP_USDHC1_DATA1 0x139e + IMX952_PAD_SD1_DATA2__WAKEUPMIX_TOP_USDHC1_DATA2 0x139e + IMX952_PAD_SD1_DATA3__WAKEUPMIX_TOP_USDHC1_DATA3 0x139e + IMX952_PAD_SD1_DATA4__WAKEUPMIX_TOP_USDHC1_DATA4 0x139e + IMX952_PAD_SD1_DATA5__WAKEUPMIX_TOP_USDHC1_DATA5 0x139e + IMX952_PAD_SD1_DATA6__WAKEUPMIX_TOP_USDHC1_DATA6 0x139e + IMX952_PAD_SD1_DATA7__WAKEUPMIX_TOP_USDHC1_DATA7 0x139e + IMX952_PAD_SD1_STROBE__WAKEUPMIX_TOP_USDHC1_STROBE 0x159e + >; + }; + + pinctrl_usdhc2_gpio: usdhc2gpiogrp { + fsl,pins = < + IMX952_PAD_SD2_CD_B__WAKEUPMIX_TOP_GPIO3_IO_0 0x31e + >; + }; + + pinctrl_usdhc2: usdhc2grp { + fsl,pins = < + IMX952_PAD_SD2_CLK__WAKEUPMIX_TOP_USDHC2_CLK 0x158e + IMX952_PAD_SD2_CMD__WAKEUPMIX_TOP_USDHC2_CMD 0x138e + IMX952_PAD_SD2_DATA0__WAKEUPMIX_TOP_USDHC2_DATA0 0x138e + IMX952_PAD_SD2_DATA1__WAKEUPMIX_TOP_USDHC2_DATA1 0x138e + IMX952_PAD_SD2_DATA2__WAKEUPMIX_TOP_USDHC2_DATA2 0x138e + IMX952_PAD_SD2_DATA3__WAKEUPMIX_TOP_USDHC2_DATA3 0x138e + IMX952_PAD_SD2_VSELECT__WAKEUPMIX_TOP_USDHC2_VSELECT 0x51e + >; + }; + + pinctrl_usdhc2_100mhz: usdhc2-100mhzgrp { + fsl,pins = < + IMX952_PAD_SD2_CLK__WAKEUPMIX_TOP_USDHC2_CLK 0x158e + IMX952_PAD_SD2_CMD__WAKEUPMIX_TOP_USDHC2_CMD 0x138e + IMX952_PAD_SD2_DATA0__WAKEUPMIX_TOP_USDHC2_DATA0 0x138e + IMX952_PAD_SD2_DATA1__WAKEUPMIX_TOP_USDHC2_DATA1 0x138e + IMX952_PAD_SD2_DATA2__WAKEUPMIX_TOP_USDHC2_DATA2 0x138e + IMX952_PAD_SD2_DATA3__WAKEUPMIX_TOP_USDHC2_DATA3 0x138e + IMX952_PAD_SD2_VSELECT__WAKEUPMIX_TOP_USDHC2_VSELECT 0x51e + >; + }; + + pinctrl_usdhc2_200mhz: usdhc2-200mhzgrp { + fsl,pins = < + IMX952_PAD_SD2_CLK__WAKEUPMIX_TOP_USDHC2_CLK 0x158e + IMX952_PAD_SD2_CMD__WAKEUPMIX_TOP_USDHC2_CMD 0x138e + IMX952_PAD_SD2_DATA0__WAKEUPMIX_TOP_USDHC2_DATA0 0x138e + IMX952_PAD_SD2_DATA1__WAKEUPMIX_TOP_USDHC2_DATA1 0x138e + IMX952_PAD_SD2_DATA2__WAKEUPMIX_TOP_USDHC2_DATA2 0x138e + IMX952_PAD_SD2_DATA3__WAKEUPMIX_TOP_USDHC2_DATA3 0x138e + IMX952_PAD_SD2_VSELECT__WAKEUPMIX_TOP_USDHC2_VSELECT 0x51e + >; + }; + + pinctrl_usdhc3: usdhc3grp { + fsl,pins = < + IMX952_PAD_SD3_CLK__WAKEUPMIX_TOP_USDHC3_CLK 0x158e + IMX952_PAD_SD3_CMD__WAKEUPMIX_TOP_USDHC3_CMD 0x138e + IMX952_PAD_SD3_DATA0__WAKEUPMIX_TOP_USDHC3_DATA0 0x138e + IMX952_PAD_SD3_DATA1__WAKEUPMIX_TOP_USDHC3_DATA1 0x138e + IMX952_PAD_SD3_DATA2__WAKEUPMIX_TOP_USDHC3_DATA2 0x138e + IMX952_PAD_SD3_DATA3__WAKEUPMIX_TOP_USDHC3_DATA3 0x138e + >; + }; + + pinctrl_usdhc3_100mhz: usdhc3-100mhzgrp { + fsl,pins = < + IMX952_PAD_SD3_CLK__WAKEUPMIX_TOP_USDHC3_CLK 0x158e + IMX952_PAD_SD3_CMD__WAKEUPMIX_TOP_USDHC3_CMD 0x138e + IMX952_PAD_SD3_DATA0__WAKEUPMIX_TOP_USDHC3_DATA0 0x138e + IMX952_PAD_SD3_DATA1__WAKEUPMIX_TOP_USDHC3_DATA1 0x138e + IMX952_PAD_SD3_DATA2__WAKEUPMIX_TOP_USDHC3_DATA2 0x138e + IMX952_PAD_SD3_DATA3__WAKEUPMIX_TOP_USDHC3_DATA3 0x138e + >; + }; + + pinctrl_usdhc3_200mhz: usdhc3-200mhzgrp { + fsl,pins = < + IMX952_PAD_SD3_CLK__WAKEUPMIX_TOP_USDHC3_CLK 0x158e + IMX952_PAD_SD3_CMD__WAKEUPMIX_TOP_USDHC3_CMD 0x138e + IMX952_PAD_SD3_DATA0__WAKEUPMIX_TOP_USDHC3_DATA0 0x138e + IMX952_PAD_SD3_DATA1__WAKEUPMIX_TOP_USDHC3_DATA1 0x138e + IMX952_PAD_SD3_DATA2__WAKEUPMIX_TOP_USDHC3_DATA2 0x138e + IMX952_PAD_SD3_DATA3__WAKEUPMIX_TOP_USDHC3_DATA3 0x138e + >; + }; +}; + +&scmi_misc { + nxp,ctrl-ids = <BRD_SM_CTRL_SD3_WAKE 1 + BRD_SM_CTRL_M2M_WAKE 1 + BRD_SM_CTRL_BUTTON 1>; +}; + +&tpm3 { + pinctrl-0 = <&pinctrl_tpm3>; + pinctrl-names = "default"; + status = "okay"; +}; + +&tpm4 { + pinctrl-0 = <&pinctrl_tpm4>; + pinctrl-names = "default"; + status = "okay"; +}; + +&usb1 { + adp-disable; + disable-over-current; + dr_mode = "otg"; + hnp-disable; + srp-disable; + usb-role-switch; + samsung,picophy-dc-vol-level-adjust = <7>; + samsung,picophy-pre-emp-curr-control = <3>; + status = "okay"; + + port { + usb1_drd_sw: endpoint { + remote-endpoint = <&typec1_dr_sw>; + }; + }; +}; + +&usb2 { + disable-over-current; + dr_mode = "host"; + vbus-supply = <®_usb_vbus>; + status = "okay"; +}; + +&usdhc1 { + bus-width = <8>; + non-removable; + no-sd; + no-sdio; + pinctrl-0 = <&pinctrl_usdhc1>; + pinctrl-1 = <&pinctrl_usdhc1_100mhz>; + pinctrl-2 = <&pinctrl_usdhc1_200mhz>; + pinctrl-3 = <&pinctrl_usdhc1>; + pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; + status = "okay"; +}; + +&usdhc2 { + bus-width = <4>; + cd-gpios = <&gpio3 0 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-1 = <&pinctrl_usdhc2_100mhz>, <&pinctrl_usdhc2_gpio>; + pinctrl-2 = <&pinctrl_usdhc2_200mhz>, <&pinctrl_usdhc2_gpio>; + pinctrl-3 = <&pinctrl_usdhc2>, <&pinctrl_usdhc2_gpio>; + pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; + vmmc-supply = <®_usdhc2_vmmc>; + status = "okay"; +}; + +&usdhc3 { + bus-width = <4>; + keep-power-in-suspend; + mmc-pwrseq = <&usdhc3_pwrseq>; + non-removable; + pinctrl-0 = <&pinctrl_usdhc3>; + pinctrl-1 = <&pinctrl_usdhc3_100mhz>; + pinctrl-2 = <&pinctrl_usdhc3_200mhz>; + pinctrl-3 = <&pinctrl_usdhc3>; + pinctrl-names = "default", "state_100mhz", "state_200mhz", "sleep"; + vmmc-supply = <®_usdhc3_vmmc>; + wakeup-source; + status = "okay"; +}; + +&wdog3 { + fsl,ext-reset-output; + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/freescale/imx952.dtsi b/arch/arm64/boot/dts/freescale/imx952.dtsi index 020de00..1154b66 100644 --- a/arch/arm64/boot/dts/freescale/imx952.dtsi +++ b/arch/arm64/boot/dts/freescale/imx952.dtsi
@@ -261,6 +261,14 @@ scmi_misc: protocol@84 { }; }; + mqs1: mqs1 { + compatible = "fsl,imx95-aonmix-mqs"; + clocks = <&scmi_clk IMX952_CLK_SAI1>; + clock-names = "mclk"; + #sound-dai-cells = <0>; + status = "disabled"; + }; + gic: interrupt-controller@48000000 { compatible = "arm,gic-v3"; reg = <0 0x48000000 0 0x10000>, @@ -323,19 +331,16 @@ gpu_opp_table: opp-table { opp-500000000 { opp-hz = /bits/ 64 <500000000>; - opp-hz-real = /bits/ 64 <500000000>; opp-microvolt = <920000>; }; opp-800000000 { opp-hz = /bits/ 64 <800000000>; - opp-hz-real = /bits/ 64 <800000000>; opp-microvolt = <920000>; }; opp-1000000000 { opp-hz = /bits/ 64 <1000000000>; - opp-hz-real = /bits/ 64 <1000000000>; opp-microvolt = <920000>; }; }; @@ -1164,7 +1169,7 @@ lpi2c1: i2c@44340000 { clock-names = "per", "ipg"; #address-cells = <1>; #size-cells = <0>; - dmas = <&edma1 12 0 0>, <&edma1 13 0 FSL_EDMA_RX> ; + dmas = <&edma1 12 0 0>, <&edma1 13 0 FSL_EDMA_RX>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -1178,7 +1183,7 @@ lpi2c2: i2c@44350000 { clock-names = "per", "ipg"; #address-cells = <1>; #size-cells = <0>; - dmas = <&edma1 14 0 0>, <&edma1 15 0 FSL_EDMA_RX> ; + dmas = <&edma1 14 0 0>, <&edma1 15 0 FSL_EDMA_RX>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -1192,7 +1197,7 @@ lpspi1: spi@44360000 { clock-names = "per", "ipg"; #address-cells = <1>; #size-cells = <0>; - dmas = <&edma1 16 0 FSL_EDMA_RX>, <&edma1 17 0 0> ; + dmas = <&edma1 16 0 FSL_EDMA_RX>, <&edma1 17 0 0>; dma-names = "tx", "rx"; status = "disabled"; }; @@ -1206,7 +1211,7 @@ lpspi2: spi@44370000 { clock-names = "per", "ipg"; #address-cells = <1>; #size-cells = <0>; - dmas = <&edma1 18 0 FSL_EDMA_RX>, <&edma1 19 0 0> ; + dmas = <&edma1 18 0 FSL_EDMA_RX>, <&edma1 19 0 0>; dma-names = "tx", "rx"; status = "disabled"; };
diff --git a/arch/arm64/boot/dts/freescale/s32g2.dtsi b/arch/arm64/boot/dts/freescale/s32g2.dtsi index 996494e..a7e5977 100644 --- a/arch/arm64/boot/dts/freescale/s32g2.dtsi +++ b/arch/arm64/boot/dts/freescale/s32g2.dtsi
@@ -14,7 +14,7 @@ / { #address-cells = <2>; #size-cells = <2>; - reserved-memory { + reserved-memory { #address-cells = <2>; #size-cells = <2>; ranges;
diff --git a/arch/arm64/boot/dts/freescale/s32g3.dtsi b/arch/arm64/boot/dts/freescale/s32g3.dtsi index 31f7aad..0770af6 100644 --- a/arch/arm64/boot/dts/freescale/s32g3.dtsi +++ b/arch/arm64/boot/dts/freescale/s32g3.dtsi
@@ -153,7 +153,7 @@ pmu { interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_HIGH>; }; - reserved-memory { + reserved-memory { #address-cells = <2>; #size-cells = <2>; ranges;
diff --git a/arch/arm64/boot/dts/google/Makefile b/arch/arm64/boot/dts/google/Makefile new file mode 100644 index 0000000..4e833b2 --- /dev/null +++ b/arch/arm64/boot/dts/google/Makefile
@@ -0,0 +1,6 @@ +# SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) + +dtb-$(CONFIG_ARCH_GOOGLE) += \ + lga-blazer.dtb \ + lga-frankel.dtb \ + lga-mustang.dtb
diff --git a/arch/arm64/boot/dts/google/lga-blazer.dts b/arch/arm64/boot/dts/google/lga-blazer.dts new file mode 100644 index 0000000..089460662 --- /dev/null +++ b/arch/arm64/boot/dts/google/lga-blazer.dts
@@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Blazer Device Tree (Pixel 10 Pro) + * + * Copyright 2021-2023 Google LLC + */ + +/dts-v1/; + +#include "lga-pixel-common.dtsi" + +/ { + model = "Blazer"; + compatible = "google,lga-blazer", "google,lga"; +};
diff --git a/arch/arm64/boot/dts/google/lga-frankel.dts b/arch/arm64/boot/dts/google/lga-frankel.dts new file mode 100644 index 0000000..7504222 --- /dev/null +++ b/arch/arm64/boot/dts/google/lga-frankel.dts
@@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Frankel Device Tree (Pixel 10) + * + * Copyright 2021-2023 Google LLC + */ + +/dts-v1/; + +#include "lga-pixel-common.dtsi" + +/ { + model = "Frankel"; + compatible = "google,lga-frankel", "google,lga"; +};
diff --git a/arch/arm64/boot/dts/google/lga-mustang.dts b/arch/arm64/boot/dts/google/lga-mustang.dts new file mode 100644 index 0000000..6ac0b5e --- /dev/null +++ b/arch/arm64/boot/dts/google/lga-mustang.dts
@@ -0,0 +1,15 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Mustang Device Tree (Pixel 10 Pro XL) + * + * Copyright 2021-2023 Google LLC + */ + +/dts-v1/; + +#include "lga-pixel-common.dtsi" + +/ { + model = "Mustang"; + compatible = "google,lga-mustang", "google,lga"; +};
diff --git a/arch/arm64/boot/dts/google/lga-pixel-common.dtsi b/arch/arm64/boot/dts/google/lga-pixel-common.dtsi new file mode 100644 index 0000000..5aaa2e5 --- /dev/null +++ b/arch/arm64/boot/dts/google/lga-pixel-common.dtsi
@@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Google Pixel 10 family common dtsi. + * + * Copyright 2024-2025 Google LLC. + */ + +#include "lga.dtsi" + +/ { + aliases { + serial0 = &lsion_cli16_uart; + }; + + chosen { + stdout-path = "serial0"; + }; +}; + +&osc { + clock-frequency = <38400000>; +};
diff --git a/arch/arm64/boot/dts/google/lga.dtsi b/arch/arm64/boot/dts/google/lga.dtsi new file mode 100644 index 0000000..3e670e5 --- /dev/null +++ b/arch/arm64/boot/dts/google/lga.dtsi
@@ -0,0 +1,411 @@ +// SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause +/* + * Google Tensor G5 (laguna) SoC rev B0 + * + * Copyright 2024-2025 Google LLC. + */ + +/dts-v1/; + +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&gic>; + + osc: clock-38400000 { + compatible = "fixed-clock"; + #clock-cells = <0>; + }; + + cpus: cpus { + #address-cells = <1>; + #size-cells = <0>; + + hayes_0: cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a520"; + reg = <0x000>; + + #cooling-cells = <2>; + capacity-dmips-mhz = <258>; + enable-method = "psci"; + power-domains = <&cpu_pd0>; + power-domain-names = "psci"; + }; + + hayes_1: cpu@100 { + device_type = "cpu"; + compatible = "arm,cortex-a520"; + reg = <0x100>; + + #cooling-cells = <2>; + capacity-dmips-mhz = <258>; + enable-method = "psci"; + power-domains = <&cpu_pd1>; + power-domain-names = "psci"; + }; + + hunter_0: cpu@200 { + device_type = "cpu"; + compatible = "arm,cortex-a725"; + reg = <0x200>; + + #cooling-cells = <2>; + capacity-dmips-mhz = <891>; + enable-method = "psci"; + power-domains = <&cpu_pd2>; + power-domain-names = "psci"; + }; + + hunter_1: cpu@300 { + device_type = "cpu"; + compatible = "arm,cortex-a725"; + reg = <0x300>; + + #cooling-cells = <2>; + capacity-dmips-mhz = <891>; + enable-method = "psci"; + power-domains = <&cpu_pd3>; + power-domain-names = "psci"; + }; + + hunter_2: cpu@400 { + device_type = "cpu"; + compatible = "arm,cortex-a725"; + reg = <0x400>; + + #cooling-cells = <2>; + capacity-dmips-mhz = <891>; + enable-method = "psci"; + power-domains = <&cpu_pd4>; + power-domain-names = "psci"; + }; + + hunter_3: cpu@500 { + device_type = "cpu"; + compatible = "arm,cortex-a725"; + reg = <0x500>; + + #cooling-cells = <2>; + capacity-dmips-mhz = <891>; + enable-method = "psci"; + power-domains = <&cpu_pd5>; + power-domain-names = "psci"; + }; + + hunter_4: cpu@600 { + device_type = "cpu"; + compatible = "arm,cortex-a725"; + reg = <0x600>; + + #cooling-cells = <2>; + capacity-dmips-mhz = <891>; + enable-method = "psci"; + power-domains = <&cpu_pd6>; + power-domain-names = "psci"; + }; + + hunterelp_0: cpu@700 { + device_type = "cpu"; + compatible = "arm,cortex-x4"; + reg = <0x700>; + + #cooling-cells = <2>; + capacity-dmips-mhz = <1024>; + enable-method = "psci"; + power-domains = <&cpu_pd7>; + power-domain-names = "psci"; + }; + + cpu-map { + cluster0 { + core0 { + cpu = <&hayes_0>; + }; + + core1 { + cpu = <&hayes_1>; + }; + + core2 { + cpu = <&hunter_0>; + }; + + core3 { + cpu = <&hunter_1>; + }; + + core4 { + cpu = <&hunter_2>; + }; + + core5 { + cpu = <&hunter_3>; + }; + + core6 { + cpu = <&hunter_4>; + }; + + core7 { + cpu = <&hunterelp_0>; + }; + }; + }; + + domain-idle-states { + cluster_1_c3: cluster-1-c3 { + compatible = "domain-idle-state"; + + entry-latency-us = <325>; + exit-latency-us = <553>; + min-residency-us = <10000>; + + idle-state-name = "cluster-1-c3"; + + arm,psci-suspend-param = <0x40010033>; + }; + + cluster_2_c3: cluster-2-c3 { + compatible = "domain-idle-state"; + + entry-latency-us = <345>; + exit-latency-us = <673>; + min-residency-us = <10000>; + + idle-state-name = "cluster-2-c3"; + + arm,psci-suspend-param = <0x40010033>; + }; + + cluster_c4_deep: cluster-c4-deep { + compatible = "domain-idle-state"; + + entry-latency-us = <510>; + exit-latency-us = <1027>; + min-residency-us = <10000>; + + idle-state-name = "cluster-c4-deep"; + + arm,psci-suspend-param = <0x40020333>; + }; + }; + + idle-states { + entry-method = "psci"; + + cpu_big_c2: cpu-big-c2 { + compatible = "arm,idle-state"; + + entry-latency-us = <110>; + exit-latency-us = <413>; + min-residency-us = <3950>; + + idle-state-name = "cpu-big-c2"; + local-timer-stop; + + arm,psci-suspend-param = <0x40000003>; + }; + + cpu_lit_c2: cpu-lit-c2 { + compatible = "arm,idle-state"; + + entry-latency-us = <132>; + exit-latency-us = <296>; + min-residency-us = <3610>; + + idle-state-name = "cpu-lit-c2"; + local-timer-stop; + + arm,psci-suspend-param = <0x40000003>; + }; + + cpu_mid1_c2: cpu-mid1-c2 { + compatible = "arm,idle-state"; + + entry-latency-us = <130>; + exit-latency-us = <274>; + min-residency-us = <2720>; + + idle-state-name = "cpu-mid1-c2"; + local-timer-stop; + + arm,psci-suspend-param = <0x40000003>; + }; + + cpu_mid2_c2: cpu-mid2-c2 { + compatible = "arm,idle-state"; + + entry-latency-us = <130>; + exit-latency-us = <274>; + min-residency-us = <2720>; + + idle-state-name = "cpu-mid2-c2"; + local-timer-stop; + + arm,psci-suspend-param = <0x40000003>; + }; + }; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + + cpucl1: power-domain-cluster-1 { + #power-domain-cells = <0>; + domain-idle-states = <&cluster_1_c3>; + power-domains = <&cpu_top_cl>; + }; + + cpucl2: power-domain-cluster-2 { + #power-domain-cells = <0>; + domain-idle-states = <&cluster_2_c3>; + power-domains = <&cpu_top_cl>; + }; + + cpu_pd0: power-domain-cpu0 { + #power-domain-cells = <0>; + domain-idle-states = <&cpu_lit_c2>; + power-domains = <&cpu_top_cl>; + }; + + cpu_pd1: power-domain-cpu1 { + #power-domain-cells = <0>; + domain-idle-states = <&cpu_lit_c2>; + power-domains = <&cpu_top_cl>; + }; + + cpu_pd2: power-domain-cpu2 { + #power-domain-cells = <0>; + domain-idle-states = <&cpu_mid1_c2>; + power-domains = <&cpucl1>; + }; + + cpu_pd3: power-domain-cpu3 { + #power-domain-cells = <0>; + domain-idle-states = <&cpu_mid1_c2>; + power-domains = <&cpucl1>; + }; + + cpu_pd4: power-domain-cpu4 { + #power-domain-cells = <0>; + domain-idle-states = <&cpu_mid1_c2>; + power-domains = <&cpucl1>; + }; + + cpu_pd5: power-domain-cpu5 { + #power-domain-cells = <0>; + domain-idle-states = <&cpu_mid2_c2>; + power-domains = <&cpucl2>; + }; + + cpu_pd6: power-domain-cpu6 { + #power-domain-cells = <0>; + domain-idle-states = <&cpu_mid2_c2>; + power-domains = <&cpucl2>; + }; + + cpu_pd7: power-domain-cpu7 { + #power-domain-cells = <0>; + domain-idle-states = <&cpu_big_c2>; + power-domains = <&cpucl2>; + }; + + cpu_top_cl: power-domain-top-cluster { + #power-domain-cells = <0>; + domain-idle-states = <&cluster_c4_deep>; + }; + }; + + reserved_memory: reserved-memory { + ranges; + #address-cells = <2>; + #size-cells = <2>; + + /* + * Store ramoops at a known location in DRAM, for access by the + * ABL following a crash-reset. + */ + ramoops@95200000 { + compatible = "ramoops"; + reg = <0x0 0x95200000 0x0 0x400000>; + console-size = <0x200000>; + pmsg-size = <0x200000>; + }; + + /* bootloader logs */ + bldr_log_reserved: bldr-log-reserved@95600000 { + reg = <0x0 0x95600000 0x0 0x100000>; + no-map; + }; + + /* gsa logs */ + gsa_reserved_log: gsa-reserved-log@a61b0000 { + reg = <0x0 0xa61b0000 0x0 0x00004000>; + no-map; + }; + + /* Android BootLoader (ABL) for ramdump/coredump processing */ + abl@be000000 { + reg = <0x0 0xbe000000 0x0 0x1000000>; + no-map; + }; + }; + + soc: soc@0 { + compatible = "simple-bus"; + ranges = <0x0 0x0 0x0 0x0 0x10 0x0>; + + dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>; + + #address-cells = <2>; + #size-cells = <2>; + + gic: interrupt-controller@5880000 { + compatible = "arm,gic-v3"; + reg = <0x0 0x05880000 0x0 0x10000>, + <0x0 0x05900000 0x0 0x200000>; + + #address-cells = <0>; + #interrupt-cells = <4>; + interrupt-controller; + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH 0>; + + ppi-partitions { + ppi_cluster0: interrupt-partition-0 { + affinity = <&hayes_0 &hayes_1 + &hunter_0 &hunter_1 &hunter_2 + &hunter_3 &hunter_4>; + }; + + ppi_cluster1: interrupt-partition-1 { + affinity = <&hunterelp_0>; + }; + }; + }; + + lsion_cli16_uart: serial@db62000 { + compatible = "google,lga-uart", "snps,dw-apb-uart"; + reg = <0x0 0x0db62000 0x0 0x100>; + + clock-frequency = <200000000>; + interrupts = <GIC_SPI 688 IRQ_TYPE_LEVEL_HIGH 0>; + reg-io-width = <4>; + reg-shift = <2>; + + status = "disabled"; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW 0>, + <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW 0>, + <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW 0>, + <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW 0>; + }; +};
diff --git a/arch/arm64/boot/dts/hisilicon/hip07.dtsi b/arch/arm64/boot/dts/hisilicon/hip07.dtsi index 00a6bfa..d175e24 100644 --- a/arch/arm64/boot/dts/hisilicon/hip07.dtsi +++ b/arch/arm64/boot/dts/hisilicon/hip07.dtsi
@@ -1113,74 +1113,6 @@ mbigen_usb: intc_usb { num-pins = <2>; }; }; - p0_mbigen_alg_a:interrupt-controller@d0080000 { - compatible = "hisilicon,mbigen-v2"; - reg = <0x0 0xd0080000 0x0 0x10000>; - - p0_mbigen_sec_a: intc_sec { - msi-parent = <&p0_its_dsa_a 0x40400>; - interrupt-controller; - #interrupt-cells = <2>; - num-pins = <33>; - }; - p0_mbigen_smmu_alg_a: intc_smmu_alg { - msi-parent = <&p0_its_dsa_a 0x40b1b>; - interrupt-controller; - #interrupt-cells = <2>; - num-pins = <3>; - }; - }; - p0_mbigen_alg_b:interrupt-controller@8,d0080000 { - compatible = "hisilicon,mbigen-v2"; - reg = <0x8 0xd0080000 0x0 0x10000>; - - p0_mbigen_sec_b: intc_sec { - msi-parent = <&p0_its_dsa_b 0x42400>; - interrupt-controller; - #interrupt-cells = <2>; - num-pins = <33>; - }; - p0_mbigen_smmu_alg_b: intc_smmu_alg { - msi-parent = <&p0_its_dsa_b 0x42b1b>; - interrupt-controller; - #interrupt-cells = <2>; - num-pins = <3>; - }; - }; - p1_mbigen_alg_a:interrupt-controller@400,d0080000 { - compatible = "hisilicon,mbigen-v2"; - reg = <0x400 0xd0080000 0x0 0x10000>; - - p1_mbigen_sec_a: intc_sec { - msi-parent = <&p1_its_dsa_a 0x44400>; - interrupt-controller; - #interrupt-cells = <2>; - num-pins = <33>; - }; - p1_mbigen_smmu_alg_a: intc_smmu_alg { - msi-parent = <&p1_its_dsa_a 0x44b1b>; - interrupt-controller; - #interrupt-cells = <2>; - num-pins = <3>; - }; - }; - p1_mbigen_alg_b:interrupt-controller@408,d0080000 { - compatible = "hisilicon,mbigen-v2"; - reg = <0x408 0xd0080000 0x0 0x10000>; - - p1_mbigen_sec_b: intc_sec { - msi-parent = <&p1_its_dsa_b 0x46400>; - interrupt-controller; - #interrupt-cells = <2>; - num-pins = <33>; - }; - p1_mbigen_smmu_alg_b: intc_smmu_alg { - msi-parent = <&p1_its_dsa_b 0x46b1b>; - interrupt-controller; - #interrupt-cells = <2>; - num-pins = <3>; - }; - }; p0_mbigen_dsa_a: interrupt-controller@c0080000 { compatible = "hisilicon,mbigen-v2"; reg = <0x0 0xc0080000 0x0 0x10000>; @@ -1237,54 +1169,6 @@ smmu0: iommu@a0040000 { hisilicon,broken-prefetch-cmd; status = "disabled"; }; - p0_smmu_alg_a: iommu@d0040000 { - compatible = "arm,smmu-v3"; - reg = <0x0 0xd0040000 0x0 0x20000>; - interrupt-parent = <&p0_mbigen_smmu_alg_a>; - interrupts = <733 1>, - <734 1>, - <735 1>; - interrupt-names = "eventq", "gerror", "priq"; - #iommu-cells = <1>; - dma-coherent; - hisilicon,broken-prefetch-cmd; - }; - p0_smmu_alg_b: iommu@8d0040000 { - compatible = "arm,smmu-v3"; - reg = <0x8 0xd0040000 0x0 0x20000>; - interrupt-parent = <&p0_mbigen_smmu_alg_b>; - interrupts = <733 1>, - <734 1>, - <735 1>; - interrupt-names = "eventq", "gerror", "priq"; - #iommu-cells = <1>; - dma-coherent; - hisilicon,broken-prefetch-cmd; - }; - p1_smmu_alg_a: iommu@400d0040000 { - compatible = "arm,smmu-v3"; - reg = <0x400 0xd0040000 0x0 0x20000>; - interrupt-parent = <&p1_mbigen_smmu_alg_a>; - interrupts = <733 1>, - <734 1>, - <735 1>; - interrupt-names = "eventq", "gerror", "priq"; - #iommu-cells = <1>; - dma-coherent; - hisilicon,broken-prefetch-cmd; - }; - p1_smmu_alg_b: iommu@408d0040000 { - compatible = "arm,smmu-v3"; - reg = <0x408 0xd0040000 0x0 0x20000>; - interrupt-parent = <&p1_mbigen_smmu_alg_b>; - interrupts = <733 1>, - <734 1>, - <735 1>; - interrupt-names = "eventq", "gerror", "priq"; - #iommu-cells = <1>; - dma-coherent; - hisilicon,broken-prefetch-cmd; - }; soc { compatible = "simple-bus"; @@ -1745,170 +1629,6 @@ p0_pcie2_a: pcie@af800000 { 0x0 0 0 4 &mbigen_pcie2_a 671 4>; status = "disabled"; }; - p0_sec_a: crypto@d0000000 { - compatible = "hisilicon,hip07-sec"; - reg = <0x0 0xd0000000 0x0 0x10000>, - <0x0 0xd2000000 0x0 0x10000>, - <0x0 0xd2010000 0x0 0x10000>, - <0x0 0xd2020000 0x0 0x10000>, - <0x0 0xd2030000 0x0 0x10000>, - <0x0 0xd2040000 0x0 0x10000>, - <0x0 0xd2050000 0x0 0x10000>, - <0x0 0xd2060000 0x0 0x10000>, - <0x0 0xd2070000 0x0 0x10000>, - <0x0 0xd2080000 0x0 0x10000>, - <0x0 0xd2090000 0x0 0x10000>, - <0x0 0xd20a0000 0x0 0x10000>, - <0x0 0xd20b0000 0x0 0x10000>, - <0x0 0xd20c0000 0x0 0x10000>, - <0x0 0xd20d0000 0x0 0x10000>, - <0x0 0xd20e0000 0x0 0x10000>, - <0x0 0xd20f0000 0x0 0x10000>, - <0x0 0xd2100000 0x0 0x10000>; - interrupt-parent = <&p0_mbigen_sec_a>; - iommus = <&p0_smmu_alg_a 0x600>; - dma-coherent; - interrupts = <576 4>, - <577 1>, <578 4>, - <579 1>, <580 4>, - <581 1>, <582 4>, - <583 1>, <584 4>, - <585 1>, <586 4>, - <587 1>, <588 4>, - <589 1>, <590 4>, - <591 1>, <592 4>, - <593 1>, <594 4>, - <595 1>, <596 4>, - <597 1>, <598 4>, - <599 1>, <600 4>, - <601 1>, <602 4>, - <603 1>, <604 4>, - <605 1>, <606 4>, - <607 1>, <608 4>; - }; - p0_sec_b: crypto@8d0000000 { - compatible = "hisilicon,hip07-sec"; - reg = <0x8 0xd0000000 0x0 0x10000>, - <0x8 0xd2000000 0x0 0x10000>, - <0x8 0xd2010000 0x0 0x10000>, - <0x8 0xd2020000 0x0 0x10000>, - <0x8 0xd2030000 0x0 0x10000>, - <0x8 0xd2040000 0x0 0x10000>, - <0x8 0xd2050000 0x0 0x10000>, - <0x8 0xd2060000 0x0 0x10000>, - <0x8 0xd2070000 0x0 0x10000>, - <0x8 0xd2080000 0x0 0x10000>, - <0x8 0xd2090000 0x0 0x10000>, - <0x8 0xd20a0000 0x0 0x10000>, - <0x8 0xd20b0000 0x0 0x10000>, - <0x8 0xd20c0000 0x0 0x10000>, - <0x8 0xd20d0000 0x0 0x10000>, - <0x8 0xd20e0000 0x0 0x10000>, - <0x8 0xd20f0000 0x0 0x10000>, - <0x8 0xd2100000 0x0 0x10000>; - interrupt-parent = <&p0_mbigen_sec_b>; - iommus = <&p0_smmu_alg_b 0x600>; - dma-coherent; - interrupts = <576 4>, - <577 1>, <578 4>, - <579 1>, <580 4>, - <581 1>, <582 4>, - <583 1>, <584 4>, - <585 1>, <586 4>, - <587 1>, <588 4>, - <589 1>, <590 4>, - <591 1>, <592 4>, - <593 1>, <594 4>, - <595 1>, <596 4>, - <597 1>, <598 4>, - <599 1>, <600 4>, - <601 1>, <602 4>, - <603 1>, <604 4>, - <605 1>, <606 4>, - <607 1>, <608 4>; - }; - p1_sec_a: crypto@400d0000000 { - compatible = "hisilicon,hip07-sec"; - reg = <0x400 0xd0000000 0x0 0x10000>, - <0x400 0xd2000000 0x0 0x10000>, - <0x400 0xd2010000 0x0 0x10000>, - <0x400 0xd2020000 0x0 0x10000>, - <0x400 0xd2030000 0x0 0x10000>, - <0x400 0xd2040000 0x0 0x10000>, - <0x400 0xd2050000 0x0 0x10000>, - <0x400 0xd2060000 0x0 0x10000>, - <0x400 0xd2070000 0x0 0x10000>, - <0x400 0xd2080000 0x0 0x10000>, - <0x400 0xd2090000 0x0 0x10000>, - <0x400 0xd20a0000 0x0 0x10000>, - <0x400 0xd20b0000 0x0 0x10000>, - <0x400 0xd20c0000 0x0 0x10000>, - <0x400 0xd20d0000 0x0 0x10000>, - <0x400 0xd20e0000 0x0 0x10000>, - <0x400 0xd20f0000 0x0 0x10000>, - <0x400 0xd2100000 0x0 0x10000>; - interrupt-parent = <&p1_mbigen_sec_a>; - iommus = <&p1_smmu_alg_a 0x600>; - dma-coherent; - interrupts = <576 4>, - <577 1>, <578 4>, - <579 1>, <580 4>, - <581 1>, <582 4>, - <583 1>, <584 4>, - <585 1>, <586 4>, - <587 1>, <588 4>, - <589 1>, <590 4>, - <591 1>, <592 4>, - <593 1>, <594 4>, - <595 1>, <596 4>, - <597 1>, <598 4>, - <599 1>, <600 4>, - <601 1>, <602 4>, - <603 1>, <604 4>, - <605 1>, <606 4>, - <607 1>, <608 4>; - }; - p1_sec_b: crypto@408d0000000 { - compatible = "hisilicon,hip07-sec"; - reg = <0x408 0xd0000000 0x0 0x10000>, - <0x408 0xd2000000 0x0 0x10000>, - <0x408 0xd2010000 0x0 0x10000>, - <0x408 0xd2020000 0x0 0x10000>, - <0x408 0xd2030000 0x0 0x10000>, - <0x408 0xd2040000 0x0 0x10000>, - <0x408 0xd2050000 0x0 0x10000>, - <0x408 0xd2060000 0x0 0x10000>, - <0x408 0xd2070000 0x0 0x10000>, - <0x408 0xd2080000 0x0 0x10000>, - <0x408 0xd2090000 0x0 0x10000>, - <0x408 0xd20a0000 0x0 0x10000>, - <0x408 0xd20b0000 0x0 0x10000>, - <0x408 0xd20c0000 0x0 0x10000>, - <0x408 0xd20d0000 0x0 0x10000>, - <0x408 0xd20e0000 0x0 0x10000>, - <0x408 0xd20f0000 0x0 0x10000>, - <0x408 0xd2100000 0x0 0x10000>; - interrupt-parent = <&p1_mbigen_sec_b>; - iommus = <&p1_smmu_alg_b 0x600>; - dma-coherent; - interrupts = <576 4>, - <577 1>, <578 4>, - <579 1>, <580 4>, - <581 1>, <582 4>, - <583 1>, <584 4>, - <585 1>, <586 4>, - <587 1>, <588 4>, - <589 1>, <590 4>, - <591 1>, <592 4>, - <593 1>, <594 4>, - <595 1>, <596 4>, - <597 1>, <598 4>, - <599 1>, <600 4>, - <601 1>, <602 4>, - <603 1>, <604 4>, - <605 1>, <606 4>, - <607 1>, <608 4>; - }; }; };
diff --git a/arch/arm64/boot/dts/marvell/Makefile b/arch/arm64/boot/dts/marvell/Makefile index 09d1544..3e301c8 100644 --- a/arch/arm64/boot/dts/marvell/Makefile +++ b/arch/arm64/boot/dts/marvell/Makefile
@@ -32,6 +32,7 @@ dtb-$(CONFIG_ARCH_MVEBU) += ac5-98dx35xx-rd.dtb dtb-$(CONFIG_ARCH_MVEBU) += cn9130-cf-base.dtb dtb-$(CONFIG_ARCH_MVEBU) += cn9130-cf-pro.dtb +dtb-$(CONFIG_ARCH_MVEBU) += cn9130-sophos-xgs107w.dtb dtb-$(CONFIG_ARCH_MVEBU) += cn9131-cf-solidwan.dtb dtb-$(CONFIG_ARCH_MVEBU) += cn9132-clearfog.dtb
diff --git a/arch/arm64/boot/dts/marvell/cn9130-sophos-xgs107w.dts b/arch/arm64/boot/dts/marvell/cn9130-sophos-xgs107w.dts new file mode 100644 index 0000000..da6a1da --- /dev/null +++ b/arch/arm64/boot/dts/marvell/cn9130-sophos-xgs107w.dts
@@ -0,0 +1,188 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device tree for the network processing unit (NPU) of the Sophos XGS 87/107 + * firewalls: a Marvell CN9130 SoC with a Marvell 88E6193X switch. + * + * The x86 host on the same board is not described here. + */ + +/dts-v1/; + +#include "cn9130.dtsi" +#include <dt-bindings/gpio/gpio.h> + +/ { + model = "Sophos XGS 107w (CN9130 NPU)"; + compatible = "sophos,xgs107w-npu", "marvell,cn9130"; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + aliases { + ethernet0 = &cp0_eth0; + i2c1 = &cp0_i2c1; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x0 0x80000000>; + }; + + reserved-memory { + /* OP-TEE, reserved by the firmware */ + tee@4400000 { + reg = <0x0 0x4400000 0x0 0x1000000>; + no-map; + }; + }; + + /* Front-panel SFP cage "F1", wired to switch port 9 */ + sfp: sfp { + compatible = "sff,sfp"; + i2c-bus = <&cp0_i2c1>; + los-gpios = <&cp0_gpio1 1 GPIO_ACTIVE_HIGH>; + tx-fault-gpios = <&cp0_gpio1 2 GPIO_ACTIVE_HIGH>; + mod-def0-gpios = <&cp0_gpio1 3 GPIO_ACTIVE_LOW>; + tx-disable-gpios = <&cp0_gpio1 7 GPIO_ACTIVE_HIGH>; + }; +}; + +&uart0 { + status = "okay"; +}; + +/* eMMC on the AP */ +&ap_sdhci0 { + bus-width = <8>; + non-removable; + mmc-ddr-1_8v; + status = "okay"; +}; + +/* + * The MPP pin muxing is left as configured by the boot loader; the pin + * controller node only exists to back the GPIO banks. + */ +&cp0_syscon0 { + cp0_pinctrl: pinctrl { + compatible = "marvell,cp115-standalone-pinctrl"; + }; +}; + +&cp0_i2c1 { + /* I2C bus of the SFP cage */ + clock-frequency = <100000>; + status = "okay"; +}; + +/* 4 MB SPI NOR with U-Boot and its environment, read-only on purpose */ +&cp0_spi0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <40000000>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "u-boot"; + reg = <0x0 0x3f0000>; + read-only; + }; + + partition@3f0000 { + label = "u-boot-env"; + reg = <0x3f0000 0x10000>; + read-only; + }; + }; + }; +}; + +&cp0_ethernet { + status = "okay"; +}; + +/* 10G link to switch port 0 */ +&cp0_eth0 { + phy-mode = "10gbase-r"; + phys = <&cp0_comphy4 0>; + managed = "in-band-status"; + status = "okay"; +}; + +&cp0_mdio { + status = "okay"; + + switch@2 { + compatible = "marvell,mv88e6190"; + reg = <2>; + reset-gpios = <&cp0_gpio2 17 GPIO_ACTIVE_LOW>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + ethernet = <&cp0_eth0>; + phy-mode = "10gbase-r"; + managed = "in-band-status"; + }; + + port@1 { + reg = <1>; + label = "p1"; + }; + + port@2 { + reg = <2>; + label = "p2"; + }; + + port@3 { + reg = <3>; + label = "p3"; + }; + + port@4 { + reg = <4>; + label = "p4"; + }; + + port@5 { + reg = <5>; + label = "p5"; + }; + + port@6 { + reg = <6>; + label = "p6"; + }; + + port@7 { + reg = <7>; + label = "p7"; + }; + + port@8 { + reg = <8>; + label = "p8"; + }; + + port@9 { + reg = <9>; + label = "sfp"; + phy-mode = "1000base-x"; + managed = "in-band-status"; + sfp = <&sfp>; + }; + }; + }; +};
diff --git a/arch/arm64/boot/dts/mediatek/mt6878-pinfunc.h b/arch/arm64/boot/dts/mediatek/mt6878-pinfunc.h index 4e8e475..5aeceb9 100644 --- a/arch/arm64/boot/dts/mediatek/mt6878-pinfunc.h +++ b/arch/arm64/boot/dts/mediatek/mt6878-pinfunc.h
@@ -9,7 +9,7 @@ #ifndef __MT6878_PINFUNC_H #define __MT6878_PINFUNC_H -#include "mt65xx.h" +#include <dt-bindings/pinctrl/mt65xx.h> #define PINMUX_GPIO0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) #define PINMUX_GPIO0__FUNC_TP_GPIO0_AO (MTK_PIN_NO(0) | 1)
diff --git a/arch/arm64/boot/dts/mediatek/mt6893-pinfunc.h b/arch/arm64/boot/dts/mediatek/mt6893-pinfunc.h index 982bc95..7cda5c7 100644 --- a/arch/arm64/boot/dts/mediatek/mt6893-pinfunc.h +++ b/arch/arm64/boot/dts/mediatek/mt6893-pinfunc.h
@@ -7,7 +7,7 @@ #ifndef __MT6893_PINFUNC_H #define __MT6893_PINFUNC_H -#include "mt65xx.h" +#include <dt-bindings/pinctrl/mt65xx.h> #define PINMUX_GPIO0__FUNC_GPIO0 (MTK_PIN_NO(0) | 0) #define PINMUX_GPIO0__FUNC_SPI6_CLK (MTK_PIN_NO(0) | 1)
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts index 637e556..70c693f 100644 --- a/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts +++ b/arch/arm64/boot/dts/mediatek/mt7986a-bananapi-bpi-r3.dts
@@ -140,6 +140,19 @@ sfp2: sfp-2 { tx-disable-gpios = <&pio 15 GPIO_ACTIVE_HIGH>; tx-fault-gpios = <&pio 48 GPIO_ACTIVE_HIGH>; }; + + reserved-memory { + ramoops@42ff0000 { + compatible = "ramoops"; + reg = <0 0x42ff0000 0 0x10000>; + no-map; + record-size = <0x2000>; + console-size = <0x8000>; + ftrace-size = <0x2000>; + pmsg-size = <0x2000>; + ecc-size = <16>; + }; + }; }; &cpu_thermal {
diff --git a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi index 9ebc196..318639a 100644 --- a/arch/arm64/boot/dts/mediatek/mt7986a.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt7986a.dtsi
@@ -657,6 +657,7 @@ cpu_trip_active_low: active-low { timer { compatible = "arm,armv8-timer"; interrupt-parent = <&gic>; + clock-frequency = <12986200>; interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>,
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn13.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn13.dtso index 973b76b..e9c322d 100644 --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn13.dtso +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn13.dtso
@@ -16,5 +16,6 @@ / { }; &{/soc/pinctrl@1001f000/pcie-2-hog} { + line-name = "pcie2-cn13-hog"; output-high; };
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn14.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn14.dtso index 90b2a64..9d8de73 100644 --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn14.dtso +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn14.dtso
@@ -16,5 +16,6 @@ / { }; &{/soc/pinctrl@1001f000/pcie-3-hog} { + line-name = "pcie3-cn14-hog"; output-high; };
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn15.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn15.dtso index 9750916..57ee7da 100644 --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn15.dtso +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn15.dtso
@@ -16,5 +16,6 @@ / { }; &{/soc/pinctrl@1001f000/pcie-2-hog} { + line-name = "pcie2-cn15-hog"; output-low; };
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn18.dtso b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn18.dtso index 9830fb0..7830980 100644 --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn18.dtso +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro-cn18.dtso
@@ -16,5 +16,6 @@ / { }; &{/soc/pinctrl@1001f000/pcie-3-hog} { + line-name = "pcie3-cn18-hog"; output-low; };
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro.dtsi index 1eeb721..f54787f 100644 --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4-pro.dtsi
@@ -315,6 +315,24 @@ pca9555: i2c-gpio-expander@20 { reg = <0x20>; gpio-controller; #gpio-cells = <2>; + + gpio-line-names = + "BKEY-A-PDN", /* GPIO0 */ + "BKEY-A-Vset", /* GPIO1 */ + "BKEY-B-PDN", /* GPIO2 */ + "BKEY-B-Vset", /* GPIO3 */ + "BKEY-C-PDN", /* GPIO4 */ + "BKEY-C-Vset", /* GPIO5 */ + "SIM_SEL", /* GPIO6 */ + "mPCIe_AB_Vset",/* GPIO7 */ + "mPCIe_A_PDN", /* GPIO8 */ + "mPCIe_B_PDN", /* GPIO9 */ + "BKEY-A-RST", /* GPIO10 */ + "VBUS_AB_PDN", /* GPIO11 */ + "BKEY-B-RST", /* GPIO12 */ + "BKEY-C-RST", /* GPIO13 */ + "SYS_LEDB", /* GPIO14 */ + "SYS_LEDR"; /* GPIO15 */ }; rtc@51 {
diff --git a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi index 0ff69da..75f5940 100644 --- a/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt7988a-bananapi-bpi-r4.dtsi
@@ -66,6 +66,19 @@ reg_3p3v: regulator-3p3v { regulator-always-on; }; + reserved-memory { + ramoops@42f00000 { + compatible = "ramoops"; + reg = <0 0x42f00000 0 0x100000>; + no-map; + record-size = <0x20000>; + console-size = <0x40000>; + ftrace-size = <0x10000>; + pmsg-size = <0x10000>; + ecc-size = <16>; + }; + }; + /* SFP1 cage (WAN) */ sfp1: sfp1 { compatible = "sff,sfp";
diff --git a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi index a0573bc..777da21 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173-elm.dtsi
@@ -16,6 +16,11 @@ aliases { mmc2 = &mmc3; }; + firmware { + #address-cells = <2>; + #size-cells = <2>; + }; + memory@40000000 { device_type = "memory"; reg = <0 0x40000000 0 0x80000000>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8173.dtsi b/arch/arm64/boot/dts/mediatek/mt8173.dtsi index 7f1af15..2ecdea33 100644 --- a/arch/arm64/boot/dts/mediatek/mt8173.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8173.dtsi
@@ -507,7 +507,7 @@ power-domain@MT8173_POWER_DOMAIN_USB { }; mfg_async: power-domain@MT8173_POWER_DOMAIN_MFG_ASYNC { reg = <MT8173_POWER_DOMAIN_MFG_ASYNC>; - clocks = <&clk26m>; + clocks = <&topckgen CLK_TOP_AXI_MFG_IN_SEL>; clock-names = "mfg"; #address-cells = <1>; #size-cells = <0>; @@ -1004,6 +1004,37 @@ u2port1: usb-phy@11291000 { }; }; + gpu: gpu@13000000 { + compatible = "mediatek,mt8173-gpu", "img,img-gx6250", + "img,img-rogue"; + reg = <0 0x13000000 0 0x10000>; + interrupts = <GIC_SPI 217 IRQ_TYPE_LEVEL_LOW>; + clocks = <&mfgtop CLK_MFG_G3D>, + <&mfgtop CLK_MFG_MEM>, + <&mfgtop CLK_MFG_AXI>; + clock-names = "core", "mem", "sys"; + /* + * Binding and GPU core HW have two power domain + * inputs, but MediaTek does not have information + * on how this is done internally. + */ + power-domains = <&mfgtop>, <&mfgtop>; + power-domain-names = "a", "b"; + }; + + mfgtop: clock-controller@13fff000 { + compatible = "mediatek,mt8173-mfgtop"; + reg = <0 0x13fff000 0 0x1000>; + clocks = <&topckgen CLK_TOP_AXI_MFG_IN_SEL>, + <&topckgen CLK_TOP_MEM_MFG_IN_SEL>, + <&topckgen CLK_TOP_MFG_SEL>, + <&clk26m>; + clock-names = "sys", "mem", "core", "clk26m"; + power-domains = <&spm MT8173_POWER_DOMAIN_MFG>; + #clock-cells = <1>; + #power-domain-cells = <0>; + }; + mmsys: syscon@14000000 { compatible = "mediatek,mt8173-mmsys", "syscon"; reg = <0 0x14000000 0 0x1000>; @@ -1293,7 +1324,7 @@ mutex: mutex@14020000 { clocks = <&mmsys CLK_MM_MUTEX_32K>; mediatek,gce-client-reg = <&gce SUBSYS_1402XXXX 0 0x1000>; mediatek,gce-events = <CMDQ_EVENT_MUTEX0_STREAM_EOF>, - <CMDQ_EVENT_MUTEX1_STREAM_EOF>; + <CMDQ_EVENT_MUTEX1_STREAM_EOF>; }; larb0: larb@14021000 {
diff --git a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi index 69cab9f..acd5f59 100644 --- a/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8183-kukui.dtsi
@@ -22,6 +22,11 @@ chosen { stdout-path = "serial0:115200n8"; }; + firmware { + #address-cells = <2>; + #size-cells = <2>; + }; + backlight_lcd0: backlight_lcd0 { compatible = "pwm-backlight"; pwms = <&pwm0 0 500000>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi index ff20376..2b327d9 100644 --- a/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8186-corsola.dtsi
@@ -26,6 +26,11 @@ chosen { stdout-path = "serial0:115200n8"; }; + firmware { + #address-cells = <2>; + #size-cells = <2>; + }; + memory@40000000 { device_type = "memory"; /* The size should be filled in by the bootloader. */
diff --git a/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi b/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi index f382f90..801eee7 100644 --- a/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8188-geralt.dtsi
@@ -41,6 +41,11 @@ dmic-codec { wakeup-delay-ms = <100>; }; + firmware { + #address-cells = <2>; + #size-cells = <2>; + }; + memory@40000000 { device_type = "memory"; /* The size will be filled in by the bootloader */ @@ -166,7 +171,7 @@ reserved_memory: reserved-memory { scp_mem_reserved: memory@50000000 { compatible = "shared-dma-pool"; - reg = <0 0x50000000 0 0x800000>; + reg = <0 0x50000000 0 0x900000>; no-map; };
diff --git a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi index 40d34b1..e8ebbb7 100644 --- a/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8192-asurada.dtsi
@@ -25,6 +25,11 @@ chosen { stdout-path = "serial0:115200n8"; }; + firmware { + #address-cells = <2>; + #size-cells = <2>; + }; + memory@40000000 { device_type = "memory"; reg = <0 0x40000000 0 0x80000000>;
diff --git a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi index ef7afc4..f06ca2b 100644 --- a/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi +++ b/arch/arm64/boot/dts/mediatek/mt8195-cherry.dtsi
@@ -42,6 +42,11 @@ dmic-codec { wakeup-delay-ms = <50>; }; + firmware { + #address-cells = <2>; + #size-cells = <2>; + }; + memory@40000000 { device_type = "memory"; reg = <0 0x40000000 0 0x80000000>;
diff --git a/arch/arm64/boot/dts/microchip/lan9696-ev23x71a.dts b/arch/arm64/boot/dts/microchip/lan9696-ev23x71a.dts index 4012ea7..a7b4be1 100644 --- a/arch/arm64/boot/dts/microchip/lan9696-ev23x71a.dts +++ b/arch/arm64/boot/dts/microchip/lan9696-ev23x71a.dts
@@ -463,6 +463,19 @@ phy27: phy@27 { }; }; +&qspi0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <100000000>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <4>; + m25p,fast-read; + }; +}; + &serdes { status = "okay"; };
diff --git a/arch/arm64/boot/dts/nuvoton/nuvoton-common-npcm8xx.dtsi b/arch/arm64/boot/dts/nuvoton/nuvoton-common-npcm8xx.dtsi index 545034a..4d1f8b93 100644 --- a/arch/arm64/boot/dts/nuvoton/nuvoton-common-npcm8xx.dtsi +++ b/arch/arm64/boot/dts/nuvoton/nuvoton-common-npcm8xx.dtsi
@@ -4,6 +4,7 @@ #include <dt-bindings/clock/nuvoton,npcm845-clk.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/gpio/gpio.h> / { #address-cells = <2>; @@ -35,6 +36,11 @@ gic: interrupt-controller@dfff9000 { }; }; + udc0_phy: usb-phy { + compatible = "usb-nop-xceiv"; + #phy-cells = <0>; + }; + ahb { #address-cells = <2>; #size-cells = <2>; @@ -51,13 +57,258 @@ clk: rstc: reset-controller@f0801000 { #clock-cells = <1>; }; - apb { + gmac1: ethernet@f0804000 { + device_type = "network"; + compatible = "snps,dwmac-3.72a", "snps,dwmac"; + reg = <0x0 0xf0804000 0x0 0x2000>; + interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "macirq"; + clocks = <&clk NPCM8XX_CLK_AHB>; + clock-names = "stmmaceth"; + pinctrl-names = "default"; + pinctrl-0 = <&rg2_pins + &rg2mdio_pins>; + status = "disabled"; + }; + + gmac2: ethernet@f0806000 { + device_type = "network"; + compatible = "snps,dwmac-3.72a", "snps,dwmac"; + reg = <0x0 0xf0806000 0x0 0x2000>; + interrupts = <GIC_SPI 16 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "macirq"; + clocks = <&clk NPCM8XX_CLK_AHB>; + clock-names = "stmmaceth"; + pinctrl-names = "default"; + pinctrl-0 = <&r1_pins + &r1err_pins + &r1md_pins>; + status = "disabled"; + }; + + gmac3: ethernet@f0808000 { + device_type = "network"; + compatible = "snps,dwmac-3.72a", "snps,dwmac"; + reg = <0x0 0xf0808000 0x0 0x2000>; + interrupts = <GIC_SPI 17 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "macirq"; + clocks = <&clk NPCM8XX_CLK_AHB>; + clock-names = "stmmaceth"; + pinctrl-names = "default"; + pinctrl-0 = <&r2_pins + &r2err_pins + &r2md_pins>; + status = "disabled"; + }; + + mc: memory-controller@f0824000 { + compatible = "nuvoton,npcm845-memory-controller"; + reg = <0x0 0xf0824000 0x0 0x1000>; + interrupts = <GIC_SPI 25 IRQ_TYPE_LEVEL_HIGH>; + }; + + udc0: usb@f0830000 { + compatible = "nuvoton,npcm845-udc", "nuvoton,npcm750-udc"; + reg = <0x0 0xf0830000 0x0 0x1000 + 0x0 0xfffeb000 0x0 0x800>; + interrupts = <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM8XX_CLK_SU>; + clock-names = "clk_usb_bridge"; + + phys = <&udc0_phy>; + phy_type = "utmi_wide"; + dr_mode = "peripheral"; + status = "disabled"; + }; + + udc1: usb@f0831000 { + compatible = "nuvoton,npcm845-udc", "nuvoton,npcm750-udc"; + reg = <0x0 0xf0831000 0x0 0x1000 + 0x0 0xfffeb800 0x0 0x800>; + interrupts = <GIC_SPI 52 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM8XX_CLK_SU>; + clock-names = "clk_usb_bridge"; + + phys = <&udc0_phy>; + phy_type = "utmi_wide"; + dr_mode = "peripheral"; + status = "disabled"; + }; + + udc2: usb@f0832000 { + compatible = "nuvoton,npcm845-udc", "nuvoton,npcm750-udc"; + reg = <0x0 0xf0832000 0x0 0x1000 + 0x0 0xfffec000 0x0 0x800>; + interrupts = <GIC_SPI 53 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM8XX_CLK_SU>; + clock-names = "clk_usb_bridge"; + + phys = <&udc0_phy>; + phy_type = "utmi_wide"; + dr_mode = "peripheral"; + status = "disabled"; + }; + + udc3: usb@f0833000 { + compatible = "nuvoton,npcm845-udc", "nuvoton,npcm750-udc"; + reg = <0x0 0xf0833000 0x0 0x1000 + 0x0 0xfffec800 0x0 0x800>; + interrupts = <GIC_SPI 54 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM8XX_CLK_SU>; + clock-names = "clk_usb_bridge"; + + phys = <&udc0_phy>; + phy_type = "utmi_wide"; + dr_mode = "peripheral"; + status = "disabled"; + }; + + udc4: usb@f0834000 { + compatible = "nuvoton,npcm845-udc", "nuvoton,npcm750-udc"; + reg = <0x0 0xf0834000 0x0 0x1000 + 0x0 0xfffed000 0x0 0x800>; + interrupts = <GIC_SPI 55 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM8XX_CLK_SU>; + clock-names = "clk_usb_bridge"; + + phys = <&udc0_phy>; + phy_type = "utmi_wide"; + dr_mode = "peripheral"; + status = "disabled"; + }; + + udc5: usb@f0835000 { + compatible = "nuvoton,npcm845-udc", "nuvoton,npcm750-udc"; + reg = <0x0 0xf0835000 0x0 0x1000 + 0x0 0xfffed800 0x0 0x800>; + interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM8XX_CLK_SU>; + clock-names = "clk_usb_bridge"; + + phys = <&udc0_phy>; + phy_type = "utmi_wide"; + dr_mode = "peripheral"; + status = "disabled"; + }; + + udc6: usb@f0836000 { + compatible = "nuvoton,npcm845-udc", "nuvoton,npcm750-udc"; + reg = <0x0 0xf0836000 0x0 0x1000 + 0x0 0xfffee000 0x0 0x800>; + interrupts = <GIC_SPI 57 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM8XX_CLK_SU>; + clock-names = "clk_usb_bridge"; + + phys = <&udc0_phy>; + phy_type = "utmi_wide"; + dr_mode = "peripheral"; + status = "disabled"; + }; + + udc7: usb@f0837000 { + compatible = "nuvoton,npcm845-udc", "nuvoton,npcm750-udc"; + reg = <0x0 0xf0837000 0x0 0x1000 + 0x0 0xfffee800 0x0 0x800>; + interrupts = <GIC_SPI 58 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM8XX_CLK_SU>; + clock-names = "clk_usb_bridge"; + + phys = <&udc0_phy>; + phy_type = "utmi_wide"; + dr_mode = "peripheral"; + status = "disabled"; + }; + + udc8: usb@f0838000 { + compatible = "nuvoton,npcm845-udc", "nuvoton,npcm750-udc"; + reg = <0x0 0xf0838000 0x0 0x1000 + 0x0 0xfffef000 0x0 0x800>; + interrupts = <GIC_SPI 59 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM8XX_CLK_SU>; + clock-names = "clk_usb_bridge"; + + phys = <&udc0_phy>; + phy_type = "utmi_wide"; + dr_mode = "peripheral"; + status = "disabled"; + }; + + udc9: usb@f0839000 { + compatible = "nuvoton,npcm845-udc", "nuvoton,npcm750-udc"; + reg = <0x0 0xf0839000 0x0 0x1000 + 0x0 0xfffef800 0x0 0x800>; + interrupts = <GIC_SPI 60 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM8XX_CLK_SU>; + clock-names = "clk_usb_bridge"; + + phys = <&udc0_phy>; + phy_type = "utmi_wide"; + dr_mode = "peripheral"; + status = "disabled"; + }; + + sdhci: mmc@f0842000 { + compatible = "nuvoton,npcm845-sdhci"; + reg = <0x0 0xf0842000 0x0 0x100>; + interrupts = <GIC_SPI 26 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM8XX_CLK_AHB>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc8_pins + &mmc_pins>; + status = "disabled"; + }; + + fiu0: spi@fb000000 { + compatible = "nuvoton,npcm845-fiu"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0xfb000000 0x0 0x1000>; + reg-names = "control"; + clocks = <&clk NPCM8XX_CLK_SPI0>; + status = "disabled"; + }; + + fiu1: spi@fb002000 { + compatible = "nuvoton,npcm845-fiu"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0xfb002000 0x0 0x1000>; + reg-names = "control"; + clocks = <&clk NPCM8XX_CLK_SPI1>; + pinctrl-names = "default"; + pinctrl-0 = <&spi1_pins>; + status = "disabled"; + }; + + fiu3: spi@c0000000 { + compatible = "nuvoton,npcm845-fiu"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0xc0000000 0x0 0x1000>; + reg-names = "control"; + clocks = <&clk NPCM8XX_CLK_SPI3>; + pinctrl-names = "default"; + pinctrl-0 = <&spi3_pins>; + status = "disabled"; + }; + + fiux: spi@fb001000 { + compatible = "nuvoton,npcm845-fiu"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0 0xfb001000 0x0 0x1000>, + <0x0 0xf8000000 0x0 0x2000000>; + reg-names = "control", "memory"; + clocks = <&clk NPCM8XX_CLK_SPIX>; + status = "disabled"; + }; + + apb@f0000000 { #address-cells = <1>; #size-cells = <1>; compatible = "simple-bus"; interrupt-parent = <&gic>; - ranges = <0x0 0x0 0xf0000000 0x00300000>, - <0xfff00000 0x0 0xfff00000 0x00016000>; + ranges = <0x0 0x0 0xf0000000 0x00300000>; serial0: serial@0 { compatible = "nuvoton,npcm845-uart", "nuvoton,npcm750-uart"; @@ -153,6 +404,245 @@ watchdog2: watchdog@a01c { clocks = <&refclk>; }; + rng: rng@b000 { + compatible = "nuvoton,npcm845-rng"; + reg = <0xb000 0x8>; + status = "disabled"; + }; + + adc: adc@c000 { + compatible = "nuvoton,npcm845-adc"; + reg = <0xC000 0x8>; + interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM8XX_CLK_ADC>; + resets = <&rstc 0x20 27>; + status = "disabled"; + }; + + i2c0: i2c@80000 { + reg = <0x80000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb0_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c1: i2c@81000 { + reg = <0x81000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb1_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c2: i2c@82000 { + reg = <0x82000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb2_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c3: i2c@83000 { + reg = <0x83000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb3_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c4: i2c@84000 { + reg = <0x84000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb4_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c5: i2c@85000 { + reg = <0x85000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb5_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c6: i2c@86000 { + reg = <0x86000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb6_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c7: i2c@87000 { + reg = <0x87000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb7_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c8: i2c@88000 { + reg = <0x88000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb8_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c9: i2c@89000 { + reg = <0x89000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb9_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c10: i2c@8a000 { + reg = <0x8a000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb10_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c11: i2c@8b000 { + reg = <0x8b000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb11_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c12: i2c@8c000 { + reg = <0x8c000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb12_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c13: i2c@8d000 { + reg = <0x8d000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb13_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c14: i2c@8e000 { + reg = <0x8e000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb14_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c15: i2c@8f000 { + reg = <0x8f000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb15_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + peci: peci-controller@100000 { compatible = "nuvoton,npcm845-peci"; reg = <0x100000 0x1000>; @@ -161,6 +651,210 @@ peci: peci-controller@100000 { cmd-timeout-ms = <1000>; status = "disabled"; }; + + pwm_fan:pwm-fan-controller@103000 { + compatible = "nuvoton,npcm845-pwm-fan"; + reg = <0x103000 0x3000>, + <0x180000 0x8000>; + reg-names = "pwm", "fan"; + clocks = <&clk NPCM8XX_CLK_APB3>, + <&clk NPCM8XX_CLK_APB4>; + clock-names = "pwm","fan"; + interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 102 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pins &pwm1_pins + &pwm2_pins &pwm3_pins + &pwm4_pins &pwm5_pins + &pwm6_pins &pwm7_pins + &pwm8_pins &pwm9_pins + &pwm10_pins &pwm11_pins + &fanin0_pins &fanin1_pins + &fanin2_pins &fanin3_pins + &fanin4_pins &fanin5_pins + &fanin6_pins &fanin7_pins + &fanin8_pins &fanin9_pins + &fanin10_pins &fanin11_pins + &fanin12_pins &fanin13_pins + &fanin14_pins &fanin15_pins>; + status = "disabled"; + }; + + pspi: spi@201000 { + compatible = "nuvoton,npcm845-pspi"; + reg = <0x201000 0x1000>; + pinctrl-names = "default"; + pinctrl-0 = <&pspi_pins>; + #address-cells = <1>; + #size-cells = <0>; + interrupts = <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clk NPCM8XX_CLK_APB5>; + clock-names = "clk_apb5"; + resets = <&rstc 0x24 23>; + status = "disabled"; + }; + }; + + apb@fff00000 { + #address-cells = <1>; + #size-cells = <1>; + compatible = "simple-bus"; + interrupt-parent = <&gic>; + ranges = <0xfff00000 0x0 0xfff00000 0x00016000>; + + i2c16: i2c@0 { + reg = <0x0 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb16_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c17: i2c@1000 { + reg = <0x1000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb17_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c18: i2c@2000 { + reg = <0x2000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb18_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c19: i2c@3000 { + reg = <0x3000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb19_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c20: i2c@4000 { + reg = <0x4000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb20_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c21: i2c@5000 { + reg = <0x5000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb21_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c22: i2c@6000 { + reg = <0x6000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb22_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c23: i2c@7000 { + reg = <0x7000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&smb23_pins>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c24: i2c@8000 { + reg = <0x8000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c25: i2c@9000 { + reg = <0x9000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; + + i2c26: i2c@a000 { + reg = <0xa000 0x1000>; + compatible = "nuvoton,npcm845-i2c"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clk NPCM8XX_CLK_APB2>; + clock-frequency = <100000>; + interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>; + nuvoton,sys-mgr = <&gcr>; + status = "disabled"; + }; }; };
diff --git a/arch/arm64/boot/dts/nuvoton/nuvoton-npcm845-evb.dts b/arch/arm64/boot/dts/nuvoton/nuvoton-npcm845-evb.dts index 5edf5d1..ed6bdcf 100644 --- a/arch/arm64/boot/dts/nuvoton/nuvoton-npcm845-evb.dts +++ b/arch/arm64/boot/dts/nuvoton/nuvoton-npcm845-evb.dts
@@ -5,10 +5,46 @@ #include "nuvoton-npcm845.dtsi" / { - model = "Nuvoton npcm845 Development Board (Device Tree)"; compatible = "nuvoton,npcm845-evb", "nuvoton,npcm845"; + model = "Nuvoton npcm845 Development Board (Device Tree)"; aliases { + ethernet1 = &gmac1; + ethernet2 = &gmac2; + ethernet3 = &gmac3; + fiu0 = &fiu0; + fiu1 = &fiu3; + fiu2 = &fiux; + fiu3 = &fiu1; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &i2c8; + i2c9 = &i2c9; + i2c10 = &i2c10; + i2c11 = &i2c11; + i2c12 = &i2c12; + i2c13 = &i2c13; + i2c14 = &i2c14; + i2c15 = &i2c15; + i2c16 = &i2c16; + i2c17 = &i2c17; + i2c18 = &i2c18; + i2c19 = &i2c19; + i2c20 = &i2c20; + i2c21 = &i2c21; + i2c22 = &i2c22; + i2c23 = &i2c23; + i2c24 = &i2c24; + i2c25 = &i2c25; + i2c26 = &i2c26; + mdio-gpio0 = &mdio0; + mdio-gpio1 = &mdio1; serial0 = &serial0; }; @@ -16,6 +52,30 @@ chosen { stdout-path = &serial0; }; + mdio0: mdio-0 { + compatible = "virtual,mdio-gpio"; + #address-cells = <1>; + gpios = <&gpio1 25 GPIO_ACTIVE_HIGH>, + <&gpio1 26 GPIO_ACTIVE_HIGH>; + #size-cells = <0>; + + phy0: ethernet-phy@0 { + reg = <0>; + }; + }; + + mdio1: mdio-1 { + compatible = "virtual,mdio-gpio"; + #address-cells = <1>; + gpios = <&gpio2 27 GPIO_ACTIVE_HIGH>, + <&gpio2 28 GPIO_ACTIVE_HIGH>; + #size-cells = <0>; + + phy1: ethernet-phy@0 { + reg = <0>; + }; + }; + memory@0 { device_type = "memory"; reg = <0x0 0x0 0x0 0x40000000>; @@ -23,15 +83,390 @@ memory@0 { refclk: refclk-25mhz { compatible = "fixed-clock"; - clock-frequency = <25000000>; #clock-cells = <0>; + clock-frequency = <25000000>; }; + + reserved-memory { + ranges; + #address-cells = <2>; + #size-cells = <2>; + + tip@0 { + reg = <0x0 0x0 0x0 0x6200000>; + no-map; + }; + }; +}; + +&gmac1 { + phy-mode = "rgmii-id"; + + status = "okay"; +}; + +&gmac2 { + phy-handle = <&phy0>; + phy-mode = "rmii"; + pinctrl-0 = <&r1_pins + &r1oen_pins>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&gmac3 { + phy-handle = <&phy1>; + phy-mode = "rmii"; + pinctrl-0 = <&r2_pins + &r2oen_pins>; + pinctrl-names = "default"; + + status = "okay"; }; &serial0 { status = "okay"; }; +&fiu0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <5000000>; + spi-rx-bus-width = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + bmc@0 { + compatible = "fixed-partitions"; + reg = <0x00000000 0x04000000>; + #address-cells = <1>; + label = "bmc"; + #size-cells = <1>; + + u-boot@0 { + reg = <0x00000000 0x007c0000>; + label = "u-boot"; + }; + + u-boot-env@7c0000 { + reg = <0x007c0000 0x00040000>; + label = "u-boot-env"; + }; + + kernel@800000 { + reg = <0x00800000 0x00800000>; + label = "kernel"; + }; + + rofs@1000000 { + reg = <0x01000000 0x02c00000>; + label = "rofs"; + }; + + rwfs@3c00000 { + reg = <0x03c00000 0x00400000>; + label = "rwfs"; + }; + }; + }; + }; +}; + +&fiu1 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <5000000>; + spi-rx-bus-width = <2>; + spi-tx-bus-width = <2>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + reg = <0x0 0x0>; + label = "spi1-system1"; + }; + }; + }; +}; + +&fiu3 { + pinctrl-0 = <&spi3_pins>, <&spi3quad_pins>; + pinctrl-names = "default"; + + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <5000000>; + spi-rx-bus-width = <1>; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + reg = <0x0 0x0>; + label = "spi3-system1"; + }; + }; + }; +}; + +&fiux { + nuvoton,spix-mode; + + status = "okay"; +}; + +&sdhci { + status = "okay"; +}; + +&udc0 { + status = "okay"; +}; + +&udc1 { + status = "okay"; +}; + +&udc2 { + status = "okay"; +}; + +&udc3 { + status = "okay"; +}; + +&udc4 { + status = "okay"; +}; + +&udc5 { + status = "okay"; +}; + +&udc6 { + status = "okay"; +}; + +&udc7 { + status = "okay"; +}; + +&mc { + status = "okay"; +}; + +&peci { + status = "okay"; +}; + +&rng { + status = "okay"; +}; + +&adc { + #io-channel-cells = <1>; + + status = "okay"; +}; + &watchdog1 { status = "okay"; }; + +&pwm_fan { + #address-cells = <1>; + pinctrl-0 = <&pwm0_pins &pwm1_pins + &pwm2_pins &pwm3_pins + &pwm4_pins &pwm5_pins + &pwm6_pins &pwm7_pins + &fanin0_pins &fanin1_pins + &fanin2_pins &fanin3_pins + &fanin4_pins &fanin5_pins + &fanin6_pins &fanin7_pins>; + pinctrl-names = "default"; + #size-cells = <0>; + + status = "okay"; + + fan@0 { + reg = <0x00>; + cooling-levels = <127 255>; + fan-tach-ch = /bits/ 8 <0x0 0x1>; + }; + + fan@1 { + reg = <0x01>; + cooling-levels = <127 255>; + fan-tach-ch = /bits/ 8 <0x2 0x3>; + }; + + fan@2 { + reg = <0x02>; + cooling-levels = <127 255>; + fan-tach-ch = /bits/ 8 <0x4 0x5>; + }; + + fan@3 { + reg = <0x03>; + cooling-levels = <127 255>; + fan-tach-ch = /bits/ 8 <0x6 0x7>; + }; + + fan@4 { + reg = <0x04>; + cooling-levels = <127 255>; + fan-tach-ch = /bits/ 8 <0x8 0x9>; + }; + + fan@5 { + reg = <0x05>; + cooling-levels = <127 255>; + fan-tach-ch = /bits/ 8 <0xa 0xb>; + }; + + fan@6 { + reg = <0x06>; + cooling-levels = <127 255>; + fan-tach-ch = /bits/ 8 <0xc 0xd>; + }; + + fan@7 { + reg = <0x07>; + cooling-levels = <127 255>; + fan-tach-ch = /bits/ 8 <0xe 0xf>; + }; +}; + +&i2c0 { + status = "okay"; +}; + +&i2c1 { + #address-cells = <1>; + #size-cells = <0>; + + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c256"; + reg = <0x50>; + }; +}; + +&i2c2 { + status = "okay"; +}; + +&i2c3 { + status = "okay"; +}; + +&i2c4 { + status = "okay"; +}; + +&i2c5 { + status = "okay"; +}; + +&i2c6 { + status = "okay"; +}; + +&i2c7 { + status = "okay"; +}; + +&i2c8 { + status = "okay"; +}; + +&i2c9 { + status = "okay"; +}; + +&i2c10 { + status = "okay"; +}; + +&i2c11 { + status = "okay"; +}; + +&i2c12 { + status = "okay"; +}; + +&i2c13 { + status = "okay"; +}; + +&i2c14 { + status = "okay"; +}; + +&i2c15 { + status = "okay"; +}; + +&i2c16 { + status = "okay"; +}; + +&i2c17 { + status = "okay"; +}; + +&i2c18 { + status = "okay"; +}; + +&i2c19 { + status = "okay"; +}; + +&i2c20 { + status = "okay"; +}; + +&i2c21 { + status = "okay"; +}; + +&i2c22 { + status = "okay"; +}; + +&i2c23 { + status = "okay"; +}; + +&i2c24 { + status = "okay"; +}; + +&i2c25 { + status = "okay"; +}; + +&i2c26 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/nuvoton/nuvoton-npcm845.dtsi b/arch/arm64/boot/dts/nuvoton/nuvoton-npcm845.dtsi index 8239d9a..0be38b0 100644 --- a/arch/arm64/boot/dts/nuvoton/nuvoton-npcm845.dtsi +++ b/arch/arm64/boot/dts/nuvoton/nuvoton-npcm845.dtsi
@@ -75,4 +75,11 @@ timer { <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>, <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_LOW)>; }; + + firmware { + optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; };
diff --git a/arch/arm64/boot/dts/nvidia/tegra132.dtsi b/arch/arm64/boot/dts/nvidia/tegra132.dtsi index 26cd11a..e9015f7 100644 --- a/arch/arm64/boot/dts/nvidia/tegra132.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra132.dtsi
@@ -644,7 +644,7 @@ hda@70030000 { reg = <0x0 0x70030000 0x0 0x10000>; interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA124_CLK_HDA>, - <&tegra_car TEGRA124_CLK_HDA2HDMI>, + <&tegra_car TEGRA124_CLK_HDA2HDMI>, <&tegra_car TEGRA124_CLK_HDA2CODEC_2X>; clock-names = "hda", "hda2hdmi", "hda2codec_2x"; resets = <&tegra_car 125>, /* hda */ @@ -872,7 +872,7 @@ soctherm: thermal-sensor@700e2000 { <GIC_SPI 51 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "thermal", "edp"; clocks = <&tegra_car TEGRA124_CLK_TSENSOR>, - <&tegra_car TEGRA124_CLK_SOC_THERM>; + <&tegra_car TEGRA124_CLK_SOC_THERM>; clock-names = "tsensor", "soctherm"; resets = <&tegra_car 78>; reset-names = "soctherm"; @@ -889,7 +889,7 @@ throttle_heavy: heavy { }; ahub@70300000 { - compatible = "nvidia,tegra124-ahub"; + compatible = "nvidia,tegra132-ahub", "nvidia,tegra124-ahub"; reg = <0x0 0x70300000 0x0 0x200>, <0x0 0x70300800 0x0 0x800>, <0x0 0x70300200 0x0 0x600>; @@ -936,13 +936,13 @@ ahub@70300000 { "rx3", "tx3", "rx4", "tx4", "rx5", "tx5", "rx6", "tx6", "rx7", "tx7", "rx8", "tx8", "rx9", "tx9"; - ranges; - #address-cells = <2>; - #size-cells = <2>; + ranges = <0x70300000 0x0 0x70300000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; tegra_i2s0: i2s@70301000 { compatible = "nvidia,tegra124-i2s"; - reg = <0x0 0x70301000 0x0 0x100>; + reg = <0x70301000 0x100>; nvidia,ahub-cif-ids = <4 4>; clocks = <&tegra_car TEGRA124_CLK_I2S0>; clock-names = "i2s"; @@ -953,7 +953,7 @@ tegra_i2s0: i2s@70301000 { tegra_i2s1: i2s@70301100 { compatible = "nvidia,tegra124-i2s"; - reg = <0x0 0x70301100 0x0 0x100>; + reg = <0x70301100 0x100>; nvidia,ahub-cif-ids = <5 5>; clocks = <&tegra_car TEGRA124_CLK_I2S1>; clock-names = "i2s"; @@ -964,7 +964,7 @@ tegra_i2s1: i2s@70301100 { tegra_i2s2: i2s@70301200 { compatible = "nvidia,tegra124-i2s"; - reg = <0x0 0x70301200 0x0 0x100>; + reg = <0x70301200 0x100>; nvidia,ahub-cif-ids = <6 6>; clocks = <&tegra_car TEGRA124_CLK_I2S2>; clock-names = "i2s"; @@ -975,7 +975,7 @@ tegra_i2s2: i2s@70301200 { tegra_i2s3: i2s@70301300 { compatible = "nvidia,tegra124-i2s"; - reg = <0x0 0x70301300 0x0 0x100>; + reg = <0x70301300 0x100>; nvidia,ahub-cif-ids = <7 7>; clocks = <&tegra_car TEGRA124_CLK_I2S3>; clock-names = "i2s"; @@ -986,7 +986,7 @@ tegra_i2s3: i2s@70301300 { tegra_i2s4: i2s@70301400 { compatible = "nvidia,tegra124-i2s"; - reg = <0x0 0x70301400 0x0 0x100>; + reg = <0x70301400 0x100>; nvidia,ahub-cif-ids = <8 8>; clocks = <&tegra_car TEGRA124_CLK_I2S4>; clock-names = "i2s";
diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p3509-0000+p3636-0001.dts b/arch/arm64/boot/dts/nvidia/tegra186-p3509-0000+p3636-0001.dts index d9aafe0..4b2fa1a 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186-p3509-0000+p3636-0001.dts +++ b/arch/arm64/boot/dts/nvidia/tegra186-p3509-0000+p3636-0001.dts
@@ -1176,22 +1176,22 @@ cpu_trip_passive: passive { }; cooling-maps { - cpu-critical { + map-critical { cooling-device = <&fan 3 3>; trip = <&cpu_trip_critical>; }; - cpu-hot { + map-hot { cooling-device = <&fan 2 2>; trip = <&cpu_trip_hot>; }; - cpu-active { + map-active { cooling-device = <&fan 1 1>; trip = <&cpu_trip_active>; }; - cpu-passive { + map-passive { cooling-device = <&fan 0 0>; trip = <&cpu_trip_passive>; };
diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi index 705af03..3d7ba77 100644 --- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi
@@ -142,15 +142,15 @@ tegra_ahub: ahub@2900800 { assigned-clocks = <&bpmp TEGRA186_CLK_AHUB>; assigned-clock-parents = <&bpmp TEGRA186_CLK_PLLP_OUT0>; assigned-clock-rates = <81600000>; - #address-cells = <2>; - #size-cells = <2>; - ranges = <0x0 0x02900800 0x0 0x02900800 0x0 0x11800>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x02900000 0x0 0x02900000 0x20000>; status = "disabled"; tegra_i2s1: i2s@2901000 { compatible = "nvidia,tegra186-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901000 0x0 0x100>; + reg = <0x2901000 0x100>; clocks = <&bpmp TEGRA186_CLK_I2S1>, <&bpmp TEGRA186_CLK_I2S1_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -164,7 +164,7 @@ tegra_i2s1: i2s@2901000 { tegra_i2s2: i2s@2901100 { compatible = "nvidia,tegra186-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901100 0x0 0x100>; + reg = <0x2901100 0x100>; clocks = <&bpmp TEGRA186_CLK_I2S2>, <&bpmp TEGRA186_CLK_I2S2_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -178,7 +178,7 @@ tegra_i2s2: i2s@2901100 { tegra_i2s3: i2s@2901200 { compatible = "nvidia,tegra186-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901200 0x0 0x100>; + reg = <0x2901200 0x100>; clocks = <&bpmp TEGRA186_CLK_I2S3>, <&bpmp TEGRA186_CLK_I2S3_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -192,7 +192,7 @@ tegra_i2s3: i2s@2901200 { tegra_i2s4: i2s@2901300 { compatible = "nvidia,tegra186-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901300 0x0 0x100>; + reg = <0x2901300 0x100>; clocks = <&bpmp TEGRA186_CLK_I2S4>, <&bpmp TEGRA186_CLK_I2S4_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -206,7 +206,7 @@ tegra_i2s4: i2s@2901300 { tegra_i2s5: i2s@2901400 { compatible = "nvidia,tegra186-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901400 0x0 0x100>; + reg = <0x2901400 0x100>; clocks = <&bpmp TEGRA186_CLK_I2S5>, <&bpmp TEGRA186_CLK_I2S5_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -220,7 +220,7 @@ tegra_i2s5: i2s@2901400 { tegra_i2s6: i2s@2901500 { compatible = "nvidia,tegra186-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901500 0x0 0x100>; + reg = <0x2901500 0x100>; clocks = <&bpmp TEGRA186_CLK_I2S6>, <&bpmp TEGRA186_CLK_I2S6_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -234,7 +234,7 @@ tegra_i2s6: i2s@2901500 { tegra_sfc1: sfc@2902000 { compatible = "nvidia,tegra186-sfc", "nvidia,tegra210-sfc"; - reg = <0x0 0x2902000 0x0 0x200>; + reg = <0x2902000 0x200>; sound-name-prefix = "SFC1"; status = "disabled"; }; @@ -242,7 +242,7 @@ tegra_sfc1: sfc@2902000 { tegra_sfc2: sfc@2902200 { compatible = "nvidia,tegra186-sfc", "nvidia,tegra210-sfc"; - reg = <0x0 0x2902200 0x0 0x200>; + reg = <0x2902200 0x200>; sound-name-prefix = "SFC2"; status = "disabled"; }; @@ -250,7 +250,7 @@ tegra_sfc2: sfc@2902200 { tegra_sfc3: sfc@2902400 { compatible = "nvidia,tegra186-sfc", "nvidia,tegra210-sfc"; - reg = <0x0 0x2902400 0x0 0x200>; + reg = <0x2902400 0x200>; sound-name-prefix = "SFC3"; status = "disabled"; }; @@ -258,7 +258,7 @@ tegra_sfc3: sfc@2902400 { tegra_sfc4: sfc@2902600 { compatible = "nvidia,tegra186-sfc", "nvidia,tegra210-sfc"; - reg = <0x0 0x2902600 0x0 0x200>; + reg = <0x2902600 0x200>; sound-name-prefix = "SFC4"; status = "disabled"; }; @@ -266,7 +266,7 @@ tegra_sfc4: sfc@2902600 { tegra_amx1: amx@2903000 { compatible = "nvidia,tegra186-amx", "nvidia,tegra210-amx"; - reg = <0x0 0x2903000 0x0 0x100>; + reg = <0x2903000 0x100>; sound-name-prefix = "AMX1"; status = "disabled"; }; @@ -274,7 +274,7 @@ tegra_amx1: amx@2903000 { tegra_amx2: amx@2903100 { compatible = "nvidia,tegra186-amx", "nvidia,tegra210-amx"; - reg = <0x0 0x2903100 0x0 0x100>; + reg = <0x2903100 0x100>; sound-name-prefix = "AMX2"; status = "disabled"; }; @@ -282,7 +282,7 @@ tegra_amx2: amx@2903100 { tegra_amx3: amx@2903200 { compatible = "nvidia,tegra186-amx", "nvidia,tegra210-amx"; - reg = <0x0 0x2903200 0x0 0x100>; + reg = <0x2903200 0x100>; sound-name-prefix = "AMX3"; status = "disabled"; }; @@ -290,7 +290,7 @@ tegra_amx3: amx@2903200 { tegra_amx4: amx@2903300 { compatible = "nvidia,tegra186-amx", "nvidia,tegra210-amx"; - reg = <0x0 0x2903300 0x0 0x100>; + reg = <0x2903300 0x100>; sound-name-prefix = "AMX4"; status = "disabled"; }; @@ -298,7 +298,7 @@ tegra_amx4: amx@2903300 { tegra_adx1: adx@2903800 { compatible = "nvidia,tegra186-adx", "nvidia,tegra210-adx"; - reg = <0x0 0x2903800 0x0 0x100>; + reg = <0x2903800 0x100>; sound-name-prefix = "ADX1"; status = "disabled"; }; @@ -306,7 +306,7 @@ tegra_adx1: adx@2903800 { tegra_adx2: adx@2903900 { compatible = "nvidia,tegra186-adx", "nvidia,tegra210-adx"; - reg = <0x0 0x2903900 0x0 0x100>; + reg = <0x2903900 0x100>; sound-name-prefix = "ADX2"; status = "disabled"; }; @@ -314,7 +314,7 @@ tegra_adx2: adx@2903900 { tegra_adx3: adx@2903a00 { compatible = "nvidia,tegra186-adx", "nvidia,tegra210-adx"; - reg = <0x0 0x2903a00 0x0 0x100>; + reg = <0x2903a00 0x100>; sound-name-prefix = "ADX3"; status = "disabled"; }; @@ -322,14 +322,14 @@ tegra_adx3: adx@2903a00 { tegra_adx4: adx@2903b00 { compatible = "nvidia,tegra186-adx", "nvidia,tegra210-adx"; - reg = <0x0 0x2903b00 0x0 0x100>; + reg = <0x2903b00 0x100>; sound-name-prefix = "ADX4"; status = "disabled"; }; tegra_dmic1: dmic@2904000 { compatible = "nvidia,tegra210-dmic"; - reg = <0x0 0x2904000 0x0 0x100>; + reg = <0x2904000 0x100>; clocks = <&bpmp TEGRA186_CLK_DMIC1>; clock-names = "dmic"; assigned-clocks = <&bpmp TEGRA186_CLK_DMIC1>; @@ -341,7 +341,7 @@ tegra_dmic1: dmic@2904000 { tegra_dmic2: dmic@2904100 { compatible = "nvidia,tegra210-dmic"; - reg = <0x0 0x2904100 0x0 0x100>; + reg = <0x2904100 0x100>; clocks = <&bpmp TEGRA186_CLK_DMIC2>; clock-names = "dmic"; assigned-clocks = <&bpmp TEGRA186_CLK_DMIC2>; @@ -353,7 +353,7 @@ tegra_dmic2: dmic@2904100 { tegra_dmic3: dmic@2904200 { compatible = "nvidia,tegra210-dmic"; - reg = <0x0 0x2904200 0x0 0x100>; + reg = <0x2904200 0x100>; clocks = <&bpmp TEGRA186_CLK_DMIC3>; clock-names = "dmic"; assigned-clocks = <&bpmp TEGRA186_CLK_DMIC3>; @@ -365,7 +365,7 @@ tegra_dmic3: dmic@2904200 { tegra_dmic4: dmic@2904300 { compatible = "nvidia,tegra210-dmic"; - reg = <0x0 0x2904300 0x0 0x100>; + reg = <0x2904300 0x100>; clocks = <&bpmp TEGRA186_CLK_DMIC4>; clock-names = "dmic"; assigned-clocks = <&bpmp TEGRA186_CLK_DMIC4>; @@ -377,7 +377,7 @@ tegra_dmic4: dmic@2904300 { tegra_dspk1: dspk@2905000 { compatible = "nvidia,tegra186-dspk"; - reg = <0x0 0x2905000 0x0 0x100>; + reg = <0x2905000 0x100>; clocks = <&bpmp TEGRA186_CLK_DSPK1>; clock-names = "dspk"; assigned-clocks = <&bpmp TEGRA186_CLK_DSPK1>; @@ -389,7 +389,7 @@ tegra_dspk1: dspk@2905000 { tegra_dspk2: dspk@2905100 { compatible = "nvidia,tegra186-dspk"; - reg = <0x0 0x2905100 0x0 0x100>; + reg = <0x2905100 0x100>; clocks = <&bpmp TEGRA186_CLK_DSPK2>; clock-names = "dspk"; assigned-clocks = <&bpmp TEGRA186_CLK_DSPK2>; @@ -402,9 +402,9 @@ tegra_dspk2: dspk@2905100 { tegra_ope1: processing-engine@2908000 { compatible = "nvidia,tegra186-ope", "nvidia,tegra210-ope"; - reg = <0x0 0x2908000 0x0 0x100>; - #address-cells = <2>; - #size-cells = <2>; + reg = <0x2908000 0x100>; + #address-cells = <1>; + #size-cells = <1>; ranges; sound-name-prefix = "OPE1"; status = "disabled"; @@ -412,20 +412,20 @@ tegra_ope1: processing-engine@2908000 { equalizer@2908100 { compatible = "nvidia,tegra186-peq", "nvidia,tegra210-peq"; - reg = <0x0 0x2908100 0x0 0x100>; + reg = <0x2908100 0x100>; }; dynamic-range-compressor@2908200 { compatible = "nvidia,tegra186-mbdrc", "nvidia,tegra210-mbdrc"; - reg = <0x0 0x2908200 0x0 0x200>; + reg = <0x2908200 0x200>; }; }; tegra_mvc1: mvc@290a000 { compatible = "nvidia,tegra186-mvc", "nvidia,tegra210-mvc"; - reg = <0x0 0x290a000 0x0 0x200>; + reg = <0x290a000 0x200>; sound-name-prefix = "MVC1"; status = "disabled"; }; @@ -433,7 +433,7 @@ tegra_mvc1: mvc@290a000 { tegra_mvc2: mvc@290a200 { compatible = "nvidia,tegra186-mvc", "nvidia,tegra210-mvc"; - reg = <0x0 0x290a200 0x0 0x200>; + reg = <0x290a200 0x200>; sound-name-prefix = "MVC2"; status = "disabled"; }; @@ -441,14 +441,14 @@ tegra_mvc2: mvc@290a200 { tegra_amixer: amixer@290bb00 { compatible = "nvidia,tegra186-amixer", "nvidia,tegra210-amixer"; - reg = <0x0 0x290bb00 0x0 0x800>; + reg = <0x290bb00 0x800>; sound-name-prefix = "MIXER1"; status = "disabled"; }; tegra_admaif: admaif@290f000 { compatible = "nvidia,tegra186-admaif"; - reg = <0x0 0x0290f000 0x0 0x1000>; + reg = <0x0290f000 0x1000>; dmas = <&adma 1>, <&adma 1>, <&adma 2>, <&adma 2>, <&adma 3>, <&adma 3>, @@ -494,7 +494,7 @@ tegra_admaif: admaif@290f000 { tegra_asrc: asrc@2910000 { compatible = "nvidia,tegra186-asrc"; - reg = <0x0 0x2910000 0x0 0x2000>; + reg = <0x2910000 0x2000>; sound-name-prefix = "ASRC1"; status = "disabled"; }; @@ -1517,7 +1517,7 @@ host1x@13e00000 { <0x0 0x13e10000 0x0 0x10000>; reg-names = "hypervisor", "vm"; interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 263 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "syncpt", "host1x"; clocks = <&bpmp TEGRA186_CLK_HOST1X>; clock-names = "host1x";
diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts b/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts index 5462200f..4784644 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts +++ b/arch/arm64/boot/dts/nvidia/tegra194-p2972-0000.dts
@@ -2450,22 +2450,22 @@ cpu_trip_passive: passive { }; cooling-maps { - cpu-critical { + map-critical { cooling-device = <&fan 3 3>; trip = <&cpu_trip_critical>; }; - cpu-hot { + map-hot { cooling-device = <&fan 2 2>; trip = <&cpu_trip_hot>; }; - cpu-active { + map-active { cooling-device = <&fan 1 1>; trip = <&cpu_trip_active>; }; - cpu-passive { + map-passive { cooling-device = <&fan 0 0>; trip = <&cpu_trip_passive>; };
diff --git a/arch/arm64/boot/dts/nvidia/tegra194-p3509-0000.dtsi b/arch/arm64/boot/dts/nvidia/tegra194-p3509-0000.dtsi index 6f4879c..569d181 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194-p3509-0000.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194-p3509-0000.dtsi
@@ -2433,22 +2433,22 @@ cpu_trip_passive: passive { }; cooling-maps { - cpu-critical { + map-critical { cooling-device = <&fan 3 3>; trip = <&cpu_trip_critical>; }; - cpu-hot { + map-hot { cooling-device = <&fan 2 2>; trip = <&cpu_trip_hot>; }; - cpu-active { + map-active { cooling-device = <&fan 1 1>; trip = <&cpu_trip_active>; }; - cpu-passive { + map-passive { cooling-device = <&fan 0 0>; trip = <&cpu_trip_passive>; };
diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi index 5e510f7..43d8284 100644 --- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi
@@ -231,14 +231,14 @@ tegra_ahub: ahub@2900800 { assigned-clock-rates = <81600000>; status = "disabled"; - #address-cells = <2>; - #size-cells = <2>; - ranges = <0x0 0x02900800 0x0 0x02900800 0x0 0x11800>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x02900000 0x0 0x02900000 0x20000>; tegra_i2s1: i2s@2901000 { compatible = "nvidia,tegra194-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901000 0x0 0x100>; + reg = <0x2901000 0x100>; clocks = <&bpmp TEGRA194_CLK_I2S1>, <&bpmp TEGRA194_CLK_I2S1_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -252,7 +252,7 @@ tegra_i2s1: i2s@2901000 { tegra_i2s2: i2s@2901100 { compatible = "nvidia,tegra194-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901100 0x0 0x100>; + reg = <0x2901100 0x100>; clocks = <&bpmp TEGRA194_CLK_I2S2>, <&bpmp TEGRA194_CLK_I2S2_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -266,7 +266,7 @@ tegra_i2s2: i2s@2901100 { tegra_i2s3: i2s@2901200 { compatible = "nvidia,tegra194-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901200 0x0 0x100>; + reg = <0x2901200 0x100>; clocks = <&bpmp TEGRA194_CLK_I2S3>, <&bpmp TEGRA194_CLK_I2S3_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -280,7 +280,7 @@ tegra_i2s3: i2s@2901200 { tegra_i2s4: i2s@2901300 { compatible = "nvidia,tegra194-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901300 0x0 0x100>; + reg = <0x2901300 0x100>; clocks = <&bpmp TEGRA194_CLK_I2S4>, <&bpmp TEGRA194_CLK_I2S4_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -294,7 +294,7 @@ tegra_i2s4: i2s@2901300 { tegra_i2s5: i2s@2901400 { compatible = "nvidia,tegra194-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901400 0x0 0x100>; + reg = <0x2901400 0x100>; clocks = <&bpmp TEGRA194_CLK_I2S5>, <&bpmp TEGRA194_CLK_I2S5_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -308,7 +308,7 @@ tegra_i2s5: i2s@2901400 { tegra_i2s6: i2s@2901500 { compatible = "nvidia,tegra194-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901500 0x0 0x100>; + reg = <0x2901500 0x100>; clocks = <&bpmp TEGRA194_CLK_I2S6>, <&bpmp TEGRA194_CLK_I2S6_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -322,7 +322,7 @@ tegra_i2s6: i2s@2901500 { tegra_sfc1: sfc@2902000 { compatible = "nvidia,tegra194-sfc", "nvidia,tegra210-sfc"; - reg = <0x0 0x2902000 0x0 0x200>; + reg = <0x2902000 0x200>; sound-name-prefix = "SFC1"; status = "disabled"; }; @@ -330,7 +330,7 @@ tegra_sfc1: sfc@2902000 { tegra_sfc2: sfc@2902200 { compatible = "nvidia,tegra194-sfc", "nvidia,tegra210-sfc"; - reg = <0x0 0x2902200 0x0 0x200>; + reg = <0x2902200 0x200>; sound-name-prefix = "SFC2"; status = "disabled"; }; @@ -338,7 +338,7 @@ tegra_sfc2: sfc@2902200 { tegra_sfc3: sfc@2902400 { compatible = "nvidia,tegra194-sfc", "nvidia,tegra210-sfc"; - reg = <0x0 0x2902400 0x0 0x200>; + reg = <0x2902400 0x200>; sound-name-prefix = "SFC3"; status = "disabled"; }; @@ -346,35 +346,35 @@ tegra_sfc3: sfc@2902400 { tegra_sfc4: sfc@2902600 { compatible = "nvidia,tegra194-sfc", "nvidia,tegra210-sfc"; - reg = <0x0 0x2902600 0x0 0x200>; + reg = <0x2902600 0x200>; sound-name-prefix = "SFC4"; status = "disabled"; }; tegra_amx1: amx@2903000 { compatible = "nvidia,tegra194-amx"; - reg = <0x0 0x2903000 0x0 0x100>; + reg = <0x2903000 0x100>; sound-name-prefix = "AMX1"; status = "disabled"; }; tegra_amx2: amx@2903100 { compatible = "nvidia,tegra194-amx"; - reg = <0x0 0x2903100 0x0 0x100>; + reg = <0x2903100 0x100>; sound-name-prefix = "AMX2"; status = "disabled"; }; tegra_amx3: amx@2903200 { compatible = "nvidia,tegra194-amx"; - reg = <0x0 0x2903200 0x0 0x100>; + reg = <0x2903200 0x100>; sound-name-prefix = "AMX3"; status = "disabled"; }; tegra_amx4: amx@2903300 { compatible = "nvidia,tegra194-amx"; - reg = <0x0 0x2903300 0x0 0x100>; + reg = <0x2903300 0x100>; sound-name-prefix = "AMX4"; status = "disabled"; }; @@ -382,7 +382,7 @@ tegra_amx4: amx@2903300 { tegra_adx1: adx@2903800 { compatible = "nvidia,tegra194-adx", "nvidia,tegra210-adx"; - reg = <0x0 0x2903800 0x0 0x100>; + reg = <0x2903800 0x100>; sound-name-prefix = "ADX1"; status = "disabled"; }; @@ -390,7 +390,7 @@ tegra_adx1: adx@2903800 { tegra_adx2: adx@2903900 { compatible = "nvidia,tegra194-adx", "nvidia,tegra210-adx"; - reg = <0x0 0x2903900 0x0 0x100>; + reg = <0x2903900 0x100>; sound-name-prefix = "ADX2"; status = "disabled"; }; @@ -398,7 +398,7 @@ tegra_adx2: adx@2903900 { tegra_adx3: adx@2903a00 { compatible = "nvidia,tegra194-adx", "nvidia,tegra210-adx"; - reg = <0x0 0x2903a00 0x0 0x100>; + reg = <0x2903a00 0x100>; sound-name-prefix = "ADX3"; status = "disabled"; }; @@ -406,7 +406,7 @@ tegra_adx3: adx@2903a00 { tegra_adx4: adx@2903b00 { compatible = "nvidia,tegra194-adx", "nvidia,tegra210-adx"; - reg = <0x0 0x2903b00 0x0 0x100>; + reg = <0x2903b00 0x100>; sound-name-prefix = "ADX4"; status = "disabled"; }; @@ -414,7 +414,7 @@ tegra_adx4: adx@2903b00 { tegra_dmic1: dmic@2904000 { compatible = "nvidia,tegra194-dmic", "nvidia,tegra210-dmic"; - reg = <0x0 0x2904000 0x0 0x100>; + reg = <0x2904000 0x100>; clocks = <&bpmp TEGRA194_CLK_DMIC1>; clock-names = "dmic"; assigned-clocks = <&bpmp TEGRA194_CLK_DMIC1>; @@ -427,7 +427,7 @@ tegra_dmic1: dmic@2904000 { tegra_dmic2: dmic@2904100 { compatible = "nvidia,tegra194-dmic", "nvidia,tegra210-dmic"; - reg = <0x0 0x2904100 0x0 0x100>; + reg = <0x2904100 0x100>; clocks = <&bpmp TEGRA194_CLK_DMIC2>; clock-names = "dmic"; assigned-clocks = <&bpmp TEGRA194_CLK_DMIC2>; @@ -440,7 +440,7 @@ tegra_dmic2: dmic@2904100 { tegra_dmic3: dmic@2904200 { compatible = "nvidia,tegra194-dmic", "nvidia,tegra210-dmic"; - reg = <0x0 0x2904200 0x0 0x100>; + reg = <0x2904200 0x100>; clocks = <&bpmp TEGRA194_CLK_DMIC3>; clock-names = "dmic"; assigned-clocks = <&bpmp TEGRA194_CLK_DMIC3>; @@ -453,7 +453,7 @@ tegra_dmic3: dmic@2904200 { tegra_dmic4: dmic@2904300 { compatible = "nvidia,tegra194-dmic", "nvidia,tegra210-dmic"; - reg = <0x0 0x2904300 0x0 0x100>; + reg = <0x2904300 0x100>; clocks = <&bpmp TEGRA194_CLK_DMIC4>; clock-names = "dmic"; assigned-clocks = <&bpmp TEGRA194_CLK_DMIC4>; @@ -466,7 +466,7 @@ tegra_dmic4: dmic@2904300 { tegra_dspk1: dspk@2905000 { compatible = "nvidia,tegra194-dspk", "nvidia,tegra186-dspk"; - reg = <0x0 0x2905000 0x0 0x100>; + reg = <0x2905000 0x100>; clocks = <&bpmp TEGRA194_CLK_DSPK1>; clock-names = "dspk"; assigned-clocks = <&bpmp TEGRA194_CLK_DSPK1>; @@ -479,7 +479,7 @@ tegra_dspk1: dspk@2905000 { tegra_dspk2: dspk@2905100 { compatible = "nvidia,tegra194-dspk", "nvidia,tegra186-dspk"; - reg = <0x0 0x2905100 0x0 0x100>; + reg = <0x2905100 0x100>; clocks = <&bpmp TEGRA194_CLK_DSPK2>; clock-names = "dspk"; assigned-clocks = <&bpmp TEGRA194_CLK_DSPK2>; @@ -492,31 +492,31 @@ tegra_dspk2: dspk@2905100 { tegra_ope1: processing-engine@2908000 { compatible = "nvidia,tegra194-ope", "nvidia,tegra210-ope"; - reg = <0x0 0x2908000 0x0 0x100>; + reg = <0x2908000 0x100>; sound-name-prefix = "OPE1"; status = "disabled"; - #address-cells = <2>; - #size-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; ranges; equalizer@2908100 { compatible = "nvidia,tegra194-peq", "nvidia,tegra210-peq"; - reg = <0x0 0x2908100 0x0 0x100>; + reg = <0x2908100 0x100>; }; dynamic-range-compressor@2908200 { compatible = "nvidia,tegra194-mbdrc", "nvidia,tegra210-mbdrc"; - reg = <0x0 0x2908200 0x0 0x200>; + reg = <0x2908200 0x200>; }; }; tegra_mvc1: mvc@290a000 { compatible = "nvidia,tegra194-mvc", "nvidia,tegra210-mvc"; - reg = <0x0 0x290a000 0x0 0x200>; + reg = <0x290a000 0x200>; sound-name-prefix = "MVC1"; status = "disabled"; }; @@ -524,7 +524,7 @@ tegra_mvc1: mvc@290a000 { tegra_mvc2: mvc@290a200 { compatible = "nvidia,tegra194-mvc", "nvidia,tegra210-mvc"; - reg = <0x0 0x290a200 0x0 0x200>; + reg = <0x290a200 0x200>; sound-name-prefix = "MVC2"; status = "disabled"; }; @@ -532,7 +532,7 @@ tegra_mvc2: mvc@290a200 { tegra_amixer: amixer@290bb00 { compatible = "nvidia,tegra194-amixer", "nvidia,tegra210-amixer"; - reg = <0x0 0x290bb00 0x0 0x800>; + reg = <0x290bb00 0x800>; sound-name-prefix = "MIXER1"; status = "disabled"; }; @@ -540,7 +540,7 @@ tegra_amixer: amixer@290bb00 { tegra_admaif: admaif@290f000 { compatible = "nvidia,tegra194-admaif", "nvidia,tegra186-admaif"; - reg = <0x0 0x0290f000 0x0 0x1000>; + reg = <0x0290f000 0x1000>; dmas = <&adma 1>, <&adma 1>, <&adma 2>, <&adma 2>, <&adma 3>, <&adma 3>, @@ -591,7 +591,7 @@ tegra_admaif: admaif@290f000 { tegra_asrc: asrc@2910000 { compatible = "nvidia,tegra194-asrc", "nvidia,tegra186-asrc"; - reg = <0x0 0x2910000 0x0 0x2000>; + reg = <0x2910000 0x2000>; sound-name-prefix = "ASRC1"; status = "disabled"; }; @@ -923,6 +923,8 @@ spi@3270000 { <&bpmp TEGRA194_CLK_QSPI0_PM>; clock-names = "qspi", "qspi_out"; resets = <&bpmp TEGRA194_RESET_QSPI0>; + dmas = <&gpcdma 5>, <&gpcdma 5>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -1013,6 +1015,8 @@ spi@3300000 { <&bpmp TEGRA194_CLK_QSPI1_PM>; clock-names = "qspi", "qspi_out"; resets = <&bpmp TEGRA194_RESET_QSPI1>; + dmas = <&gpcdma 6>, <&gpcdma 6>; + dma-names = "rx", "tx"; status = "disabled"; }; @@ -1360,17 +1364,17 @@ hsp_top0: hsp@3c00000 { compatible = "nvidia,tegra194-hsp"; reg = <0x0 0x03c00000 0x0 0xa0000>; interrupts = <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 120 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 121 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 122 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 124 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 125 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "doorbell", "shared0", "shared1", "shared2", - "shared3", "shared4", "shared5", "shared6", - "shared7"; + "shared3", "shared4", "shared5", "shared6", + "shared7"; #mbox-cells = <2>; }; @@ -1556,9 +1560,9 @@ hsp_aon: hsp@c150000 { compatible = "nvidia,tegra194-hsp"; reg = <0x0 0x0c150000 0x0 0x90000>; interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; /* * Shared interrupt 0 is routed only to AON/SPE, so * we only have 4 shared interrupts for the CCPLEX. @@ -2596,8 +2600,7 @@ pcie-ep@14160000 { interconnects = <&mc TEGRA194_MEMORY_CLIENT_PCIE4R &emc>, <&mc TEGRA194_MEMORY_CLIENT_PCIE4W &emc>; interconnect-names = "dma-mem", "write"; - iommu-map = <0x0 &smmu TEGRA194_SID_PCIE4 0x1000>; - iommu-map-mask = <0x0>; + iommus = <&smmu TEGRA194_SID_PCIE4>; dma-coherent; }; @@ -2689,8 +2692,7 @@ pcie-ep@14180000 { interconnects = <&mc TEGRA194_MEMORY_CLIENT_PCIE0R &emc>, <&mc TEGRA194_MEMORY_CLIENT_PCIE0W &emc>; interconnect-names = "dma-mem", "write"; - iommu-map = <0x0 &smmu TEGRA194_SID_PCIE0 0x1000>; - iommu-map-mask = <0x0>; + iommus = <&smmu TEGRA194_SID_PCIE0>; dma-coherent; }; @@ -2788,8 +2790,7 @@ pcie-ep@141a0000 { interconnects = <&mc TEGRA194_MEMORY_CLIENT_PCIE5R &emc>, <&mc TEGRA194_MEMORY_CLIENT_PCIE5W &emc>; interconnect-names = "dma-mem", "write"; - iommu-map = <0x0 &smmu TEGRA194_SID_PCIE5 0x1000>; - iommu-map-mask = <0x0>; + iommus = <&smmu TEGRA194_SID_PCIE5>; dma-coherent; };
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts index 627abf5..9610781 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-p2371-2180.dts
@@ -129,1206 +129,86 @@ admaif@702d0000 { i2s@702d1000 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - i2s1_cif_ep: endpoint { - remote-endpoint = <&xbar_i2s1_ep>; - }; - }; - - i2s1_port: port@1 { - reg = <1>; - - i2s1_dap_ep: endpoint { - dai-format = "i2s"; - /* Placeholder for external Codec */ - }; - }; - }; }; i2s@702d1100 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - i2s2_cif_ep: endpoint { - remote-endpoint = <&xbar_i2s2_ep>; - }; - }; - - i2s2_port: port@1 { - reg = <1>; - - i2s2_dap_ep: endpoint { - dai-format = "i2s"; - /* Placeholder for external Codec */ - }; - }; - }; }; i2s@702d1200 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - i2s3_cif_ep: endpoint { - remote-endpoint = <&xbar_i2s3_ep>; - }; - }; - - i2s3_port: port@1 { - reg = <1>; - - i2s3_dap_ep: endpoint { - dai-format = "i2s"; - /* Placeholder for external Codec */ - }; - }; - }; }; i2s@702d1300 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - i2s4_cif_ep: endpoint { - remote-endpoint = <&xbar_i2s4_ep>; - }; - }; - - i2s4_port: port@1 { - reg = <1>; - - i2s4_dap_ep: endpoint { - dai-format = "i2s"; - /* Placeholder for external Codec */ - }; - }; - }; }; i2s@702d1400 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - i2s5_cif_ep: endpoint { - remote-endpoint = <&xbar_i2s5_ep>; - }; - }; - - i2s5_port: port@1 { - reg = <1>; - - i2s5_dap_ep: endpoint { - dai-format = "i2s"; - /* Placeholder for external Codec */ - }; - }; - }; }; sfc@702d2000 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - sfc1_cif_in_ep: endpoint { - remote-endpoint = <&xbar_sfc1_in_ep>; - }; - }; - - sfc1_out_port: port@1 { - reg = <1>; - - sfc1_cif_out_ep: endpoint { - remote-endpoint = <&xbar_sfc1_out_ep>; - }; - }; - }; }; sfc@702d2200 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - sfc2_cif_in_ep: endpoint { - remote-endpoint = <&xbar_sfc2_in_ep>; - }; - }; - - sfc2_out_port: port@1 { - reg = <1>; - - sfc2_cif_out_ep: endpoint { - remote-endpoint = <&xbar_sfc2_out_ep>; - }; - }; - }; }; sfc@702d2400 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - sfc3_cif_in_ep: endpoint { - remote-endpoint = <&xbar_sfc3_in_ep>; - }; - }; - - sfc3_out_port: port@1 { - reg = <1>; - - sfc3_cif_out_ep: endpoint { - remote-endpoint = <&xbar_sfc3_out_ep>; - }; - }; - }; }; sfc@702d2600 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - sfc4_cif_in_ep: endpoint { - remote-endpoint = <&xbar_sfc4_in_ep>; - }; - }; - - sfc4_out_port: port@1 { - reg = <1>; - - sfc4_cif_out_ep: endpoint { - remote-endpoint = <&xbar_sfc4_out_ep>; - }; - }; - }; }; amx@702d3000 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - amx1_in1_ep: endpoint { - remote-endpoint = <&xbar_amx1_in1_ep>; - }; - }; - - port@1 { - reg = <1>; - - amx1_in2_ep: endpoint { - remote-endpoint = <&xbar_amx1_in2_ep>; - }; - }; - - port@2 { - reg = <2>; - - amx1_in3_ep: endpoint { - remote-endpoint = <&xbar_amx1_in3_ep>; - }; - }; - - port@3 { - reg = <3>; - - amx1_in4_ep: endpoint { - remote-endpoint = <&xbar_amx1_in4_ep>; - }; - }; - - amx1_out_port: port@4 { - reg = <4>; - - amx1_out_ep: endpoint { - remote-endpoint = <&xbar_amx1_out_ep>; - }; - }; - }; }; amx@702d3100 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - amx2_in1_ep: endpoint { - remote-endpoint = <&xbar_amx2_in1_ep>; - }; - }; - - port@1 { - reg = <1>; - - amx2_in2_ep: endpoint { - remote-endpoint = <&xbar_amx2_in2_ep>; - }; - }; - - amx2_in3_port: port@2 { - reg = <2>; - - amx2_in3_ep: endpoint { - remote-endpoint = <&xbar_amx2_in3_ep>; - }; - }; - - amx2_in4_port: port@3 { - reg = <3>; - - amx2_in4_ep: endpoint { - remote-endpoint = <&xbar_amx2_in4_ep>; - }; - }; - - amx2_out_port: port@4 { - reg = <4>; - - amx2_out_ep: endpoint { - remote-endpoint = <&xbar_amx2_out_ep>; - }; - }; - }; }; adx@702d3800 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - adx1_in_ep: endpoint { - remote-endpoint = <&xbar_adx1_in_ep>; - }; - }; - - adx1_out1_port: port@1 { - reg = <1>; - - adx1_out1_ep: endpoint { - remote-endpoint = <&xbar_adx1_out1_ep>; - }; - }; - - adx1_out2_port: port@2 { - reg = <2>; - - adx1_out2_ep: endpoint { - remote-endpoint = <&xbar_adx1_out2_ep>; - }; - }; - - adx1_out3_port: port@3 { - reg = <3>; - - adx1_out3_ep: endpoint { - remote-endpoint = <&xbar_adx1_out3_ep>; - }; - }; - - adx1_out4_port: port@4 { - reg = <4>; - - adx1_out4_ep: endpoint { - remote-endpoint = <&xbar_adx1_out4_ep>; - }; - }; - }; }; adx@702d3900 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - adx2_in_ep: endpoint { - remote-endpoint = <&xbar_adx2_in_ep>; - }; - }; - - adx2_out1_port: port@1 { - reg = <1>; - - adx2_out1_ep: endpoint { - remote-endpoint = <&xbar_adx2_out1_ep>; - }; - }; - - adx2_out2_port: port@2 { - reg = <2>; - - adx2_out2_ep: endpoint { - remote-endpoint = <&xbar_adx2_out2_ep>; - }; - }; - - adx2_out3_port: port@3 { - reg = <3>; - - adx2_out3_ep: endpoint { - remote-endpoint = <&xbar_adx2_out3_ep>; - }; - }; - - adx2_out4_port: port@4 { - reg = <4>; - - adx2_out4_ep: endpoint { - remote-endpoint = <&xbar_adx2_out4_ep>; - }; - }; - }; }; dmic@702d4000 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - dmic1_cif_ep: endpoint { - remote-endpoint = <&xbar_dmic1_ep>; - }; - }; - - dmic1_port: port@1 { - reg = <1>; - - dmic1_dap_ep: endpoint { - /* Placeholder for external Codec */ - }; - }; - }; }; dmic@702d4100 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - dmic2_cif_ep: endpoint { - remote-endpoint = <&xbar_dmic2_ep>; - }; - }; - - dmic2_port: port@1 { - reg = <1>; - - dmic2_dap_ep: endpoint { - /* Placeholder for external Codec */ - }; - }; - }; }; dmic@702d4200 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - dmic3_cif_ep: endpoint { - remote-endpoint = <&xbar_dmic3_ep>; - }; - }; - - dmic3_port: port@1 { - reg = <1>; - - dmic3_dap_ep: endpoint { - /* Placeholder for external Codec */ - }; - }; - }; }; processing-engine@702d8000 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0x0>; - - ope1_cif_in_ep: endpoint { - remote-endpoint = <&xbar_ope1_in_ep>; - }; - }; - - ope1_out_port: port@1 { - reg = <0x1>; - - ope1_cif_out_ep: endpoint { - remote-endpoint = <&xbar_ope1_out_ep>; - }; - }; - }; }; processing-engine@702d8400 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0x0>; - - ope2_cif_in_ep: endpoint { - remote-endpoint = <&xbar_ope2_in_ep>; - }; - }; - - ope2_out_port: port@1 { - reg = <0x1>; - - ope2_cif_out_ep: endpoint { - remote-endpoint = <&xbar_ope2_out_ep>; - }; - }; - }; }; mvc@702da000 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - mvc1_cif_in_ep: endpoint { - remote-endpoint = <&xbar_mvc1_in_ep>; - }; - }; - - mvc1_out_port: port@1 { - reg = <1>; - - mvc1_cif_out_ep: endpoint { - remote-endpoint = <&xbar_mvc1_out_ep>; - }; - }; - }; }; mvc@702da200 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - mvc2_cif_in_ep: endpoint { - remote-endpoint = <&xbar_mvc2_in_ep>; - }; - }; - - mvc2_out_port: port@1 { - reg = <1>; - - mvc2_cif_out_ep: endpoint { - remote-endpoint = <&xbar_mvc2_out_ep>; - }; - }; - }; }; amixer@702dbb00 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0x0>; - - mixer_in1_ep: endpoint { - remote-endpoint = <&xbar_mixer_in1_ep>; - }; - }; - - port@1 { - reg = <0x1>; - - mixer_in2_ep: endpoint { - remote-endpoint = <&xbar_mixer_in2_ep>; - }; - }; - - port@2 { - reg = <0x2>; - - mixer_in3_ep: endpoint { - remote-endpoint = <&xbar_mixer_in3_ep>; - }; - }; - - port@3 { - reg = <0x3>; - - mixer_in4_ep: endpoint { - remote-endpoint = <&xbar_mixer_in4_ep>; - }; - }; - - port@4 { - reg = <0x4>; - - mixer_in5_ep: endpoint { - remote-endpoint = <&xbar_mixer_in5_ep>; - }; - }; - - port@5 { - reg = <0x5>; - - mixer_in6_ep: endpoint { - remote-endpoint = <&xbar_mixer_in6_ep>; - }; - }; - - port@6 { - reg = <0x6>; - - mixer_in7_ep: endpoint { - remote-endpoint = <&xbar_mixer_in7_ep>; - }; - }; - - port@7 { - reg = <0x7>; - - mixer_in8_ep: endpoint { - remote-endpoint = <&xbar_mixer_in8_ep>; - }; - }; - - port@8 { - reg = <0x8>; - - mixer_in9_ep: endpoint { - remote-endpoint = <&xbar_mixer_in9_ep>; - }; - }; - - port@9 { - reg = <0x9>; - - mixer_in10_ep: endpoint { - remote-endpoint = <&xbar_mixer_in10_ep>; - }; - }; - - mixer_out1_port: port@a { - reg = <0xa>; - - mixer_out1_ep: endpoint { - remote-endpoint = <&xbar_mixer_out1_ep>; - }; - }; - - mixer_out2_port: port@b { - reg = <0xb>; - - mixer_out2_ep: endpoint { - remote-endpoint = <&xbar_mixer_out2_ep>; - }; - }; - - mixer_out3_port: port@c { - reg = <0xc>; - - mixer_out3_ep: endpoint { - remote-endpoint = <&xbar_mixer_out3_ep>; - }; - }; - - mixer_out4_port: port@d { - reg = <0xd>; - - mixer_out4_ep: endpoint { - remote-endpoint = <&xbar_mixer_out4_ep>; - }; - }; - - mixer_out5_port: port@e { - reg = <0xe>; - - mixer_out5_ep: endpoint { - remote-endpoint = <&xbar_mixer_out5_ep>; - }; - }; - }; - }; - - ports { - xbar_i2s1_port: port@a { - reg = <0xa>; - - xbar_i2s1_ep: endpoint { - remote-endpoint = <&i2s1_cif_ep>; - }; - }; - - xbar_i2s2_port: port@b { - reg = <0xb>; - - xbar_i2s2_ep: endpoint { - remote-endpoint = <&i2s2_cif_ep>; - }; - }; - - xbar_i2s3_port: port@c { - reg = <0xc>; - - xbar_i2s3_ep: endpoint { - remote-endpoint = <&i2s3_cif_ep>; - }; - }; - - xbar_i2s4_port: port@d { - reg = <0xd>; - - xbar_i2s4_ep: endpoint { - remote-endpoint = <&i2s4_cif_ep>; - }; - }; - - xbar_i2s5_port: port@e { - reg = <0xe>; - - xbar_i2s5_ep: endpoint { - remote-endpoint = <&i2s5_cif_ep>; - }; - }; - - xbar_dmic1_port: port@f { - reg = <0xf>; - - xbar_dmic1_ep: endpoint { - remote-endpoint = <&dmic1_cif_ep>; - }; - }; - - xbar_dmic2_port: port@10 { - reg = <0x10>; - - xbar_dmic2_ep: endpoint { - remote-endpoint = <&dmic2_cif_ep>; - }; - }; - - xbar_dmic3_port: port@11 { - reg = <0x11>; - - xbar_dmic3_ep: endpoint { - remote-endpoint = <&dmic3_cif_ep>; - }; - }; - - xbar_sfc1_in_port: port@12 { - reg = <0x12>; - - xbar_sfc1_in_ep: endpoint { - remote-endpoint = <&sfc1_cif_in_ep>; - }; - }; - - port@13 { - reg = <0x13>; - - xbar_sfc1_out_ep: endpoint { - remote-endpoint = <&sfc1_cif_out_ep>; - }; - }; - - xbar_sfc2_in_port: port@14 { - reg = <0x14>; - - xbar_sfc2_in_ep: endpoint { - remote-endpoint = <&sfc2_cif_in_ep>; - }; - }; - - port@15 { - reg = <0x15>; - - xbar_sfc2_out_ep: endpoint { - remote-endpoint = <&sfc2_cif_out_ep>; - }; - }; - - xbar_sfc3_in_port: port@16 { - reg = <0x16>; - - xbar_sfc3_in_ep: endpoint { - remote-endpoint = <&sfc3_cif_in_ep>; - }; - }; - - port@17 { - reg = <0x17>; - - xbar_sfc3_out_ep: endpoint { - remote-endpoint = <&sfc3_cif_out_ep>; - }; - }; - - xbar_sfc4_in_port: port@18 { - reg = <0x18>; - - xbar_sfc4_in_ep: endpoint { - remote-endpoint = <&sfc4_cif_in_ep>; - }; - }; - - port@19 { - reg = <0x19>; - - xbar_sfc4_out_ep: endpoint { - remote-endpoint = <&sfc4_cif_out_ep>; - }; - }; - - xbar_mvc1_in_port: port@1a { - reg = <0x1a>; - - xbar_mvc1_in_ep: endpoint { - remote-endpoint = <&mvc1_cif_in_ep>; - }; - }; - - port@1b { - reg = <0x1b>; - - xbar_mvc1_out_ep: endpoint { - remote-endpoint = <&mvc1_cif_out_ep>; - }; - }; - - xbar_mvc2_in_port: port@1c { - reg = <0x1c>; - - xbar_mvc2_in_ep: endpoint { - remote-endpoint = <&mvc2_cif_in_ep>; - }; - }; - - port@1d { - reg = <0x1d>; - - xbar_mvc2_out_ep: endpoint { - remote-endpoint = <&mvc2_cif_out_ep>; - }; - }; - - xbar_amx1_in1_port: port@1e { - reg = <0x1e>; - - xbar_amx1_in1_ep: endpoint { - remote-endpoint = <&amx1_in1_ep>; - }; - }; - - xbar_amx1_in2_port: port@1f { - reg = <0x1f>; - - xbar_amx1_in2_ep: endpoint { - remote-endpoint = <&amx1_in2_ep>; - }; - }; - - xbar_amx1_in3_port: port@20 { - reg = <0x20>; - - xbar_amx1_in3_ep: endpoint { - remote-endpoint = <&amx1_in3_ep>; - }; - }; - - xbar_amx1_in4_port: port@21 { - reg = <0x21>; - - xbar_amx1_in4_ep: endpoint { - remote-endpoint = <&amx1_in4_ep>; - }; - }; - - port@22 { - reg = <0x22>; - - xbar_amx1_out_ep: endpoint { - remote-endpoint = <&amx1_out_ep>; - }; - }; - - xbar_amx2_in1_port: port@23 { - reg = <0x23>; - - xbar_amx2_in1_ep: endpoint { - remote-endpoint = <&amx2_in1_ep>; - }; - }; - - xbar_amx2_in2_port: port@24 { - reg = <0x24>; - - xbar_amx2_in2_ep: endpoint { - remote-endpoint = <&amx2_in2_ep>; - }; - }; - - xbar_amx2_in3_port: port@25 { - reg = <0x25>; - - xbar_amx2_in3_ep: endpoint { - remote-endpoint = <&amx2_in3_ep>; - }; - }; - - xbar_amx2_in4_port: port@26 { - reg = <0x26>; - - xbar_amx2_in4_ep: endpoint { - remote-endpoint = <&amx2_in4_ep>; - }; - }; - - port@27 { - reg = <0x27>; - - xbar_amx2_out_ep: endpoint { - remote-endpoint = <&amx2_out_ep>; - }; - }; - - xbar_adx1_in_port: port@28 { - reg = <0x28>; - - xbar_adx1_in_ep: endpoint { - remote-endpoint = <&adx1_in_ep>; - }; - }; - - port@29 { - reg = <0x29>; - - xbar_adx1_out1_ep: endpoint { - remote-endpoint = <&adx1_out1_ep>; - }; - }; - - port@2a { - reg = <0x2a>; - - xbar_adx1_out2_ep: endpoint { - remote-endpoint = <&adx1_out2_ep>; - }; - }; - - port@2b { - reg = <0x2b>; - - xbar_adx1_out3_ep: endpoint { - remote-endpoint = <&adx1_out3_ep>; - }; - }; - - port@2c { - reg = <0x2c>; - - xbar_adx1_out4_ep: endpoint { - remote-endpoint = <&adx1_out4_ep>; - }; - }; - - xbar_adx2_in_port: port@2d { - reg = <0x2d>; - - xbar_adx2_in_ep: endpoint { - remote-endpoint = <&adx2_in_ep>; - }; - }; - - port@2e { - reg = <0x2e>; - - xbar_adx2_out1_ep: endpoint { - remote-endpoint = <&adx2_out1_ep>; - }; - }; - - port@2f { - reg = <0x2f>; - - xbar_adx2_out2_ep: endpoint { - remote-endpoint = <&adx2_out2_ep>; - }; - }; - - port@30 { - reg = <0x30>; - - xbar_adx2_out3_ep: endpoint { - remote-endpoint = <&adx2_out3_ep>; - }; - }; - - port@31 { - reg = <0x31>; - - xbar_adx2_out4_ep: endpoint { - remote-endpoint = <&adx2_out4_ep>; - }; - }; - - xbar_mixer_in1_port: port@32 { - reg = <0x32>; - - xbar_mixer_in1_ep: endpoint { - remote-endpoint = <&mixer_in1_ep>; - }; - }; - - xbar_mixer_in2_port: port@33 { - reg = <0x33>; - - xbar_mixer_in2_ep: endpoint { - remote-endpoint = <&mixer_in2_ep>; - }; - }; - - xbar_mixer_in3_port: port@34 { - reg = <0x34>; - - xbar_mixer_in3_ep: endpoint { - remote-endpoint = <&mixer_in3_ep>; - }; - }; - - xbar_mixer_in4_port: port@35 { - reg = <0x35>; - - xbar_mixer_in4_ep: endpoint { - remote-endpoint = <&mixer_in4_ep>; - }; - }; - - xbar_mixer_in5_port: port@36 { - reg = <0x36>; - - xbar_mixer_in5_ep: endpoint { - remote-endpoint = <&mixer_in5_ep>; - }; - }; - - xbar_mixer_in6_port: port@37 { - reg = <0x37>; - - xbar_mixer_in6_ep: endpoint { - remote-endpoint = <&mixer_in6_ep>; - }; - }; - - xbar_mixer_in7_port: port@38 { - reg = <0x38>; - - xbar_mixer_in7_ep: endpoint { - remote-endpoint = <&mixer_in7_ep>; - }; - }; - - xbar_mixer_in8_port: port@39 { - reg = <0x39>; - - xbar_mixer_in8_ep: endpoint { - remote-endpoint = <&mixer_in8_ep>; - }; - }; - - xbar_mixer_in9_port: port@3a { - reg = <0x3a>; - - xbar_mixer_in9_ep: endpoint { - remote-endpoint = <&mixer_in9_ep>; - }; - }; - - xbar_mixer_in10_port: port@3b { - reg = <0x3b>; - - xbar_mixer_in10_ep: endpoint { - remote-endpoint = <&mixer_in10_ep>; - }; - }; - - port@3c { - reg = <0x3c>; - - xbar_mixer_out1_ep: endpoint { - remote-endpoint = <&mixer_out1_ep>; - }; - }; - - port@3d { - reg = <0x3d>; - - xbar_mixer_out2_ep: endpoint { - remote-endpoint = <&mixer_out2_ep>; - }; - }; - - port@3e { - reg = <0x3e>; - - xbar_mixer_out3_ep: endpoint { - remote-endpoint = <&mixer_out3_ep>; - }; - }; - - port@3f { - reg = <0x3f>; - - xbar_mixer_out4_ep: endpoint { - remote-endpoint = <&mixer_out4_ep>; - }; - }; - - port@40 { - reg = <0x40>; - - xbar_mixer_out5_ep: endpoint { - remote-endpoint = <&mixer_out5_ep>; - }; - }; - - xbar_ope1_in_port: port@41 { - reg = <0x41>; - - xbar_ope1_in_ep: endpoint { - remote-endpoint = <&ope1_cif_in_ep>; - }; - }; - - port@42 { - reg = <0x42>; - - xbar_ope1_out_ep: endpoint { - remote-endpoint = <&ope1_cif_out_ep>; - }; - }; - - xbar_ope2_in_port: port@43 { - reg = <0x43>; - - xbar_ope2_in_ep: endpoint { - remote-endpoint = <&ope2_cif_in_ep>; - }; - }; - - port@44 { - reg = <0x44>; - - xbar_ope2_out_ep: endpoint { - remote-endpoint = <&ope2_cif_out_ep>; - }; - }; }; };
diff --git a/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts b/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts index d78b9bd4..de4c4c1 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts +++ b/arch/arm64/boot/dts/nvidia/tegra210-p3450-0000.dts
@@ -624,1071 +624,70 @@ admaif@702d0000 { i2s@702d1200 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - i2s3_cif_ep: endpoint { - remote-endpoint = <&xbar_i2s3_ep>; - }; - }; - - i2s3_port: port@1 { - reg = <1>; - - i2s3_dap_ep: endpoint { - dai-format = "i2s"; - /* Placeholder for external Codec */ - }; - }; - }; }; i2s@702d1300 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - i2s4_cif_ep: endpoint { - remote-endpoint = <&xbar_i2s4_ep>; - }; - }; - - i2s4_port: port@1 { - reg = <1>; - - i2s4_dap_ep: endpoint { - dai-format = "i2s"; - /* Placeholder for external Codec */ - }; - }; - }; }; sfc@702d2000 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - sfc1_cif_in_ep: endpoint { - remote-endpoint = <&xbar_sfc1_in_ep>; - }; - }; - - sfc1_out_port: port@1 { - reg = <1>; - - sfc1_cif_out_ep: endpoint { - remote-endpoint = <&xbar_sfc1_out_ep>; - }; - }; - }; }; sfc@702d2200 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - sfc2_cif_in_ep: endpoint { - remote-endpoint = <&xbar_sfc2_in_ep>; - }; - }; - - sfc2_out_port: port@1 { - reg = <1>; - - sfc2_cif_out_ep: endpoint { - remote-endpoint = <&xbar_sfc2_out_ep>; - }; - }; - }; }; sfc@702d2400 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - sfc3_cif_in_ep: endpoint { - remote-endpoint = <&xbar_sfc3_in_ep>; - }; - }; - - sfc3_out_port: port@1 { - reg = <1>; - - sfc3_cif_out_ep: endpoint { - remote-endpoint = <&xbar_sfc3_out_ep>; - }; - }; - }; }; sfc@702d2600 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - sfc4_cif_in_ep: endpoint { - remote-endpoint = <&xbar_sfc4_in_ep>; - }; - }; - - sfc4_out_port: port@1 { - reg = <1>; - - sfc4_cif_out_ep: endpoint { - remote-endpoint = <&xbar_sfc4_out_ep>; - }; - }; - }; }; amx@702d3000 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - amx1_in1_ep: endpoint { - remote-endpoint = <&xbar_amx1_in1_ep>; - }; - }; - - port@1 { - reg = <1>; - - amx1_in2_ep: endpoint { - remote-endpoint = <&xbar_amx1_in2_ep>; - }; - }; - - port@2 { - reg = <2>; - - amx1_in3_ep: endpoint { - remote-endpoint = <&xbar_amx1_in3_ep>; - }; - }; - - port@3 { - reg = <3>; - - amx1_in4_ep: endpoint { - remote-endpoint = <&xbar_amx1_in4_ep>; - }; - }; - - amx1_out_port: port@4 { - reg = <4>; - - amx1_out_ep: endpoint { - remote-endpoint = <&xbar_amx1_out_ep>; - }; - }; - }; }; amx@702d3100 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - amx2_in1_ep: endpoint { - remote-endpoint = <&xbar_amx2_in1_ep>; - }; - }; - - port@1 { - reg = <1>; - - amx2_in2_ep: endpoint { - remote-endpoint = <&xbar_amx2_in2_ep>; - }; - }; - - amx2_in3_port: port@2 { - reg = <2>; - - amx2_in3_ep: endpoint { - remote-endpoint = <&xbar_amx2_in3_ep>; - }; - }; - - amx2_in4_port: port@3 { - reg = <3>; - - amx2_in4_ep: endpoint { - remote-endpoint = <&xbar_amx2_in4_ep>; - }; - }; - - amx2_out_port: port@4 { - reg = <4>; - - amx2_out_ep: endpoint { - remote-endpoint = <&xbar_amx2_out_ep>; - }; - }; - }; }; adx@702d3800 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - adx1_in_ep: endpoint { - remote-endpoint = <&xbar_adx1_in_ep>; - }; - }; - - adx1_out1_port: port@1 { - reg = <1>; - - adx1_out1_ep: endpoint { - remote-endpoint = <&xbar_adx1_out1_ep>; - }; - }; - - adx1_out2_port: port@2 { - reg = <2>; - - adx1_out2_ep: endpoint { - remote-endpoint = <&xbar_adx1_out2_ep>; - }; - }; - - adx1_out3_port: port@3 { - reg = <3>; - - adx1_out3_ep: endpoint { - remote-endpoint = <&xbar_adx1_out3_ep>; - }; - }; - - adx1_out4_port: port@4 { - reg = <4>; - - adx1_out4_ep: endpoint { - remote-endpoint = <&xbar_adx1_out4_ep>; - }; - }; - }; }; adx@702d3900 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - adx2_in_ep: endpoint { - remote-endpoint = <&xbar_adx2_in_ep>; - }; - }; - - adx2_out1_port: port@1 { - reg = <1>; - - adx2_out1_ep: endpoint { - remote-endpoint = <&xbar_adx2_out1_ep>; - }; - }; - - adx2_out2_port: port@2 { - reg = <2>; - - adx2_out2_ep: endpoint { - remote-endpoint = <&xbar_adx2_out2_ep>; - }; - }; - - adx2_out3_port: port@3 { - reg = <3>; - - adx2_out3_ep: endpoint { - remote-endpoint = <&xbar_adx2_out3_ep>; - }; - }; - - adx2_out4_port: port@4 { - reg = <4>; - - adx2_out4_ep: endpoint { - remote-endpoint = <&xbar_adx2_out4_ep>; - }; - }; - }; }; dmic@702d4000 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - dmic1_cif_ep: endpoint { - remote-endpoint = <&xbar_dmic1_ep>; - }; - }; - - dmic1_port: port@1 { - reg = <1>; - - dmic1_dap_ep: endpoint { - /* Placeholder for external Codec */ - }; - }; - }; }; dmic@702d4100 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - dmic2_cif_ep: endpoint { - remote-endpoint = <&xbar_dmic2_ep>; - }; - }; - - dmic2_port: port@1 { - reg = <1>; - - dmic2_dap_ep: endpoint { - /* Placeholder for external Codec */ - }; - }; - }; }; processing-engine@702d8000 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0x0>; - - ope1_cif_in_ep: endpoint { - remote-endpoint = <&xbar_ope1_in_ep>; - }; - }; - - ope1_out_port: port@1 { - reg = <0x1>; - - ope1_cif_out_ep: endpoint { - remote-endpoint = <&xbar_ope1_out_ep>; - }; - }; - }; }; processing-engine@702d8400 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0x0>; - - ope2_cif_in_ep: endpoint { - remote-endpoint = <&xbar_ope2_in_ep>; - }; - }; - - ope2_out_port: port@1 { - reg = <0x1>; - - ope2_cif_out_ep: endpoint { - remote-endpoint = <&xbar_ope2_out_ep>; - }; - }; - }; }; mvc@702da000 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - mvc1_cif_in_ep: endpoint { - remote-endpoint = <&xbar_mvc1_in_ep>; - }; - }; - - mvc1_out_port: port@1 { - reg = <1>; - - mvc1_cif_out_ep: endpoint { - remote-endpoint = <&xbar_mvc1_out_ep>; - }; - }; - }; }; mvc@702da200 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0>; - - mvc2_cif_in_ep: endpoint { - remote-endpoint = <&xbar_mvc2_in_ep>; - }; - }; - - mvc2_out_port: port@1 { - reg = <1>; - - mvc2_cif_out_ep: endpoint { - remote-endpoint = <&xbar_mvc2_out_ep>; - }; - }; - }; }; amixer@702dbb00 { status = "okay"; - - ports { - #address-cells = <1>; - #size-cells = <0>; - - port@0 { - reg = <0x0>; - - mixer_in1_ep: endpoint { - remote-endpoint = <&xbar_mixer_in1_ep>; - }; - }; - - port@1 { - reg = <0x1>; - - mixer_in2_ep: endpoint { - remote-endpoint = <&xbar_mixer_in2_ep>; - }; - }; - - port@2 { - reg = <0x2>; - - mixer_in3_ep: endpoint { - remote-endpoint = <&xbar_mixer_in3_ep>; - }; - }; - - port@3 { - reg = <0x3>; - - mixer_in4_ep: endpoint { - remote-endpoint = <&xbar_mixer_in4_ep>; - }; - }; - - port@4 { - reg = <0x4>; - - mixer_in5_ep: endpoint { - remote-endpoint = <&xbar_mixer_in5_ep>; - }; - }; - - port@5 { - reg = <0x5>; - - mixer_in6_ep: endpoint { - remote-endpoint = <&xbar_mixer_in6_ep>; - }; - }; - - port@6 { - reg = <0x6>; - - mixer_in7_ep: endpoint { - remote-endpoint = <&xbar_mixer_in7_ep>; - }; - }; - - port@7 { - reg = <0x7>; - - mixer_in8_ep: endpoint { - remote-endpoint = <&xbar_mixer_in8_ep>; - }; - }; - - port@8 { - reg = <0x8>; - - mixer_in9_ep: endpoint { - remote-endpoint = <&xbar_mixer_in9_ep>; - }; - }; - - port@9 { - reg = <0x9>; - - mixer_in10_ep: endpoint { - remote-endpoint = <&xbar_mixer_in10_ep>; - }; - }; - - mixer_out1_port: port@a { - reg = <0xa>; - - mixer_out1_ep: endpoint { - remote-endpoint = <&xbar_mixer_out1_ep>; - }; - }; - - mixer_out2_port: port@b { - reg = <0xb>; - - mixer_out2_ep: endpoint { - remote-endpoint = <&xbar_mixer_out2_ep>; - }; - }; - - mixer_out3_port: port@c { - reg = <0xc>; - - mixer_out3_ep: endpoint { - remote-endpoint = <&xbar_mixer_out3_ep>; - }; - }; - - mixer_out4_port: port@d { - reg = <0xd>; - - mixer_out4_ep: endpoint { - remote-endpoint = <&xbar_mixer_out4_ep>; - }; - }; - - mixer_out5_port: port@e { - reg = <0xe>; - - mixer_out5_ep: endpoint { - remote-endpoint = <&xbar_mixer_out5_ep>; - }; - }; - }; - }; - - ports { - xbar_i2s3_port: port@c { - reg = <0xc>; - - xbar_i2s3_ep: endpoint { - remote-endpoint = <&i2s3_cif_ep>; - }; - }; - - xbar_i2s4_port: port@d { - reg = <0xd>; - - xbar_i2s4_ep: endpoint { - remote-endpoint = <&i2s4_cif_ep>; - }; - }; - - xbar_dmic1_port: port@f { - reg = <0xf>; - - xbar_dmic1_ep: endpoint { - remote-endpoint = <&dmic1_cif_ep>; - }; - }; - - xbar_dmic2_port: port@10 { - reg = <0x10>; - - xbar_dmic2_ep: endpoint { - remote-endpoint = <&dmic2_cif_ep>; - }; - }; - - xbar_sfc1_in_port: port@12 { - reg = <0x12>; - - xbar_sfc1_in_ep: endpoint { - remote-endpoint = <&sfc1_cif_in_ep>; - }; - }; - - port@13 { - reg = <0x13>; - - xbar_sfc1_out_ep: endpoint { - remote-endpoint = <&sfc1_cif_out_ep>; - }; - }; - - xbar_sfc2_in_port: port@14 { - reg = <0x14>; - - xbar_sfc2_in_ep: endpoint { - remote-endpoint = <&sfc2_cif_in_ep>; - }; - }; - - port@15 { - reg = <0x15>; - - xbar_sfc2_out_ep: endpoint { - remote-endpoint = <&sfc2_cif_out_ep>; - }; - }; - - xbar_sfc3_in_port: port@16 { - reg = <0x16>; - - xbar_sfc3_in_ep: endpoint { - remote-endpoint = <&sfc3_cif_in_ep>; - }; - }; - - port@17 { - reg = <0x17>; - - xbar_sfc3_out_ep: endpoint { - remote-endpoint = <&sfc3_cif_out_ep>; - }; - }; - - xbar_sfc4_in_port: port@18 { - reg = <0x18>; - - xbar_sfc4_in_ep: endpoint { - remote-endpoint = <&sfc4_cif_in_ep>; - }; - }; - - port@19 { - reg = <0x19>; - - xbar_sfc4_out_ep: endpoint { - remote-endpoint = <&sfc4_cif_out_ep>; - }; - }; - - xbar_mvc1_in_port: port@1a { - reg = <0x1a>; - - xbar_mvc1_in_ep: endpoint { - remote-endpoint = <&mvc1_cif_in_ep>; - }; - }; - - port@1b { - reg = <0x1b>; - - xbar_mvc1_out_ep: endpoint { - remote-endpoint = <&mvc1_cif_out_ep>; - }; - }; - - xbar_mvc2_in_port: port@1c { - reg = <0x1c>; - - xbar_mvc2_in_ep: endpoint { - remote-endpoint = <&mvc2_cif_in_ep>; - }; - }; - - port@1d { - reg = <0x1d>; - - xbar_mvc2_out_ep: endpoint { - remote-endpoint = <&mvc2_cif_out_ep>; - }; - }; - - xbar_amx1_in1_port: port@1e { - reg = <0x1e>; - - xbar_amx1_in1_ep: endpoint { - remote-endpoint = <&amx1_in1_ep>; - }; - }; - - xbar_amx1_in2_port: port@1f { - reg = <0x1f>; - - xbar_amx1_in2_ep: endpoint { - remote-endpoint = <&amx1_in2_ep>; - }; - }; - - xbar_amx1_in3_port: port@20 { - reg = <0x20>; - - xbar_amx1_in3_ep: endpoint { - remote-endpoint = <&amx1_in3_ep>; - }; - }; - - xbar_amx1_in4_port: port@21 { - reg = <0x21>; - - xbar_amx1_in4_ep: endpoint { - remote-endpoint = <&amx1_in4_ep>; - }; - }; - - port@22 { - reg = <0x22>; - - xbar_amx1_out_ep: endpoint { - remote-endpoint = <&amx1_out_ep>; - }; - }; - - xbar_amx2_in1_port: port@23 { - reg = <0x23>; - - xbar_amx2_in1_ep: endpoint { - remote-endpoint = <&amx2_in1_ep>; - }; - }; - - xbar_amx2_in2_port: port@24 { - reg = <0x24>; - - xbar_amx2_in2_ep: endpoint { - remote-endpoint = <&amx2_in2_ep>; - }; - }; - - xbar_amx2_in3_port: port@25 { - reg = <0x25>; - - xbar_amx2_in3_ep: endpoint { - remote-endpoint = <&amx2_in3_ep>; - }; - }; - - xbar_amx2_in4_port: port@26 { - reg = <0x26>; - - xbar_amx2_in4_ep: endpoint { - remote-endpoint = <&amx2_in4_ep>; - }; - }; - - port@27 { - reg = <0x27>; - - xbar_amx2_out_ep: endpoint { - remote-endpoint = <&amx2_out_ep>; - }; - }; - - xbar_adx1_in_port: port@28 { - reg = <0x28>; - - xbar_adx1_in_ep: endpoint { - remote-endpoint = <&adx1_in_ep>; - }; - }; - - port@29 { - reg = <0x29>; - - xbar_adx1_out1_ep: endpoint { - remote-endpoint = <&adx1_out1_ep>; - }; - }; - - port@2a { - reg = <0x2a>; - - xbar_adx1_out2_ep: endpoint { - remote-endpoint = <&adx1_out2_ep>; - }; - }; - - port@2b { - reg = <0x2b>; - - xbar_adx1_out3_ep: endpoint { - remote-endpoint = <&adx1_out3_ep>; - }; - }; - - port@2c { - reg = <0x2c>; - - xbar_adx1_out4_ep: endpoint { - remote-endpoint = <&adx1_out4_ep>; - }; - }; - - xbar_adx2_in_port: port@2d { - reg = <0x2d>; - - xbar_adx2_in_ep: endpoint { - remote-endpoint = <&adx2_in_ep>; - }; - }; - - port@2e { - reg = <0x2e>; - - xbar_adx2_out1_ep: endpoint { - remote-endpoint = <&adx2_out1_ep>; - }; - }; - - port@2f { - reg = <0x2f>; - - xbar_adx2_out2_ep: endpoint { - remote-endpoint = <&adx2_out2_ep>; - }; - }; - - port@30 { - reg = <0x30>; - - xbar_adx2_out3_ep: endpoint { - remote-endpoint = <&adx2_out3_ep>; - }; - }; - - port@31 { - reg = <0x31>; - - xbar_adx2_out4_ep: endpoint { - remote-endpoint = <&adx2_out4_ep>; - }; - }; - - xbar_mixer_in1_port: port@32 { - reg = <0x32>; - - xbar_mixer_in1_ep: endpoint { - remote-endpoint = <&mixer_in1_ep>; - }; - }; - - xbar_mixer_in2_port: port@33 { - reg = <0x33>; - - xbar_mixer_in2_ep: endpoint { - remote-endpoint = <&mixer_in2_ep>; - }; - }; - - xbar_mixer_in3_port: port@34 { - reg = <0x34>; - - xbar_mixer_in3_ep: endpoint { - remote-endpoint = <&mixer_in3_ep>; - }; - }; - - xbar_mixer_in4_port: port@35 { - reg = <0x35>; - - xbar_mixer_in4_ep: endpoint { - remote-endpoint = <&mixer_in4_ep>; - }; - }; - - xbar_mixer_in5_port: port@36 { - reg = <0x36>; - - xbar_mixer_in5_ep: endpoint { - remote-endpoint = <&mixer_in5_ep>; - }; - }; - - xbar_mixer_in6_port: port@37 { - reg = <0x37>; - - xbar_mixer_in6_ep: endpoint { - remote-endpoint = <&mixer_in6_ep>; - }; - }; - - xbar_mixer_in7_port: port@38 { - reg = <0x38>; - - xbar_mixer_in7_ep: endpoint { - remote-endpoint = <&mixer_in7_ep>; - }; - }; - - xbar_mixer_in8_port: port@39 { - reg = <0x39>; - - xbar_mixer_in8_ep: endpoint { - remote-endpoint = <&mixer_in8_ep>; - }; - }; - - xbar_mixer_in9_port: port@3a { - reg = <0x3a>; - - xbar_mixer_in9_ep: endpoint { - remote-endpoint = <&mixer_in9_ep>; - }; - }; - - xbar_mixer_in10_port: port@3b { - reg = <0x3b>; - - xbar_mixer_in10_ep: endpoint { - remote-endpoint = <&mixer_in10_ep>; - }; - }; - - port@3c { - reg = <0x3c>; - - xbar_mixer_out1_ep: endpoint { - remote-endpoint = <&mixer_out1_ep>; - }; - }; - - port@3d { - reg = <0x3d>; - - xbar_mixer_out2_ep: endpoint { - remote-endpoint = <&mixer_out2_ep>; - }; - }; - - port@3e { - reg = <0x3e>; - - xbar_mixer_out3_ep: endpoint { - remote-endpoint = <&mixer_out3_ep>; - }; - }; - - port@3f { - reg = <0x3f>; - - xbar_mixer_out4_ep: endpoint { - remote-endpoint = <&mixer_out4_ep>; - }; - }; - - port@40 { - reg = <0x40>; - - xbar_mixer_out5_ep: endpoint { - remote-endpoint = <&mixer_out5_ep>; - }; - }; - - xbar_ope1_in_port: port@41 { - reg = <0x41>; - - xbar_ope1_in_ep: endpoint { - remote-endpoint = <&ope1_cif_in_ep>; - }; - }; - - port@42 { - reg = <0x42>; - - xbar_ope1_out_ep: endpoint { - remote-endpoint = <&ope1_cif_out_ep>; - }; - }; - - xbar_ope2_in_port: port@43 { - reg = <0x43>; - - xbar_ope2_in_ep: endpoint { - remote-endpoint = <&ope2_cif_in_ep>; - }; - }; - - port@44 { - reg = <0x44>; - - xbar_ope2_out_ep: endpoint { - remote-endpoint = <&ope2_cif_out_ep>; - }; - }; }; }; @@ -1750,7 +749,7 @@ key-force-recovery { label = "Force Recovery"; gpios = <&gpio TEGRA_GPIO(X, 6) GPIO_ACTIVE_LOW>; linux,input-type = <EV_KEY>; - linux,code = <BTN_1>; + linux,code = <KEY_SLEEP>; debounce-interval = <30>; }; @@ -1968,22 +967,22 @@ cpu_trip_passive: passive { }; cooling-maps { - cpu-critical { + map-critical { cooling-device = <&fan 3 3>; trip = <&cpu_trip_critical>; }; - cpu-hot { + map-hot { cooling-device = <&fan 2 2>; trip = <&cpu_trip_hot>; }; - cpu-active { + map-active { cooling-device = <&fan 1 1>; trip = <&cpu_trip_active>; }; - cpu-passive { + map-passive { cooling-device = <&fan 0 0>; trip = <&cpu_trip_passive>; };
diff --git a/arch/arm64/boot/dts/nvidia/tegra210.dtsi b/arch/arm64/boot/dts/nvidia/tegra210.dtsi index 5f5e537..49d2250 100644 --- a/arch/arm64/boot/dts/nvidia/tegra210.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra210.dtsi
@@ -1065,7 +1065,7 @@ hda@70030000 { reg = <0x0 0x70030000 0x0 0x10000>; interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>; clocks = <&tegra_car TEGRA210_CLK_HDA>, - <&tegra_car TEGRA210_CLK_HDA2HDMI>, + <&tegra_car TEGRA210_CLK_HDA2HDMI>, <&tegra_car TEGRA210_CLK_HDA2CODEC_2X>; clock-names = "hda", "hda2hdmi", "hda2codec_2x"; resets = <&tegra_car 125>, /* hda */ @@ -1461,7 +1461,7 @@ tegra_ahub: ahub@702d0800 { assigned-clock-rates = <81600000>; #address-cells = <1>; #size-cells = <1>; - ranges = <0x702d0000 0x702d0000 0x0000e400>; + ranges = <0x702d0000 0x702d0000 0x00010000>; status = "disabled"; tegra_admaif: admaif@702d0000 { @@ -1586,6 +1586,28 @@ tegra_i2s1: i2s@702d1000 { assigned-clock-rates = <1536000>; sound-name-prefix = "I2S1"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2s1_cif_ep: endpoint { + remote-endpoint = <&xbar_i2s1_ep>; + }; + }; + + i2s1_port: port@1 { + reg = <1>; + + i2s1_dap_ep: endpoint { + dai-format = "i2s"; + /* Placeholder for external Codec */ + }; + }; + }; }; tegra_i2s2: i2s@702d1100 { @@ -1599,6 +1621,28 @@ tegra_i2s2: i2s@702d1100 { assigned-clock-rates = <1536000>; sound-name-prefix = "I2S2"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2s2_cif_ep: endpoint { + remote-endpoint = <&xbar_i2s2_ep>; + }; + }; + + i2s2_port: port@1 { + reg = <1>; + + i2s2_dap_ep: endpoint { + dai-format = "i2s"; + /* Placeholder for external Codec */ + }; + }; + }; }; tegra_i2s3: i2s@702d1200 { @@ -1612,6 +1656,28 @@ tegra_i2s3: i2s@702d1200 { assigned-clock-rates = <1536000>; sound-name-prefix = "I2S3"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2s3_cif_ep: endpoint { + remote-endpoint = <&xbar_i2s3_ep>; + }; + }; + + i2s3_port: port@1 { + reg = <1>; + + i2s3_dap_ep: endpoint { + dai-format = "i2s"; + /* Placeholder for external Codec */ + }; + }; + }; }; tegra_i2s4: i2s@702d1300 { @@ -1625,6 +1691,28 @@ tegra_i2s4: i2s@702d1300 { assigned-clock-rates = <1536000>; sound-name-prefix = "I2S4"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2s4_cif_ep: endpoint { + remote-endpoint = <&xbar_i2s4_ep>; + }; + }; + + i2s4_port: port@1 { + reg = <1>; + + i2s4_dap_ep: endpoint { + dai-format = "i2s"; + /* Placeholder for external Codec */ + }; + }; + }; }; tegra_i2s5: i2s@702d1400 { @@ -1638,6 +1726,28 @@ tegra_i2s5: i2s@702d1400 { assigned-clock-rates = <1536000>; sound-name-prefix = "I2S5"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + i2s5_cif_ep: endpoint { + remote-endpoint = <&xbar_i2s5_ep>; + }; + }; + + i2s5_port: port@1 { + reg = <1>; + + i2s5_dap_ep: endpoint { + dai-format = "i2s"; + /* Placeholder for external Codec */ + }; + }; + }; }; tegra_sfc1: sfc@702d2000 { @@ -1645,6 +1755,27 @@ tegra_sfc1: sfc@702d2000 { reg = <0x702d2000 0x200>; sound-name-prefix = "SFC1"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + sfc1_cif_in_ep: endpoint { + remote-endpoint = <&xbar_sfc1_in_ep>; + }; + }; + + sfc1_out_port: port@1 { + reg = <1>; + + sfc1_cif_out_ep: endpoint { + remote-endpoint = <&xbar_sfc1_out_ep>; + }; + }; + }; }; tegra_sfc2: sfc@702d2200 { @@ -1652,6 +1783,27 @@ tegra_sfc2: sfc@702d2200 { reg = <0x702d2200 0x200>; sound-name-prefix = "SFC2"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + sfc2_cif_in_ep: endpoint { + remote-endpoint = <&xbar_sfc2_in_ep>; + }; + }; + + sfc2_out_port: port@1 { + reg = <1>; + + sfc2_cif_out_ep: endpoint { + remote-endpoint = <&xbar_sfc2_out_ep>; + }; + }; + }; }; tegra_sfc3: sfc@702d2400 { @@ -1659,6 +1811,27 @@ tegra_sfc3: sfc@702d2400 { reg = <0x702d2400 0x200>; sound-name-prefix = "SFC3"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + sfc3_cif_in_ep: endpoint { + remote-endpoint = <&xbar_sfc3_in_ep>; + }; + }; + + sfc3_out_port: port@1 { + reg = <1>; + + sfc3_cif_out_ep: endpoint { + remote-endpoint = <&xbar_sfc3_out_ep>; + }; + }; + }; }; tegra_sfc4: sfc@702d2600 { @@ -1666,6 +1839,27 @@ tegra_sfc4: sfc@702d2600 { reg = <0x702d2600 0x200>; sound-name-prefix = "SFC4"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + sfc4_cif_in_ep: endpoint { + remote-endpoint = <&xbar_sfc4_in_ep>; + }; + }; + + sfc4_out_port: port@1 { + reg = <1>; + + sfc4_cif_out_ep: endpoint { + remote-endpoint = <&xbar_sfc4_out_ep>; + }; + }; + }; }; tegra_amx1: amx@702d3000 { @@ -1673,6 +1867,51 @@ tegra_amx1: amx@702d3000 { reg = <0x702d3000 0x100>; sound-name-prefix = "AMX1"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + amx1_in1_ep: endpoint { + remote-endpoint = <&xbar_amx1_in1_ep>; + }; + }; + + port@1 { + reg = <1>; + + amx1_in2_ep: endpoint { + remote-endpoint = <&xbar_amx1_in2_ep>; + }; + }; + + port@2 { + reg = <2>; + + amx1_in3_ep: endpoint { + remote-endpoint = <&xbar_amx1_in3_ep>; + }; + }; + + port@3 { + reg = <3>; + + amx1_in4_ep: endpoint { + remote-endpoint = <&xbar_amx1_in4_ep>; + }; + }; + + amx1_out_port: port@4 { + reg = <4>; + + amx1_out_ep: endpoint { + remote-endpoint = <&xbar_amx1_out_ep>; + }; + }; + }; }; tegra_amx2: amx@702d3100 { @@ -1680,6 +1919,51 @@ tegra_amx2: amx@702d3100 { reg = <0x702d3100 0x100>; sound-name-prefix = "AMX2"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + amx2_in1_ep: endpoint { + remote-endpoint = <&xbar_amx2_in1_ep>; + }; + }; + + port@1 { + reg = <1>; + + amx2_in2_ep: endpoint { + remote-endpoint = <&xbar_amx2_in2_ep>; + }; + }; + + amx2_in3_port: port@2 { + reg = <2>; + + amx2_in3_ep: endpoint { + remote-endpoint = <&xbar_amx2_in3_ep>; + }; + }; + + amx2_in4_port: port@3 { + reg = <3>; + + amx2_in4_ep: endpoint { + remote-endpoint = <&xbar_amx2_in4_ep>; + }; + }; + + amx2_out_port: port@4 { + reg = <4>; + + amx2_out_ep: endpoint { + remote-endpoint = <&xbar_amx2_out_ep>; + }; + }; + }; }; tegra_adx1: adx@702d3800 { @@ -1687,6 +1971,51 @@ tegra_adx1: adx@702d3800 { reg = <0x702d3800 0x100>; sound-name-prefix = "ADX1"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + adx1_in_ep: endpoint { + remote-endpoint = <&xbar_adx1_in_ep>; + }; + }; + + adx1_out1_port: port@1 { + reg = <1>; + + adx1_out1_ep: endpoint { + remote-endpoint = <&xbar_adx1_out1_ep>; + }; + }; + + adx1_out2_port: port@2 { + reg = <2>; + + adx1_out2_ep: endpoint { + remote-endpoint = <&xbar_adx1_out2_ep>; + }; + }; + + adx1_out3_port: port@3 { + reg = <3>; + + adx1_out3_ep: endpoint { + remote-endpoint = <&xbar_adx1_out3_ep>; + }; + }; + + adx1_out4_port: port@4 { + reg = <4>; + + adx1_out4_ep: endpoint { + remote-endpoint = <&xbar_adx1_out4_ep>; + }; + }; + }; }; tegra_adx2: adx@702d3900 { @@ -1694,6 +2023,51 @@ tegra_adx2: adx@702d3900 { reg = <0x702d3900 0x100>; sound-name-prefix = "ADX2"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + adx2_in_ep: endpoint { + remote-endpoint = <&xbar_adx2_in_ep>; + }; + }; + + adx2_out1_port: port@1 { + reg = <1>; + + adx2_out1_ep: endpoint { + remote-endpoint = <&xbar_adx2_out1_ep>; + }; + }; + + adx2_out2_port: port@2 { + reg = <2>; + + adx2_out2_ep: endpoint { + remote-endpoint = <&xbar_adx2_out2_ep>; + }; + }; + + adx2_out3_port: port@3 { + reg = <3>; + + adx2_out3_ep: endpoint { + remote-endpoint = <&xbar_adx2_out3_ep>; + }; + }; + + adx2_out4_port: port@4 { + reg = <4>; + + adx2_out4_ep: endpoint { + remote-endpoint = <&xbar_adx2_out4_ep>; + }; + }; + }; }; tegra_dmic1: dmic@702d4000 { @@ -1706,6 +2080,27 @@ tegra_dmic1: dmic@702d4000 { assigned-clock-rates = <3072000>; sound-name-prefix = "DMIC1"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dmic1_cif_ep: endpoint { + remote-endpoint = <&xbar_dmic1_ep>; + }; + }; + + dmic1_port: port@1 { + reg = <1>; + + dmic1_dap_ep: endpoint { + /* Placeholder for external Codec */ + }; + }; + }; }; tegra_dmic2: dmic@702d4100 { @@ -1718,6 +2113,27 @@ tegra_dmic2: dmic@702d4100 { assigned-clock-rates = <3072000>; sound-name-prefix = "DMIC2"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dmic2_cif_ep: endpoint { + remote-endpoint = <&xbar_dmic2_ep>; + }; + }; + + dmic2_port: port@1 { + reg = <1>; + + dmic2_dap_ep: endpoint { + /* Placeholder for external Codec */ + }; + }; + }; }; tegra_dmic3: dmic@702d4200 { @@ -1730,6 +2146,27 @@ tegra_dmic3: dmic@702d4200 { assigned-clock-rates = <3072000>; sound-name-prefix = "DMIC3"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dmic3_cif_ep: endpoint { + remote-endpoint = <&xbar_dmic3_ep>; + }; + }; + + dmic3_port: port@1 { + reg = <1>; + + dmic3_dap_ep: endpoint { + /* Placeholder for external Codec */ + }; + }; + }; }; tegra_ope1: processing-engine@702d8000 { @@ -1750,6 +2187,27 @@ dynamic-range-compressor@702d8200 { compatible = "nvidia,tegra210-mbdrc"; reg = <0x702d8200 0x200>; }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0x0>; + + ope1_cif_in_ep: endpoint { + remote-endpoint = <&xbar_ope1_in_ep>; + }; + }; + + ope1_out_port: port@1 { + reg = <0x1>; + + ope1_cif_out_ep: endpoint { + remote-endpoint = <&xbar_ope1_out_ep>; + }; + }; + }; }; tegra_ope2: processing-engine@702d8400 { @@ -1770,6 +2228,27 @@ dynamic-range-compressor@702d8600 { compatible = "nvidia,tegra210-mbdrc"; reg = <0x702d8600 0x200>; }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0x0>; + + ope2_cif_in_ep: endpoint { + remote-endpoint = <&xbar_ope2_in_ep>; + }; + }; + + ope2_out_port: port@1 { + reg = <0x1>; + + ope2_cif_out_ep: endpoint { + remote-endpoint = <&xbar_ope2_out_ep>; + }; + }; + }; }; tegra_mvc1: mvc@702da000 { @@ -1777,6 +2256,27 @@ tegra_mvc1: mvc@702da000 { reg = <0x702da000 0x200>; sound-name-prefix = "MVC1"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mvc1_cif_in_ep: endpoint { + remote-endpoint = <&xbar_mvc1_in_ep>; + }; + }; + + mvc1_out_port: port@1 { + reg = <1>; + + mvc1_cif_out_ep: endpoint { + remote-endpoint = <&xbar_mvc1_out_ep>; + }; + }; + }; }; tegra_mvc2: mvc@702da200 { @@ -1784,6 +2284,27 @@ tegra_mvc2: mvc@702da200 { reg = <0x702da200 0x200>; sound-name-prefix = "MVC2"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + mvc2_cif_in_ep: endpoint { + remote-endpoint = <&xbar_mvc2_in_ep>; + }; + }; + + mvc2_out_port: port@1 { + reg = <1>; + + mvc2_cif_out_ep: endpoint { + remote-endpoint = <&xbar_mvc2_out_ep>; + }; + }; + }; }; tegra_amixer: amixer@702dbb00 { @@ -1791,6 +2312,131 @@ tegra_amixer: amixer@702dbb00 { reg = <0x702dbb00 0x800>; sound-name-prefix = "MIXER1"; status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0x0>; + + mixer_in1_ep: endpoint { + remote-endpoint = <&xbar_mixer_in1_ep>; + }; + }; + + port@1 { + reg = <0x1>; + + mixer_in2_ep: endpoint { + remote-endpoint = <&xbar_mixer_in2_ep>; + }; + }; + + port@2 { + reg = <0x2>; + + mixer_in3_ep: endpoint { + remote-endpoint = <&xbar_mixer_in3_ep>; + }; + }; + + port@3 { + reg = <0x3>; + + mixer_in4_ep: endpoint { + remote-endpoint = <&xbar_mixer_in4_ep>; + }; + }; + + port@4 { + reg = <0x4>; + + mixer_in5_ep: endpoint { + remote-endpoint = <&xbar_mixer_in5_ep>; + }; + }; + + port@5 { + reg = <0x5>; + + mixer_in6_ep: endpoint { + remote-endpoint = <&xbar_mixer_in6_ep>; + }; + }; + + port@6 { + reg = <0x6>; + + mixer_in7_ep: endpoint { + remote-endpoint = <&xbar_mixer_in7_ep>; + }; + }; + + port@7 { + reg = <0x7>; + + mixer_in8_ep: endpoint { + remote-endpoint = <&xbar_mixer_in8_ep>; + }; + }; + + port@8 { + reg = <0x8>; + + mixer_in9_ep: endpoint { + remote-endpoint = <&xbar_mixer_in9_ep>; + }; + }; + + port@9 { + reg = <0x9>; + + mixer_in10_ep: endpoint { + remote-endpoint = <&xbar_mixer_in10_ep>; + }; + }; + + mixer_out1_port: port@a { + reg = <0xa>; + + mixer_out1_ep: endpoint { + remote-endpoint = <&xbar_mixer_out1_ep>; + }; + }; + + mixer_out2_port: port@b { + reg = <0xb>; + + mixer_out2_ep: endpoint { + remote-endpoint = <&xbar_mixer_out2_ep>; + }; + }; + + mixer_out3_port: port@c { + reg = <0xc>; + + mixer_out3_ep: endpoint { + remote-endpoint = <&xbar_mixer_out3_ep>; + }; + }; + + mixer_out4_port: port@d { + reg = <0xd>; + + mixer_out4_ep: endpoint { + remote-endpoint = <&xbar_mixer_out4_ep>; + }; + }; + + mixer_out5_port: port@e { + reg = <0xe>; + + mixer_out5_ep: endpoint { + remote-endpoint = <&xbar_mixer_out5_ep>; + }; + }; + }; }; ports { @@ -1874,6 +2520,478 @@ xbar_admaif10_ep: endpoint { remote-endpoint = <&admaif10_ep>; }; }; + + xbar_i2s1_port: port@a { + reg = <0xa>; + + xbar_i2s1_ep: endpoint { + remote-endpoint = <&i2s1_cif_ep>; + }; + }; + + xbar_i2s2_port: port@b { + reg = <0xb>; + + xbar_i2s2_ep: endpoint { + remote-endpoint = <&i2s2_cif_ep>; + }; + }; + + xbar_i2s3_port: port@c { + reg = <0xc>; + + xbar_i2s3_ep: endpoint { + remote-endpoint = <&i2s3_cif_ep>; + }; + }; + + xbar_i2s4_port: port@d { + reg = <0xd>; + + xbar_i2s4_ep: endpoint { + remote-endpoint = <&i2s4_cif_ep>; + }; + }; + + xbar_i2s5_port: port@e { + reg = <0xe>; + + xbar_i2s5_ep: endpoint { + remote-endpoint = <&i2s5_cif_ep>; + }; + }; + + xbar_dmic1_port: port@f { + reg = <0xf>; + + xbar_dmic1_ep: endpoint { + remote-endpoint = <&dmic1_cif_ep>; + }; + }; + + xbar_dmic2_port: port@10 { + reg = <0x10>; + + xbar_dmic2_ep: endpoint { + remote-endpoint = <&dmic2_cif_ep>; + }; + }; + + xbar_dmic3_port: port@11 { + reg = <0x11>; + + xbar_dmic3_ep: endpoint { + remote-endpoint = <&dmic3_cif_ep>; + }; + }; + + xbar_sfc1_in_port: port@12 { + reg = <0x12>; + + xbar_sfc1_in_ep: endpoint { + remote-endpoint = <&sfc1_cif_in_ep>; + }; + }; + + port@13 { + reg = <0x13>; + + xbar_sfc1_out_ep: endpoint { + remote-endpoint = <&sfc1_cif_out_ep>; + }; + }; + + xbar_sfc2_in_port: port@14 { + reg = <0x14>; + + xbar_sfc2_in_ep: endpoint { + remote-endpoint = <&sfc2_cif_in_ep>; + }; + }; + + port@15 { + reg = <0x15>; + + xbar_sfc2_out_ep: endpoint { + remote-endpoint = <&sfc2_cif_out_ep>; + }; + }; + + xbar_sfc3_in_port: port@16 { + reg = <0x16>; + + xbar_sfc3_in_ep: endpoint { + remote-endpoint = <&sfc3_cif_in_ep>; + }; + }; + + port@17 { + reg = <0x17>; + + xbar_sfc3_out_ep: endpoint { + remote-endpoint = <&sfc3_cif_out_ep>; + }; + }; + + xbar_sfc4_in_port: port@18 { + reg = <0x18>; + + xbar_sfc4_in_ep: endpoint { + remote-endpoint = <&sfc4_cif_in_ep>; + }; + }; + + port@19 { + reg = <0x19>; + + xbar_sfc4_out_ep: endpoint { + remote-endpoint = <&sfc4_cif_out_ep>; + }; + }; + + xbar_mvc1_in_port: port@1a { + reg = <0x1a>; + + xbar_mvc1_in_ep: endpoint { + remote-endpoint = <&mvc1_cif_in_ep>; + }; + }; + + port@1b { + reg = <0x1b>; + + xbar_mvc1_out_ep: endpoint { + remote-endpoint = <&mvc1_cif_out_ep>; + }; + }; + + xbar_mvc2_in_port: port@1c { + reg = <0x1c>; + + xbar_mvc2_in_ep: endpoint { + remote-endpoint = <&mvc2_cif_in_ep>; + }; + }; + + port@1d { + reg = <0x1d>; + + xbar_mvc2_out_ep: endpoint { + remote-endpoint = <&mvc2_cif_out_ep>; + }; + }; + + xbar_amx1_in1_port: port@1e { + reg = <0x1e>; + + xbar_amx1_in1_ep: endpoint { + remote-endpoint = <&amx1_in1_ep>; + }; + }; + + xbar_amx1_in2_port: port@1f { + reg = <0x1f>; + + xbar_amx1_in2_ep: endpoint { + remote-endpoint = <&amx1_in2_ep>; + }; + }; + + xbar_amx1_in3_port: port@20 { + reg = <0x20>; + + xbar_amx1_in3_ep: endpoint { + remote-endpoint = <&amx1_in3_ep>; + }; + }; + + xbar_amx1_in4_port: port@21 { + reg = <0x21>; + + xbar_amx1_in4_ep: endpoint { + remote-endpoint = <&amx1_in4_ep>; + }; + }; + + port@22 { + reg = <0x22>; + + xbar_amx1_out_ep: endpoint { + remote-endpoint = <&amx1_out_ep>; + }; + }; + + xbar_amx2_in1_port: port@23 { + reg = <0x23>; + + xbar_amx2_in1_ep: endpoint { + remote-endpoint = <&amx2_in1_ep>; + }; + }; + + xbar_amx2_in2_port: port@24 { + reg = <0x24>; + + xbar_amx2_in2_ep: endpoint { + remote-endpoint = <&amx2_in2_ep>; + }; + }; + + xbar_amx2_in3_port: port@25 { + reg = <0x25>; + + xbar_amx2_in3_ep: endpoint { + remote-endpoint = <&amx2_in3_ep>; + }; + }; + + xbar_amx2_in4_port: port@26 { + reg = <0x26>; + + xbar_amx2_in4_ep: endpoint { + remote-endpoint = <&amx2_in4_ep>; + }; + }; + + port@27 { + reg = <0x27>; + + xbar_amx2_out_ep: endpoint { + remote-endpoint = <&amx2_out_ep>; + }; + }; + + xbar_adx1_in_port: port@28 { + reg = <0x28>; + + xbar_adx1_in_ep: endpoint { + remote-endpoint = <&adx1_in_ep>; + }; + }; + + port@29 { + reg = <0x29>; + + xbar_adx1_out1_ep: endpoint { + remote-endpoint = <&adx1_out1_ep>; + }; + }; + + port@2a { + reg = <0x2a>; + + xbar_adx1_out2_ep: endpoint { + remote-endpoint = <&adx1_out2_ep>; + }; + }; + + port@2b { + reg = <0x2b>; + + xbar_adx1_out3_ep: endpoint { + remote-endpoint = <&adx1_out3_ep>; + }; + }; + + port@2c { + reg = <0x2c>; + + xbar_adx1_out4_ep: endpoint { + remote-endpoint = <&adx1_out4_ep>; + }; + }; + + xbar_adx2_in_port: port@2d { + reg = <0x2d>; + + xbar_adx2_in_ep: endpoint { + remote-endpoint = <&adx2_in_ep>; + }; + }; + + port@2e { + reg = <0x2e>; + + xbar_adx2_out1_ep: endpoint { + remote-endpoint = <&adx2_out1_ep>; + }; + }; + + port@2f { + reg = <0x2f>; + + xbar_adx2_out2_ep: endpoint { + remote-endpoint = <&adx2_out2_ep>; + }; + }; + + port@30 { + reg = <0x30>; + + xbar_adx2_out3_ep: endpoint { + remote-endpoint = <&adx2_out3_ep>; + }; + }; + + port@31 { + reg = <0x31>; + + xbar_adx2_out4_ep: endpoint { + remote-endpoint = <&adx2_out4_ep>; + }; + }; + + xbar_mixer_in1_port: port@32 { + reg = <0x32>; + + xbar_mixer_in1_ep: endpoint { + remote-endpoint = <&mixer_in1_ep>; + }; + }; + + xbar_mixer_in2_port: port@33 { + reg = <0x33>; + + xbar_mixer_in2_ep: endpoint { + remote-endpoint = <&mixer_in2_ep>; + }; + }; + + xbar_mixer_in3_port: port@34 { + reg = <0x34>; + + xbar_mixer_in3_ep: endpoint { + remote-endpoint = <&mixer_in3_ep>; + }; + }; + + xbar_mixer_in4_port: port@35 { + reg = <0x35>; + + xbar_mixer_in4_ep: endpoint { + remote-endpoint = <&mixer_in4_ep>; + }; + }; + + xbar_mixer_in5_port: port@36 { + reg = <0x36>; + + xbar_mixer_in5_ep: endpoint { + remote-endpoint = <&mixer_in5_ep>; + }; + }; + + xbar_mixer_in6_port: port@37 { + reg = <0x37>; + + xbar_mixer_in6_ep: endpoint { + remote-endpoint = <&mixer_in6_ep>; + }; + }; + + xbar_mixer_in7_port: port@38 { + reg = <0x38>; + + xbar_mixer_in7_ep: endpoint { + remote-endpoint = <&mixer_in7_ep>; + }; + }; + + xbar_mixer_in8_port: port@39 { + reg = <0x39>; + + xbar_mixer_in8_ep: endpoint { + remote-endpoint = <&mixer_in8_ep>; + }; + }; + + xbar_mixer_in9_port: port@3a { + reg = <0x3a>; + + xbar_mixer_in9_ep: endpoint { + remote-endpoint = <&mixer_in9_ep>; + }; + }; + + xbar_mixer_in10_port: port@3b { + reg = <0x3b>; + + xbar_mixer_in10_ep: endpoint { + remote-endpoint = <&mixer_in10_ep>; + }; + }; + + port@3c { + reg = <0x3c>; + + xbar_mixer_out1_ep: endpoint { + remote-endpoint = <&mixer_out1_ep>; + }; + }; + + port@3d { + reg = <0x3d>; + + xbar_mixer_out2_ep: endpoint { + remote-endpoint = <&mixer_out2_ep>; + }; + }; + + port@3e { + reg = <0x3e>; + + xbar_mixer_out3_ep: endpoint { + remote-endpoint = <&mixer_out3_ep>; + }; + }; + + port@3f { + reg = <0x3f>; + + xbar_mixer_out4_ep: endpoint { + remote-endpoint = <&mixer_out4_ep>; + }; + }; + + port@40 { + reg = <0x40>; + + xbar_mixer_out5_ep: endpoint { + remote-endpoint = <&mixer_out5_ep>; + }; + }; + + xbar_ope1_in_port: port@41 { + reg = <0x41>; + + xbar_ope1_in_ep: endpoint { + remote-endpoint = <&ope1_cif_in_ep>; + }; + }; + + port@42 { + reg = <0x42>; + + xbar_ope1_out_ep: endpoint { + remote-endpoint = <&ope1_cif_out_ep>; + }; + }; + + xbar_ope2_in_port: port@43 { + reg = <0x43>; + + xbar_ope2_in_ep: endpoint { + remote-endpoint = <&ope2_cif_in_ep>; + }; + }; + + port@44 { + reg = <0x44>; + + xbar_ope2_out_ep: endpoint { + remote-endpoint = <&ope2_cif_out_ep>; + }; + }; }; }; @@ -2164,12 +3282,12 @@ mem-shutdown-trip { }; cooling-maps { - dram-passive { + map-passive { cooling-device = <&emc 0 0>; trip = <&dram_nominal>; }; - dram-active { + map-active { cooling-device = <&emc 1 1>; trip = <&dram_throttle>; };
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701.dtsi index 420858a..9b990d1 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234-p3737-0000+p3701.dtsi
@@ -391,7 +391,7 @@ key-force-recovery { label = "Force Recovery"; gpios = <&gpio TEGRA234_MAIN_GPIO(G, 0) GPIO_ACTIVE_LOW>; linux,input-type = <EV_KEY>; - linux,code = <BTN_1>; + linux,code = <KEY_SLEEP>; }; key-power { @@ -402,13 +402,6 @@ key-power { wakeup-event-action = <EV_ACT_ASSERTED>; wakeup-source; }; - - key-suspend { - label = "Suspend"; - gpios = <&gpio TEGRA234_MAIN_GPIO(G, 2) GPIO_ACTIVE_LOW>; - linux,input-type = <EV_KEY>; - linux,code = <KEY_SLEEP>; - }; }; fan: pwm-fan {
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3740-0002+p3701-0008.dts b/arch/arm64/boot/dts/nvidia/tegra234-p3740-0002+p3701-0008.dts index 97cede1..8c8c715 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234-p3740-0002+p3701-0008.dts +++ b/arch/arm64/boot/dts/nvidia/tegra234-p3740-0002+p3701-0008.dts
@@ -93,6 +93,29 @@ rt5640_ep: endpoint { }; }; + typec@28 { + compatible = "st,stusb1600"; + reg = <0x28>; + interrupt-parent = <&gpio>; + interrupts = <TEGRA234_MAIN_GPIO(K, 6) IRQ_TYPE_LEVEL_LOW>; + vdd-supply = <&vdd_5v_sys>; + vsys-supply = <&vdd_3v3_sys>; + + connector { + compatible = "usb-c-connector"; + label = "USB-C"; + data-role = "dual"; + power-role = "dual"; + typec-power-opmode = "default"; + + port { + typec_con_ep: endpoint { + remote-endpoint = <&usb_role_switch0>; + }; + }; + }; + }; + /* carrier board ID EEPROM */ eeprom@55 { compatible = "atmel,24c02"; @@ -173,6 +196,12 @@ usb2-0 { mode = "otg"; usb-role-switch; status = "okay"; + + port { + usb_role_switch0: endpoint { + remote-endpoint = <&typec_con_ep>; + }; + }; }; usb2-1 { @@ -337,7 +366,7 @@ key-force-recovery { label = "Force Recovery"; gpios = <&gpio TEGRA234_MAIN_GPIO(G, 0) GPIO_ACTIVE_LOW>; linux,input-type = <EV_KEY>; - linux,code = <BTN_1>; + linux,code = <KEY_SLEEP>; }; key-power { @@ -348,13 +377,6 @@ key-power { wakeup-event-action = <EV_ACT_ASSERTED>; wakeup-source; }; - - key-suspend { - label = "Suspend"; - gpios = <&gpio TEGRA234_MAIN_GPIO(G, 2) GPIO_ACTIVE_LOW>; - linux,input-type = <EV_KEY>; - linux,code = <KEY_SLEEP>; - }; }; serial { @@ -473,4 +495,11 @@ vdd_3v3_wifi: regulator-vdd-3v3-wifi { regulator-boot-on; enable-active-high; }; + + vdd_5v_sys: regulator-vdd-5v-sys { + compatible = "regulator-fixed"; + regulator-name = "vdd-5v-sys"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; };
diff --git a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767.dtsi b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767.dtsi index 4182135..520b0a2 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234-p3768-0000+p3767.dtsi
@@ -163,6 +163,16 @@ pcie@140a0000 { vddio-pex-ctl-supply = <&vdd_1v8_ao>; vpcie3v3-supply = <&vdd_3v3_pcie>; + + pci@0,0 { + reg = <0x0000 0 0 0 0>; + device_type = "pci"; + #address-cells = <3>; + #size-cells = <2>; + ranges; + + wake-gpios = <&gpio TEGRA234_MAIN_GPIO(L, 2) GPIO_ACTIVE_LOW>; + }; }; /* C1 - M.2 Key-E */ @@ -216,7 +226,7 @@ key-force-recovery { label = "Force Recovery"; gpios = <&gpio TEGRA234_MAIN_GPIO(G, 0) GPIO_ACTIVE_LOW>; linux,input-type = <EV_KEY>; - linux,code = <BTN_1>; + linux,code = <KEY_SLEEP>; }; key-power {
diff --git a/arch/arm64/boot/dts/nvidia/tegra234.dtsi b/arch/arm64/boot/dts/nvidia/tegra234.dtsi index 5e29316..d5ba289 100644 --- a/arch/arm64/boot/dts/nvidia/tegra234.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra234.dtsi
@@ -245,14 +245,14 @@ tegra_ahub: ahub@2900800 { assigned-clock-rates = <81600000>; status = "disabled"; - #address-cells = <2>; - #size-cells = <2>; - ranges = <0x0 0x02900800 0x0 0x02900800 0x0 0x11800>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x02900000 0x0 0x02900000 0x20000>; tegra_i2s1: i2s@2901000 { compatible = "nvidia,tegra234-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901000 0x0 0x100>; + reg = <0x2901000 0x100>; clocks = <&bpmp TEGRA234_CLK_I2S1>, <&bpmp TEGRA234_CLK_I2S1_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -288,7 +288,7 @@ i2s1_dap: endpoint { tegra_i2s2: i2s@2901100 { compatible = "nvidia,tegra234-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901100 0x0 0x100>; + reg = <0x2901100 0x100>; clocks = <&bpmp TEGRA234_CLK_I2S2>, <&bpmp TEGRA234_CLK_I2S2_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -324,7 +324,7 @@ i2s2_dap: endpoint { tegra_i2s3: i2s@2901200 { compatible = "nvidia,tegra234-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901200 0x0 0x100>; + reg = <0x2901200 0x100>; clocks = <&bpmp TEGRA234_CLK_I2S3>, <&bpmp TEGRA234_CLK_I2S3_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -360,7 +360,7 @@ i2s3_dap: endpoint { tegra_i2s4: i2s@2901300 { compatible = "nvidia,tegra234-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901300 0x0 0x100>; + reg = <0x2901300 0x100>; clocks = <&bpmp TEGRA234_CLK_I2S4>, <&bpmp TEGRA234_CLK_I2S4_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -396,7 +396,7 @@ i2s4_dap: endpoint { tegra_i2s5: i2s@2901400 { compatible = "nvidia,tegra234-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901400 0x0 0x100>; + reg = <0x2901400 0x100>; clocks = <&bpmp TEGRA234_CLK_I2S5>, <&bpmp TEGRA234_CLK_I2S5_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -432,7 +432,7 @@ i2s5_dap: endpoint { tegra_i2s6: i2s@2901500 { compatible = "nvidia,tegra234-i2s", "nvidia,tegra210-i2s"; - reg = <0x0 0x2901500 0x0 0x100>; + reg = <0x2901500 0x100>; clocks = <&bpmp TEGRA234_CLK_I2S6>, <&bpmp TEGRA234_CLK_I2S6_SYNC_INPUT>; clock-names = "i2s", "sync_input"; @@ -468,7 +468,7 @@ i2s6_dap: endpoint { tegra_sfc1: sfc@2902000 { compatible = "nvidia,tegra234-sfc", "nvidia,tegra210-sfc"; - reg = <0x0 0x2902000 0x0 0x200>; + reg = <0x2902000 0x200>; sound-name-prefix = "SFC1"; ports { @@ -496,7 +496,7 @@ sfc1_cif_out: endpoint { tegra_sfc2: sfc@2902200 { compatible = "nvidia,tegra234-sfc", "nvidia,tegra210-sfc"; - reg = <0x0 0x2902200 0x0 0x200>; + reg = <0x2902200 0x200>; sound-name-prefix = "SFC2"; ports { @@ -524,7 +524,7 @@ sfc2_cif_out: endpoint { tegra_sfc3: sfc@2902400 { compatible = "nvidia,tegra234-sfc", "nvidia,tegra210-sfc"; - reg = <0x0 0x2902400 0x0 0x200>; + reg = <0x2902400 0x200>; sound-name-prefix = "SFC3"; ports { @@ -552,7 +552,7 @@ sfc3_cif_out: endpoint { tegra_sfc4: sfc@2902600 { compatible = "nvidia,tegra234-sfc", "nvidia,tegra210-sfc"; - reg = <0x0 0x2902600 0x0 0x200>; + reg = <0x2902600 0x200>; sound-name-prefix = "SFC4"; ports { @@ -580,7 +580,7 @@ sfc4_cif_out: endpoint { tegra_amx1: amx@2903000 { compatible = "nvidia,tegra234-amx", "nvidia,tegra194-amx"; - reg = <0x0 0x2903000 0x0 0x100>; + reg = <0x2903000 0x100>; sound-name-prefix = "AMX1"; ports { @@ -632,7 +632,7 @@ amx1_out: endpoint { tegra_amx2: amx@2903100 { compatible = "nvidia,tegra234-amx", "nvidia,tegra194-amx"; - reg = <0x0 0x2903100 0x0 0x100>; + reg = <0x2903100 0x100>; sound-name-prefix = "AMX2"; ports { @@ -684,7 +684,7 @@ amx2_out: endpoint { tegra_amx3: amx@2903200 { compatible = "nvidia,tegra234-amx", "nvidia,tegra194-amx"; - reg = <0x0 0x2903200 0x0 0x100>; + reg = <0x2903200 0x100>; sound-name-prefix = "AMX3"; ports { @@ -736,7 +736,7 @@ amx3_out: endpoint { tegra_amx4: amx@2903300 { compatible = "nvidia,tegra234-amx", "nvidia,tegra194-amx"; - reg = <0x0 0x2903300 0x0 0x100>; + reg = <0x2903300 0x100>; sound-name-prefix = "AMX4"; ports { @@ -788,7 +788,7 @@ amx4_out: endpoint { tegra_adx1: adx@2903800 { compatible = "nvidia,tegra234-adx", "nvidia,tegra210-adx"; - reg = <0x0 0x2903800 0x0 0x100>; + reg = <0x2903800 0x100>; sound-name-prefix = "ADX1"; ports { @@ -840,7 +840,7 @@ adx1_out4: endpoint { tegra_adx2: adx@2903900 { compatible = "nvidia,tegra234-adx", "nvidia,tegra210-adx"; - reg = <0x0 0x2903900 0x0 0x100>; + reg = <0x2903900 0x100>; sound-name-prefix = "ADX2"; ports { @@ -892,7 +892,7 @@ adx2_out4: endpoint { tegra_adx3: adx@2903a00 { compatible = "nvidia,tegra234-adx", "nvidia,tegra210-adx"; - reg = <0x0 0x2903a00 0x0 0x100>; + reg = <0x2903a00 0x100>; sound-name-prefix = "ADX3"; ports { @@ -944,7 +944,7 @@ adx3_out4: endpoint { tegra_adx4: adx@2903b00 { compatible = "nvidia,tegra234-adx", "nvidia,tegra210-adx"; - reg = <0x0 0x2903b00 0x0 0x100>; + reg = <0x2903b00 0x100>; sound-name-prefix = "ADX4"; ports { @@ -997,7 +997,7 @@ adx4_out4: endpoint { tegra_dmic1: dmic@2904000 { compatible = "nvidia,tegra234-dmic", "nvidia,tegra210-dmic"; - reg = <0x0 0x2904000 0x0 0x100>; + reg = <0x2904000 0x100>; clocks = <&bpmp TEGRA234_CLK_DMIC1>; clock-names = "dmic"; assigned-clocks = <&bpmp TEGRA234_CLK_DMIC1>; @@ -1031,7 +1031,7 @@ dmic1_dap: endpoint { tegra_dmic2: dmic@2904100 { compatible = "nvidia,tegra234-dmic", "nvidia,tegra210-dmic"; - reg = <0x0 0x2904100 0x0 0x100>; + reg = <0x2904100 0x100>; clocks = <&bpmp TEGRA234_CLK_DMIC2>; clock-names = "dmic"; assigned-clocks = <&bpmp TEGRA234_CLK_DMIC2>; @@ -1065,7 +1065,7 @@ dmic2_dap: endpoint { tegra_dmic3: dmic@2904200 { compatible = "nvidia,tegra234-dmic", "nvidia,tegra210-dmic"; - reg = <0x0 0x2904200 0x0 0x100>; + reg = <0x2904200 0x100>; clocks = <&bpmp TEGRA234_CLK_DMIC3>; clock-names = "dmic"; assigned-clocks = <&bpmp TEGRA234_CLK_DMIC3>; @@ -1099,7 +1099,7 @@ dmic3_dap: endpoint { tegra_dmic4: dmic@2904300 { compatible = "nvidia,tegra234-dmic", "nvidia,tegra210-dmic"; - reg = <0x0 0x2904300 0x0 0x100>; + reg = <0x2904300 0x100>; clocks = <&bpmp TEGRA234_CLK_DMIC4>; clock-names = "dmic"; assigned-clocks = <&bpmp TEGRA234_CLK_DMIC4>; @@ -1133,7 +1133,7 @@ dmic4_dap: endpoint { tegra_dspk1: dspk@2905000 { compatible = "nvidia,tegra234-dspk", "nvidia,tegra186-dspk"; - reg = <0x0 0x2905000 0x0 0x100>; + reg = <0x2905000 0x100>; clocks = <&bpmp TEGRA234_CLK_DSPK1>; clock-names = "dspk"; assigned-clocks = <&bpmp TEGRA234_CLK_DSPK1>; @@ -1167,7 +1167,7 @@ dspk1_dap: endpoint { tegra_dspk2: dspk@2905100 { compatible = "nvidia,tegra234-dspk", "nvidia,tegra186-dspk"; - reg = <0x0 0x2905100 0x0 0x100>; + reg = <0x2905100 0x100>; clocks = <&bpmp TEGRA234_CLK_DSPK2>; clock-names = "dspk"; assigned-clocks = <&bpmp TEGRA234_CLK_DSPK2>; @@ -1201,23 +1201,23 @@ dspk2_dap: endpoint { tegra_ope1: processing-engine@2908000 { compatible = "nvidia,tegra234-ope", "nvidia,tegra210-ope"; - reg = <0x0 0x2908000 0x0 0x100>; + reg = <0x2908000 0x100>; sound-name-prefix = "OPE1"; - #address-cells = <2>; - #size-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; ranges; equalizer@2908100 { compatible = "nvidia,tegra234-peq", "nvidia,tegra210-peq"; - reg = <0x0 0x2908100 0x0 0x100>; + reg = <0x2908100 0x100>; }; dynamic-range-compressor@2908200 { compatible = "nvidia,tegra234-mbdrc", "nvidia,tegra210-mbdrc"; - reg = <0x0 0x2908200 0x0 0x200>; + reg = <0x2908200 0x200>; }; ports { @@ -1247,7 +1247,7 @@ ope1_cif_out_ep: endpoint { tegra_mvc1: mvc@290a000 { compatible = "nvidia,tegra234-mvc", "nvidia,tegra210-mvc"; - reg = <0x0 0x290a000 0x0 0x200>; + reg = <0x290a000 0x200>; sound-name-prefix = "MVC1"; ports { @@ -1275,7 +1275,7 @@ mvc1_cif_out: endpoint { tegra_mvc2: mvc@290a200 { compatible = "nvidia,tegra234-mvc", "nvidia,tegra210-mvc"; - reg = <0x0 0x290a200 0x0 0x200>; + reg = <0x290a200 0x200>; sound-name-prefix = "MVC2"; ports { @@ -1303,7 +1303,7 @@ mvc2_cif_out: endpoint { tegra_amixer: amixer@290bb00 { compatible = "nvidia,tegra234-amixer", "nvidia,tegra210-amixer"; - reg = <0x0 0x290bb00 0x0 0x800>; + reg = <0x290bb00 0x800>; sound-name-prefix = "MIXER1"; ports { @@ -1435,7 +1435,7 @@ mix_out5: endpoint { tegra_admaif: admaif@290f000 { compatible = "nvidia,tegra234-admaif", "nvidia,tegra186-admaif"; - reg = <0x0 0x0290f000 0x0 0x1000>; + reg = <0x0290f000 0x1000>; dmas = <&adma 1>, <&adma 1>, <&adma 2>, <&adma 2>, <&adma 3>, <&adma 3>, @@ -1650,7 +1650,7 @@ admaif19: endpoint { tegra_asrc: asrc@2910000 { compatible = "nvidia,tegra234-asrc", "nvidia,tegra186-asrc"; - reg = <0x0 0x2910000 0x0 0x2000>; + reg = <0x2910000 0x2000>; sound-name-prefix = "ASRC1"; ports { @@ -4694,8 +4694,7 @@ pcie-ep@140e0000 { interconnects = <&mc TEGRA234_MEMORY_CLIENT_PCIE10AR &emc>, <&mc TEGRA234_MEMORY_CLIENT_PCIE10AW &emc>; interconnect-names = "dma-mem", "write"; - iommu-map = <0x0 &smmu_niso1 TEGRA234_SID_PCIE10 0x1000>; - iommu-map-mask = <0x0>; + iommus = <&smmu_niso1 TEGRA234_SID_PCIE10>; dma-coherent; status = "disabled"; @@ -5099,8 +5098,7 @@ pcie-ep@141a0000 { interconnects = <&mc TEGRA234_MEMORY_CLIENT_PCIE5R &emc>, <&mc TEGRA234_MEMORY_CLIENT_PCIE5W &emc>; interconnect-names = "dma-mem", "write"; - iommu-map = <0x0 &smmu_niso0 TEGRA234_SID_PCIE5 0x1000>; - iommu-map-mask = <0x0>; + iommus = <&smmu_niso0 TEGRA234_SID_PCIE5>; dma-coherent; status = "disabled"; @@ -5195,8 +5193,7 @@ pcie-ep@141c0000 { interconnects = <&mc TEGRA234_MEMORY_CLIENT_PCIE6AR &emc>, <&mc TEGRA234_MEMORY_CLIENT_PCIE6AW &emc>; interconnect-names = "dma-mem", "write"; - iommu-map = <0x0 &smmu_niso0 TEGRA234_SID_PCIE6 0x1000>; - iommu-map-mask = <0x0>; + iommus = <&smmu_niso0 TEGRA234_SID_PCIE6>; dma-coherent; status = "disabled"; @@ -5291,8 +5288,7 @@ pcie-ep@141e0000 { interconnects = <&mc TEGRA234_MEMORY_CLIENT_PCIE7AR &emc>, <&mc TEGRA234_MEMORY_CLIENT_PCIE7AW &emc>; interconnect-names = "dma-mem", "write"; - iommu-map = <0x0 &smmu_niso1 TEGRA234_SID_PCIE7 0x1000>; - iommu-map-mask = <0x0>; + iommus = <&smmu_niso1 TEGRA234_SID_PCIE7>; dma-coherent; status = "disabled";
diff --git a/arch/arm64/boot/dts/nvidia/tegra264-p3834.dtsi b/arch/arm64/boot/dts/nvidia/tegra264-p3834.dtsi index 58cd81b..f39f33a 100644 --- a/arch/arm64/boot/dts/nvidia/tegra264-p3834.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra264-p3834.dtsi
@@ -38,5 +38,62 @@ iommu@6000000 { cmdqv@6200000 { status = "okay"; }; + + i2c@c640000 { + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + label = "module"; + address-width = <8>; + pagesize = <8>; + size = <256>; + read-only; + }; + }; + }; + + bpmp { + i2c { + status = "okay"; + + thermal-sensor@4c { + compatible = "ti,tmp451"; + reg = <0x4c>; + }; + }; + }; + + thermal-zones { + cpu-thermal { + polling-delay-passive = <40>; + polling-delay = <1000>; + status = "okay"; + }; + + gpu-thermal { + polling-delay-passive = <40>; + polling-delay = <1000>; + status = "okay"; + }; + + soc012-thermal { + polling-delay-passive = <40>; + polling-delay = <1000>; + status = "okay"; + }; + + soc345-thermal { + polling-delay-passive = <40>; + polling-delay = <1000>; + status = "okay"; + }; + + tj-thermal { + polling-delay-passive = <40>; + polling-delay = <1000>; + status = "okay"; + }; }; };
diff --git a/arch/arm64/boot/dts/nvidia/tegra264-p4071-0000+p3834.dtsi b/arch/arm64/boot/dts/nvidia/tegra264-p4071-0000+p3834.dtsi index 4550e84..9295f9c8 100644 --- a/arch/arm64/boot/dts/nvidia/tegra264-p4071-0000+p3834.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra264-p4071-0000+p3834.dtsi
@@ -1,5 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +#include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/input/gpio-keys.h> + / { aliases { serial0 = &{/bus@0/serial@c4e0000}; @@ -11,15 +14,105 @@ chosen { }; bus@0 { + rtc@c2c0000 { + status = "okay"; + }; + pwm@c6a0000 { status = "okay"; }; }; + bus@8100000000 { + i2c@c640000 { + eeprom@56 { + compatible = "atmel,24c02"; + reg = <0x56>; + label = "system"; + address-width = <8>; + pagesize = <8>; + size = <256>; + read-only; + }; + }; + }; + fan: pwm-fan { compatible = "pwm-fan"; cooling-levels = <77 102 140 192 255>; pwms = <&pwm4 0 40000>; #cooling-cells = <2>; }; + + gpio-keys { + compatible = "gpio-keys"; + + key-force-recovery { + label = "Force Recovery"; + gpios = <&gpio_aon TEGRA264_AON_GPIO(EE, 1) GPIO_ACTIVE_LOW>; + linux,input-type = <EV_KEY>; + linux,code = <KEY_SLEEP>; + }; + + key-power { + label = "Power"; + gpios = <&gpio_aon TEGRA264_AON_GPIO(AA, 5) GPIO_ACTIVE_LOW>; + linux,input-type = <EV_KEY>; + linux,code = <KEY_POWER>; + wakeup-event-action = <EV_ACT_ASSERTED>; + wakeup-source; + }; + }; + + thermal-zones { + tj-thermal { + trips { + tj_trip_active0: active-0 { + temperature = <80000>; + hysteresis = <0>; + type = "active"; + }; + + tj_trip_active1: active-1 { + temperature = <86000>; + hysteresis = <0>; + type = "active"; + }; + + tj_trip_active2: active-2 { + temperature = <91000>; + hysteresis = <0>; + type = "active"; + }; + + tj_trip_active3: active-3 { + temperature = <100000>; + hysteresis = <0>; + type = "active"; + }; + }; + + cooling-maps { + map-active-0 { + cooling-device = <&fan 0 1>; + trip = <&tj_trip_active0>; + }; + + map-active-1 { + cooling-device = <&fan 1 2>; + trip = <&tj_trip_active1>; + }; + + map-active-2 { + cooling-device = <&fan 2 3>; + trip = <&tj_trip_active2>; + }; + + map-active-3 { + cooling-device = <&fan 3 4>; + trip = <&tj_trip_active3>; + }; + }; + }; + }; };
diff --git a/arch/arm64/boot/dts/nvidia/tegra264.dtsi b/arch/arm64/boot/dts/nvidia/tegra264.dtsi index 6b2e3a6..5ab34cd 100644 --- a/arch/arm64/boot/dts/nvidia/tegra264.dtsi +++ b/arch/arm64/boot/dts/nvidia/tegra264.dtsi
@@ -1,18 +1,40 @@ // SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause #include <dt-bindings/clock/nvidia,tegra264.h> +#include <dt-bindings/gpio/nvidia,tegra264-gpio.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/mailbox/tegra186-hsp.h> #include <dt-bindings/memory/nvidia,tegra264.h> #include <dt-bindings/power/nvidia,tegra264-bpmp.h> #include <dt-bindings/reset/nvidia,tegra264.h> +#include "thermal/nvidia,tegra264-bpmp.h" + / { compatible = "nvidia,tegra264"; interrupt-parent = <&gic>; #address-cells = <2>; #size-cells = <2>; + aliases { + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &{/bpmp/i2c}; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &i2c8; + i2c9 = &i2c9; + i2c10 = &i2c10; + i2c11 = &i2c11; + i2c12 = &i2c12; + i2c14 = &i2c14; + i2c15 = &i2c15; + i2c16 = &i2c16; + }; + reserved-memory { #address-cells = <2>; #size-cells = <2>; @@ -40,6 +62,13 @@ misc@100000 { <0x0 0x0c140000 0x0 0x10000>; }; + fuse@1000000 { + compatible = "nvidia,tegra264-efuse"; + reg = <0x0 0x1000000 0x0 0x20000>; + clocks = <&bpmp TEGRA264_CLK_FUSE>; + clock-names = "fuse"; + }; + timer@8000000 { compatible = "nvidia,tegra234-timer"; reg = <0x0 0x08000000 0x0 0x140000>; @@ -122,85 +151,85 @@ hsp_top: hsp@8800000 { aconnect@9000000 { compatible = "nvidia,tegra264-aconnect", - "nvidia,tegra210-aconnect"; + "nvidia,tegra210-aconnect"; clocks = <&bpmp TEGRA264_CLK_APE>, - <&bpmp TEGRA264_CLK_ADSP>; + <&bpmp TEGRA264_CLK_ADSP>; clock-names = "ape", "apb2ape"; power-domains = <&bpmp TEGRA264_POWER_DOMAIN_AUD>; status = "disabled"; - #address-cells = <2>; - #size-cells = <2>; - ranges = <0x0 0x9000000 0x0 0x9000000 0x0 0x2000000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x9000000 0x0 0x9000000 0x2000000>; adma: dma-controller@9440000 { compatible = "nvidia,tegra264-adma"; - reg = <0x0 0x9440000 0x0 0xb0000>; + reg = <0x9440000 0xb0000>; interrupt-parent = <&agic_page0>; interrupts = <GIC_SPI 0x90 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0x91 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0x92 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0x93 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0x94 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0x95 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0x96 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0x97 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0x98 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0x99 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0x9a IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0x9b IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0x9c IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0x9d IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0x9e IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0x9f IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xa0 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xa1 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xa2 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xa3 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xa4 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xa5 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xa6 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xa7 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xa8 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xa9 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xaa IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xab IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xac IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xad IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xae IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xaf IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xb0 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xb1 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xb2 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xb3 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xb4 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xb5 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xb6 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xb7 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xb8 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xb9 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xba IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xbb IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xbc IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xbd IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xbe IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xbf IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xc0 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xc1 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xc2 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xc3 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xc4 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xc5 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xc6 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xc7 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xc8 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xc9 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xca IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xcb IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xcc IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xcd IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xce IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 0xcf IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 0x91 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0x92 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0x93 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0x94 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0x95 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0x96 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0x97 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0x98 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0x99 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0x9a IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0x9b IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0x9c IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0x9d IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0x9e IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0x9f IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xa0 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xa1 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xa2 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xa3 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xa4 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xa5 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xa6 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xa7 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xa8 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xa9 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xaa IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xab IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xac IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xad IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xae IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xaf IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xb0 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xb1 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xb2 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xb3 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xb4 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xb5 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xb6 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xb7 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xb8 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xb9 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xba IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xbb IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xbc IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xbd IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xbe IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xbf IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xc0 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xc1 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xc2 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xc3 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xc4 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xc5 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xc6 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xc7 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xc8 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xc9 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xca IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xcb IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xcc IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xcd IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xce IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 0xcf IRQ_TYPE_LEVEL_HIGH>; #dma-cells = <1>; clocks = <&bpmp TEGRA264_CLK_AHUB>; clock-names = "d_audio"; @@ -209,24 +238,24 @@ adma: dma-controller@9440000 { tegra_ahub: ahub@9630000 { compatible = "nvidia,tegra264-ahub"; - reg = <0x0 0x9630000 0x0 0x10000>; + reg = <0x9630000 0x10000>; clocks = <&bpmp TEGRA264_CLK_AHUB>; clock-names = "ahub"; assigned-clocks = <&bpmp TEGRA264_CLK_AHUB>; assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLAON_APE>; status = "disabled"; - #address-cells = <2>; - #size-cells = <2>; + #address-cells = <1>; + #size-cells = <1>; /* ADMA is under AHUB range, its excluded in the defined range */ - ranges = <0x0 0x9280000 0x0 0x9280000 0x0 0x1c0000>, - <0x0 0x9510000 0x0 0x9510000 0x0 0x370000>; + ranges = <0x9280000 0x9280000 0x1c0000>, + <0x9510000 0x9510000 0x370000>; tegra_i2s1: i2s@9280000 { compatible = "nvidia,tegra264-i2s"; - reg = <0x0 0x9280000 0x0 0x10000>; + reg = <0x9280000 0x10000>; clocks = <&bpmp TEGRA264_CLK_I2S1>, - <&bpmp TEGRA264_CLK_I2S1_SCLK_IN>; + <&bpmp TEGRA264_CLK_I2S1_SCLK_IN>; clock-names = "i2s", "sync_input"; assigned-clocks = <&bpmp TEGRA264_CLK_I2S1>; assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; @@ -259,7 +288,7 @@ i2s1_dap: endpoint { tegra_i2s2: i2s@9290000 { compatible = "nvidia,tegra264-i2s"; - reg = <0x0 0x9290000 0x0 0x10000>; + reg = <0x9290000 0x10000>; clocks = <&bpmp TEGRA264_CLK_I2S2>, <&bpmp TEGRA264_CLK_I2S2_SCLK_IN>; clock-names = "i2s", "sync_input"; @@ -294,9 +323,9 @@ i2s2_dap: endpoint { tegra_i2s3: i2s@92a0000 { compatible = "nvidia,tegra264-i2s"; - reg = <0x0 0x92a0000 0x0 0x10000>; + reg = <0x92a0000 0x10000>; clocks = <&bpmp TEGRA264_CLK_I2S3>, - <&bpmp TEGRA264_CLK_I2S3_SCLK_IN>; + <&bpmp TEGRA264_CLK_I2S3_SCLK_IN>; clock-names = "i2s", "sync_input"; assigned-clocks = <&bpmp TEGRA264_CLK_I2S3>; assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; @@ -329,9 +358,9 @@ i2s3_dap: endpoint { tegra_i2s4: i2s@92b0000 { compatible = "nvidia,tegra264-i2s"; - reg = <0x0 0x92b0000 0x0 0x10000>; + reg = <0x92b0000 0x10000>; clocks = <&bpmp TEGRA264_CLK_I2S4>, - <&bpmp TEGRA264_CLK_I2S4_SCLK_IN>; + <&bpmp TEGRA264_CLK_I2S4_SCLK_IN>; clock-names = "i2s", "sync_input"; assigned-clocks = <&bpmp TEGRA264_CLK_I2S4>; assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; @@ -364,9 +393,9 @@ i2s4_dap: endpoint { tegra_i2s5: i2s@92c0000 { compatible = "nvidia,tegra264-i2s"; - reg = <0x0 0x92c0000 0x0 0x10000>; + reg = <0x92c0000 0x10000>; clocks = <&bpmp TEGRA264_CLK_I2S5>, - <&bpmp TEGRA264_CLK_I2S5_SCLK_IN>; + <&bpmp TEGRA264_CLK_I2S5_SCLK_IN>; clock-names = "i2s", "sync_input"; assigned-clocks = <&bpmp TEGRA264_CLK_I2S5>; assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; @@ -399,9 +428,9 @@ i2s5_dap: endpoint { tegra_i2s6: i2s@92d0000 { compatible = "nvidia,tegra264-i2s"; - reg = <0x0 0x92d0000 0x0 0x10000>; + reg = <0x92d0000 0x10000>; clocks = <&bpmp TEGRA264_CLK_I2S6>, - <&bpmp TEGRA264_CLK_I2S6_SCLK_IN>; + <&bpmp TEGRA264_CLK_I2S6_SCLK_IN>; clock-names = "i2s", "sync_input"; assigned-clocks = <&bpmp TEGRA264_CLK_I2S6>; assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; @@ -434,9 +463,9 @@ i2s6_dap: endpoint { tegra_i2s7: i2s@92e0000 { compatible = "nvidia,tegra264-i2s"; - reg = <0x0 0x92e0000 0x0 0x10000>; + reg = <0x92e0000 0x10000>; clocks = <&bpmp TEGRA264_CLK_I2S7>, - <&bpmp TEGRA264_CLK_I2S7_SCLK_IN>; + <&bpmp TEGRA264_CLK_I2S7_SCLK_IN>; clock-names = "i2s", "sync_input"; assigned-clocks = <&bpmp TEGRA264_CLK_I2S7>; assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; @@ -469,9 +498,9 @@ i2s7_dap: endpoint { tegra_i2s8: i2s@92f0000 { compatible = "nvidia,tegra264-i2s"; - reg = <0x0 0x92f0000 0x0 0x10000>; + reg = <0x92f0000 0x10000>; clocks = <&bpmp TEGRA264_CLK_I2S8>, - <&bpmp TEGRA264_CLK_I2S8_SCLK_IN>; + <&bpmp TEGRA264_CLK_I2S8_SCLK_IN>; clock-names = "i2s", "sync_input"; assigned-clocks = <&bpmp TEGRA264_CLK_I2S8>; assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLA1_OUT1>; @@ -504,8 +533,8 @@ i2s8_dap: endpoint { tegra_dmic1: dmic@9300000 { compatible = "nvidia,tegra264-dmic", - "nvidia,tegra210-dmic"; - reg = <0x0 0x9300000 0x0 0x10000>; + "nvidia,tegra210-dmic"; + reg = <0x9300000 0x10000>; clocks = <&bpmp TEGRA264_CLK_DMIC1>; clock-names = "dmic"; assigned-clocks = <&bpmp TEGRA264_CLK_DMIC1>; @@ -538,8 +567,8 @@ dmic1_dap: endpoint { tegra_dmic2: dmic@9310000 { compatible = "nvidia,tegra264-dmic", - "nvidia,tegra210-dmic"; - reg = <0x0 0x9310000 0x0 0x10000>; + "nvidia,tegra210-dmic"; + reg = <0x9310000 0x10000>; clocks = <&bpmp TEGRA264_CLK_DMIC1>; clock-names = "dmic"; assigned-clocks = <&bpmp TEGRA264_CLK_DMIC1>; @@ -572,8 +601,8 @@ dmic2_dap: endpoint { tegra_dspk1: dspk@9380000 { compatible = "nvidia,tegra264-dspk", - "nvidia,tegra186-dspk"; - reg = <0x0 0x9380000 0x0 0x10000>; + "nvidia,tegra186-dspk"; + reg = <0x9380000 0x10000>; clocks = <&bpmp TEGRA264_CLK_DSPK1>; clock-names = "dspk"; assigned-clocks = <&bpmp TEGRA264_CLK_DSPK1>; @@ -606,7 +635,7 @@ dspk1_dap: endpoint { tegra_amx1: amx@9510000 { compatible = "nvidia,tegra264-amx"; - reg = <0x0 0x9510000 0x0 0x10000>; + reg = <0x9510000 0x10000>; sound-name-prefix = "AMX1"; ports { @@ -657,7 +686,7 @@ amx1_out: endpoint { tegra_amx2: amx@9520000 { compatible = "nvidia,tegra264-amx"; - reg = <0x0 0x9520000 0x0 0x10000>; + reg = <0x9520000 0x10000>; sound-name-prefix = "AMX2"; ports { @@ -708,7 +737,7 @@ amx2_out: endpoint { tegra_amx3: amx@9530000 { compatible = "nvidia,tegra264-amx"; - reg = <0x0 0x9530000 0x0 0x10000>; + reg = <0x9530000 0x10000>; sound-name-prefix = "AMX3"; ports { @@ -759,7 +788,7 @@ amx3_out: endpoint { tegra_amx4: amx@9540000 { compatible = "nvidia,tegra264-amx"; - reg = <0x0 0x9540000 0x0 0x10000>; + reg = <0x9540000 0x10000>; sound-name-prefix = "AMX4"; ports { @@ -810,7 +839,7 @@ amx4_out: endpoint { tegra_amx5: amx@9550000 { compatible = "nvidia,tegra264-amx"; - reg = <0x0 0x9550000 0x0 0x10000>; + reg = <0x9550000 0x10000>; sound-name-prefix = "AMX5"; ports { @@ -861,7 +890,7 @@ amx5_out: endpoint { tegra_amx6: amx@9560000 { compatible = "nvidia,tegra264-amx"; - reg = <0x0 0x9560000 0x0 0x10000>; + reg = <0x9560000 0x10000>; sound-name-prefix = "AMX6"; ports { @@ -912,7 +941,7 @@ amx6_out: endpoint { tegra_adx1: adx@9590000 { compatible = "nvidia,tegra264-adx"; - reg = <0x0 0x9590000 0x0 0x10000>; + reg = <0x9590000 0x10000>; sound-name-prefix = "ADX1"; ports { @@ -963,7 +992,7 @@ adx1_out4: endpoint { tegra_adx2: adx@95a0000 { compatible = "nvidia,tegra264-adx"; - reg = <0x0 0x95a0000 0x0 0x10000>; + reg = <0x95a0000 0x10000>; sound-name-prefix = "ADX2"; ports { @@ -1014,7 +1043,7 @@ adx2_out4: endpoint { tegra_adx3: adx@95b0000 { compatible = "nvidia,tegra264-adx"; - reg = <0x0 0x95b0000 0x0 0x10000>; + reg = <0x95b0000 0x10000>; sound-name-prefix = "ADX3"; ports { @@ -1065,7 +1094,7 @@ adx3_out4: endpoint { tegra_adx4: adx@95c0000 { compatible = "nvidia,tegra264-adx"; - reg = <0x0 0x95c0000 0x0 0x10000>; + reg = <0x95c0000 0x10000>; sound-name-prefix = "ADX4"; ports { @@ -1116,7 +1145,7 @@ adx4_out4: endpoint { tegra_adx5: adx@95d0000 { compatible = "nvidia,tegra264-adx"; - reg = <0x0 0x95d0000 0x0 0x10000>; + reg = <0x95d0000 0x10000>; sound-name-prefix = "ADX5"; ports { @@ -1167,7 +1196,7 @@ adx5_out4: endpoint { tegra_adx6: adx@95e0000 { compatible = "nvidia,tegra264-adx"; - reg = <0x0 0x95e0000 0x0 0x10000>; + reg = <0x95e0000 0x10000>; sound-name-prefix = "ADX6"; ports { @@ -1218,76 +1247,75 @@ adx6_out4: endpoint { tegra_admaif: admaif@9610000 { compatible = "nvidia,tegra264-admaif"; - reg = <0x0 0x9610000 0x0 0x10000>; + reg = <0x9610000 0x10000>; dmas = <&adma 1>, <&adma 1>, - <&adma 2>, <&adma 2>, - <&adma 3>, <&adma 3>, - <&adma 4>, <&adma 4>, - <&adma 5>, <&adma 5>, - <&adma 6>, <&adma 6>, - <&adma 7>, <&adma 7>, - <&adma 8>, <&adma 8>, - <&adma 9>, <&adma 9>, - <&adma 10>, <&adma 10>, - <&adma 11>, <&adma 11>, - <&adma 12>, <&adma 12>, - <&adma 13>, <&adma 13>, - <&adma 14>, <&adma 14>, - <&adma 15>, <&adma 15>, - <&adma 16>, <&adma 16>, - <&adma 17>, <&adma 17>, - <&adma 18>, <&adma 18>, - <&adma 19>, <&adma 19>, - <&adma 20>, <&adma 20>, - <&adma 21>, <&adma 21>, - <&adma 22>, <&adma 22>, - <&adma 23>, <&adma 23>, - <&adma 24>, <&adma 24>, - <&adma 25>, <&adma 25>, - <&adma 26>, <&adma 26>, - <&adma 27>, <&adma 27>, - <&adma 28>, <&adma 28>, - <&adma 29>, <&adma 29>, - <&adma 30>, <&adma 30>, - <&adma 31>, <&adma 31>, - <&adma 32>, <&adma 32>; + <&adma 2>, <&adma 2>, + <&adma 3>, <&adma 3>, + <&adma 4>, <&adma 4>, + <&adma 5>, <&adma 5>, + <&adma 6>, <&adma 6>, + <&adma 7>, <&adma 7>, + <&adma 8>, <&adma 8>, + <&adma 9>, <&adma 9>, + <&adma 10>, <&adma 10>, + <&adma 11>, <&adma 11>, + <&adma 12>, <&adma 12>, + <&adma 13>, <&adma 13>, + <&adma 14>, <&adma 14>, + <&adma 15>, <&adma 15>, + <&adma 16>, <&adma 16>, + <&adma 17>, <&adma 17>, + <&adma 18>, <&adma 18>, + <&adma 19>, <&adma 19>, + <&adma 20>, <&adma 20>, + <&adma 21>, <&adma 21>, + <&adma 22>, <&adma 22>, + <&adma 23>, <&adma 23>, + <&adma 24>, <&adma 24>, + <&adma 25>, <&adma 25>, + <&adma 26>, <&adma 26>, + <&adma 27>, <&adma 27>, + <&adma 28>, <&adma 28>, + <&adma 29>, <&adma 29>, + <&adma 30>, <&adma 30>, + <&adma 31>, <&adma 31>, + <&adma 32>, <&adma 32>; dma-names = "rx1", "tx1", - "rx2", "tx2", - "rx3", "tx3", - "rx4", "tx4", - "rx5", "tx5", - "rx6", "tx6", - "rx7", "tx7", - "rx8", "tx8", - "rx9", "tx9", - "rx10", "tx10", - "rx11", "tx11", - "rx12", "tx12", - "rx13", "tx13", - "rx14", "tx14", - "rx15", "tx15", - "rx16", "tx16", - "rx17", "tx17", - "rx18", "tx18", - "rx19", "tx19", - "rx20", "tx20", - "rx21", "tx21", - "rx22", "tx22", - "rx23", "tx23", - "rx24", "tx24", - "rx25", "tx25", - "rx26", "tx26", - "rx27", "tx27", - "rx28", "tx28", - "rx29", "tx29", - "rx30", "tx30", - "rx31", "tx31", - "rx32", "tx32"; + "rx2", "tx2", + "rx3", "tx3", + "rx4", "tx4", + "rx5", "tx5", + "rx6", "tx6", + "rx7", "tx7", + "rx8", "tx8", + "rx9", "tx9", + "rx10", "tx10", + "rx11", "tx11", + "rx12", "tx12", + "rx13", "tx13", + "rx14", "tx14", + "rx15", "tx15", + "rx16", "tx16", + "rx17", "tx17", + "rx18", "tx18", + "rx19", "tx19", + "rx20", "tx20", + "rx21", "tx21", + "rx22", "tx22", + "rx23", "tx23", + "rx24", "tx24", + "rx25", "tx25", + "rx26", "tx26", + "rx27", "tx27", + "rx28", "tx28", + "rx29", "tx29", + "rx30", "tx30", + "rx31", "tx31", + "rx32", "tx32"; - interconnects = - <&mc TEGRA264_MEMORY_CLIENT_APEDMAR &emc>, - <&mc TEGRA264_MEMORY_CLIENT_APEDMAW &emc>; - interconnect-names = "dma-mem", "write"; + interconnects = <&mc TEGRA264_MEMORY_CLIENT_APEDMAR &emc>, + <&mc TEGRA264_MEMORY_CLIENT_APEDMAW &emc>; + interconnect-names = "dma-mem", "write"; iommus = <&smmu1 TEGRA264_SID_APE>; @@ -1555,8 +1583,8 @@ admaif31: endpoint { tegra_sfc1: sfc@9700000 { compatible = "nvidia,tegra264-sfc", - "nvidia,tegra210-sfc"; - reg = <0x0 0x9700000 0x0 0x10000>; + "nvidia,tegra210-sfc"; + reg = <0x9700000 0x10000>; sound-name-prefix = "SFC1"; ports { @@ -1583,8 +1611,8 @@ sfc1_cif_out: endpoint { tegra_sfc2: sfc@9710000 { compatible = "nvidia,tegra264-sfc", - "nvidia,tegra210-sfc"; - reg = <0x0 0x9710000 0x0 0x10000>; + "nvidia,tegra210-sfc"; + reg = <0x9710000 0x10000>; sound-name-prefix = "SFC2"; ports { @@ -1611,8 +1639,8 @@ sfc2_cif_out: endpoint { tegra_sfc3: sfc@9720000 { compatible = "nvidia,tegra264-sfc", - "nvidia,tegra210-sfc"; - reg = <0x0 0x9720000 0x0 0x10000>; + "nvidia,tegra210-sfc"; + reg = <0x9720000 0x10000>; sound-name-prefix = "SFC3"; ports { @@ -1639,8 +1667,8 @@ sfc3_cif_out: endpoint { tegra_sfc4: sfc@9730000 { compatible = "nvidia,tegra264-sfc", - "nvidia,tegra210-sfc"; - reg = <0x0 0x9730000 0x0 0x10000>; + "nvidia,tegra210-sfc"; + reg = <0x9730000 0x10000>; sound-name-prefix = "SFC4"; ports { @@ -1667,23 +1695,23 @@ sfc4_cif_out: endpoint { tegra_ope1: processing-engine@9780000 { compatible = "nvidia,tegra264-ope", - "nvidia,tegra210-ope"; - reg = <0x0 0x9780000 0x0 0x10000>; - #address-cells = <2>; - #size-cells = <2>; - ranges = <0x0 0x9780000 0x0 0x9780000 0x0 0x30000>; + "nvidia,tegra210-ope"; + reg = <0x9780000 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x9780000 0x9780000 0x30000>; sound-name-prefix = "OPE1"; equalizer@9790000 { compatible = "nvidia,tegra264-peq", - "nvidia,tegra210-peq"; - reg = <0x0 0x9790000 0x0 0x10000>; + "nvidia,tegra210-peq"; + reg = <0x9790000 0x10000>; }; dynamic-range-compressor@97a0000 { compatible = "nvidia,tegra264-mbdrc", - "nvidia,tegra210-mbdrc"; - reg = <0x0 0x97a0000 0x0 0x10000>; + "nvidia,tegra210-mbdrc"; + reg = <0x97a0000 0x10000>; }; ports { @@ -1694,8 +1722,7 @@ port@0 { reg = <0x0>; ope1_cif_in_ep: endpoint { - remote-endpoint = - <&xbar_ope1_in_ep>; + remote-endpoint = <&xbar_ope1_in_ep>; }; }; @@ -1703,8 +1730,7 @@ ope1_out_port: port@1 { reg = <0x1>; ope1_cif_out_ep: endpoint { - remote-endpoint = - <&xbar_ope1_out_ep>; + remote-endpoint = <&xbar_ope1_out_ep>; }; }; }; @@ -1712,8 +1738,8 @@ ope1_cif_out_ep: endpoint { tegra_mvc1: mvc@9800000 { compatible = "nvidia,tegra264-mvc", - "nvidia,tegra210-mvc"; - reg = <0x0 0x9800000 0x0 0x10000>; + "nvidia,tegra210-mvc"; + reg = <0x9800000 0x10000>; sound-name-prefix = "MVC1"; ports { @@ -1740,8 +1766,8 @@ mvc1_cif_out: endpoint { tegra_mvc2: mvc@9810000 { compatible = "nvidia,tegra264-mvc", - "nvidia,tegra210-mvc"; - reg = <0x0 0x9810000 0x0 0x10000>; + "nvidia,tegra210-mvc"; + reg = <0x9810000 0x10000>; sound-name-prefix = "MVC2"; ports { @@ -1768,8 +1794,8 @@ mvc2_cif_out: endpoint { tegra_amixer: amixer@9820000 { compatible = "nvidia,tegra264-amixer", - "nvidia,tegra210-amixer"; - reg = <0x0 0x9820000 0x0 0x10000>; + "nvidia,tegra210-amixer"; + reg = <0x9820000 0x10000>; sound-name-prefix = "MIXER1"; ports { @@ -1900,7 +1926,7 @@ mix_out5: endpoint { tegra_asrc: asrc@9850000 { compatible = "nvidia,tegra264-asrc"; - reg = <0x0 0x9850000 0x0 0x10000>; + reg = <0x9850000 0x10000>; sound-name-prefix = "ASRC1"; ports { @@ -1911,8 +1937,7 @@ port@0 { reg = <0x0>; asrc_in1_ep: endpoint { - remote-endpoint = - <&xbar_asrc_in1_ep>; + remote-endpoint = <&xbar_asrc_in1_ep>; }; }; @@ -1920,8 +1945,7 @@ port@1 { reg = <0x1>; asrc_in2_ep: endpoint { - remote-endpoint = - <&xbar_asrc_in2_ep>; + remote-endpoint = <&xbar_asrc_in2_ep>; }; }; @@ -1929,8 +1953,7 @@ port@2 { reg = <0x2>; asrc_in3_ep: endpoint { - remote-endpoint = - <&xbar_asrc_in3_ep>; + remote-endpoint = <&xbar_asrc_in3_ep>; }; }; @@ -1938,8 +1961,7 @@ port@3 { reg = <0x3>; asrc_in4_ep: endpoint { - remote-endpoint = - <&xbar_asrc_in4_ep>; + remote-endpoint = <&xbar_asrc_in4_ep>; }; }; @@ -1947,8 +1969,7 @@ port@4 { reg = <0x4>; asrc_in5_ep: endpoint { - remote-endpoint = - <&xbar_asrc_in5_ep>; + remote-endpoint = <&xbar_asrc_in5_ep>; }; }; @@ -1956,8 +1977,7 @@ port@5 { reg = <0x5>; asrc_in6_ep: endpoint { - remote-endpoint = - <&xbar_asrc_in6_ep>; + remote-endpoint = <&xbar_asrc_in6_ep>; }; }; @@ -1965,8 +1985,7 @@ port@6 { reg = <0x6>; asrc_in7_ep: endpoint { - remote-endpoint = - <&xbar_asrc_in7_ep>; + remote-endpoint = <&xbar_asrc_in7_ep>; }; }; @@ -1974,8 +1993,7 @@ asrc_out1_port: port@7 { reg = <0x7>; asrc_out1_ep: endpoint { - remote-endpoint = - <&xbar_asrc_out1_ep>; + remote-endpoint = <&xbar_asrc_out1_ep>; }; }; @@ -1983,8 +2001,7 @@ asrc_out2_port: port@8 { reg = <0x8>; asrc_out2_ep: endpoint { - remote-endpoint = - <&xbar_asrc_out2_ep>; + remote-endpoint = <&xbar_asrc_out2_ep>; }; }; @@ -1992,8 +2009,7 @@ asrc_out3_port: port@9 { reg = <0x9>; asrc_out3_ep: endpoint { - remote-endpoint = - <&xbar_asrc_out3_ep>; + remote-endpoint = <&xbar_asrc_out3_ep>; }; }; @@ -2001,8 +2017,7 @@ asrc_out4_port: port@a { reg = <0xa>; asrc_out4_ep: endpoint { - remote-endpoint = - <&xbar_asrc_out4_ep>; + remote-endpoint = <&xbar_asrc_out4_ep>; }; }; @@ -2010,8 +2025,7 @@ asrc_out5_port: port@b { reg = <0xb>; asrc_out5_ep: endpoint { - remote-endpoint = - <&xbar_asrc_out5_ep>; + remote-endpoint = <&xbar_asrc_out5_ep>; }; }; @@ -2019,8 +2033,7 @@ asrc_out6_port: port@c { reg = <0xc>; asrc_out6_ep: endpoint { - remote-endpoint = - <&xbar_asrc_out6_ep>; + remote-endpoint = <&xbar_asrc_out6_ep>; }; }; }; @@ -3194,13 +3207,12 @@ xbar_ope1_out_ep: endpoint { agic_page0: interrupt-controller@9960000 { compatible = "nvidia,tegra264-agic", - "nvidia,tegra210-agic"; + "nvidia,tegra210-agic"; #interrupt-cells = <3>; interrupt-controller; - reg = <0x0 0x9961000 0x0 0x1000>, - <0x0 0x9962000 0x0 0x1000>; - interrupts = <GIC_SPI 0x230 - (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + reg = <0x9961000 0x1000>, + <0x9962000 0x1000>; + interrupts = <GIC_SPI 0x230 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; clocks = <&bpmp TEGRA264_CLK_ADSP>; clock-names = "clk"; status = "disabled"; @@ -3208,13 +3220,12 @@ agic_page0: interrupt-controller@9960000 { agic_page1: interrupt-controller@9970000 { compatible = "nvidia,tegra264-agic", - "nvidia,tegra210-agic"; + "nvidia,tegra210-agic"; #interrupt-cells = <3>; interrupt-controller; - reg = <0x0 0x9971000 0x0 0x1000>, - <0x0 0x9972000 0x0 0x1000>; - interrupts = <GIC_SPI 0x231 - (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + reg = <0x9971000 0x1000>, + <0x9972000 0x1000>; + interrupts = <GIC_SPI 0x231 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; clocks = <&bpmp TEGRA264_CLK_ADSP>; clock-names = "clk"; status = "disabled"; @@ -3222,13 +3233,12 @@ agic_page1: interrupt-controller@9970000 { agic_page2: interrupt-controller@9980000 { compatible = "nvidia,tegra264-agic", - "nvidia,tegra210-agic"; + "nvidia,tegra210-agic"; #interrupt-cells = <3>; interrupt-controller; - reg = <0x0 0x9981000 0x0 0x1000>, - <0x0 0x9982000 0x0 0x1000>; - interrupts = <GIC_SPI 0x232 - (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + reg = <0x9981000 0x1000>, + <0x9982000 0x1000>; + interrupts = <GIC_SPI 0x232 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; clocks = <&bpmp TEGRA264_CLK_ADSP>; clock-names = "clk"; status = "disabled"; @@ -3236,13 +3246,12 @@ agic_page2: interrupt-controller@9980000 { agic_page3: interrupt-controller@9990000 { compatible = "nvidia,tegra264-agic", - "nvidia,tegra210-agic"; + "nvidia,tegra210-agic"; #interrupt-cells = <3>; interrupt-controller; - reg = <0x0 0x9991000 0x0 0x1000>, - <0x0 0x9992000 0x0 0x1000>; - interrupts = <GIC_SPI 0x233 - (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + reg = <0x9991000 0x1000>, + <0x9992000 0x1000>; + interrupts = <GIC_SPI 0x233 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; clocks = <&bpmp TEGRA264_CLK_ADSP>; clock-names = "clk"; status = "disabled"; @@ -3250,13 +3259,12 @@ agic_page3: interrupt-controller@9990000 { agic_page4: interrupt-controller@99a0000 { compatible = "nvidia,tegra264-agic", - "nvidia,tegra210-agic"; + "nvidia,tegra210-agic"; #interrupt-cells = <3>; interrupt-controller; - reg = <0x0 0x99a1000 0x0 0x1000>, - <0x0 0x99a2000 0x0 0x1000>; - interrupts = <GIC_SPI 0x234 - (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + reg = <0x99a1000 0x1000>, + <0x99a2000 0x1000>; + interrupts = <GIC_SPI 0x234 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; clocks = <&bpmp TEGRA264_CLK_ADSP>; clock-names = "clk"; status = "disabled"; @@ -3264,13 +3272,12 @@ agic_page4: interrupt-controller@99a0000 { agic_page5: interrupt-controller@99b0000 { compatible = "nvidia,tegra264-agic", - "nvidia,tegra210-agic"; + "nvidia,tegra210-agic"; #interrupt-cells = <3>; interrupt-controller; - reg = <0x0 0x99b1000 0x0 0x1000>, - <0x0 0x99b2000 0x0 0x1000>; - interrupts = <GIC_SPI 0x235 - (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; + reg = <0x99b1000 0x1000>, + <0x99b2000 0x1000>; + interrupts = <GIC_SPI 0x235 (GIC_CPU_MASK_SIMPLE(4) | IRQ_TYPE_LEVEL_HIGH)>; clocks = <&bpmp TEGRA264_CLK_ADSP>; clock-names = "clk"; status = "disabled"; @@ -3330,6 +3337,8 @@ i2c2: i2c@c600000 { compatible = "nvidia,tegra264-i2c"; reg = <0x0 0x0c600000 0x0 0x10000>; interrupts = <GIC_SPI 532 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; clock-frequency = <400000>; clocks = <&bpmp TEGRA264_CLK_AON_I2C>, <&bpmp TEGRA264_CLK_PLLAON>; @@ -3345,6 +3354,8 @@ i2c3: i2c@c610000 { compatible = "nvidia,tegra264-i2c"; reg = <0x0 0x0c610000 0x0 0x10000>; interrupts = <GIC_SPI 533 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; clock-frequency = <400000>; clocks = <&bpmp TEGRA264_CLK_AON_I2C>, <&bpmp TEGRA264_CLK_PLLAON>; @@ -3642,6 +3653,8 @@ i2c14: i2c@c410000 { compatible = "nvidia,tegra264-i2c"; reg = <0x00 0x0c410000 0x0 0x10000>; interrupts = <GIC_SPI 128 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; clock-frequency = <400000>; clocks = <&bpmp TEGRA264_CLK_TOP_I2C>, <&bpmp TEGRA264_CLK_PLLP_OUT0>; @@ -3657,6 +3670,8 @@ i2c15: i2c@c420000 { compatible = "nvidia,tegra264-i2c"; reg = <0x00 0x0c420000 0x0 0x10000>; interrupts = <GIC_SPI 129 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; clock-frequency = <400000>; clocks = <&bpmp TEGRA264_CLK_TOP_I2C>, <&bpmp TEGRA264_CLK_PLLP_OUT0>; @@ -3672,6 +3687,8 @@ i2c16: i2c@c430000 { compatible = "nvidia,tegra264-i2c"; reg = <0x00 0x0c430000 0x0 0x10000>; interrupts = <GIC_SPI 130 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; clock-frequency = <400000>; clocks = <&bpmp TEGRA264_CLK_TOP_I2C>, <&bpmp TEGRA264_CLK_PLLP_OUT0>; @@ -3683,6 +3700,40 @@ i2c16: i2c@c430000 { status = "disabled"; }; + mmc@c570000 { + compatible = "nvidia,tegra264-sdhci", "nvidia,tegra194-sdhci"; + reg = <0x00 0x0c570000 0x0 0x10000>; + interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&bpmp TEGRA264_CLK_SDMMC1>, + <&bpmp TEGRA264_CLK_SDMMC_LEGACY_TM>; + clock-names = "sdhci", "tmclk"; + assigned-clocks = <&bpmp TEGRA264_CLK_SDMMC1>, + <&bpmp TEGRA264_CLK_PLLC4_MUXED>; + assigned-clock-parents = <&bpmp TEGRA264_CLK_PLLC4_MUXED>, + <&bpmp TEGRA264_CLK_PLLC4_OUT0>; + resets = <&bpmp TEGRA264_RESET_SDMMC1>; + reset-names = "sdhci"; + interconnects = <&mc TEGRA264_MEMORY_CLIENT_SDMMC0R &emc>, + <&mc TEGRA264_MEMORY_CLIENT_SDMMC0W &emc>; + interconnect-names = "dma-mem", "write"; + iommus = <&smmu2 TEGRA264_SID_SDMMC0>; + nvidia,pad-autocal-pull-up-offset-3v3-timeout = <0x07>; + nvidia,pad-autocal-pull-down-offset-3v3-timeout = <0x07>; + nvidia,pad-autocal-pull-up-offset-1v8-timeout = <0x06>; + nvidia,pad-autocal-pull-down-offset-1v8-timeout = <0x07>; + nvidia,pad-autocal-pull-up-offset-sdr104 = <0x00>; + nvidia,pad-autocal-pull-down-offset-sdr104 = <0x00>; + nvidia,default-tap = <0x6>; + nvidia,default-trim = <0x0>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + mmc-hs200-1_8v; + dma-coherent; + status = "disabled"; + }; + pwm2: pwm@c5e0000 { compatible = "nvidia,tegra264-pwm"; reg = <0x0 0xc5e0000 0x0 0x10000>; @@ -3747,6 +3798,8 @@ i2c0: i2c@c630000 { compatible = "nvidia,tegra264-i2c"; reg = <0x00 0x0c630000 0x0 0x10000>; interrupts = <GIC_SPI 131 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; clock-frequency = <400000>; clocks = <&bpmp TEGRA264_CLK_TOP_I2C>, <&bpmp TEGRA264_CLK_PLLP_OUT0>; @@ -3762,6 +3815,8 @@ i2c1: i2c@c640000 { compatible = "nvidia,tegra264-i2c"; reg = <0x00 0x0c640000 0x0 0x10000>; interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; clock-frequency = <400000>; clocks = <&bpmp TEGRA264_CLK_TOP_I2C>, <&bpmp TEGRA264_CLK_PLLP_OUT0>; @@ -3777,6 +3832,8 @@ i2c4: i2c@c650000 { compatible = "nvidia,tegra264-i2c"; reg = <0x00 0x0c650000 0x0 0x10000>; interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; clock-frequency = <400000>; clocks = <&bpmp TEGRA264_CLK_TOP_I2C>, <&bpmp TEGRA264_CLK_PLLP_OUT0>; @@ -3792,6 +3849,8 @@ i2c6: i2c@c670000 { compatible = "nvidia,tegra264-i2c"; reg = <0x00 0x0c670000 0x0 0x10000>; interrupts = <GIC_SPI 136 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; clock-frequency = <400000>; clocks = <&bpmp TEGRA264_CLK_TOP_I2C>, <&bpmp TEGRA264_CLK_PLLP_OUT0>; @@ -3807,6 +3866,8 @@ i2c7: i2c@c680000 { compatible = "nvidia,tegra264-i2c"; reg = <0x00 0x0c680000 0x0 0x10000>; interrupts = <GIC_SPI 126 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; clock-frequency = <400000>; clocks = <&bpmp TEGRA264_CLK_TOP_I2C>, <&bpmp TEGRA264_CLK_PLLP_OUT0>; @@ -3822,6 +3883,8 @@ i2c8: i2c@c690000 { compatible = "nvidia,tegra264-i2c"; reg = <0x00 0x0c690000 0x0 0x10000>; interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; clock-frequency = <400000>; clocks = <&bpmp TEGRA264_CLK_TOP_I2C>, <&bpmp TEGRA264_CLK_PLLP_OUT0>; @@ -3837,6 +3900,8 @@ i2c9: i2c@c6a0000 { compatible = "nvidia,tegra264-i2c"; reg = <0x00 0x0c6a0000 0x0 0x10000>; interrupts = <GIC_SPI 127 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; clock-frequency = <400000>; clocks = <&bpmp TEGRA264_CLK_TOP_I2C>, <&bpmp TEGRA264_CLK_PLLP_OUT0>; @@ -3852,6 +3917,8 @@ i2c10: i2c@c6b0000 { compatible = "nvidia,tegra264-i2c"; reg = <0x00 0x0c6b0000 0x0 0x10000>; interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; clock-frequency = <400000>; clocks = <&bpmp TEGRA264_CLK_TOP_I2C>, <&bpmp TEGRA264_CLK_PLLP_OUT0>; @@ -3867,6 +3934,8 @@ i2c11: i2c@c6c0000 { compatible = "nvidia,tegra264-i2c"; reg = <0x00 0x0c6c0000 0x0 0x10000>; interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; clock-frequency = <400000>; clocks = <&bpmp TEGRA264_CLK_TOP_I2C>, <&bpmp TEGRA264_CLK_PLLP_OUT0>; @@ -3882,6 +3951,8 @@ i2c12: i2c@c6d0000 { compatible = "nvidia,tegra264-i2c"; reg = <0x00 0x0c6d0000 0x0 0x10000>; interrupts = <GIC_SPI 134 IRQ_TYPE_LEVEL_HIGH>; + #address-cells = <1>; + #size-cells = <0>; clock-frequency = <400000>; clocks = <&bpmp TEGRA264_CLK_TOP_I2C>, <&bpmp TEGRA264_CLK_PLLP_OUT0>; @@ -4685,6 +4756,33 @@ sound { status = "disabled"; }; + thermal-zones { + cpu-thermal { + thermal-sensors = <&{/bpmp/thermal} TEGRA264_THERMAL_ZONE_CPU_MAX>; + status = "disabled"; + }; + + gpu-thermal { + thermal-sensors = <&{/bpmp/thermal} TEGRA264_THERMAL_ZONE_GPU_MAX>; + status = "disabled"; + }; + + soc012-thermal { + thermal-sensors = <&{/bpmp/thermal} TEGRA264_THERMAL_ZONE_SOC_012_MAX>; + status = "disabled"; + }; + + soc345-thermal { + thermal-sensors = <&{/bpmp/thermal} TEGRA264_THERMAL_ZONE_SOC_345_MAX>; + status = "disabled"; + }; + + tj-thermal { + thermal-sensors = <&{/bpmp/thermal} TEGRA264_THERMAL_ZONE_TJ_MAX>; + status = "disabled"; + }; + }; + timer { compatible = "arm,armv8-timer"; interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>,
diff --git a/arch/arm64/boot/dts/nvidia/thermal/nvidia,tegra264-bpmp.h b/arch/arm64/boot/dts/nvidia/thermal/nvidia,tegra264-bpmp.h new file mode 100644 index 0000000..2969588 --- /dev/null +++ b/arch/arm64/boot/dts/nvidia/thermal/nvidia,tegra264-bpmp.h
@@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* SPDX-FileCopyrightText: Copyright (c) 2023-2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved. */ + +#ifndef DT_BINDINGS_THERMAL_NVIDIA_TEGRA264_BPMP_H +#define DT_BINDINGS_THERMAL_NVIDIA_TEGRA264_BPMP_H + +#define TEGRA264_THERMAL_ZONE_TJ_MAX 0 +#define TEGRA264_THERMAL_ZONE_TJ_MIN 1 +#define TEGRA264_THERMAL_ZONE_GPU_AVG 2 +#define TEGRA264_THERMAL_ZONE_CPU_AVG 3 +#define TEGRA264_THERMAL_ZONE_SOC_012_AVG 4 +#define TEGRA264_THERMAL_ZONE_SOC_45_AVG 5 +#define TEGRA264_THERMAL_ZONE_SOC_3_AVG 6 +#define TEGRA264_THERMAL_ZONE_GPU_MAX 7 +#define TEGRA264_THERMAL_ZONE_CPU_MAX 8 +#define TEGRA264_THERMAL_ZONE_SOC_012_MAX 9 +#define TEGRA264_THERMAL_ZONE_SOC_345_MAX 10 +#define TEGRA264_THERMAL_ZONE_TJ_AVG 11 + +#endif /* DT_BINDINGS_THERMAL_NVIDIA_TEGRA264_BPMP_H */
diff --git a/arch/arm64/boot/dts/qcom/Makefile b/arch/arm64/boot/dts/qcom/Makefile index 1c86e7e..88230c4 100644 --- a/arch/arm64/boot/dts/qcom/Makefile +++ b/arch/arm64/boot/dts/qcom/Makefile
@@ -16,14 +16,20 @@ dtb-$(CONFIG_ARCH_QCOM) += apq8096-ifc6640.dtb dtb-$(CONFIG_ARCH_QCOM) += eliza-cqs-evk.dtb dtb-$(CONFIG_ARCH_QCOM) += eliza-mtp.dtb +dtb-$(CONFIG_ARCH_QCOM) += glymur-asus-zenbook-a14-ux3407na.dtb dtb-$(CONFIG_ARCH_QCOM) += glymur-asus-zenbook-a16-ux3607oa.dtb dtb-$(CONFIG_ARCH_QCOM) += glymur-crd.dtb +dtb-$(CONFIG_ARCH_QCOM) += glymur-hp-elitebook-x-g2q.dtb +dtb-$(CONFIG_ARCH_QCOM) += glymur-lenovo-yoga-slim7x.dtb +dtb-$(CONFIG_ARCH_QCOM) += glymur-qcb.dtb +dtb-$(CONFIG_ARCH_QCOM) += hamoa-advantech-som-db5830.dtb dtb-$(CONFIG_ARCH_QCOM) += hamoa-iot-evk.dtb hamoa-iot-evk-el2-dtbs := hamoa-iot-evk.dtb x1-el2.dtbo dtb-$(CONFIG_ARCH_QCOM) += hamoa-iot-evk-el2.dtb dtb-$(CONFIG_ARCH_QCOM) += hamoa-lenovo-ideacentre-mini-01q8x10.dtb +dtb-$(CONFIG_ARCH_QCOM) += hawi-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq5018-rdp432-c2.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq5018-tplink-archer-ax55-v1.dtb dtb-$(CONFIG_ARCH_QCOM) += ipq5210-rdp504.dtb @@ -58,9 +64,11 @@ lemans-evk-ifp-mezzanine-dtbs := lemans-evk.dtb lemans-evk-ifp-mezzanine.dtbo dtb-$(CONFIG_ARCH_QCOM) += lemans-evk-ifp-mezzanine.dtb dtb-$(CONFIG_ARCH_QCOM) += mahua-crd.dtb +dtb-$(CONFIG_ARCH_QCOM) += mahua-lenovo-thinkpad-t14s-gen7-lcd.dtb dtb-$(CONFIG_ARCH_QCOM) += milos-fairphone-fp6.dtb dtb-$(CONFIG_ARCH_QCOM) += milos-nothing-asteroids.dtb dtb-$(CONFIG_ARCH_QCOM) += monaco-arduino-monza.dtb +dtb-$(CONFIG_ARCH_QCOM) += monaco-ac-evk.dtb dtb-$(CONFIG_ARCH_QCOM) += monaco-evk.dtb monaco-evk-camera-imx577-dtbs := monaco-evk.dtb monaco-evk-camera-imx577.dtbo @@ -68,6 +76,9 @@ monaco-evk-el2-dtbs := monaco-evk.dtb monaco-el2.dtbo +monaco-ac-evk-ifp-mezzanine-dtbs := monaco-ac-evk.dtb monaco-evk-ifp-mezzanine.dtbo +dtb-$(CONFIG_ARCH_QCOM) += monaco-ac-evk-ifp-mezzanine.dtb + dtb-$(CONFIG_ARCH_QCOM) += monaco-evk-el2.dtb monaco-evk-ifp-mezzanine-dtbs := monaco-evk.dtb monaco-evk-ifp-mezzanine.dtbo dtb-$(CONFIG_ARCH_QCOM) += monaco-evk-ifp-mezzanine.dtb @@ -120,6 +131,7 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8939-wingtech-wt82918.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8939-wingtech-wt82918hd.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8953-flipkart-rimob.dtb +dtb-$(CONFIG_ARCH_QCOM) += msm8953-motorola-deen.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8953-motorola-potter.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8953-xiaomi-daisy.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8953-xiaomi-mido.dtb @@ -127,6 +139,7 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8953-xiaomi-vince.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8956-sony-xperia-loire-kugo.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8956-sony-xperia-loire-suzu.dtb +dtb-$(CONFIG_ARCH_QCOM) += msm8976-leeco-s2.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8976-longcheer-l9360.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8992-lg-bullhead-rev-10.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8992-lg-bullhead-rev-101.dtb @@ -160,6 +173,8 @@ dtb-$(CONFIG_ARCH_QCOM) += msm8998-sony-xperia-yoshino-maple.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8998-sony-xperia-yoshino-poplar.dtb dtb-$(CONFIG_ARCH_QCOM) += msm8998-xiaomi-sagit.dtb +dtb-$(CONFIG_ARCH_QCOM) += nord-ride.dtb +dtb-$(CONFIG_ARCH_QCOM) += nord-rrd.dtb dtb-$(CONFIG_ARCH_QCOM) += purwa-iot-evk.dtb purwa-iot-evk-el2-dtbs := purwa-iot-evk.dtb x1-el2.dtbo @@ -186,6 +201,21 @@ dtb-$(CONFIG_ARCH_QCOM) += qcs6490-rb3gen2-vision-mezzanine.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs6490-thundercomm-minipc-g1iot.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs6490-thundercomm-rubikpi3.dtb + +qcs6490-thundercomm-rubikpi3-cam1-imx219-dtbs := \ + qcs6490-thundercomm-rubikpi3.dtb \ + qcs6490-thundercomm-rubikpi3-cam1-imx219.dtbo +qcs6490-thundercomm-rubikpi3-cam2-imx219-dtbs := \ + qcs6490-thundercomm-rubikpi3.dtb \ + qcs6490-thundercomm-rubikpi3-cam2-imx219.dtbo +qcs6490-thundercomm-rubikpi3-dual-imx219-dtbs := \ + qcs6490-thundercomm-rubikpi3.dtb \ + qcs6490-thundercomm-rubikpi3-cam1-imx219.dtbo \ + qcs6490-thundercomm-rubikpi3-cam2-imx219.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += qcs6490-thundercomm-rubikpi3-cam1-imx219.dtb +dtb-$(CONFIG_ARCH_QCOM) += qcs6490-thundercomm-rubikpi3-cam2-imx219.dtb +dtb-$(CONFIG_ARCH_QCOM) += qcs6490-thundercomm-rubikpi3-dual-imx219.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs6490-vicharak-axon-mini.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs8300-ride.dtb @@ -193,7 +223,13 @@ dtb-$(CONFIG_ARCH_QCOM) += qcs8300-ride-el2.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs8550-aim300-aiot.dtb +dtb-$(CONFIG_ARCH_QCOM) += qcs8550-ayntec-odin2mini.dtb +dtb-$(CONFIG_ARCH_QCOM) += qcs8550-ayntec-odin2portal.dtb +dtb-$(CONFIG_ARCH_QCOM) += qcs8550-ayntec-thor.dtb +dtb-$(CONFIG_ARCH_QCOM) += qcs8550-imdt-sbc.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs8550-rb5gen2.dtb +dtb-$(CONFIG_ARCH_QCOM) += qcs8550-retroidpocket-nova.dtb +dtb-$(CONFIG_ARCH_QCOM) += qcs8550-retroidpocket-rp6.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride.dtb dtb-$(CONFIG_ARCH_QCOM) += qcs9100-ride-r3.dtb @@ -339,9 +375,18 @@ dtb-$(CONFIG_ARCH_QCOM) += shikra-cqm-evk.dtb dtb-$(CONFIG_ARCH_QCOM) += shikra-cqs-evk.dtb dtb-$(CONFIG_ARCH_QCOM) += shikra-iqs-evk.dtb + +shikra-cqm-evk-imx577-camera-dtbs := shikra-cqm-evk.dtb shikra-cqm-cqs-evk-imx577-camera.dtbo +shikra-cqs-evk-imx577-camera-dtbs := shikra-cqs-evk.dtb shikra-cqm-cqs-evk-imx577-camera.dtbo +shikra-iqs-evk-imx577-camera-dtbs := shikra-iqs-evk.dtb shikra-iqs-evk-imx577-camera.dtbo + +dtb-$(CONFIG_ARCH_QCOM) += shikra-cqm-evk-imx577-camera.dtb +dtb-$(CONFIG_ARCH_QCOM) += shikra-cqs-evk-imx577-camera.dtb +dtb-$(CONFIG_ARCH_QCOM) += shikra-iqs-evk-imx577-camera.dtb dtb-$(CONFIG_ARCH_QCOM) += sm4250-oneplus-billie2.dtb dtb-$(CONFIG_ARCH_QCOM) += sm4450-qrd.dtb dtb-$(CONFIG_ARCH_QCOM) += sm6115-fxtec-pro1x.dtb +dtb-$(CONFIG_ARCH_QCOM) += sm6115-xiaomi-lemon.dtb dtb-$(CONFIG_ARCH_QCOM) += sm6115p-lenovo-j606f.dtb dtb-$(CONFIG_ARCH_QCOM) += sm6125-sony-xperia-seine-pdx201.dtb dtb-$(CONFIG_ARCH_QCOM) += sm6125-xiaomi-ginkgo.dtb @@ -356,6 +401,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sm7325-motorola-dubai-csot.dtb dtb-$(CONFIG_ARCH_QCOM) += sm7325-motorola-dubai-tianma.dtb dtb-$(CONFIG_ARCH_QCOM) += sm7325-nothing-spacewar.dtb +dtb-$(CONFIG_ARCH_QCOM) += sm7325-xiaomi-lisa.dtb dtb-$(CONFIG_ARCH_QCOM) += sm7325-xiaomi-taoyao.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8150-hdk.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8150-microsoft-surface-duo.dtb @@ -406,6 +452,7 @@ dtb-$(CONFIG_ARCH_QCOM) += sm8650-hdk.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8650-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8650-qrd.dtb +dtb-$(CONFIG_ARCH_QCOM) += sm8650-valve-deckard.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8750-mtp.dtb dtb-$(CONFIG_ARCH_QCOM) += sm8750-qrd.dtb dtb-$(CONFIG_ARCH_QCOM) += talos-evk.dtb @@ -421,6 +468,9 @@ talos-evk-lvds-auo,g133han01-dtbs := \ talos-evk.dtb talos-evk-lvds-auo,g133han01.dtbo dtb-$(CONFIG_ARCH_QCOM) += talos-evk-lvds-auo,g133han01.dtb +talos-evk-rpi-display-2-5in-dtbs := \ + talos-evk.dtb talos-evk-rpi-display-2-5in.dtbo +dtb-$(CONFIG_ARCH_QCOM) += talos-evk-rpi-display-2-5in.dtb x1e001de-devkit-el2-dtbs := x1e001de-devkit.dtb x1-el2.dtbo dtb-$(CONFIG_ARCH_QCOM) += x1e001de-devkit.dtb x1e001de-devkit-el2.dtb x1e78100-lenovo-thinkpad-t14s-el2-dtbs := x1e78100-lenovo-thinkpad-t14s.dtb x1-el2.dtbo
diff --git a/arch/arm64/boot/dts/qcom/agatti.dtsi b/arch/arm64/boot/dts/qcom/agatti.dtsi index 590bd24..d9f4cbf 100644 --- a/arch/arm64/boot/dts/qcom/agatti.dtsi +++ b/arch/arm64/boot/dts/qcom/agatti.dtsi
@@ -381,6 +381,14 @@ rmtfs_mem: memory@89b01000 { qcom,client-id = <1>; qcom,vmid = <QCOM_SCM_VMID_MSS_MSA QCOM_SCM_VMID_NAV>; }; + + adsp_rpc_remote_heap_mem: adsp-rpc-remote-heap { + compatible = "shared-dma-pool"; + alloc-ranges = <0x0 0x0 0x1 0x0>; + reusable; + alignment = <0x0 0x400000>; + size = <0x0 0x800000>; + }; }; smp2p-adsp { @@ -1572,12 +1580,15 @@ &qup_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>, }; }; - usb: usb@4ef8800 { - compatible = "qcom,qcm2290-dwc3", "qcom,dwc3"; - reg = <0x0 0x04ef8800 0x0 0x400>; - interrupts-extended = <&intc GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>, + usb: usb@4e00000 { + compatible = "qcom,qcm2290-dwc3", "qcom,snps-dwc3"; + reg = <0x0 0x04e00000 0x0 0xfc100>; + + interrupts-extended = <&intc GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_SPI 260 IRQ_TYPE_LEVEL_HIGH>, <&mpm 12 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "hs_phy_irq", + interrupt-names = "dwc_usb3", + "hs_phy_irq", "ss_phy_irq"; clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>, @@ -1595,7 +1606,8 @@ usb: usb@4ef8800 { assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>, <&gcc GCC_USB30_PRIM_MASTER_CLK>; - assigned-clock-rates = <19200000>, <133333333>; + assigned-clock-rates = <19200000>, + <133333333>; resets = <&gcc GCC_USB30_PRIM_BCR>; power-domains = <&gcc GCC_USB30_PRIM_GDSC>; @@ -1606,48 +1618,42 @@ &bimc SLAVE_EBI1 RPM_ALWAYS_TAG>, &config_noc SLAVE_USB3 RPM_ALWAYS_TAG>; interconnect-names = "usb-ddr", "apps-usb"; - wakeup-source; - #address-cells = <2>; - #size-cells = <2>; - ranges; + iommus = <&apps_smmu 0x120 0x0>; + + phys = <&usb_hsphy>, + <&usb_qmpphy>; + phy-names = "usb2-phy", + "usb3-phy"; + + snps,hird-threshold = /bits/ 8 <0x10>; + snps,parkmode-disable-ss-quirk; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + snps,has-lpm-erratum; + snps,usb3_lpm_capable; + + usb-role-switch; + wakeup-source; status = "disabled"; - usb_dwc3: usb@4e00000 { - compatible = "snps,dwc3"; - reg = <0x0 0x04e00000 0x0 0xcd00>; - interrupts = <GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH>; - phys = <&usb_hsphy>, <&usb_qmpphy>; - phy-names = "usb2-phy", "usb3-phy"; - iommus = <&apps_smmu 0x120 0x0>; - snps,dis_u2_susphy_quirk; - snps,dis_enblslpm_quirk; - snps,has-lpm-erratum; - snps,hird-threshold = /bits/ 8 <0x10>; - snps,usb3_lpm_capable; - snps,parkmode-disable-ss-quirk; - maximum-speed = "super-speed"; - dr_mode = "otg"; - usb-role-switch; + ports { + #address-cells = <1>; + #size-cells = <0>; - ports { - #address-cells = <1>; - #size-cells = <0>; + port@0 { + reg = <0>; - port@0 { - reg = <0>; - - usb_dwc3_hs: endpoint { - }; + usb_dwc3_hs: endpoint { }; + }; - port@1 { - reg = <1>; + port@1 { + reg = <1>; - usb_dwc3_ss: endpoint { - remote-endpoint = <&usb_qmpphy_usb_ss_in>; - }; + usb_dwc3_ss: endpoint { + remote-endpoint = <&usb_qmpphy_usb_ss_in>; }; }; }; @@ -1917,7 +1923,7 @@ camss: camss@5c11000 { <&gcc GCC_CAMSS_TFE_0_CLK>, <&gcc GCC_CAMSS_TFE_0_CPHY_RX_CLK>, <&gcc GCC_CAMSS_TFE_1_CLK>, - <&gcc GCC_CAMSS_TFE_1_CPHY_RX_CLK> ; + <&gcc GCC_CAMSS_TFE_1_CPHY_RX_CLK>; clock-names = "ahb", "axi", "camnoc_nrt_axi", @@ -2348,6 +2354,9 @@ fastrpc { compatible = "qcom,fastrpc"; qcom,glink-channels = "fastrpcglink-apps-dsp"; label = "adsp"; + memory-region = <&adsp_rpc_remote_heap_mem>; + qcom,vmids = <QCOM_SCM_VMID_LPASS + QCOM_SCM_VMID_ADSP_HEAP>; qcom,non-secure-domain;
diff --git a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi index 0c07685..ad435a1 100644 --- a/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi +++ b/arch/arm64/boot/dts/qcom/apq8096-db820c.dtsi
@@ -458,23 +458,32 @@ hdmi_ddc_suspend: hdmi-ddc-suspend-state { &pcie0 { status = "okay"; - perst-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; vddpe-3v3-supply = <&wlan_en>; vdda-supply = <&vreg_l28a_0p925>; }; +&pcie0_port0 { + reset-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; +}; + &pcie1 { status = "okay"; - perst-gpios = <&tlmm 130 GPIO_ACTIVE_LOW>; vdda-supply = <&vreg_l28a_0p925>; }; +&pcie1_port0 { + reset-gpios = <&tlmm 130 GPIO_ACTIVE_LOW>; +}; + &pcie2 { status = "okay"; - perst-gpios = <&tlmm 114 GPIO_ACTIVE_LOW>; vdda-supply = <&vreg_l28a_0p925>; }; +&pcie2_port0 { + reset-gpios = <&tlmm 114 GPIO_ACTIVE_LOW>; +}; + &pcie_phy { status = "okay";
diff --git a/arch/arm64/boot/dts/qcom/eliza-cqs-som.dtsi b/arch/arm64/boot/dts/qcom/eliza-cqs-som.dtsi index 5ef6c51..03f9192 100644 --- a/arch/arm64/boot/dts/qcom/eliza-cqs-som.dtsi +++ b/arch/arm64/boot/dts/qcom/eliza-cqs-som.dtsi
@@ -374,6 +374,14 @@ &pm7550ba_eusb2_repeater { vdd3-supply = <&vreg_l17b>; }; +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/eliza/gen71700_zap.mbn"; +}; + &remoteproc_adsp { firmware-name = "qcom/eliza/adsp.mbn", "qcom/eliza/adsp_dtb.mbn"; @@ -381,6 +389,13 @@ &remoteproc_adsp { status = "okay"; }; +&remoteproc_cdsp { + firmware-name = "qcom/eliza/cdsp.mbn", + "qcom/eliza/cdsp_dtb.mbn"; + + status = "okay"; +}; + &sdhc_1 { vmmc-supply = <&vreg_l12b>; vqmmc-supply = <&vreg_l1d>;
diff --git a/arch/arm64/boot/dts/qcom/eliza-evk.dtsi b/arch/arm64/boot/dts/qcom/eliza-evk.dtsi index 2fc9456..6c5cc47 100644 --- a/arch/arm64/boot/dts/qcom/eliza-evk.dtsi +++ b/arch/arm64/boot/dts/qcom/eliza-evk.dtsi
@@ -12,6 +12,19 @@ chosen { stdout-path = "serial0:115200n8"; }; + gpio-keys { + compatible = "gpio-keys"; + + key-volume-up { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + gpios = <&pm7550_gpios 6 GPIO_ACTIVE_LOW>; + debounce-interval = <10>; + linux,can-disable; + wakeup-source; + }; + }; + pmic-glink { compatible = "qcom,eliza-pmic-glink", "qcom,sm8550-pmic-glink", @@ -49,6 +62,121 @@ pmic_glink_ss_in: endpoint { }; }; }; + + vreg_0p9: regulator-0v9 { + compatible = "regulator-fixed"; + regulator-name = "VREG_0P9"; + + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + regulator-always-on; + regulator-boot-on; + }; + + vreg_1p8: regulator-1v8 { + compatible = "regulator-fixed"; + regulator-name = "VREG_1P8"; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + vreg_pcie_m_3p3: regulator-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "vreg_3p3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&gpio_expander1 6 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + connector-0 { + compatible = "pcie-m2-e-connector"; + vpcie3v3-supply = <&vreg_pcie_m_3p3>; + w-disable1-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; + w-disable2-gpios = <&pm8550vs_g_gpios 4 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&m2_w_disable1>, <&m2_w_disable2>; + pinctrl-names = "default"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + m2_e_pcie_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&pcieport0_ep>; + }; + }; + + port@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + + m2_e_uart_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&uart5_ep>; + }; + }; + }; + }; +}; + +&i2c4 { + pinctrl-0 = <&qup_i2c4_data_clk>; + pinctrl-names = "default"; + + clock-frequency = <400000>; + + status = "okay"; + + gpio_expander1: gpio@3c { + compatible = "ti,tca9538"; + #gpio-cells = <2>; + gpio-controller; + reg = <0x3c>; + }; +}; + +&pcie0 { + status = "okay"; +}; + +&pcie0_phy { + vdda-phy-supply = <&vreg_l1k>; + vdda-pll-supply = <&vreg_l3k>; + + status = "okay"; +}; + +&pcie0_port0 { + wake-gpios = <&tlmm 114 GPIO_ACTIVE_LOW>; + reset-gpios = <&tlmm 78 GPIO_ACTIVE_LOW>; + + port { + pcieport0_ep: endpoint { + remote-endpoint = <&m2_e_pcie_ep>; + }; + }; +}; + +&pon_pwrkey { + status = "okay"; +}; + +&pon_resin { + linux,code = <KEY_VOLUMEDOWN>; + status = "okay"; }; &pm7550ba_eusb2_repeater { @@ -77,6 +205,91 @@ sd_cd: sd-cd-state { }; }; +&pcie1 { + iommu-map = <0x0 &apps_smmu 0x1400 0x0 0x1>, + <0x100 &apps_smmu 0x1401 0x0 0x1>, + <0x208 &apps_smmu 0x1402 0x0 0x1>, + <0x210 &apps_smmu 0x1403 0x0 0x1>, + <0x218 &apps_smmu 0x1404 0x0 0x1>, + <0x300 &apps_smmu 0x1405 0x0 0x1>, + <0x400 &apps_smmu 0x1406 0x0 0x1>, + <0x500 &apps_smmu 0x1407 0x0 0x1>, + <0x501 &apps_smmu 0x1408 0x0 0x1>; + + status = "okay"; +}; + +&pcie1_phy { + vdda-phy-supply = <&vreg_l1k>; + vdda-pll-supply = <&vreg_l3k>; + + status = "okay"; +}; + +&pcie1_port0 { + wake-gpios = <&tlmm 53 GPIO_ACTIVE_LOW>; + /* Same GPIO is used for both PERST# and resx-gpio */ + + tc9563: pcie@0,0 { + compatible = "pci1179,0623"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + ranges; + bus-range = <0x2 0xff>; + + vddc-supply = <&vreg_0p9>; + vdd18-supply = <&vreg_1p8>; + vdd09-supply = <&vreg_0p9>; + vddio1-supply = <&vreg_1p8>; + vddio2-supply = <&vreg_1p8>; + vddio18-supply = <&vreg_1p8>; + + i2c-parent = <&i2c4 0x77>; + + resx-gpios = <&tlmm 54 GPIO_ACTIVE_LOW>; + + pcie@1,0 { + reg = <0x20800 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + ranges; + bus-range = <0x3 0xff>; + }; + + pcie@2,0 { + reg = <0x21000 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + + device_type = "pci"; + ranges; + bus-range = <0x4 0xff>; + }; + + pcie@3,0 { + reg = <0x21800 0x0 0x0 0x0 0x0>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + ranges; + bus-range = <0x5 0xff>; + + ethernet@0,0 { + reg = <0x50000 0x0 0x0 0x0 0x0>; + }; + + ethernet@0,1 { + reg = <0x50100 0x0 0x0 0x0 0x0>; + }; + }; + }; +}; + &uart13 { compatible = "qcom,geni-debug-uart"; @@ -110,3 +323,33 @@ &usb_hsphy { status = "okay"; }; + +&uart5 { + status = "okay"; + + port { + uart5_ep: endpoint { + remote-endpoint = <&m2_e_uart_ep>; + }; + }; +}; + +&pm8550vs_g_gpios { + m2_w_disable2: m2-w-disable2-state { + pins = "gpio4"; + function = "normal"; + input-disable; + output-enable; + bias-disable; + power-source = <2>; + }; +}; + +&tlmm { + m2_w_disable1: m2-w-disable1-state { + pins = "gpio35"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; +};
diff --git a/arch/arm64/boot/dts/qcom/eliza-mtp.dts b/arch/arm64/boot/dts/qcom/eliza-mtp.dts index 868ae6c..ee05192 100644 --- a/arch/arm64/boot/dts/qcom/eliza-mtp.dts +++ b/arch/arm64/boot/dts/qcom/eliza-mtp.dts
@@ -422,6 +422,14 @@ vreg_l7k: ldo7 { }; }; +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/eliza/gen71700_zap.mbn"; +}; + &mdss { status = "okay"; }; @@ -484,6 +492,26 @@ &remoteproc_adsp { status = "okay"; }; +&remoteproc_cdsp { + firmware-name = "qcom/eliza/cdsp.mbn", + "qcom/eliza/cdsp_dtb.mbn"; + + status = "okay"; +}; + +&sdhc_2 { + vmmc-supply = <&vreg_l13b>; + vqmmc-supply = <&vreg_l23b>; + + cd-gpios = <&tlmm 58 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&sdc2_default>, <&sd_cd>; + pinctrl-1 = <&sdc2_sleep>, <&sd_cd>; + pinctrl-names = "default", "sleep"; + + status = "okay"; +}; + &spi8 { status = "okay"; @@ -534,6 +562,12 @@ mdp_vsync: mdp-vsync-state { bias-pull-down; }; + sd_cd: sd-cd-state { + pins = "gpio58"; + function = "gpio"; + bias-pull-up; + }; + ts_irq: ts-irq-state { pins = "gpio13"; function = "gpio";
diff --git a/arch/arm64/boot/dts/qcom/eliza.dtsi b/arch/arm64/boot/dts/qcom/eliza.dtsi index 66ea4aa..a804229 100644 --- a/arch/arm64/boot/dts/qcom/eliza.dtsi +++ b/arch/arm64/boot/dts/qcom/eliza.dtsi
@@ -4,9 +4,13 @@ */ #include <dt-bindings/clock/qcom,dsi-phy-28nm.h> +#include <dt-bindings/clock/qcom,eliza-cambistmclkcc.h> +#include <dt-bindings/clock/qcom,eliza-camcc.h> #include <dt-bindings/clock/qcom,eliza-dispcc.h> #include <dt-bindings/clock/qcom,eliza-gcc.h> +#include <dt-bindings/clock/qcom,eliza-gpucc.h> #include <dt-bindings/clock/qcom,eliza-tcsr.h> +#include <dt-bindings/clock/qcom,eliza-videocc.h> #include <dt-bindings/clock/qcom,rpmh.h> #include <dt-bindings/dma/qcom-gpi.h> #include <dt-bindings/gpio/gpio.h> @@ -20,6 +24,7 @@ #include <dt-bindings/soc/qcom,gpr.h> #include <dt-bindings/soc/qcom,rpmh-rsc.h> #include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h> +#include <dt-bindings/thermal/thermal.h> / { interrupt-parent = <&intc>; @@ -636,6 +641,30 @@ smp2p_adsp_in: slave-kernel { }; }; + smp2p-cdsp { + compatible = "qcom,smp2p"; + qcom,smem = <94>, <432>; + interrupts-extended = <&ipcc IPCC_CLIENT_CDSP + IPCC_MPROC_SIGNAL_SMP2P + IRQ_TYPE_EDGE_RISING>; + mboxes = <&ipcc IPCC_CLIENT_CDSP + IPCC_MPROC_SIGNAL_SMP2P>; + + qcom,local-pid = <0>; + qcom,remote-pid = <5>; + + smp2p_cdsp_out: master-kernel { + qcom,entry-name = "master-kernel"; + #qcom,smem-state-cells = <1>; + }; + + smp2p_cdsp_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + soc: soc@0 { compatible = "simple-bus"; @@ -650,12 +679,12 @@ gcc: clock-controller@100000 { clocks = <&bi_tcxo_div2>, <&sleep_clk>, - <0>, - <0>, + <&pcie0_phy>, + <&pcie1_phy>, <&ufs_mem_phy 0>, <&ufs_mem_phy 1>, <&ufs_mem_phy 2>, - <0>; + <&usb_dp_qmpphy QMP_USB43DP_USB3_PIPE_CLK>; power-domains = <&rpmhpd RPMHPD_CX>; @@ -1787,6 +1816,23 @@ aggre2_noc: interconnect@1700000 { #interconnect-cells = <2>; }; + cambistmclkcc: clock-controller@1760000 { + compatible = "qcom,eliza-cambistmclkcc"; + reg = <0x0 0x01760000 0x0 0x6000>; + + clocks = <&bi_tcxo_div2>, + <&sleep_clk>, + <&gcc GCC_CAM_BIST_MCLK_AHB_CLK>; + + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MX>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + + #clock-cells = <1>; + #reset-cells = <1>; + }; + mmss_noc: interconnect@1780000 { compatible = "qcom,eliza-mmss-noc"; reg = <0x0 0x01780000 0x0 0x7d800>; @@ -1794,6 +1840,369 @@ mmss_noc: interconnect@1780000 { #interconnect-cells = <2>; }; + pcie0: pcie@1c00000 { + device_type = "pci"; + compatible = "qcom,eliza-pcie", "qcom,pcie-sm8550"; + reg = <0x0 0x01c00000 0x0 0x3000>, + <0x0 0x40000000 0x0 0xf1d>, + <0x0 0x40000f20 0x0 0xa8>, + <0x0 0x40001000 0x0 0x1000>, + <0x0 0x40100000 0x0 0x100000>, + <0x0 0x01c03000 0x0 0x1000>; + reg-names = "parf", + "dbi", + "elbi", + "atu", + "config", + "mhi"; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>, + <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x3d00000>; + + interrupts = <GIC_SPI 376 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 535 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 536 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 537 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 540 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 653 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + + clocks = <&gcc GCC_PCIE_0_AUX_CLK>, + <&gcc GCC_PCIE_0_CFG_AHB_CLK>, + <&gcc GCC_PCIE_0_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_0_SLV_AXI_CLK>, + <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>, + <&gcc GCC_DDRSS_PCIE_SF_QTB_CLK>, + <&gcc GCC_AGGRE_NOC_PCIE_AXI_CLK>, + <&gcc GCC_CNOC_PCIE_SF_AXI_CLK>; + clock-names = "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a", + "ddrss_sf_tbu", + "noc_aggr", + "cnoc_sf_axi"; + + resets = <&gcc GCC_PCIE_0_BCR>, + <&gcc GCC_PCIE_0_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; + + interconnects = <&pcie_noc MASTER_PCIE_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &cnoc_main SLAVE_PCIE_0 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "pcie-mem", + "cpu-pcie"; + + power-domains = <&gcc GCC_PCIE_0_GDSC>; + + operating-points-v2 = <&pcie0_opp_table>; + + iommu-map = <0x0 &apps_smmu 0x1480 0x0 0x1>, + <0x100 &apps_smmu 0x1481 0x0 0x1>; + + interrupt-map = <0 0 0 1 &intc 0 0 0 564 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc 0 0 0 565 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc 0 0 0 566 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc 0 0 0 567 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + #interrupt-cells = <1>; + + linux,pci-domain = <0>; + bus-range = <0x0 0xff>; + + dma-coherent; + + pinctrl-0 = <&pcie0_default_state>; + pinctrl-names = "default"; + + status = "disabled"; + + pcie0_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* 2.5 GT/s x1 */ + opp-2500000-1 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <250000 1>; + opp-level = <1>; + }; + + /* 5 GT/s x1 */ + opp-5000000-2 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <2>; + }; + + /* 8 GT/s x1 */ + opp-8000000-3 { + opp-hz = /bits/ 64 <8000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <984500 1>; + opp-level = <3>; + }; + + }; + + pcie0_port0: pcie@0 { + compatible = "pciclass,0604"; + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + phys = <&pcie0_phy>; + }; + }; + + pcie0_phy: phy@1c06000 { + compatible = "qcom,eliza-qmp-gen3x1-pcie-phy"; + reg = <0x0 0x01c06000 0x0 0x2000>; + + clocks = <&gcc GCC_PCIE_0_AUX_CLK>, + <&gcc GCC_PCIE_0_CFG_AHB_CLK>, + <&tcsr TCSR_PCIE_0_CLKREF_EN>, + <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_0_PIPE_CLK>, + <&gcc GCC_PCIE_0_PIPE_DIV2_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "rchng", + "pipe", + "pipediv2"; + + assigned-clocks = <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>; + assigned-clock-rates = <100000000>; + + resets = <&gcc GCC_PCIE_0_PHY_BCR>, + <&gcc GCC_PCIE_0_NOCSR_COM_PHY_BCR>; + reset-names = "phy", + "phy_nocsr"; + + power-domains = <&gcc GCC_PCIE_0_PHY_GDSC>; + + #clock-cells = <0>; + clock-output-names = "pcie0_pipe_clk"; + + #phy-cells = <0>; + + status = "disabled"; + }; + + pcie1: pcie@1c08000 { + device_type = "pci"; + compatible = "qcom,eliza-pcie", "qcom,pcie-sm8550"; + reg = <0x0 0x01c08000 0x0 0x3000>, + <0x0 0x44000000 0x0 0xf1d>, + <0x0 0x44000f20 0x0 0xa8>, + <0x0 0x44001000 0x0 0x1000>, + <0x0 0x44100000 0x0 0x100000>, + <0x0 0x01c0b000 0x0 0x1000>; + reg-names = "parf", + "dbi", + "elbi", + "atu", + "config", + "mhi"; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x0 0x44200000 0x0 0x100000>, + <0x02000000 0x0 0x44300000 0x0 0x44300000 0x0 0x3d00000>, + <0x43000000 0x4 0x00000000 0x4 0x00000000 0x3 0x00000000>; + + interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 142 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 143 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 144 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 145 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 146 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 147 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + + clocks = <&gcc GCC_PCIE_1_AUX_CLK>, + <&gcc GCC_PCIE_1_CFG_AHB_CLK>, + <&gcc GCC_PCIE_1_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_1_SLV_AXI_CLK>, + <&gcc GCC_PCIE_1_SLV_Q2A_AXI_CLK>, + <&gcc GCC_DDRSS_PCIE_SF_QTB_CLK>, + <&gcc GCC_AGGRE_NOC_PCIE_AXI_CLK>, + <&gcc GCC_CNOC_PCIE_SF_AXI_CLK>; + clock-names = "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a", + "ddrss_sf_tbu", + "noc_aggr", + "cnoc_sf_axi"; + + resets = <&gcc GCC_PCIE_1_BCR>, + <&gcc GCC_PCIE_1_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; + + interconnects = <&pcie_noc MASTER_PCIE_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &cnoc_main SLAVE_PCIE_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "pcie-mem", + "cpu-pcie"; + + power-domains = <&gcc GCC_PCIE_1_GDSC>; + + operating-points-v2 = <&pcie1_opp_table>; + + iommu-map = <0x0 &apps_smmu 0x1400 0x0 0x1>, + <0x100 &apps_smmu 0x1401 0x0 0x1>; + + interrupt-map = <0 0 0 1 &intc 0 0 0 149 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc 0 0 0 150 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc 0 0 0 151 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc 0 0 0 152 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + #interrupt-cells = <1>; + + linux,pci-domain = <1>; + bus-range = <0x0 0xff>; + + dma-coherent; + + pinctrl-0 = <&pcie1_default_state>; + pinctrl-names = "default"; + + status = "disabled"; + + pcie1_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* 2.5 GT/s x1 */ + opp-2500000-1 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <250000 1>; + opp-level = <1>; + }; + + /* 2.5 GT/s x2 */ + opp-5000000-1 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <1>; + }; + + /* 5 GT/s x1 */ + opp-5000000-2 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <2>; + }; + + /* 5 GT/s x2 */ + opp-10000000-2 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <2>; + }; + + /* 8 GT/s x1 */ + opp-8000000-3 { + opp-hz = /bits/ 64 <8000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <984500 1>; + opp-level = <3>; + }; + + /* 8 GT/s x2 */ + opp-16000000-3 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <3>; + }; + + }; + + pcie1_port0: pcie@0 { + compatible = "pciclass,0604"; + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + phys = <&pcie1_phy>; + }; + }; + + pcie1_phy: phy@1c0e000 { + compatible = "qcom,eliza-qmp-gen3x2-pcie-phy"; + reg = <0x0 0x01c0e000 0x0 0x2000>; + + clocks = <&gcc GCC_PCIE_1_AUX_CLK>, + <&gcc GCC_PCIE_1_CFG_AHB_CLK>, + <&tcsr TCSR_PCIE_1_CLKREF_EN>, + <&gcc GCC_PCIE_1_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_1_PIPE_CLK>, + <&gcc GCC_PCIE_1_PIPE_DIV2_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "rchng", + "pipe", + "pipediv2"; + + assigned-clocks = <&gcc GCC_PCIE_1_PHY_RCHNG_CLK>; + assigned-clock-rates = <100000000>; + + resets = <&gcc GCC_PCIE_1_PHY_BCR>, + <&gcc GCC_PCIE_1_NOCSR_COM_PHY_BCR>; + reset-names = "phy", + "phy_nocsr"; + + power-domains = <&gcc GCC_PCIE_1_PHY_GDSC>; + + #clock-cells = <0>; + clock-output-names = "pcie1_pipe_clk"; + + #phy-cells = <0>; + + status = "disabled"; + }; + ufs_mem_phy: phy@1d80000 { compatible = "qcom,eliza-qmp-ufs-phy", "qcom,sm8650-qmp-ufs-phy"; @@ -2893,6 +3302,98 @@ mdss_dp0_out: endpoint { }; }; + adreno_smmu: iommu@3da0000 { + compatible = "qcom,eliza-smmu-500", "qcom,adreno-smmu", + "qcom,smmu-500", "arm,mmu-500"; + reg = <0x0 0x03da0000 0x0 0x40000>; + #iommu-cells = <2>; + #global-interrupts = <1>; + interrupts = <GIC_SPI 673 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 677 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 678 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 679 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 680 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 681 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 682 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 683 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 684 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 685 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 686 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 687 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 574 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 575 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 576 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 577 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 659 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 661 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 664 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 665 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 666 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 668 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 669 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 699 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>; + clock-names = "hlos"; + power-domains = <&gpucc GPU_CC_CX_GDSC>; + dma-coherent; + }; + + gpucc: clock-controller@3d90000 { + compatible = "qcom,eliza-gpucc"; + reg = <0x0 0x03d90000 0x0 0xa000>; + + clocks = <&bi_tcxo_div2>, + <&gcc GCC_GPU_GPLL0_CPH_CLK_SRC>, + <&gcc GCC_GPU_GPLL0_DIV_CPH_CLK_SRC>; + + power-domains = <&rpmhpd RPMHPD_MX>, + <&rpmhpd RPMHPD_CX>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + videocc: clock-controller@aaf0000 { + compatible = "qcom,eliza-videocc"; + reg = <0x0 0xaaf0000 0x0 0x10000>; + + clocks = <&bi_tcxo_div2>, + <&bi_tcxo_ao_div2>, + <&sleep_clk>, + <&gcc GCC_VIDEO_AHB_CLK>; + + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MX>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + camcc: clock-controller@ade0000 { + compatible = "qcom,eliza-camcc"; + reg = <0x0 0x0ade0000 0x0 0x20000>; + + clocks = <&bi_tcxo_div2>, + <&sleep_clk>, + <&gcc GCC_CAMERA_AHB_CLK>; + + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MX>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + dispcc: clock-controller@af00000 { compatible = "qcom,eliza-dispcc"; reg = <0x0 0x0af00000 0x0 0x20000>; @@ -3079,6 +3580,52 @@ tlmm: pinctrl@f100000 { gpio-ranges = <&tlmm 0 0 184>; wakeup-parent = <&pdc>; + pcie0_default_state: pcie0-default-state { + perst-pins { + pins = "gpio78"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + clkreq-pins { + pins = "gpio80"; + function = "pcie0_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + wake-pins { + pins = "gpio114"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie1_default_state: pcie1-default-state { + perst-pins { + pins = "gpio54"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + clkreq-pins { + pins = "gpio52"; + function = "pcie1_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + wake-pins { + pins = "gpio53"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + qup_i2c0_data_clk: qup-i2c0-data-clk-state { pins = "gpio28", "gpio29"; function = "qup1_se0"; @@ -3975,6 +4522,209 @@ nsp_noc: interconnect@320c0000 { qcom,bcm-voters = <&apps_bcm_voter>; #interconnect-cells = <2>; }; + + remoteproc_cdsp: remoteproc@32300000 { + compatible = "qcom,eliza-cdsp-pas"; + reg = <0x0 0x32300000 0x0 0x10000>; + + interrupts-extended = <&intc GIC_SPI 578 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 3 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 7 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack", + "shutdown-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MX>, + <&rpmhpd RPMHPD_NSP>; + power-domain-names = "cx", + "mx", + "nsp"; + + interconnects = <&nsp_noc MASTER_CDSP_PROC QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + + memory-region = <&cdsp_mem>, <&q6_cdsp_dtb_mem>, <&global_sync_mem>; + + qcom,qmp = <&aoss_qmp>; + + qcom,smem-states = <&smp2p_cdsp_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + + glink-edge { + interrupts-extended = <&ipcc IPCC_CLIENT_CDSP + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + mboxes = <&ipcc IPCC_CLIENT_CDSP + IPCC_MPROC_SIGNAL_GLINK_QMP>; + + label = "cdsp"; + qcom,remote-pid = <5>; + }; + }; + + gpu: gpu@3d00000 { + compatible = "qcom,adreno-43020100", "qcom,adreno"; + reg = <0x0 0x03d00000 0x0 0x40000>, + <0x0 0x03d9e000 0x0 0x1000>, + <0x0 0x03d61000 0x0 0x800>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem", + "cx_dbgc"; + + interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>; + + iommus = <&adreno_smmu 0x0 0x0>; + + operating-points-v2 = <&gpu_opp_table>; + qcom,gmu = <&gmu>; + #cooling-cells = <2>; + interconnects = <&gem_noc MASTER_GFX3D QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "gfx-mem"; + + status = "disabled"; + + gpu_zap_shader: zap-shader { + memory-region = <&gpu_micro_code_mem>; + }; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2-adreno", + "operating-points-v2"; + + opp-259000000 { + opp-hz = /bits/ 64 <259000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>; + opp-peak-kBps = <781250>; + qcom,opp-acd-level = <0xc82f5ffd>; + }; + + opp-345000000 { + opp-hz = /bits/ 64 <345000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>; + opp-peak-kBps = <2136718>; + qcom,opp-acd-level = <0xc82f5ffd>; + }; + + opp-515000000 { + opp-hz = /bits/ 64 <515000000>; + opp-level = <RPMH_REGULATOR_LEVEL_SVS>; + opp-peak-kBps = <5285156>; + qcom,opp-acd-level = <0xc02d5ffd>; + }; + + opp-645000000 { + opp-hz = /bits/ 64 <645000000>; + opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>; + opp-peak-kBps = <6074218>; + qcom,opp-acd-level = <0x882f5ffd>; + }; + + opp-724000000 { + opp-hz = /bits/ 64 <724000000>; + opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2>; + opp-peak-kBps = <6671875>; + qcom,opp-acd-level = <0xa82d5ffd>; + }; + + opp-796000000 { + opp-hz = /bits/ 64 <796000000>; + opp-level = <RPMH_REGULATOR_LEVEL_NOM>; + opp-peak-kBps = <10687500>; + qcom,opp-acd-level = <0x882d5ffd>; + }; + + opp-900000000 { + opp-hz = /bits/ 64 <900000000>; + opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>; + opp-peak-kBps = <10687500>; + qcom,opp-acd-level = <0x882d5ffd>; + }; + + opp-975000000 { + opp-hz = /bits/ 64 <975000000>; + opp-level = <RPMH_REGULATOR_LEVEL_TURBO>; + opp-peak-kBps = <12449218>; + qcom,opp-acd-level = <0x882c5ffd>; + }; + + opp-1075000000 { + opp-hz = /bits/ 64 <1075000000>; + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>; + opp-peak-kBps = <16500000>; + qcom,opp-acd-level = <0xa82a5ffd>; + }; + + opp-1150000000 { + opp-hz = /bits/ 64 <1150000000>; + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L2>; + opp-peak-kBps = <16500000>; + qcom,opp-acd-level = <0xa8295ffd>; + }; + }; + }; + + gmu: gmu@3d6a000 { + compatible = "qcom,adreno-gmu-722.0", "qcom,adreno-gmu"; + reg = <0x0 0x03d6a000 0x0 0x35000>, + <0x0 0x03d50000 0x0 0x10000>, + <0x0 0x0b290000 0x0 0x10000>; + reg-names = "gmu", "rscc", "gmu_pdc"; + + interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "hfi", "gmu"; + + clocks = <&gpucc GPU_CC_AHB_CLK>, + <&gpucc GPU_CC_CX_GMU_CLK>, + <&gpucc GPU_CC_CXO_CLK>, + <&gcc GCC_DDRSS_GPU_AXI_CLK>, + <&gcc GCC_GPU_GEMNOC_GFX_CLK>, + <&gpucc GPU_CC_HUB_CX_INT_CLK>, + <&gpucc GPU_CC_DEMET_CLK>; + clock-names = "ahb", + "gmu", + "cxo", + "axi", + "memnoc", + "hub", + "demet"; + + power-domains = <&gpucc GPU_CC_CX_GDSC>, + <&gpucc GPU_CC_GX_GDSC>; + power-domain-names = "cx", + "gx"; + + iommus = <&adreno_smmu 0x5 0x0>; + qcom,qmp = <&aoss_qmp>; + operating-points-v2 = <&gmu_opp_table>; + + gmu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-220000000 { + opp-hz = /bits/ 64 <220000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>; + }; + + opp-550000000 { + opp-hz = /bits/ 64 <550000000>; + opp-level = <RPMH_REGULATOR_LEVEL_SVS>; + }; + }; + }; }; thermal-zones { @@ -4284,7 +5034,7 @@ gpuss0-thermal { thermal-sensors = <&tsens1 8>; trips { - gpu-alert { + gpuss0_alert0: gpu-alert { temperature = <95000>; hysteresis = <1000>; type = "passive"; @@ -4302,6 +5052,13 @@ gpu-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss0_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss1-thermal { @@ -4310,7 +5067,7 @@ gpuss1-thermal { thermal-sensors = <&tsens1 9>; trips { - gpu-alert { + gpuss1_alert0: gpu-alert { temperature = <95000>; hysteresis = <1000>; type = "passive"; @@ -4328,6 +5085,13 @@ gpu-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss1_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; modem0-thermal {
diff --git a/arch/arm64/boot/dts/qcom/glymur-asus-zenbook-a14-ux3407na.dts b/arch/arm64/boot/dts/qcom/glymur-asus-zenbook-a14-ux3407na.dts new file mode 100644 index 0000000..e96e65a0 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/glymur-asus-zenbook-a14-ux3407na.dts
@@ -0,0 +1,1140 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +/dts-v1/; + +#include "glymur.dtsi" + +#include "pmcx0102.dtsi" +#include "pmh0101.dtsi" +#include "pmh0110-glymur.dtsi" +#include "pmh0104-glymur.dtsi" +#include "pmk8850.dtsi" +#include "smb2370.dtsi" + +#include <dt-bindings/input/gpio-keys.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/pinctrl/qcom,pmic-gpio.h> + +/ { + compatible = "asus,zenbook-a14-ux3407na", "qcom,glymur"; + model = "ASUS Zenbook A14 (UX3407NA)"; + + aliases { + i2c0 = &i2c0; + i2c5 = &i2c5; + i2c8 = &i2c8; + i2c10 = &i2c10; + i2c19 = &i2c19; + serial0 = &uart14; + }; + + clocks { + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + clock-frequency = <32000>; + #clock-cells = <0>; + }; + + xo_board: xo-board { + compatible = "fixed-clock"; + clock-frequency = <38400000>; + #clock-cells = <0>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&hall_int_n_default>; + pinctrl-names = "default"; + + switch-lid { + label = "lid"; + gpios = <&tlmm 92 GPIO_ACTIVE_LOW>; + linux,input-type = <EV_SW>; + linux,code = <SW_LID>; + wakeup-source; + wakeup-event-action = <EV_ACT_DEASSERTED>; + }; + }; + + hdmi-bridge { + compatible = "parade,ps185hdm"; + + pinctrl-0 = <&usb2_dp_hot_plug_detect>; + pinctrl-names = "default"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + hdmi_bridge_in: endpoint { + remote-endpoint = <&usb_2_qmpphy_out_dp>; + }; + }; + + port@1 { + reg = <1>; + + hdmi_bridge_out: endpoint { + remote-endpoint = <&hdmi_con>; + }; + }; + }; + }; + + hdmi-connector { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con: endpoint { + remote-endpoint = <&hdmi_bridge_out>; + }; + }; + }; + + leds { + compatible = "gpio-leds"; + + pinctrl-0 = <&cam_indicator_en>, + <&keyboard_cam_led>, + <&keyboard_mic_led>; + pinctrl-names = "default"; + + keyboard-camera-led { + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_ORANGE>; + gpios = <&tlmm 120 GPIO_ACTIVE_HIGH>; + default-state = "off"; + panic-indicator; + }; + + keyboard-mic-led { + function = LED_FUNCTION_MICMUTE; + color = <LED_COLOR_ID_ORANGE>; + gpios = <&tlmm 98 GPIO_ACTIVE_LOW>; + default-state = "off"; + panic-indicator; + }; + + privacy-led { + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_WHITE>; + gpios = <&tlmm 111 GPIO_ACTIVE_HIGH>; + default-state = "off"; + panic-indicator; + }; + }; + + pmic-glink { + compatible = "qcom,glymur-pmic-glink", + "qcom,pmic-glink"; + #address-cells = <1>; + #size-cells = <0>; + + /* Left side display-adjacent port */ + connector@0 { + compatible = "usb-c-connector"; + reg = <0>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in: endpoint { + remote-endpoint = <&usb_0_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in: endpoint { + remote-endpoint = <&usb_0_qmpphy_out>; + }; + }; + }; + }; + + /* Left side user-adjacent port */ + connector@1 { + compatible = "usb-c-connector"; + reg = <1>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in1: endpoint { + remote-endpoint = <&usb_1_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in1: endpoint { + remote-endpoint = <&usb_1_qmpphy_out>; + }; + }; + }; + }; + }; + + vreg_edp: regulator-edp { + compatible = "regulator-fixed"; + + regulator-name = "VREG_EDP_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 70 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&edp_pwr_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_misc_3p3: regulator-misc-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_MISC_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pmh0110_f_e0_gpios 6 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&misc_3p3_reg_en>; + pinctrl-names = "default"; + + regulator-always-on; + regulator-boot-on; + }; + + vreg_nvme: regulator-nvme { + compatible = "regulator-fixed"; + + regulator-name = "VREG_NVME_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pmh0101_gpios 14 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&nvme_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_wcn_3p3: regulator-wcn-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 94 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&wcn_sw_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + reserved-memory { + linux,cma { + compatible = "shared-dma-pool"; + size = <0x0 0x10000000>; + reusable; + linux,cma-default; + }; + }; + + sound { + compatible = "qcom,glymur-sndcard"; + model = "GLYMUR-ASUS-Zenbook-A14-UX3407NA"; + + audio-routing = "SpkrLeft IN", "WSA WSA_SPK1 OUT", + "SpkrRight IN", "WSA WSA_SPK2 OUT", + "VA DMIC0", "vdd-micb", + "VA DMIC1", "vdd-micb"; + + va-dai-link { + link-name = "VA Capture"; + + codec { + sound-dai = <&lpass_vamacro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + wsa-dai-link { + link-name = "WSA Playback"; + + codec { + sound-dai = <&left_speaker>, <&right_speaker>, + <&swr0 0>, <&lpass_wsamacro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + }; + + wlan-connector { + compatible = "pcie-m2-e-connector"; + vpcie3v3-supply = <&vreg_wcn_3p3>; + vpcie1v8-supply = <&vreg_l15b0>; + + w-disable1-gpios = <&tlmm 117 GPIO_ACTIVE_LOW>; + w-disable2-gpios = <&tlmm 116 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&wcn_wlan_bt_en>; + pinctrl-names = "default"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + m2_e_pcie_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&pcie4_port0_ep>; + }; + }; + + port@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + + m2_e_uart_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&uart14_ep>; + }; + }; + }; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pmh0101-rpmh-regulators"; + qcom,pmic-id = "B_E0"; + + vreg_l1b0: ldo1 { + regulator-name = "vreg_l1b0"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7b0: ldo7 { + regulator-name = "vreg_l7b0"; + regulator-min-microvolt = <3072000>; + regulator-max-microvolt = <3072000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l8b0: ldo8 { + regulator-name = "vreg_l8b0"; + regulator-min-microvolt = <3304000>; + regulator-max-microvolt = <3304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l15b0: ldo15 { + regulator-name = "vreg_l15b0"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + /* Provides reference voltage for many undescribed components */ + regulator-always-on; + }; + + vreg_l18b0: ldo18 { + regulator-name = "vreg_l18b0"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + + /* + * This is also reference voltage for &pcie3b wake and + * reset signals. + */ + regulator-always-on; + }; + }; + + regulators-1 { + compatible = "qcom,pmcx0102-rpmh-regulators"; + qcom,pmic-id = "C_E1"; + + vreg_l1c1: ldo1 { + regulator-name = "vreg_l1c1"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2c1: ldo2 { + regulator-name = "vreg_l2c1"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3c1: ldo3 { + regulator-name = "vreg_l3c1"; + regulator-min-microvolt = <936000>; + regulator-max-microvolt = <936000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4c1: ldo4 { + regulator-name = "vreg_l4c1"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-2 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "F_E0"; + + vreg_l2f0: ldo2 { + regulator-name = "vreg_l2f0"; + regulator-min-microvolt = <936000>; + regulator-max-microvolt = <936000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3f0: ldo3 { + regulator-name = "vreg_l3f0"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-3 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "F_E1"; + + vreg_l1f1: ldo1 { + regulator-name = "vreg_l1f1"; + regulator-min-microvolt = <904000>; + regulator-max-microvolt = <904000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2f1: ldo2 { + regulator-name = "vreg_l2f1"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4f1: ldo4 { + regulator-name = "vreg_l4f1"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-4 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "H_E0"; + + vreg_l1h0: ldo1 { + regulator-name = "vreg_l1h0"; + regulator-min-microvolt = <936000>; + regulator-max-microvolt = <936000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2h0: ldo2 { + regulator-name = "vreg_l2h0"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4h0: ldo4 { + regulator-name = "vreg_l4h0"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; +}; + +&gpu { + status = "okay"; +}; + +&gmu { + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + + status = "okay"; + + touchpad@15 { + compatible = "hid-over-i2c"; + reg = <0x15>; + + hid-descr-addr = <0x1>; + interrupts-extended = <&tlmm 3 IRQ_TYPE_LEVEL_LOW>; + + vdd-supply = <&vreg_misc_3p3>; + vddl-supply = <&vreg_l15b0>; + + pinctrl-0 = <&tpad_default>; + pinctrl-names = "default"; + + wakeup-source; + }; +}; + +&i2c5 { + clock-frequency = <400000>; + + status = "okay"; + + ptn3222_1: redriver@43 { + compatible = "nxp,ptn3222"; + reg = <0x43>; + + reset-gpios = <&tlmm 184 GPIO_ACTIVE_LOW>; + + vdd3v3-supply = <&vreg_l8b0>; + vdd1v8-supply = <&vreg_l15b0>; + + #phy-cells = <0>; + }; + + ptn3222_0: redriver@4f { + compatible = "nxp,ptn3222"; + reg = <0x4f>; + + reset-gpios = <&tlmm 8 GPIO_ACTIVE_LOW>; + + vdd3v3-supply = <&vreg_l8b0>; + vdd1v8-supply = <&vreg_l15b0>; + + #phy-cells = <0>; + }; +}; + +&i2c8 { + clock-frequency = <400000>; + + status = "okay"; + + touchscreen@15 { + compatible = "hid-over-i2c"; + reg = <0x15>; + + hid-descr-addr = <0x1>; + interrupts-extended = <&tlmm 51 IRQ_TYPE_LEVEL_LOW>; + + pinctrl-0 = <&ts_default>; + pinctrl-names = "default"; + + wakeup-source; + }; +}; + +&i2c10 { + clock-frequency = <400000>; + + status = "okay"; + + hid@17 { + compatible = "hid-over-i2c"; + reg = <0x17>; + interrupts-extended = <&tlmm 43 IRQ_TYPE_LEVEL_LOW>; + hid-descr-addr = <0x1>; + wakeup-source; + + pinctrl-0 = <&hid_app_default>; + pinctrl-names = "default"; + }; +}; + +&i2c19 { + clock-frequency = <400000>; + + status = "okay"; + + keyboard@15 { + compatible = "hid-over-i2c"; + reg = <0x15>; + + hid-descr-addr = <0x1>; + interrupts-extended = <&tlmm 67 IRQ_TYPE_LEVEL_LOW>; + + wakeup-source; + + pinctrl-0 = <&kybd_default>; + pinctrl-names = "default"; + }; +}; + +&lpass_vamacro { + vdd-micb-supply = <&vreg_l1b0>; + + pinctrl-0 = <&dmic01_default>; + pinctrl-names = "default"; + + qcom,dmic-sample-rate = <2400000>; +}; + +&mdss { + status = "okay"; +}; + +&mdss_dp0 { + status = "okay"; +}; + +&mdss_dp0_out { + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; +}; + +&mdss_dp1 { + status = "okay"; +}; + +&mdss_dp1_out { + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; +}; + +&mdss_dp2 { + status = "okay"; +}; + +&mdss_dp2_out { + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; +}; + +&mdss_dp3 { + /delete-property/ #sound-dai-cells; + + pinctrl-0 = <&edp0_hpd_default>; + pinctrl-names = "default"; + + status = "okay"; + + aux-bus { + panel { + compatible = "samsung,atna40ct06", "samsung,atna33xc20"; + enable-gpios = <&tlmm 18 GPIO_ACTIVE_HIGH>; + power-supply = <&vreg_edp>; + + pinctrl-0 = <&edp_bl_en>; + pinctrl-names = "default"; + + port { + edp_panel_in: endpoint { + remote-endpoint = <&mdss_dp3_out>; + }; + }; + }; + }; +}; + +&mdss_dp3_out { + data-lanes = <0 1 2 3>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; + + remote-endpoint = <&edp_panel_in>; +}; + +&mdss_dp3_phy { + vdda-phy-supply = <&vreg_l2f1>; + vdda-pll-supply = <&vreg_l4f1>; + + status = "okay"; +}; + +&pcie3_phy { + vdda-phy-supply = <&vreg_l3c1>; + vdda-pll-supply = <&vreg_l2c1>; + + vdda-refgen0p9-supply = <&vreg_l1c1>; + vdda-refgen1p2-supply = <&vreg_l4f1>; + + status = "okay"; +}; + +&pcie3b { + vddpe-3v3-supply = <&vreg_nvme>; + + pinctrl-0 = <&pcie3b_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie3b_port0 { + reset-gpios = <&tlmm 155 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 157 GPIO_ACTIVE_LOW>; +}; + +&pcie4 { + pinctrl-0 = <&pcie4_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie4_phy { + vdda-phy-supply = <&vreg_l1c1>; + vdda-pll-supply = <&vreg_l4f1>; + + status = "okay"; +}; + +&pcie4_port0 { + reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>; +}; + +&pcie4_port0_ep { + remote-endpoint = <&m2_e_pcie_ep>; +}; + +&pmh0101_gpios { + nvme_reg_en: nvme-reg-en-state { + pins = "gpio14"; + function = "normal"; + bias-disable; + }; +}; + +&pmh0110_f_e0_gpios { + misc_3p3_reg_en: misc-3p3-reg-en-state { + pins = "gpio6"; + function = "normal"; + bias-disable; + input-disable; + output-enable; + drive-push-pull; + power-source = <1>; /* 1.8 V */ + qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>; + }; +}; + +&pmk8850_rtc { + qcom,no-alarm; +}; + +&remoteproc_adsp { + firmware-name = "qcom/glymur/ASUSTeK/UX3407NA/qcadsp8480.mbn", + "qcom/glymur/ASUSTeK/UX3407NA/adsp_dtbs.elf"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/glymur/ASUSTeK/UX3407NA/qccdsp8480.mbn", + "qcom/glymur/ASUSTeK/UX3407NA/cdsp_dtbs.elf"; + + status = "okay"; +}; + +&remoteproc_soccp { + status = "okay"; +}; + +&smb2370_j_e2_eusb2_repeater { + vdd18-supply = <&vreg_l15b0>; + vdd3-supply = <&vreg_l7b0>; +}; + +&smb2370_k_e2_eusb2_repeater { + vdd18-supply = <&vreg_l15b0>; + vdd3-supply = <&vreg_l7b0>; +}; + +&swr0 { + status = "okay"; + + /* WSA8845, left */ + left_speaker: speaker@0,0 { + compatible = "sdw20217020400"; + reg = <0 0>; + reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "SpkrLeft"; + vdd-1p8-supply = <&vreg_l15b0>; + vdd-io-supply = <&vreg_l18b0>; + qcom,port-mapping = <1 2 3 7 12 14>; + }; + + /* WSA8845, right */ + right_speaker: speaker@0,1 { + compatible = "sdw20217020400"; + reg = <0 1>; + reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "SpkrRight"; + vdd-1p8-supply = <&vreg_l15b0>; + vdd-io-supply = <&vreg_l18b0>; + qcom,port-mapping = <4 5 6 7 13 15>; + }; +}; + +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l2f1>; + vdda-qrefrpt1-0p9-supply = <&vreg_l2f1>; + vdda-qrefrpt2-0p9-supply = <&vreg_l2f1>; + vdda-qrefrpt3-0p9-supply = <&vreg_l2h0>; + vdda-qrefrpt4-0p9-supply = <&vreg_l2h0>; + vdda-qrefrx0-0p9-supply = <&vreg_l2f1>; + vdda-qrefrx1-0p9-supply = <&vreg_l2f1>; + vdda-qrefrx2-0p9-supply = <&vreg_l2f1>; + vdda-qrefrx4-0p9-supply = <&vreg_l2h0>; + vdda-qrefrx5-0p9-supply = <&vreg_l3f0>; + vdda-qreftx0-0p9-supply = <&vreg_l3f0>; + vdda-qreftx0-1p2-supply = <&vreg_l4h0>; + vdda-qreftx1-0p9-supply = <&vreg_l1f1>; + vdda-refgen3-0p9-supply = <&vreg_l2f0>; + vdda-refgen3-1p2-supply = <&vreg_l4h0>; + vdda-refgen4-0p9-supply = <&vreg_l1f1>; + vdda-refgen4-1p2-supply = <&vreg_l4f1>; +}; + +&tlmm { + gpio-reserved-ranges = <4 4>, /* EC Secure */ + <10 2>, /* OOB UART */ + <44 4>, /* TPM */ + <65 1>, /* EC reset */ + <90 2>; /* TPM */ + + tpad_default: tpad-default-state { + pins = "gpio3"; + function = "gpio"; + bias-disable; + }; + + edp_bl_en: edp-bl-en-state { + pins = "gpio18"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + hid_app_default: hid-app-default-state { + pins = "gpio43"; + function = "gpio"; + bias-disable; + }; + + ts_default: ts-default-state { + reset-n-pins { + pins = "gpio48"; + function = "gpio"; + bias-disable; + }; + + int-pins { + pins = "gpio51"; + function = "gpio"; + bias-disable; + }; + }; + + kybd_default: kybd-default-state { + pins = "gpio67"; + function = "gpio"; + bias-disable; + }; + + edp_pwr_en: edp-pwr-en-state { + pins = "gpio70"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + hall_int_n_default: hall-int-n-state { + pins = "gpio92"; + function = "gpio"; + bias-disable; + }; + + wcn_sw_en: wcn-sw-en-state { + pins = "gpio94"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + keyboard_mic_led: keyboard-mic-led-state { + pins = "gpio98"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + cam_indicator_en: cam-indicator-en-state { + pins = "gpio111"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wcn_wlan_bt_en: wcn-wlan-bt-en-state { + pins = "gpio116", "gpio117"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + edp0_hpd_default: edp0-hpd-default-state { + pins = "gpio119"; + function = "edp0_hot"; + bias-disable; + }; + + keyboard_cam_led: keyboard-cam-led-state { + pins = "gpio120"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + usb2_dp_hot_plug_detect: usb2-dp-hot-plug-detect-state { + pins = "gpio126"; + function = "usb2_dp"; + bias-disable; + }; + + pcie4_default: pcie4-default-state { + clkreq-n-pins { + pins = "gpio147"; + function = "pcie4_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio146"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio148"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie3b_default: pcie3b-default-state { + clkreq-n-pins { + pins = "gpio156"; + function = "pcie3b_clk"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio155"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio157"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; +}; + +&uart14 { + status = "okay"; + + port { + uart14_ep: endpoint { + remote-endpoint = <&m2_e_uart_ep>; + }; + }; +}; + +&uart21 { + status = "disabled"; +}; + +&usb_0 { + status = "okay"; +}; + +&usb_0_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in>; +}; + +&usb_0_hsphy { + vdd-supply = <&vreg_l3f0>; + vdda12-supply = <&vreg_l4h0>; + + phys = <&smb2370_j_e2_eusb2_repeater>; + + status = "okay"; +}; + +&usb_0_qmpphy { + vdda-phy-supply = <&vreg_l3f0>; + vdda-pll-supply = <&vreg_l4h0>; + refgen-supply = <&vreg_l2f0>; + + status = "okay"; +}; + +&usb_0_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in>; +}; + +&usb_1 { + status = "okay"; +}; + +&usb_1_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in1>; +}; + +&usb_1_hsphy { + vdd-supply = <&vreg_l3f0>; + vdda12-supply = <&vreg_l4h0>; + + phys = <&smb2370_k_e2_eusb2_repeater>; + + status = "okay"; +}; + +&usb_1_qmpphy { + vdda-phy-supply = <&vreg_l1h0>; + vdda-pll-supply = <&vreg_l4h0>; + refgen-supply = <&vreg_l2f0>; + + status = "okay"; +}; + +&usb_1_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in1>; +}; + +&usb_2_qmpphy { + vdda-phy-supply = <&vreg_l4c1>; + vdda-pll-supply = <&vreg_l4f1>; + refgen-supply = <&vreg_l4f1>; + + /delete-property/ mode-switch; + /delete-property/ orientation-switch; + + status = "okay"; + + ports { + port@0 { + #address-cells = <1>; + #size-cells = <0>; + + /delete-node/ endpoint; + + usb_2_qmpphy_out_dp: endpoint@0 { + reg = <0>; + + data-lanes = <3 2 1 0>; + remote-endpoint = <&hdmi_bridge_in>; + }; + }; + }; +}; + +&usb_mp { + status = "okay"; +}; + +&usb_mp_hsphy0 { + vdd-supply = <&vreg_l2h0>; + vdda12-supply = <&vreg_l4h0>; + + phys = <&ptn3222_0>; + + status = "okay"; +}; + +&usb_mp_hsphy1 { + vdd-supply = <&vreg_l2h0>; + vdda12-supply = <&vreg_l4h0>; + + phys = <&ptn3222_1>; + + status = "okay"; +}; + +&usb_mp_qmpphy0 { + vdda-phy-supply = <&vreg_l2h0>; + vdda-pll-supply = <&vreg_l4h0>; + refgen-supply = <&vreg_l4f1>; + + status = "okay"; +}; + +&usb_mp_qmpphy1 { + vdda-phy-supply = <&vreg_l2h0>; + vdda-pll-supply = <&vreg_l4h0>; + refgen-supply = <&vreg_l4f1>; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/qcom/glymur-asus-zenbook-a16-ux3607oa.dts b/arch/arm64/boot/dts/qcom/glymur-asus-zenbook-a16-ux3607oa.dts index 939e1a9..95da351 100644 --- a/arch/arm64/boot/dts/qcom/glymur-asus-zenbook-a16-ux3607oa.dts +++ b/arch/arm64/boot/dts/qcom/glymur-asus-zenbook-a16-ux3607oa.dts
@@ -737,7 +737,7 @@ &lpass_vamacro { pinctrl-0 = <&dmic01_default>; pinctrl-names = "default"; - qcom,dmic-sample-rate = <4800000>; + qcom,dmic-sample-rate = <2400000>; }; &mdss { @@ -861,7 +861,6 @@ nvme_reg_en: nvme-reg-en-state { }; &pmk8850_rtc { - qcom,uefi-rtc-info; qcom,no-alarm; };
diff --git a/arch/arm64/boot/dts/qcom/glymur-crd.dts b/arch/arm64/boot/dts/qcom/glymur-crd.dts index 44766a7..b8e3fed 100644 --- a/arch/arm64/boot/dts/qcom/glymur-crd.dts +++ b/arch/arm64/boot/dts/qcom/glymur-crd.dts
@@ -29,6 +29,14 @@ &mdss_dp1_out { link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; }; +&pcie3_phy { + vdda-phy-supply = <&vreg_l3c_e1_0p89>; + vdda-pll-supply = <&vreg_l2c_e1_1p14>; + + vdda-refgen0p9-supply = <&vreg_l1c_e1_0p82>; + vdda-refgen1p2-supply = <&vreg_l4f_e1_1p08>; +}; + &tcsr { vdda-qrefrpt0-0p9-supply = <&vreg_l2f_e1_0p83>; vdda-qrefrpt1-0p9-supply = <&vreg_l2f_e1_0p83>;
diff --git a/arch/arm64/boot/dts/qcom/glymur-crd.dtsi b/arch/arm64/boot/dts/qcom/glymur-crd.dtsi index e27c697..58158b5 100644 --- a/arch/arm64/boot/dts/qcom/glymur-crd.dtsi +++ b/arch/arm64/boot/dts/qcom/glymur-crd.dtsi
@@ -373,7 +373,7 @@ vreg_l1b_e0_1p8: ldo1 { vreg_l2b_e0_2p9: ldo2 { regulator-name = "vreg_l2b_e0_2p9"; - regulator-min-microvolt = <2904000>; + regulator-min-microvolt = <1804000>; regulator-max-microvolt = <2904000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; }; @@ -392,10 +392,10 @@ vreg_l8b_e0_1p50: ldo8 { regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; }; - vreg_l9b_e0_2p7: ldo9 { - regulator-name = "vreg_l9b_e0_2p7"; - regulator-min-microvolt = <2704000>; - regulator-max-microvolt = <2704000>; + vreg_l9b_e0_2p9: ldo9 { + regulator-name = "vreg_l9b_e0_2p9"; + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <2960000>; regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; }; @@ -899,6 +899,22 @@ &smb2370_k_e2_eusb2_repeater { vdd3-supply = <&vreg_l7b_e0_2p79>; }; +&sdhc_2 { + vmmc-supply = <&vreg_l9b_e0_2p9>; + vqmmc-supply = <&vreg_l2b_e0_2p9>; + + pinctrl-0 = <&sdc2_default_state &sdc2_card_det_n>; + pinctrl-1 = <&sdc2_sleep_state &sdc2_card_det_n>; + pinctrl-names = "default", "sleep"; + + cd-gpios = <&tlmm 221 GPIO_ACTIVE_LOW>; + + no-mmc; + no-sdio; + + status = "okay"; +}; + &swr0 { status = "okay"; @@ -963,7 +979,8 @@ &remoteproc_soccp { &tlmm { gpio-reserved-ranges = <4 4>, /* EC TZ Secure I3C */ <10 2>, /* OOB UART */ - <44 4>; /* Security SPI (TPM) */ + <44 4>, /* Security SPI (TPM) */ + <65 1>; /* EC reset */ edp_bl_en: edp-bl-en-state { pins = "gpio18"; @@ -1089,6 +1106,13 @@ wake-n-pins { }; }; + sdc2_card_det_n: sd-card-det-n-state { + pins = "gpio221"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + tpad_default: tpad-default-state { pins = "gpio3"; function = "gpio";
diff --git a/arch/arm64/boot/dts/qcom/glymur-hp-elitebook-x-g2q.dts b/arch/arm64/boot/dts/qcom/glymur-hp-elitebook-x-g2q.dts new file mode 100644 index 0000000..096d40e --- /dev/null +++ b/arch/arm64/boot/dts/qcom/glymur-hp-elitebook-x-g2q.dts
@@ -0,0 +1,940 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +/dts-v1/; + +#include "glymur.dtsi" + +#include "pmcx0102.dtsi" +#include "pmh0101.dtsi" +#include "pmh0110-glymur.dtsi" +#include "pmh0104-glymur.dtsi" +#include "pmk8850.dtsi" +#include "smb2370.dtsi" + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/gpio-keys.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/regulator/qcom,rpmh-regulator.h> +#include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h> + +/ { + model = "HP EliteBook X G2q 14 AI"; + compatible = "hp,elitebook-x-g2q", "qcom,glymur"; + + aliases { + i2c0 = &i2c0; + i2c8 = &i2c8; + + serial0 = &uart21; + serial1 = &uart14; + }; + + clocks { + xo_board: xo-board { + compatible = "fixed-clock"; + clock-frequency = <38400000>; + #clock-cells = <0>; + }; + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + clock-frequency = <32000>; + #clock-cells = <0>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&lid_default>; + pinctrl-names = "default"; + + switch-lid { + label = "lid"; + gpios = <&tlmm 92 GPIO_ACTIVE_LOW>; + linux,input-type = <EV_SW>; + linux,code = <SW_LID>; + wakeup-source; + wakeup-event-action = <EV_ACT_DEASSERTED>; + }; + }; + + pmic-glink { + compatible = "qcom,glymur-pmic-glink", + "qcom,pmic-glink"; + #address-cells = <1>; + #size-cells = <0>; + + /* Left side port */ + connector@0 { + compatible = "usb-c-connector"; + reg = <0>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in: endpoint { + remote-endpoint = <&usb_0_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in: endpoint { + remote-endpoint = <&usb_0_qmpphy_out>; + }; + }; + }; + }; + + /* Right side port */ + connector@1 { + compatible = "usb-c-connector"; + reg = <1>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in1: endpoint { + remote-endpoint = <&usb_1_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in1: endpoint { + remote-endpoint = <&usb_1_qmpphy_out>; + }; + }; + }; + }; + }; + + vreg_edp_3p3: regulator-edp-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_EDP_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 70 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&edp_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_nvme: regulator-nvme { + compatible = "regulator-fixed"; + + regulator-name = "VREG_NVME_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pmh0101_gpios 14 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&nvme_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_wcn_0p95: regulator-wcn-0p95 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_0P95"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <950000>; + + vin-supply = <&vreg_wcn_3p3>; + }; + + vreg_wcn_3p3: regulator-wcn-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 94 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&wcn_sw_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + sound { + compatible = "qcom,glymur-sndcard"; + model = "GLYMUR-HP-EliteBook-X-G2q"; + + audio-routing = "WooferLeft IN", "WSA WSA_SPK1 OUT", + "TweeterLeft IN", "WSA WSA_SPK2 OUT", + "WooferRight IN", "WSA2 WSA_SPK1 OUT", + "TweeterRight IN", "WSA2 WSA_SPK2 OUT", + "VA DMIC0", "vdd-micb", + "VA DMIC1", "vdd-micb"; + + va-dai-link { + link-name = "VA Capture"; + + codec { + sound-dai = <&lpass_vamacro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + wsa-dai-link { + link-name = "WSA Playback"; + + codec { + sound-dai = <&left_woofer>, <&left_tweeter>, + <&swr0 0>, <&lpass_wsamacro 0>, + <&right_woofer>, <&right_tweeter>, + <&swr3 0>, <&lpass_wsa2macro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + }; + + wcn7850-pmu { + compatible = "qcom,wcn7850-pmu"; + + vdd-supply = <&vreg_wcn_0p95>; + vddio-supply = <&vreg_l15b_e0_1p8>; + vddaon-supply = <&vreg_l15b_e0_1p8>; + vdddig-supply = <&vreg_l15b_e0_1p8>; + vddrfa1p2-supply = <&vreg_l15b_e0_1p8>; + vddrfa1p8-supply = <&vreg_l15b_e0_1p8>; + + wlan-enable-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>; + bt-enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&wcn_wlan_bt_en>; + pinctrl-names = "default"; + + regulators { + vreg_pmu_rfa_cmn: ldo0 { + regulator-name = "vreg_pmu_rfa_cmn"; + }; + + vreg_pmu_aon_0p59: ldo1 { + regulator-name = "vreg_pmu_aon_0p59"; + }; + + vreg_pmu_wlcx_0p8: ldo2 { + regulator-name = "vreg_pmu_wlcx_0p8"; + }; + + vreg_pmu_wlmx_0p85: ldo3 { + regulator-name = "vreg_pmu_wlmx_0p85"; + }; + + vreg_pmu_btcmx_0p85: ldo4 { + regulator-name = "vreg_pmu_btcmx_0p85"; + }; + + vreg_pmu_rfa_0p8: ldo5 { + regulator-name = "vreg_pmu_rfa_0p8"; + }; + + vreg_pmu_rfa_1p2: ldo6 { + regulator-name = "vreg_pmu_rfa_1p2"; + }; + + vreg_pmu_rfa_1p8: ldo7 { + regulator-name = "vreg_pmu_rfa_1p8"; + }; + + vreg_pmu_pcie_0p9: ldo8 { + regulator-name = "vreg_pmu_pcie_0p9"; + }; + + vreg_pmu_pcie_1p8: ldo9 { + regulator-name = "vreg_pmu_pcie_1p8"; + }; + }; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pmh0101-rpmh-regulators"; + qcom,pmic-id = "B_E0"; + + vreg_l1b_e0_1p8: ldo1 { + regulator-name = "vreg_l1b_e0_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7b_e0_3p1: ldo7 { + regulator-name = "vreg_l7b_e0_3p1"; + regulator-min-microvolt = <3072000>; + regulator-max-microvolt = <3072000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l15b_e0_1p8: ldo15 { + regulator-name = "vreg_l15b_e0_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l18b_e0_1p2: ldo18 { + regulator-name = "vreg_l18b_e0_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-1 { + compatible = "qcom,pmcx0102-rpmh-regulators"; + qcom,pmic-id = "C_E1"; + + vreg_l1c_e1_0p91: ldo1 { + regulator-name = "vreg_l1c_e1_0p91"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-2 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "F_E0"; + + vreg_l2f_e0_0p94: ldo2 { + regulator-name = "vreg_l2f_e0_0p94"; + regulator-min-microvolt = <936000>; + regulator-max-microvolt = <936000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3f_e0_0p91: ldo3 { + regulator-name = "vreg_l3f_e0_0p91"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-3 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "F_E1"; + + vreg_l1f_e1_0p88: ldo1 { + regulator-name = "vreg_l1f_e1_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2f_e1_0p88: ldo2 { + regulator-name = "vreg_l2f_e1_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4f_e1_1p2: ldo4 { + regulator-name = "vreg_l4f_e1_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-4 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "H_E0"; + + vreg_l1h_e0_0p94: ldo1 { + regulator-name = "vreg_l1h_e0_0p94"; + regulator-min-microvolt = <936000>; + regulator-max-microvolt = <936000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2h_e0_0p88: ldo2 { + regulator-name = "vreg_l2h_e0_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4h_e0_1p2: ldo4 { + regulator-name = "vreg_l4h_e0_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; +}; + +&gmu { + status = "okay"; +}; + +&gpu { + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + + status = "okay"; + + touchpad@2c { + compatible = "hid-over-i2c"; + reg = <0x2c>; + + hid-descr-addr = <0x20>; + interrupts-extended = <&tlmm 3 IRQ_TYPE_LEVEL_LOW>; + + pinctrl-0 = <&tpad_default>; + pinctrl-names = "default"; + + wakeup-source; + }; + + keyboard@3a { + compatible = "hid-over-i2c"; + reg = <0x3a>; + + hid-descr-addr = <0x1>; + interrupts-extended = <&tlmm 67 IRQ_TYPE_LEVEL_LOW>; + + pinctrl-0 = <&kybd_default>; + pinctrl-names = "default"; + + wakeup-source; + }; +}; + +&i2c8 { + clock-frequency = <400000>; + + status = "okay"; + + touchscreen@10 { + compatible = "hid-over-i2c"; + reg = <0x10>; + + hid-descr-addr = <0x1>; + interrupts-extended = <&tlmm 51 IRQ_TYPE_LEVEL_LOW>; + + post-power-on-delay-ms = <200>; + + pinctrl-0 = <&ts0_default>; + pinctrl-names = "default"; + }; +}; + +&lpass_vamacro { + vdd-micb-supply = <&vreg_l1b_e0_1p8>; + + pinctrl-0 = <&dmic01_default>; + pinctrl-names = "default"; + + qcom,dmic-sample-rate = <4800000>; +}; + +&mdss { + status = "okay"; +}; + +&mdss_dp0 { + status = "okay"; +}; + +&mdss_dp0_out { + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; +}; + +&mdss_dp1 { + status = "okay"; +}; + +&mdss_dp1_out { + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; +}; + +&mdss_dp3 { + /delete-property/ #sound-dai-cells; + + status = "okay"; + + aux-bus { + panel { + compatible = "samsung,atna33xc20"; + enable-gpios = <&tlmm 18 GPIO_ACTIVE_HIGH>; + power-supply = <&vreg_edp_3p3>; + + pinctrl-0 = <&edp_bl_en>; + pinctrl-names = "default"; + + port { + edp_panel_in: endpoint { + remote-endpoint = <&mdss_dp3_out>; + }; + }; + }; + }; +}; + +&mdss_dp3_out { + data-lanes = <0 1 2 3>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; + + remote-endpoint = <&edp_panel_in>; +}; + +&mdss_dp3_phy { + vdda-phy-supply = <&vreg_l2f_e1_0p88>; + vdda-pll-supply = <&vreg_l4f_e1_1p2>; + + status = "okay"; +}; + +&pcie4 { + pinctrl-0 = <&pcie4_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie4_phy { + vdda-phy-supply = <&vreg_l1c_e1_0p91>; + vdda-pll-supply = <&vreg_l4f_e1_1p2>; + + status = "okay"; +}; + +&pcie4_port0 { + reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>; + + wifi@0 { + compatible = "pci17cb,1107"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; + vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; + }; +}; + +&pcie5 { + vddpe-3v3-supply = <&vreg_nvme>; + + pinctrl-0 = <&pcie5_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie5_phy { + vdda-phy-supply = <&vreg_l2f_e0_0p94>; + vdda-pll-supply = <&vreg_l4h_e0_1p2>; + + status = "okay"; +}; + +&pcie5_port0 { + reset-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>; + + status = "okay"; +}; + +&pmh0101_gpios { + nvme_reg_en: nvme-reg-en-state { + pins = "gpio14"; + function = "normal"; + bias-disable; + }; +}; + +&pmk8850_rtc { + qcom,no-alarm; + qcom,uefi-rtc-info; +}; + +&remoteproc_adsp { + firmware-name = "qcom/glymur/hp/elitebook-x-g2q/qcadsp8480.mbn", + "qcom/glymur/hp/elitebook-x-g2q/adsp_dtbs.elf"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/glymur/hp/elitebook-x-g2q/qccdsp8480.mbn", + "qcom/glymur/hp/elitebook-x-g2q/cdsp_dtbs.elf"; + + status = "okay"; +}; + +&remoteproc_soccp { + firmware-name = "qcom/glymur/hp/elitebook-x-g2q/soccp.mbn", + "qcom/glymur/hp/elitebook-x-g2q/soccp_dtb.mbn"; +}; + +&smb2370_j_e2_eusb2_repeater { + vdd18-supply = <&vreg_l15b_e0_1p8>; + vdd3-supply = <&vreg_l7b_e0_3p1>; +}; + +&smb2370_k_e2_eusb2_repeater { + vdd18-supply = <&vreg_l15b_e0_1p8>; + vdd3-supply = <&vreg_l7b_e0_3p1>; +}; + +&swr0 { + status = "okay"; + + /* WSA8845, left woofer */ + left_woofer: speaker@0,0 { + compatible = "sdw20217020400"; + reg = <0 0>; + reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "WooferLeft"; + vdd-1p8-supply = <&vreg_l15b_e0_1p8>; + vdd-io-supply = <&vreg_l18b_e0_1p2>; + qcom,port-mapping = <1 2 3 7 12 14>; + }; + + /* WSA8845, left tweeter */ + left_tweeter: speaker@0,1 { + compatible = "sdw20217020400"; + reg = <0 1>; + reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "TweeterLeft"; + vdd-1p8-supply = <&vreg_l15b_e0_1p8>; + vdd-io-supply = <&vreg_l18b_e0_1p2>; + qcom,port-mapping = <4 5 6 7 13 15>; + }; +}; + +&swr3 { + status = "okay"; + + /* WSA8845, right woofer */ + right_woofer: speaker@0,0 { + compatible = "sdw20217020400"; + reg = <0 0>; + reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "WooferRight"; + vdd-1p8-supply = <&vreg_l15b_e0_1p8>; + vdd-io-supply = <&vreg_l18b_e0_1p2>; + qcom,port-mapping = <1 2 3 7 12 14>; + }; + + /* WSA8845, right tweeter */ + right_tweeter: speaker@0,1 { + compatible = "sdw20217020400"; + reg = <0 1>; + reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "TweeterRight"; + vdd-1p8-supply = <&vreg_l15b_e0_1p8>; + vdd-io-supply = <&vreg_l18b_e0_1p2>; + qcom,port-mapping = <4 5 6 7 13 15>; + }; +}; + +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l2f_e1_0p88>; + vdda-qrefrpt1-0p9-supply = <&vreg_l2f_e1_0p88>; + vdda-qrefrpt2-0p9-supply = <&vreg_l2f_e1_0p88>; + vdda-qrefrpt3-0p9-supply = <&vreg_l2h_e0_0p88>; + vdda-qrefrpt4-0p9-supply = <&vreg_l2h_e0_0p88>; + vdda-qrefrx0-0p9-supply = <&vreg_l2f_e1_0p88>; + vdda-qrefrx1-0p9-supply = <&vreg_l2f_e1_0p88>; + vdda-qrefrx2-0p9-supply = <&vreg_l2f_e1_0p88>; + vdda-qrefrx4-0p9-supply = <&vreg_l2h_e0_0p88>; + vdda-qrefrx5-0p9-supply = <&vreg_l3f_e0_0p91>; + vdda-qreftx0-0p9-supply = <&vreg_l3f_e0_0p91>; + vdda-qreftx0-1p2-supply = <&vreg_l4h_e0_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l1f_e1_0p88>; + vdda-refgen3-0p9-supply = <&vreg_l2f_e0_0p94>; + vdda-refgen3-1p2-supply = <&vreg_l4h_e0_1p2>; + vdda-refgen4-0p9-supply = <&vreg_l1f_e1_0p88>; + vdda-refgen4-1p2-supply = <&vreg_l4f_e1_1p2>; +}; + +&tlmm { + gpio-reserved-ranges = <4 4>, /* EC TZ Secure I3C */ + <10 2>, /* OOB UART */ + <44 4>, /* Security SPI (TPM) */ + <65 1>; /* EC reset */ + + tpad_default: tpad-default-state { + pins = "gpio3"; + function = "gpio"; + bias-disable; + }; + + edp_bl_en: edp-bl-en-state { + pins = "gpio18"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + ts0_default: ts0-default-state { + pins = "gpio51"; + function = "gpio"; + bias-disable; + }; + + kybd_default: kybd-default-state { + pins = "gpio67"; + function = "gpio"; + bias-disable; + }; + + edp_reg_en: edp-reg-en-state { + pins = "gpio70"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + lid_default: lid-default-state { + pins = "gpio92"; + function = "gpio"; + bias-disable; + }; + + wcn_sw_en: wcn-sw-en-state { + pins = "gpio94"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wcn_wlan_bt_en: wcn-wlan-bt-en-state { + pins = "gpio116", "gpio117"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + pcie4_default: pcie4-default-state { + clkreq-n-pins { + pins = "gpio147"; + function = "pcie4_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio146"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio148"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie5_default: pcie5-default-state { + clkreq-n-pins { + pins = "gpio153"; + function = "pcie5_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio152"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio154"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; +}; + +&uart14 { + status = "okay"; + + bluetooth { + compatible = "qcom,wcn7850-bt"; + max-speed = <3200000>; + + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + }; +}; + +&usb_0 { + status = "okay"; +}; + +&usb_0_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in>; +}; + +&usb_0_hsphy { + vdd-supply = <&vreg_l3f_e0_0p91>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + phys = <&smb2370_j_e2_eusb2_repeater>; + + status = "okay"; +}; + +&usb_0_qmpphy { + vdda-phy-supply = <&vreg_l3f_e0_0p91>; + vdda-pll-supply = <&vreg_l4h_e0_1p2>; + refgen-supply = <&vreg_l2f_e0_0p94>; + + status = "okay"; +}; + +&usb_0_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in>; +}; + +&usb_1 { + status = "okay"; +}; + +&usb_1_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in1>; +}; + +&usb_1_hsphy { + vdd-supply = <&vreg_l3f_e0_0p91>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + phys = <&smb2370_k_e2_eusb2_repeater>; + + status = "okay"; +}; + +&usb_1_qmpphy { + vdda-phy-supply = <&vreg_l1h_e0_0p94>; + vdda-pll-supply = <&vreg_l4h_e0_1p2>; + refgen-supply = <&vreg_l2f_e0_0p94>; + + status = "okay"; +}; + +&usb_1_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in1>; +}; + +/* Internal USB2 host for the Elan fingerprint reader (usb 04f3:0ca8). */ +&usb_hs { + dr_mode = "host"; + + status = "okay"; +}; + +&usb_hs_phy { + vdd-supply = <&vreg_l2h_e0_0p88>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + status = "okay"; +}; + +/* Multiport host: port 0 = chassis USB-A, port 1 = internal USB HID. */ +&usb_mp { + status = "okay"; +}; + +&usb_mp_hsphy0 { + vdd-supply = <&vreg_l2h_e0_0p88>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + status = "okay"; +}; + +&usb_mp_hsphy1 { + vdd-supply = <&vreg_l2h_e0_0p88>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + status = "okay"; +}; + +&usb_mp_qmpphy0 { + vdda-phy-supply = <&vreg_l2h_e0_0p88>; + vdda-pll-supply = <&vreg_l4h_e0_1p2>; + refgen-supply = <&vreg_l4f_e1_1p2>; + + status = "okay"; +}; + +&usb_mp_qmpphy1 { + vdda-phy-supply = <&vreg_l2h_e0_0p88>; + vdda-pll-supply = <&vreg_l4h_e0_1p2>; + refgen-supply = <&vreg_l4f_e1_1p2>; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/qcom/glymur-lenovo-yoga-slim7x.dts b/arch/arm64/boot/dts/qcom/glymur-lenovo-yoga-slim7x.dts new file mode 100644 index 0000000..769f195 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/glymur-lenovo-yoga-slim7x.dts
@@ -0,0 +1,1221 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +/dts-v1/; + +#include "glymur.dtsi" + +#include "pmcx0102.dtsi" /* SPMI0: SID-2/3 SPMI1: SID-2/3 */ +#include "pmh0101.dtsi" /* SPMI0: SID-1 */ +#include "pmh0110-glymur.dtsi" /* SPMI0: SID-5/7 SPMI1: SID-5 */ +#include "pmh0104-glymur.dtsi" /* SPMI0: SID-8/9 SPMI1: SID-11 */ +#include "pmk8850.dtsi" /* SPMI0: SID-0 */ +#include "smb2370.dtsi" /* SPMI2: SID-9/10/11 */ + +#include <dt-bindings/input/gpio-keys.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/pinctrl/qcom,pmic-gpio.h> + +/ { + model = "Lenovo Yoga Slim 7x Gen 11"; + compatible = "lenovo,yoga-slim7x-gen11", "qcom,glymur"; + + aliases { + serial0 = &uart21; + serial1 = &uart14; + i2c0 = &i2c0; + i2c5 = &i2c5; + i2c8 = &i2c8; + i2c9 = &i2c9; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + clocks { + xo_board: xo-board { + compatible = "fixed-clock"; + clock-frequency = <38400000>; + #clock-cells = <0>; + }; + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + clock-frequency = <32000>; + #clock-cells = <0>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&hall_int_n_default>, <&cam_privacy_default>; + pinctrl-names = "default"; + + switch-lid { + label = "lid"; + gpios = <&tlmm 92 GPIO_ACTIVE_LOW>; + linux,input-type = <EV_SW>; + linux,code = <SW_LID>; + wakeup-source; + wakeup-event-action = <EV_ACT_DEASSERTED>; + }; + + switch-camera-privacy { + label = "Camera privacy switch"; + gpios = <&tlmm 99 GPIO_ACTIVE_LOW>; + linux,input-type = <EV_SW>; + linux,code = <SW_CAMERA_LENS_COVER>; + }; + }; + + leds { + compatible = "gpio-leds"; + + pinctrl-0 = <&cam_indicator_en>; + pinctrl-names = "default"; + + privacy_led: privacy-led { + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_WHITE>; + gpios = <&tlmm 111 GPIO_ACTIVE_HIGH>; + default-state = "off"; + panic-indicator; + }; + }; + + pmic-glink { + compatible = "qcom,glymur-pmic-glink", + "qcom,pmic-glink"; + #address-cells = <1>; + #size-cells = <0>; + + /* Left side display-adjacent port */ + connector@0 { + compatible = "usb-c-connector"; + reg = <0>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in: endpoint { + remote-endpoint = <&usb_0_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in: endpoint { + remote-endpoint = <&usb_0_qmpphy_out>; + }; + }; + }; + }; + + /* Left side user-adjacent port */ + connector@1 { + compatible = "usb-c-connector"; + reg = <1>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in1: endpoint { + remote-endpoint = <&usb_1_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in1: endpoint { + remote-endpoint = <&usb_1_qmpphy_out>; + }; + }; + }; + }; + + /* Right side port */ + connector@2 { + compatible = "usb-c-connector"; + reg = <2>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in2: endpoint { + remote-endpoint = <&usb_2_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in2: endpoint { + remote-endpoint = <&usb_2_qmpphy_out>; + }; + }; + }; + }; + }; + + vreg_edp_3p3: regulator-edp-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_EDP_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 70 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&edp_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_misc_3p3: regulator-misc-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_MISC_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pmh0110_f_e0_gpios 6 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&misc_3p3_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_nvme: regulator-nvme { + compatible = "regulator-fixed"; + + regulator-name = "VREG_NVME_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pmh0101_gpios 14 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&nvme_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_wcn_0p95: regulator-wcn-0p95 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_0P95"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <950000>; + + vin-supply = <&vreg_wcn_3p3>; + }; + + vreg_wcn_3p3: regulator-wcn-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 94 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&wcn_sw_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_wwan: regulator-wwan { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WWAN_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 246 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&wwan_reg_en>; + pinctrl-names = "default"; + }; + + sound { + compatible = "qcom,glymur-sndcard"; + model = "GLYMUR-LENOVO-Yoga-Slim7x"; + audio-routing = "WooferLeft IN", "WSA WSA_SPK1 OUT", + "TweeterLeft IN", "WSA WSA_SPK2 OUT", + "WooferRight IN", "WSA2 WSA_SPK1 OUT", + "TweeterRight IN", "WSA2 WSA_SPK2 OUT", + "VA DMIC0", "vdd-micb", + "VA DMIC1", "vdd-micb", + "VA DMIC2", "vdd-micb", + "VA DMIC3", "vdd-micb"; + + va-dai-link { + link-name = "VA Capture"; + + codec { + sound-dai = <&lpass_vamacro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + wsa-dai-link { + link-name = "WSA Playback"; + + codec { + sound-dai = <&left_woofer>, <&left_tweeter>, + <&swr0 0>, <&lpass_wsamacro 0>, + <&right_woofer>, <&right_tweeter>, + <&swr3 0>, <&lpass_wsa2macro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + }; + + wcn7850-pmu { + compatible = "qcom,wcn7850-pmu"; + + vdd-supply = <&vreg_wcn_0p95>; + vddio-supply = <&vreg_l15b_e0>; + vddaon-supply = <&vreg_l15b_e0>; + vdddig-supply = <&vreg_l15b_e0>; + vddrfa1p2-supply = <&vreg_l15b_e0>; + vddrfa1p8-supply = <&vreg_l15b_e0>; + + wlan-enable-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>; + bt-enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&wcn_wlan_bt_en>; + pinctrl-names = "default"; + + regulators { + vreg_pmu_rfa_cmn: ldo0 { + regulator-name = "vreg_pmu_rfa_cmn"; + }; + + vreg_pmu_aon_0p59: ldo1 { + regulator-name = "vreg_pmu_aon_0p59"; + }; + + vreg_pmu_wlcx_0p8: ldo2 { + regulator-name = "vreg_pmu_wlcx_0p8"; + }; + + vreg_pmu_wlmx_0p85: ldo3 { + regulator-name = "vreg_pmu_wlmx_0p85"; + }; + + vreg_pmu_btcmx_0p85: ldo4 { + regulator-name = "vreg_pmu_btcmx_0p85"; + }; + + vreg_pmu_rfa_0p8: ldo5 { + regulator-name = "vreg_pmu_rfa_0p8"; + }; + + vreg_pmu_rfa_1p2: ldo6 { + regulator-name = "vreg_pmu_rfa_1p2"; + }; + + vreg_pmu_rfa_1p8: ldo7 { + regulator-name = "vreg_pmu_rfa_1p8"; + }; + + vreg_pmu_pcie_0p9: ldo8 { + regulator-name = "vreg_pmu_pcie_0p9"; + }; + + vreg_pmu_pcie_1p8: ldo9 { + regulator-name = "vreg_pmu_pcie_1p8"; + }; + }; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pmh0101-rpmh-regulators"; + qcom,pmic-id = "B_E0"; + + vreg_l1b_e0: ldo1 { + regulator-name = "vreg_l1b_e0"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7b_e0: ldo7 { + regulator-name = "vreg_l7b_e0"; + regulator-min-microvolt = <3072000>; + regulator-max-microvolt = <3072000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l8b_e0: ldo8 { + regulator-name = "vreg_l8b_e0"; + regulator-min-microvolt = <3304000>; + regulator-max-microvolt = <3304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l9b_e0: ldo9 { + regulator-name = "vreg_l9b_e0"; + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l10b_e0: ldo10 { + regulator-name = "vreg_l10b_e0"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l11b_e0: ldo11 { + regulator-name = "vreg_l11b_e0"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l12b_e0: ldo12 { + regulator-name = "vreg_l12b_e0"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l15b_e0: ldo15 { + regulator-name = "vreg_l15b_e0"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l17b_e0: ldo17 { + regulator-name = "vreg_l17b_e0"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <2504000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l18b_e0: ldo18 { + regulator-name = "vreg_l18b_e0"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-1 { + compatible = "qcom,pmcx0102-rpmh-regulators"; + qcom,pmic-id = "C_E1"; + + vreg_l1c_e1: ldo1 { + regulator-name = "vreg_l1c_e1"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2c_e1: ldo2 { + regulator-name = "vreg_l2c_e1"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3c_e1: ldo3 { + regulator-name = "vreg_l3c_e1"; + regulator-min-microvolt = <936000>; + regulator-max-microvolt = <936000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4c_e1: ldo4 { + regulator-name = "vreg_l4c_e1"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-2 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "F_E0"; + + vreg_s7f_e0: smps7 { + regulator-name = "vreg_s7f_e0"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s8f_e0: smps8 { + regulator-name = "vreg_s8f_e0"; + regulator-min-microvolt = <952000>; + regulator-max-microvolt = <952000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2f_e0: ldo2 { + regulator-name = "vreg_l2f_e0"; + regulator-min-microvolt = <936000>; + regulator-max-microvolt = <936000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3f_e0: ldo3 { + regulator-name = "vreg_l3f_e0"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-3 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "F_E1"; + + vreg_l1f_e1: ldo1 { + regulator-name = "vreg_l1f_e1"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <904000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2f_e1: ldo2 { + regulator-name = "vreg_l2f_e1"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4f_e1: ldo4 { + regulator-name = "vreg_l4f_e1"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-4 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "H_E0"; + + vreg_l1h_e0: ldo1 { + regulator-name = "vreg_l1h_e0"; + regulator-min-microvolt = <936000>; + regulator-max-microvolt = <936000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2h_e0: ldo2 { + regulator-name = "vreg_l2h_e0"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3h_e0: ldo3 { + regulator-name = "vreg_l3h_e0"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4h_e0: ldo4 { + regulator-name = "vreg_l4h_e0"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; +}; + +&gpu { + status = "okay"; +}; + +&gmu { + status = "okay"; +}; + +&i2c0 { + clock-frequency = <400000>; + + status = "okay"; + + touchpad@2c { + compatible = "hid-over-i2c"; + reg = <0x2c>; + + hid-descr-addr = <0x20>; + interrupts-extended = <&tlmm 3 IRQ_TYPE_LEVEL_LOW>; + + vdd-supply = <&vreg_misc_3p3>; + vddl-supply = <&vreg_l15b_e0>; + + pinctrl-0 = <&tpad_default>; + pinctrl-names = "default"; + + wakeup-source; + }; + + keyboard@3a { + compatible = "hid-over-i2c"; + reg = <0x3a>; + + hid-descr-addr = <0x1>; + interrupts-extended = <&tlmm 67 IRQ_TYPE_LEVEL_LOW>; + + vdd-supply = <&vreg_misc_3p3>; + vddl-supply = <&vreg_l15b_e0>; + + pinctrl-0 = <&kybd_default>; + pinctrl-names = "default"; + + wakeup-source; + }; + + /* Something @ 0x5b */ +}; + +&i2c5 { + clock-frequency = <400000>; + + status = "okay"; +}; + +&i2c8 { + clock-frequency = <400000>; + + status = "okay"; + + touchscreen@14 { + compatible = "hid-over-i2c"; + reg = <0x14>; + + hid-descr-addr = <0x1>; + interrupts-extended = <&tlmm 51 IRQ_TYPE_LEVEL_LOW>; + + post-power-on-delay-ms = <200>; + + vdd-supply = <&vreg_misc_3p3>; + vddl-supply = <&vreg_l15b_e0>; + + pinctrl-0 = <&ts0_default>; + pinctrl-names = "default"; + }; +}; + +&i2c9 { + clock-frequency = <400000>; + + status = "okay"; + + /* EC @ 0x70, irq = TLMM 66 */ +}; + +&lpass_vamacro { + pinctrl-0 = <&dmic01_default>, <&dmic23_default>; + pinctrl-names = "default"; + qcom,dmic-sample-rate = <4800000>; +}; + +&mdss { + status = "okay"; +}; + +&mdss_dp0 { + status = "okay"; +}; + +&mdss_dp0_out { + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; +}; + +&mdss_dp1 { + status = "okay"; +}; + +&mdss_dp1_out { + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; +}; + +&mdss_dp2 { + status = "okay"; +}; + +&mdss_dp2_out { + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; +}; + +&mdss_dp3 { + /delete-property/ #sound-dai-cells; + + status = "okay"; + + aux-bus { + panel { + compatible = "samsung,atna40hq08", "samsung,atna33xc20"; + enable-gpios = <&tlmm 18 GPIO_ACTIVE_HIGH>; + power-supply = <&vreg_edp_3p3>; + + pinctrl-0 = <&edp_bl_en>; + pinctrl-names = "default"; + + port { + edp_panel_in: endpoint { + remote-endpoint = <&mdss_dp3_out>; + }; + }; + }; + }; +}; + +&mdss_dp3_out { + data-lanes = <0 1 2 3>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; + + remote-endpoint = <&edp_panel_in>; +}; + +&mdss_dp3_phy { + vdda-phy-supply = <&vreg_l2f_e1>; + vdda-pll-supply = <&vreg_l4f_e1>; + + status = "okay"; +}; + +&pcie4 { + pinctrl-0 = <&pcie4_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie4_phy { + vdda-phy-supply = <&vreg_l1c_e1>; + vdda-pll-supply = <&vreg_l4f_e1>; + + status = "okay"; +}; + +&pcie4_port0 { + reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>; + + wifi@0 { + compatible = "pci17cb,1107"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; + vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; + }; +}; + +&pcie5 { + vddpe-3v3-supply = <&vreg_nvme>; + + pinctrl-0 = <&pcie5_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie5_phy { + vdda-phy-supply = <&vreg_l2f_e0>; + vdda-pll-supply = <&vreg_l4h_e0>; + + status = "okay"; +}; + +&pcie5_port0 { + reset-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>; +}; + +&pcie6 { + vddpe-3v3-supply = <&vreg_wwan>; + + pinctrl-0 = <&pcie6_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie6_phy { + vdda-phy-supply = <&vreg_l1c_e1>; + vdda-pll-supply = <&vreg_l4f_e1>; + + status = "okay"; +}; + +&pcie6_port0 { + reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 151 GPIO_ACTIVE_LOW>; +}; + +&pmh0101_gpios { + nvme_reg_en: nvme-reg-en-state { + pins = "gpio14"; + function = "normal"; + bias-disable; + }; +}; + +&pmh0110_f_e0_gpios { + misc_3p3_reg_en: misc-3p3-reg-en-state { + pins = "gpio6"; + function = "normal"; + bias-disable; + input-disable; + output-enable; + drive-push-pull; + power-source = <1>; /* 1.8 V */ + qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>; + }; +}; + +&pmh0110_f_e1_gpios { + nvme_sec_reg_en: nvme-reg-en-state { + pins = "gpio14"; + function = "normal"; + bias-disable; + }; +}; + +&pmk8850_rtc { + qcom,no-alarm; +}; + +&remoteproc_adsp { + firmware-name = "qcom/glymur/LENOVO/83QR/qcadsp8480.mbn", + "qcom/glymur/LENOVO/83QR/adsp_dtbs.elf"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/glymur/LENOVO/83QR/qccdsp8480.mbn", + "qcom/glymur/LENOVO/83QR/cdsp_dtbs.elf"; + + status = "okay"; +}; + +&remoteproc_soccp { + status = "okay"; +}; + +&smb2370_j_e2_eusb2_repeater { + vdd18-supply = <&vreg_l15b_e0>; + vdd3-supply = <&vreg_l7b_e0>; +}; + +&smb2370_k_e2_eusb2_repeater { + vdd18-supply = <&vreg_l15b_e0>; + vdd3-supply = <&vreg_l7b_e0>; +}; + +&smb2370_l_e2_eusb2_repeater { + vdd18-supply = <&vreg_l15b_e0>; + vdd3-supply = <&vreg_l7b_e0>; + + status = "okay"; +}; + +&swr0 { + status = "okay"; + + /* WSA8845, Left Woofer */ + left_woofer: speaker@0,0 { + compatible = "sdw20217020400"; + reg = <0 0>; + reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "WooferLeft"; + vdd-1p8-supply = <&vreg_l15b_e0>; + vdd-io-supply = <&vreg_l18b_e0>; + qcom,port-mapping = <1 2 3 7 12 14>; + }; + + /* WSA8845, Left Tweeter */ + left_tweeter: speaker@0,1 { + compatible = "sdw20217020400"; + reg = <0 1>; + reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "TweeterLeft"; + vdd-1p8-supply = <&vreg_l15b_e0>; + vdd-io-supply = <&vreg_l18b_e0>; + qcom,port-mapping = <4 5 6 7 13 15>; + }; +}; + +&swr3 { + status = "okay"; + + /* WSA8845, Right Woofer */ + right_woofer: speaker@0,0 { + compatible = "sdw20217020400"; + reg = <0 0>; + reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "WooferRight"; + vdd-1p8-supply = <&vreg_l15b_e0>; + vdd-io-supply = <&vreg_l18b_e0>; + qcom,port-mapping = <1 2 3 7 12 14>; + }; + + /* WSA8845, Right Tweeter */ + right_tweeter: speaker@0,1 { + compatible = "sdw20217020400"; + reg = <0 1>; + reset-gpios = <&lpass_tlmm 13 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "TweeterRight"; + vdd-1p8-supply = <&vreg_l15b_e0>; + vdd-io-supply = <&vreg_l18b_e0>; + qcom,port-mapping = <4 5 6 7 13 15>; + }; +}; + +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l2f_e1>; + vdda-qrefrpt1-0p9-supply = <&vreg_l2f_e1>; + vdda-qrefrpt2-0p9-supply = <&vreg_l2f_e1>; + vdda-qrefrpt3-0p9-supply = <&vreg_l2h_e0>; + vdda-qrefrpt4-0p9-supply = <&vreg_l2h_e0>; + vdda-qrefrx0-0p9-supply = <&vreg_l2f_e1>; + vdda-qrefrx1-0p9-supply = <&vreg_l2f_e1>; + vdda-qrefrx2-0p9-supply = <&vreg_l2f_e1>; + vdda-qrefrx4-0p9-supply = <&vreg_l2h_e0>; + vdda-qrefrx5-0p9-supply = <&vreg_l3f_e0>; + vdda-qreftx0-0p9-supply = <&vreg_l3f_e0>; + vdda-qreftx0-1p2-supply = <&vreg_l4h_e0>; + vdda-qreftx1-0p9-supply = <&vreg_l1f_e1>; + vdda-refgen3-0p9-supply = <&vreg_l2f_e0>; + vdda-refgen3-1p2-supply = <&vreg_l4h_e0>; + vdda-refgen4-0p9-supply = <&vreg_l1f_e1>; + vdda-refgen4-1p2-supply = <&vreg_l4f_e1>; +}; + +&tlmm { + gpio-reserved-ranges = <4 4>, /* EC TZ Secure I3C */ + <10 2>, /* OOB UART */ + <44 4>, /* Security SPI (TPM) */ + <65 1>; /* EC reset (need to unplug the battery if asserted) */ + + tpad_default: tpad-default-state { + pins = "gpio3"; + function = "gpio"; + bias-disable; + }; + + edp_bl_en: edp-bl-en-state { + pins = "gpio18"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + ts0_default: ts0-default-state { + int-n-pins { + pins = "gpio51"; + function = "gpio"; + bias-disable; + }; + + reset-n-pins { + pins = "gpio48"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + }; + + ec_int_n_default: ec-int-n-state { + pins = "gpio66"; + function = "gpio"; + bias-disable; + }; + + kybd_default: kybd-default-state { + pins = "gpio67"; + function = "gpio"; + bias-disable; + }; + + edp_reg_en: edp-reg-en-state { + pins = "gpio70"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + hall_int_n_default: hall-int-n-state { + pins = "gpio92"; + function = "gpio"; + bias-disable; + }; + + wcn_sw_en: wcn-sw-en-state { + pins = "gpio94"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + cam_privacy_default: cam-privacy-default-state { + pins = "gpio99"; + function = "gpio"; + bias-pull-up; + }; + + cam_indicator_en: cam-indicator-en-state { + pins = "gpio111"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wcn_wlan_bt_en: wcn-wlan-bt-en-state { + pins = "gpio116", "gpio117"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + pcie4_default: pcie4-default-state { + clkreq-n-pins { + pins = "gpio147"; + function = "pcie4_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio146"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio148"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie5_default: pcie5-default-state { + clkreq-n-pins { + pins = "gpio153"; + function = "pcie5_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio152"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio154"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie6_default: pcie6-default-state { + clkreq-n-pins { + pins = "gpio150"; + function = "pcie6_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio149"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio151"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + wwan_reg_en: wwan-reg-en-state { + pins = "gpio246"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; +}; + +&uart14 { + status = "okay"; + + bluetooth { + compatible = "qcom,wcn7850-bt"; + max-speed = <3200000>; + + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + }; +}; + +&usb_0 { + status = "okay"; +}; + +&usb_0_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in>; +}; + +&usb_0_hsphy { + vdd-supply = <&vreg_l3f_e0>; + vdda12-supply = <&vreg_l4h_e0>; + + phys = <&smb2370_j_e2_eusb2_repeater>; + + status = "okay"; +}; + +&usb_0_qmpphy { + vdda-phy-supply = <&vreg_l4h_e0>; + vdda-pll-supply = <&vreg_l3f_e0>; + refgen-supply = <&vreg_l2f_e0>; + + status = "okay"; +}; + +&usb_0_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in>; +}; + +&usb_1 { + status = "okay"; +}; + +&usb_1_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in1>; +}; + +&usb_1_hsphy { + vdd-supply = <&vreg_l3f_e0>; + vdda12-supply = <&vreg_l4h_e0>; + + phys = <&smb2370_k_e2_eusb2_repeater>; + + status = "okay"; +}; + +&usb_1_qmpphy { + vdda-phy-supply = <&vreg_l4h_e0>; + vdda-pll-supply = <&vreg_l1h_e0>; + refgen-supply = <&vreg_l2f_e0>; + + status = "okay"; +}; + +&usb_1_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in1>; +}; + +&usb_2 { + status = "okay"; +}; + +&usb_2_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in2>; +}; + +&usb_2_hsphy { + vdd-supply = <&vreg_l4c_e1>; + vdda12-supply = <&vreg_l4f_e1>; + + phys = <&smb2370_l_e2_eusb2_repeater>; + + status = "okay"; +}; + +&usb_2_qmpphy { + vdda-phy-supply = <&vreg_l4f_e1>; + vdda-pll-supply = <&vreg_l4c_e1>; + refgen-supply = <&vreg_l1c_e1>; + + status = "okay"; +}; + +&usb_2_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in2>; +};
diff --git a/arch/arm64/boot/dts/qcom/glymur-qcb.dts b/arch/arm64/boot/dts/qcom/glymur-qcb.dts new file mode 100644 index 0000000..17d8ff3 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/glymur-qcb.dts
@@ -0,0 +1,699 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; + +#include "glymur.dtsi" + +#include "pmcx0102.dtsi" /* SPMI0: SID-2/3 SPMI1: SID-2/3 */ +#include "pmh0101.dtsi" /* SPMI0: SID-1 */ +#include "pmh0110-glymur.dtsi" /* SPMI0: SID-5/7 SPMI1: SID-5 */ +#include "pmh0104-glymur.dtsi" /* SPMI0: SID-8/9 SPMI1: SID-11 */ +#include "pmk8850.dtsi" /* SPMI0: SID-0 */ +#include "smb2370.dtsi" /* SPMI2: SID-9/10/11 */ + +/ { + model = "Qualcomm Technologies, Inc. Glymur QCB"; + compatible = "qcom,glymur-qcb", "qcom,glymur"; + + aliases { + serial0 = &uart21; + serial1 = &uart14; + i2c0 = &i2c0; + i2c1 = &i2c4; + i2c2 = &i2c5; + i2c3 = &i2c9; + spi0 = &spi18; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + clocks { + xo_board: xo-board { + compatible = "fixed-clock"; + clock-frequency = <38400000>; + #clock-cells = <0>; + }; + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + clock-frequency = <32000>; + #clock-cells = <0>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&key_vol_up_default>; + pinctrl-names = "default"; + + key-volume-up { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + gpios = <&pmh0101_gpios 6 GPIO_ACTIVE_LOW>; + debounce-interval = <15>; + linux,can-disable; + wakeup-source; + }; + }; + + vreg_nvme: regulator-nvme { + compatible = "regulator-fixed"; + + regulator-name = "VREG_NVME_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pmh0101_gpios 14 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&nvme_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_wcn_0p95: regulator-wcn-0p95 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_0P95"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <950000>; + + vin-supply = <&vreg_wcn_3p3>; + }; + + vreg_wcn_3p3: regulator-wcn-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 94 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&wcn_sw_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_wwan: regulator-wwan { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WWAN_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 246 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&wwan_reg_en>; + pinctrl-names = "default"; + }; + + wcn7850-pmu { + compatible = "qcom,wcn7850-pmu"; + + vdd-supply = <&vreg_wcn_0p95>; + vddio-supply = <&vreg_l15b_e0_1p8>; + vddaon-supply = <&vreg_l15b_e0_1p8>; + vdddig-supply = <&vreg_l15b_e0_1p8>; + vddrfa1p2-supply = <&vreg_l15b_e0_1p8>; + vddrfa1p8-supply = <&vreg_l15b_e0_1p8>; + + wlan-enable-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>; + bt-enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&wcn_wlan_bt_en>; + pinctrl-names = "default"; + + regulators { + vreg_pmu_rfa_cmn: ldo0 { + regulator-name = "vreg_pmu_rfa_cmn"; + }; + + vreg_pmu_aon_0p59: ldo1 { + regulator-name = "vreg_pmu_aon_0p59"; + }; + + vreg_pmu_wlcx_0p8: ldo2 { + regulator-name = "vreg_pmu_wlcx_0p8"; + }; + + vreg_pmu_wlmx_0p85: ldo3 { + regulator-name = "vreg_pmu_wlmx_0p85"; + }; + + vreg_pmu_btcmx_0p85: ldo4 { + regulator-name = "vreg_pmu_btcmx_0p85"; + }; + + vreg_pmu_rfa_0p8: ldo5 { + regulator-name = "vreg_pmu_rfa_0p8"; + }; + + vreg_pmu_rfa_1p2: ldo6 { + regulator-name = "vreg_pmu_rfa_1p2"; + }; + + vreg_pmu_rfa_1p8: ldo7 { + regulator-name = "vreg_pmu_rfa_1p8"; + }; + + vreg_pmu_pcie_0p9: ldo8 { + regulator-name = "vreg_pmu_pcie_0p9"; + }; + + vreg_pmu_pcie_1p8: ldo9 { + regulator-name = "vreg_pmu_pcie_1p8"; + }; + }; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pmh0101-rpmh-regulators"; + qcom,pmic-id = "B_E0"; + + vreg_bob1_e0: bob1 { + regulator-name = "vreg_bob1_e0"; + regulator-min-microvolt = <2200000>; + regulator-max-microvolt = <4224000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_bob2_e0: bob2 { + regulator-name = "vreg_bob2_e0"; + regulator-min-microvolt = <2540000>; + regulator-max-microvolt = <3600000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l1b_e0_1p8: ldo1 { + regulator-name = "vreg_l1b_e0_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2b_e0_2p9: ldo2 { + regulator-name = "vreg_l2b_e0_2p9"; + regulator-min-microvolt = <2904000>; + regulator-max-microvolt = <2904000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7b_e0_2p79: ldo7 { + regulator-name = "vreg_l7b_e0_2p79"; + regulator-min-microvolt = <2790000>; + regulator-max-microvolt = <2792000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l8b_e0_1p50: ldo8 { + regulator-name = "vreg_l8b_e0_1p50"; + regulator-min-microvolt = <1504000>; + regulator-max-microvolt = <1504000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l9b_e0_2p7: ldo9 { + regulator-name = "vreg_l9b_e0_2p7"; + regulator-min-microvolt = <2704000>; + regulator-max-microvolt = <2704000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l10b_e0_1p8: ldo10 { + regulator-name = "vreg_l10b_e0_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l11b_e0_1p2: ldo11 { + regulator-name = "vreg_l11b_e0_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l12b_e0_1p14: ldo12 { + regulator-name = "vreg_l12b_e0_1p14"; + regulator-min-microvolt = <1144000>; + regulator-max-microvolt = <1144000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l15b_e0_1p8: ldo15 { + regulator-name = "vreg_l15b_e0_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l17b_e0_2p4: ldo17 { + regulator-name = "vreg_l17b_e0_2p4"; + regulator-min-microvolt = <2400000>; + regulator-max-microvolt = <2700000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l18b_e0_1p2: ldo18 { + regulator-name = "vreg_l18b_e0_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-1 { + compatible = "qcom,pmcx0102-rpmh-regulators"; + qcom,pmic-id = "C_E1"; + + vreg_l1c_e1_0p82: ldo1 { + regulator-name = "vreg_l1c_e1_0p82"; + regulator-min-microvolt = <832000>; + regulator-max-microvolt = <832000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2c_e1_1p14: ldo2 { + regulator-name = "vreg_l2c_e1_1p14"; + regulator-min-microvolt = <1144000>; + regulator-max-microvolt = <1144000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3c_e1_0p89: ldo3 { + regulator-name = "vreg_l3c_e1_0p89"; + regulator-min-microvolt = <890000>; + regulator-max-microvolt = <980000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4c_e1_0p72: ldo4 { + regulator-name = "vreg_l4c_e1_0p72"; + regulator-min-microvolt = <720000>; + regulator-max-microvolt = <720000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-2 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "F_E0"; + + vreg_s7f_e0_1p32: smps7 { + regulator-name = "vreg_s7f_e0_1p32"; + regulator-min-microvolt = <1320000>; + regulator-max-microvolt = <1352000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s8f_e0_0p95: smps8 { + regulator-name = "vreg_s8f_e0_0p95"; + regulator-min-microvolt = <952000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s9f_e0_1p9: smps9 { + regulator-name = "vreg_s9f_e0_1p9"; + regulator-min-microvolt = <1900000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2f_e0_0p82: ldo2 { + regulator-name = "vreg_l2f_e0_0p82"; + regulator-min-microvolt = <832000>; + regulator-max-microvolt = <832000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3f_e0_0p72: ldo3 { + regulator-name = "vreg_l3f_e0_0p72"; + regulator-min-microvolt = <720000>; + regulator-max-microvolt = <720000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4f_e0_1p08: ldo4 { + regulator-name = "vreg_l4f_e0_1p08"; + regulator-min-microvolt = <1080000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-3 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "F_E1"; + + vreg_s7f_e1_0p3: smps7 { + regulator-name = "vreg_s7f_e1_0p3"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1f_e1_0p82: ldo1 { + regulator-name = "vreg_l1f_e1_0p82"; + regulator-min-microvolt = <832000>; + regulator-max-microvolt = <832000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2f_e1_0p83: ldo2 { + regulator-name = "vreg_l2f_e1_0p83"; + regulator-min-microvolt = <832000>; + regulator-max-microvolt = <832000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4f_e1_1p08: ldo4 { + regulator-name = "vreg_l4f_e1_1p08"; + regulator-min-microvolt = <1080000>; + regulator-max-microvolt = <1320000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-4 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "H_E0"; + + vreg_l1h_e0_0p89: ldo1 { + regulator-name = "vreg_l1h_e0_0p89"; + regulator-min-microvolt = <832000>; + regulator-max-microvolt = <832000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2h_e0_0p72: ldo2 { + regulator-name = "vreg_l2h_e0_0p72"; + regulator-min-microvolt = <832000>; + regulator-max-microvolt = <832000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3h_e0_0p32: ldo3 { + regulator-name = "vreg_l3h_e0_0p32"; + regulator-min-microvolt = <320000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4h_e0_1p2: ldo4 { + regulator-name = "vreg_l4h_e0_1p2"; + regulator-min-microvolt = <1080000>; + regulator-max-microvolt = <1320000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; +}; + +&i2c9 { + clock-frequency = <400000>; + + status = "okay"; + + embedded-controller@76 { + compatible = "qcom,glymur-qcb-ec", "qcom,hamoa-crd-ec"; + reg = <0x76>; + + interrupts-extended = <&tlmm 66 IRQ_TYPE_EDGE_FALLING>; + + pinctrl-0 = <&ec_int_n_default>; + pinctrl-names = "default"; + }; +}; + +&pcie4 { + pinctrl-0 = <&pcie4_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie4_phy { + vdda-phy-supply = <&vreg_l1c_e1_0p82>; + vdda-pll-supply = <&vreg_l4f_e1_1p08>; + + status = "okay"; +}; + +&pcie4_port0 { + reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>; + + wifi@0 { + compatible = "pci17cb,1107"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; + vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; + }; +}; + +&pcie5 { + vddpe-3v3-supply = <&vreg_nvme>; + + pinctrl-0 = <&pcie5_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie5_phy { + vdda-phy-supply = <&vreg_l2f_e0_0p82>; + vdda-pll-supply = <&vreg_l4h_e0_1p2>; + + status = "okay"; +}; + +&pcie5_port0 { + reset-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>; +}; + +&pcie6 { + vddpe-3v3-supply = <&vreg_wwan>; + + pinctrl-0 = <&pcie6_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie6_phy { + vdda-phy-supply = <&vreg_l1c_e1_0p82>; + vdda-pll-supply = <&vreg_l4f_e1_1p08>; + + status = "okay"; +}; + +&pcie6_port0 { + reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 151 GPIO_ACTIVE_LOW>; +}; + +&pmh0101_gpios { + key_vol_up_default: key-vol-up-default-state { + pins = "gpio6"; + function = "normal"; + output-disable; + bias-pull-up; + }; + + nvme_reg_en: nvme-reg-en-state { + pins = "gpio14"; + function = "normal"; + bias-disable; + }; +}; + +&pmk8850_rtc { + qcom,no-alarm; + qcom,uefi-rtc-info; +}; + +&pon_resin { + linux,code = <KEY_VOLUMEDOWN>; + + status = "okay"; +}; + +&remoteproc_adsp { + firmware-name = "qcom/glymur/adsp.mbn", + "qcom/glymur/adsp_dtb.mbn"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/glymur/cdsp.mbn", + "qcom/glymur/cdsp_dtb.mbn"; + + status = "okay"; +}; + +&remoteproc_soccp { + firmware-name = "qcom/glymur/soccp.mbn", + "qcom/glymur/soccp_dtb.mbn"; +}; + +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l2f_e1_0p83>; + vdda-qrefrpt1-0p9-supply = <&vreg_l2f_e1_0p83>; + vdda-qrefrpt2-0p9-supply = <&vreg_l2f_e1_0p83>; + vdda-qrefrpt3-0p9-supply = <&vreg_l2h_e0_0p72>; + vdda-qrefrpt4-0p9-supply = <&vreg_l2h_e0_0p72>; + vdda-qrefrx0-0p9-supply = <&vreg_l2f_e1_0p83>; + vdda-qrefrx1-0p9-supply = <&vreg_l2f_e1_0p83>; + vdda-qrefrx2-0p9-supply = <&vreg_l2f_e1_0p83>; + vdda-qrefrx4-0p9-supply = <&vreg_l2h_e0_0p72>; + vdda-qrefrx5-0p9-supply = <&vreg_l3f_e0_0p72>; + vdda-qreftx0-0p9-supply = <&vreg_l3f_e0_0p72>; + vdda-qreftx0-1p2-supply = <&vreg_l4h_e0_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l1f_e1_0p82>; + vdda-refgen3-0p9-supply = <&vreg_l2f_e0_0p82>; + vdda-refgen3-1p2-supply = <&vreg_l4h_e0_1p2>; + vdda-refgen4-0p9-supply = <&vreg_l1f_e1_0p82>; + vdda-refgen4-1p2-supply = <&vreg_l4f_e1_1p08>; +}; + +&tlmm { + gpio-reserved-ranges = <4 4>, /* EC TZ Secure I3C */ + <10 2>, /* OOB UART */ + <44 4>; /* Security SPI (TPM) */ + + ec_int_n_default: ec-int-n-state { + pins = "gpio66"; + function = "gpio"; + bias-disable; + }; + + pcie4_default: pcie4-default-state { + clkreq-n-pins { + pins = "gpio147"; + function = "pcie4_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio146"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio148"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie5_default: pcie5-default-state { + clkreq-n-pins { + pins = "gpio153"; + function = "pcie5_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio152"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio154"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie6_default: pcie6-default-state { + clkreq-n-pins { + pins = "gpio150"; + function = "pcie6_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio149"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio151"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + wcn_wlan_bt_en: wcn-wlan-bt-en-state { + pins = "gpio116", "gpio117"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wcn_sw_en: wcn-sw-en-state { + pins = "gpio94"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wwan_reg_en: wwan-reg-en-state { + pins = "gpio246"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; +}; + +&uart14 { + status = "okay"; + + bluetooth { + compatible = "qcom,wcn7850-bt"; + max-speed = <3200000>; + + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + }; +};
diff --git a/arch/arm64/boot/dts/qcom/glymur.dtsi b/arch/arm64/boot/dts/qcom/glymur.dtsi index f04058d..65a398c 100644 --- a/arch/arm64/boot/dts/qcom/glymur.dtsi +++ b/arch/arm64/boot/dts/qcom/glymur.dtsi
@@ -21,7 +21,6 @@ #include <dt-bindings/mailbox/qcom-ipcc.h> #include <dt-bindings/phy/phy-qcom-qmp.h> #include <dt-bindings/power/qcom,rpmhpd.h> -#include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/regulator/qcom,rpmh-regulator.h> #include <dt-bindings/soc/qcom,gpr.h> #include <dt-bindings/soc/qcom,rpmh-rsc.h> @@ -801,8 +800,8 @@ gcc: clock-controller@100000 { <0>, /* USB 2 Phy PCIE PIPEGMUX */ <0>, /* USB 2 Phy PIPEGMUX */ <0>, /* USB 2 Phy SYS PCIE PIPEGMUX */ - <0>, /* PCIe 3a */ - <0>, /* PCIe 3b */ + <&pcie3_phy 0>, /* PCIe 3a pipe */ + <&pcie3_phy 1>, /* PCIe 3b pipe */ <&pcie4_phy>, /* PCIe 4 */ <&pcie5_phy>, /* PCIe 5 */ <&pcie6_phy>, /* PCIe 6 */ @@ -2374,6 +2373,62 @@ IPCC_MPROC_SIGNAL_GLINK_QMP }; }; + pcie3_phy: phy@f00000 { + compatible = "qcom,glymur-qmp-gen5x8-pcie-phy"; + reg = <0x0 0x00f00000 0x0 0x10000>, + <0x0 0x00f10000 0x0 0x10000>; + reg-names = "port_a", + "port_b"; + + clocks = <&gcc GCC_PCIE_PHY_3A_AUX_CLK>, + <&gcc GCC_PCIE_3A_CFG_AHB_CLK>, + <&tcsr TCSR_PCIE_3_CLKREF_EN>, + <&gcc GCC_PCIE_3A_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_3A_PIPE_CLK>, + <&gcc GCC_PCIE_PHY_3B_AUX_CLK>, + <&gcc GCC_PCIE_3B_CFG_AHB_CLK>, + <&gcc GCC_PCIE_3B_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_3B_PIPE_CLK>, + <&gcc GCC_PCIE_3B_PIPE_DIV2_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "rchng", + "pipe", + "phy_b_aux", + "cfg_ahb_b", + "rchng_b", + "pipe_b", + "pipediv2_b"; + + resets = <&gcc GCC_PCIE_3A_PHY_BCR>, + <&gcc GCC_PCIE_3A_NOCSR_COM_PHY_BCR>, + <&gcc GCC_PCIE_3B_PHY_BCR>, + <&gcc GCC_PCIE_3B_NOCSR_COM_PHY_BCR>; + reset-names = "port_a", + "port_a_nocsr", + "port_b", + "port_b_nocsr"; + + assigned-clocks = <&gcc GCC_PCIE_3A_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_3B_PHY_RCHNG_CLK>; + assigned-clock-rates = <100000000>, <100000000>; + + power-domains = <&gcc GCC_PCIE_3A_PHY_GDSC>, + <&gcc GCC_PCIE_3B_PHY_GDSC>; + power-domain-names = "port_a", "port_b"; + + qcom,link-mode = <&tcsr 0x5000>; + + #clock-cells = <1>; + clock-output-names = "pcie3a_pipe_clk", + "pcie3b_pipe_clk"; + + #phy-cells = <1>; + + status = "disabled"; + }; + usb_hs_phy: phy@fa0000 { compatible = "qcom,glymur-m31-eusb2-phy", "qcom,sm8750-m31-eusb2-phy"; @@ -2403,7 +2458,7 @@ usb_mp_hsphy0: phy@fa1000 { status = "disabled"; }; - usb_mp_hsphy1: phy@fa2000 { + usb_mp_hsphy1: phy@fa2000 { compatible = "qcom,glymur-m31-eusb2-phy", "qcom,sm8750-m31-eusb2-phy"; @@ -2568,7 +2623,7 @@ usb_dp_qmpphy_dp_in: endpoint { }; }; - usb_1_hsphy: phy@fdd000 { + usb_1_hsphy: phy@fdd000 { compatible = "qcom,glymur-m31-eusb2-phy", "qcom,sm8750-m31-eusb2-phy"; @@ -3755,6 +3810,8 @@ pcie3b_port0: pcie@0 { reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie3_phy 1>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -3766,6 +3823,280 @@ pcie3b_port0_ep: endpoint { }; }; + pcie3a: pcie@1c10000 { + device_type = "pci"; + compatible = "qcom,glymur-pcie", "qcom,pcie-x1e80100"; + reg = <0x0 0x01c10000 0x0 0x3000>, + <0x0 0x70000000 0x0 0xf20>, + <0x0 0x70000f40 0x0 0xa8>, + <0x0 0x70001000 0x0 0x4000>, + <0x0 0x70100000 0x0 0x100000>, + <0x0 0x01c13000 0x0 0x1000>; + reg-names = "parf", + "dbi", + "elbi", + "atu", + "config", + "mhi"; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x0 0x70200000 0x0 0x100000>, + <0x02000000 0x0 0x70300000 0x0 0x70300000 0x0 0x3d00000>, + <0x03000000 0x7 0x00000000 0x7 0x00000000 0x0 0x40000000>, + <0x43000000 0x70 0x00000000 0x70 0x00000000 0x10 0x00000000>; + + bus-range = <0x00 0xff>; + + dma-coherent; + + linux,pci-domain = <3>; + + operating-points-v2 = <&pcie3a_opp_table>; + + msi-map = <0x0 &gic_its 0xb0000 0x10000>; + iommu-map = <0x0 &pcie_smmu 0x30000 0x10000>; + + interrupts = <GIC_SPI 948 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 949 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 844 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 845 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 202 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 846 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 847 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 942 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc 0 0 GIC_SPI 848 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc 0 0 GIC_SPI 849 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc 0 0 GIC_SPI 850 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc 0 0 GIC_SPI 851 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_PCIE_3A_AUX_CLK>, + <&gcc GCC_PCIE_3A_CFG_AHB_CLK>, + <&gcc GCC_PCIE_3A_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_3A_SLV_AXI_CLK>, + <&gcc GCC_PCIE_3A_SLV_Q2A_AXI_CLK>, + <&gcc GCC_AGGRE_NOC_PCIE_3A_WEST_SF_AXI_CLK>; + clock-names = "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a", + "noc_aggr"; + + assigned-clocks = <&gcc GCC_PCIE_3A_AUX_CLK>; + assigned-clock-rates = <19200000>; + + interconnects = <&pcie_west_anoc MASTER_PCIE_3A QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &pcie_west_slv_noc SLAVE_PCIE_3A QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "pcie-mem", + "cpu-pcie"; + + resets = <&gcc GCC_PCIE_3A_BCR>, + <&gcc GCC_PCIE_3A_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; + + power-domains = <&gcc GCC_PCIE_3A_GDSC>; + + eq-presets-8gts = /bits/ 16 <0x5555 0x5555 0x5555 0x5555 + 0x5555 0x5555 0x5555 0x5555>; + eq-presets-16gts = /bits/ 8 <0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55>; + eq-presets-32gts = /bits/ 8 <0x55 0x55 0x55 0x55 0x55 0x55 0x55 0x55>; + + status = "disabled"; + + pcie3a_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* GEN 1 x1 */ + opp-2500000-1 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <250000 1>; + opp-level = <1>; + }; + + /* GEN 1 x2 */ + opp-5000000-1 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <1>; + }; + + /* GEN 1 x4 */ + opp-10000000-1 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <1>; + }; + + /* GEN 1 x8 */ + opp-20000000-1 { + opp-hz = /bits/ 64 <20000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <2000000 1>; + opp-level = <1>; + }; + + /* GEN 2 x1 */ + opp-5000000-2 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <500000 1>; + opp-level = <2>; + }; + + /* GEN 2 x2 */ + opp-10000000-2 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1000000 1>; + opp-level = <2>; + }; + + /* GEN 2 x4 */ + opp-20000000-2 { + opp-hz = /bits/ 64 <20000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <2000000 1>; + opp-level = <2>; + }; + + /* GEN 2 x8 */ + opp-40000000-2 { + opp-hz = /bits/ 64 <40000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <4000000 1>; + opp-level = <2>; + }; + + /* GEN 3 x1 */ + opp-8000000-3 { + opp-hz = /bits/ 64 <8000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <984500 1>; + opp-level = <3>; + }; + + /* GEN 3 x2 */ + opp-16000000-3 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <3>; + }; + + /* GEN 3 x4 */ + opp-32000000-3 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <3938000 1>; + opp-level = <3>; + }; + + /* GEN 3 x8 */ + opp-64000000-3 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <7876000 1>; + opp-level = <3>; + }; + + /* GEN 4 x1 */ + opp-16000000-4 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <1969000 1>; + opp-level = <4>; + }; + + /* GEN 4 x2 */ + opp-32000000-4 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <3938000 1>; + opp-level = <4>; + }; + + /* GEN 4 x4 */ + opp-64000000-4 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <7876000 1>; + opp-level = <4>; + }; + + /* GEN 4 x8 */ + opp-128000000-4 { + opp-hz = /bits/ 64 <128000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <15753000 1>; + opp-level = <4>; + }; + + /* GEN 5 x1 */ + opp-32000000-5 { + opp-hz = /bits/ 64 <32000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <3938000 1>; + opp-level = <5>; + }; + + /* GEN 5 x2 */ + opp-64000000-5 { + opp-hz = /bits/ 64 <64000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <7876000 1>; + opp-level = <5>; + }; + + /* GEN 5 x4 */ + opp-128000000-5 { + opp-hz = /bits/ 64 <128000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <15753000 1>; + opp-level = <5>; + }; + + /* GEN 5 x8 */ + opp-256000000-5 { + opp-hz = /bits/ 64 <256000000>; + required-opps = <&rpmhpd_opp_nom>; + opp-peak-kBps = <31506000 1>; + opp-level = <5>; + }; + }; + + pcie3a_port0: pcie@0 { + device_type = "pci"; + compatible = "pciclass,0604"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + phys = <&pcie3_phy 0>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; + }; + rng: rng@10c3000 { compatible = "qcom,glymur-trng", "qcom,trng"; reg = <0x0 0x010c3000 0x0 0x1000>; @@ -4481,7 +4812,59 @@ lpass_ag_noc: interconnect@7e40000 { #interconnect-cells = <2>; }; - usb_2_hsphy: phy@88e0000 { + sdhc_2: mmc@8804000 { + compatible = "qcom,glymur-sdhci", "qcom,sdhci-msm-v5"; + + reg = <0x0 0x08804000 0x0 0x1000>; + interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 223 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "hc_irq", + "pwr_irq"; + + clocks = <&gcc GCC_SDCC2_AHB_CLK>, + <&gcc GCC_SDCC2_APPS_CLK>, + <&rpmhcc RPMH_CXO_CLK>; + clock-names = "iface", + "core", + "xo"; + + iommus = <&apps_smmu 0xd00 0x0>; + qcom,dll-config = <0x0007442c>; + qcom,ddr-config = <0x80040868>; + + power-domains = <&rpmhpd RPMHPD_CX>; + operating-points-v2 = <&sdhc2_opp_table>; + + interconnects = <&aggre3_noc MASTER_SDCC_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_SDCC_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "sdhc-ddr", + "cpu-sdhc"; + + bus-width = <4>; + dma-coherent; + + resets = <&gcc GCC_SDCC2_BCR>; + + status = "disabled"; + + sdhc2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-202000000 { + opp-hz = /bits/ 64 <202000000>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + usb_2_hsphy: phy@88e0000 { compatible = "qcom,glymur-m31-eusb2-phy", "qcom,sm8750-m31-eusb2-phy"; @@ -4572,6 +4955,10 @@ usb_0: usb@a600000 { "noc_aggr_north", "noc_aggr_south"; + assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_PRIM_MASTER_CLK>; + assigned-clock-rates = <19200000>, <200000000>; + interrupts-extended = <&intc GIC_SPI 140 IRQ_TYPE_LEVEL_HIGH>, <&intc GIC_SPI 371 IRQ_TYPE_LEVEL_HIGH>, <&pdc 90 IRQ_TYPE_EDGE_BOTH>, @@ -4584,9 +4971,18 @@ usb_0: usb@a600000 { "ss_phy_irq"; power-domains = <&gcc GCC_USB30_PRIM_GDSC>; + required-opps = <&rpmhpd_opp_nom>; resets = <&gcc GCC_USB30_PRIM_BCR>; iommus = <&apps_smmu 0x1420 0x0>; + + interconnects = <&aggre4_noc MASTER_USB3_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_USB3_0 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "usb-ddr", + "apps-usb"; + phys = <&usb_0_hsphy>, <&usb_0_qmpphy QMP_USB43DP_USB3_PHY>; phy-names = "usb2-phy", @@ -4605,6 +5001,8 @@ usb_0: usb@a600000 { usb-role-switch; wakeup-source; + dma-coherent; + status = "disabled"; ports { @@ -4647,6 +5045,10 @@ usb_1: usb@a800000 { "noc_aggr_north", "noc_aggr_south"; + assigned-clocks = <&gcc GCC_USB30_SEC_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_SEC_MASTER_CLK>; + assigned-clock-rates = <19200000>, <200000000>; + interrupts-extended = <&intc GIC_SPI 875 IRQ_TYPE_LEVEL_HIGH>, <&intc GIC_SPI 369 IRQ_TYPE_LEVEL_HIGH>, <&pdc 88 IRQ_TYPE_EDGE_BOTH>, @@ -4660,9 +5062,17 @@ usb_1: usb@a800000 { resets = <&gcc GCC_USB30_SEC_BCR>; power-domains = <&gcc GCC_USB30_SEC_GDSC>; + required-opps = <&rpmhpd_opp_nom>; iommus = <&apps_smmu 0x1460 0x0>; + interconnects = <&aggre4_noc MASTER_USB3_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_USB3_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "usb-ddr", + "apps-usb"; + phys = <&usb_1_hsphy>, <&usb_1_qmpphy QMP_USB43DP_USB3_PHY>; phy-names = "usb2-phy", @@ -4681,6 +5091,8 @@ usb_1: usb@a800000 { usb-role-switch; wakeup-source; + dma-coherent; + status = "disabled"; ports { @@ -4723,6 +5135,10 @@ usb_2: usb@a000000 { "noc_aggr_north", "noc_aggr_south"; + assigned-clocks = <&gcc GCC_USB30_TERT_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_TERT_MASTER_CLK>; + assigned-clock-rates = <19200000>, <200000000>; + interrupts-extended = <&intc GIC_SPI 871 IRQ_TYPE_LEVEL_HIGH>, <&intc GIC_SPI 370 IRQ_TYPE_LEVEL_HIGH>, <&pdc 89 IRQ_TYPE_EDGE_BOTH>, @@ -4736,9 +5152,17 @@ usb_2: usb@a000000 { resets = <&gcc GCC_USB30_TERT_BCR>; power-domains = <&gcc GCC_USB30_TERT_GDSC>; + required-opps = <&rpmhpd_opp_nom>; iommus = <&apps_smmu 0x420 0x0>; + interconnects = <&aggre2_noc MASTER_USB3_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_USB3_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "usb-ddr", + "apps-usb"; + phys = <&usb_2_hsphy>, <&usb_2_qmpphy QMP_USB43DP_USB3_PHY>; phy-names = "usb2-phy", @@ -4757,6 +5181,8 @@ usb_2: usb@a000000 { usb-role-switch; wakeup-source; + dma-coherent; + status = "disabled"; ports { @@ -4847,6 +5273,8 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, usb-role-switch; wakeup-source; + dma-coherent; + status = "disabled"; }; @@ -4869,6 +5297,10 @@ usb_mp: usb@a400000 { "noc_aggr_north", "noc_aggr_south"; + assigned-clocks = <&gcc GCC_USB30_MP_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_MP_MASTER_CLK>; + assigned-clock-rates = <19200000>, <200000000>; + interrupts-extended = <&intc GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>, <&intc GIC_SPI 345 IRQ_TYPE_LEVEL_HIGH>, <&intc GIC_SPI 346 IRQ_TYPE_LEVEL_HIGH>, @@ -4894,9 +5326,17 @@ usb_mp: usb@a400000 { resets = <&gcc GCC_USB30_MP_BCR>; power-domains = <&gcc GCC_USB30_MP_GDSC>; + required-opps = <&rpmhpd_opp_nom>; iommus = <&apps_smmu 0xda0 0x0>; + interconnects = <&aggre3_noc MASTER_USB3_MP QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hsc_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_USB3_MP QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "usb-ddr", + "apps-usb"; + phys = <&usb_mp_hsphy0>, <&usb_mp_qmpphy0>, <&usb_mp_hsphy1>, @@ -4919,6 +5359,8 @@ usb_mp: usb@a400000 { dr_mode = "host"; wakeup-source; + dma-coherent; + status = "disabled"; }; @@ -6311,6 +6753,46 @@ rx-pins { bias-disable; }; }; + + sdc2_default_state: sdc2-default-state { + clk-pins { + pins = "sdc2_clk"; + drive-strength = <16>; + bias-disable; + }; + + cmd-pins { + pins = "sdc2_cmd"; + drive-strength = <10>; + bias-pull-up; + }; + + data-pins { + pins = "sdc2_data"; + drive-strength = <10>; + bias-pull-up; + }; + }; + + sdc2_sleep_state: sdc2-sleep-state { + clk-pins { + pins = "sdc2_clk"; + drive-strength = <2>; + bias-disable; + }; + + cmd-pins { + pins = "sdc2_cmd"; + drive-strength = <2>; + bias-pull-up; + }; + + data-pins { + pins = "sdc2_data"; + drive-strength = <2>; + bias-pull-up; + }; + }; }; ctcu@10001000 { @@ -6787,7 +7269,7 @@ qm_tpdm_out: endpoint { }; }; - itnoc@11200000 { + itnoc@11200000 { compatible = "qcom,coresight-itnoc"; reg = <0x0 0x11200000 0x0 0x3c00>;
diff --git a/arch/arm64/boot/dts/qcom/hamoa-advantech-som-6820.dtsi b/arch/arm64/boot/dts/qcom/hamoa-advantech-som-6820.dtsi new file mode 100644 index 0000000..fec6c4d --- /dev/null +++ b/arch/arm64/boot/dts/qcom/hamoa-advantech-som-6820.dtsi
@@ -0,0 +1,54 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * SoM: https://advdownload.advantech.com.cn/productfile/PIS/SOM-6820/file/SOM-6820_DS(052925)20250529110758.pdf + */ + +#include "hamoa-iot-som.dtsi" + +/ { + vph_pwr: regulator-vph-pwr { + compatible = "regulator-fixed"; + + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-always-on; + regulator-boot-on; + }; +}; + +&ufs_mem_phy { + vdda-phy-supply = <&vreg_l3i_0p8>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&ufs_mem_hc { + reset-gpios = <&tlmm 238 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l17b_2p5>; + vcc-max-microamp = <1300000>; + vccq-supply = <&vreg_l2i_1p2>; + vccq-max-microamp = <1200000>; + + status = "okay"; +}; + +&usb_1_ss0 { + /delete-property/ usb-role-switch; + dr_mode = "peripheral"; +}; + +&usb_1_ss1 { + /delete-property/ usb-role-switch; + dr_mode = "host"; +}; + +&usb_1_ss2 { + /delete-property/ usb-role-switch; + dr_mode = "host"; +};
diff --git a/arch/arm64/boot/dts/qcom/hamoa-advantech-som-db5830.dts b/arch/arm64/boot/dts/qcom/hamoa-advantech-som-db5830.dts new file mode 100644 index 0000000..9d87c98 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/hamoa-advantech-som-db5830.dts
@@ -0,0 +1,119 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * SoM: https://advdownload.advantech.com.cn/productfile/PIS/SOM-6820/file/SOM-6820_DS(052925)20250529110758.pdf + * carrier board: https://www.advantech.com.cn/zh-cn/products/1-fc23ff/som-db5830/mod_16b1a718-27d6-4a4c-8684-e8f2a8e9c57b + */ + +/dts-v1/; + +#include "hamoa-advantech-som-6820.dtsi" + +/ { + model = "Advantech SOM-6820 on SOM-DB5830"; + compatible = "advantech,som-db5830", "advantech,som-6820", + "qcom,iq-x7181-evk-som", "qcom,x1e80100"; + chassis-type = "embedded"; + + aliases { + serial0 = &uart21; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + +}; + +&pcie3_port0 { + reset-gpios = <&tlmm 143 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 145 GPIO_ACTIVE_LOW>; +}; + +&pcie4_port0 { + reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>; +}; + +&pcie5_port0 { + reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 151 GPIO_ACTIVE_LOW>; +}; + +&pcie6a_port0 { + reset-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>; +}; + +&thermal_zones { + gpuss-0-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + }; + }; + + gpuss-1-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + }; + }; + + gpuss-2-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + }; + }; + + gpuss-3-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + }; + }; + + gpuss-4-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + }; + }; + + gpuss-5-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + }; + }; + + gpuss-6-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + }; + }; + + gpuss-7-thermal { + trips { + trip-point0 { + temperature = <105000>; + }; + }; + }; +}; + +&uart21 { + compatible = "qcom,geni-debug-uart"; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts index 9fa86bb..d0433cc 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-evk.dts
@@ -35,6 +35,24 @@ mcp2518fd_osc: clock-40000000 { clock-frequency = <40000000>; #clock-cells = <0>; }; + + clk_rtmr0_xo: clock-rtmr0-xo { + compatible = "fixed-clock"; + clock-frequency = <25000000>; + #clock-cells = <0>; + }; + + clk_rtmr1_xo: clock-rtmr1-xo { + compatible = "fixed-clock"; + clock-frequency = <25000000>; + #clock-cells = <0>; + }; + + clk_rtmr2_xo: clock-rtmr2-xo { + compatible = "fixed-clock"; + clock-frequency = <25000000>; + #clock-cells = <0>; + }; }; wcd938x: audio-codec { @@ -126,15 +144,15 @@ port@1 { reg = <1>; pmic_glink_ss0_ss_in: endpoint { - remote-endpoint = <&usb_1_ss0_qmpphy_out>; + remote-endpoint = <&retimer_ss0_ss_out>; }; }; port@2 { reg = <2>; - pmic_glink_ss0_sbu: endpoint { - remote-endpoint = <&usb_1_ss0_sbu_mux>; + pmic_glink_ss0_con_sbu_in: endpoint { + remote-endpoint = <&retimer_ss0_con_sbu_out>; }; }; }; @@ -303,7 +321,6 @@ vreg_pcie_3v3_aux: regulator-pcie-3v3-aux { pinctrl-names = "default"; }; - /* Left unused as the retimer is not used on this board. */ vreg_rtmr0_1p15: regulator-rtmr0-1p15 { compatible = "regulator-fixed"; @@ -479,32 +496,6 @@ vph_pwr: regulator-vph-pwr { regulator-boot-on; }; - /* - * TODO: These two regulators are actually part of the removable M.2 - * card and not the EVK mainboard. Need to describe this differently. - * Functionally it works correctly, because all we need to do is to - * turn on the actual 3.3V supply above. - */ - vreg_wcn_0p95: regulator-wcn-0p95 { - compatible = "regulator-fixed"; - - regulator-name = "VREG_WCN_0P95"; - regulator-min-microvolt = <950000>; - regulator-max-microvolt = <950000>; - - vin-supply = <&vreg_wcn_3p3>; - }; - - vreg_wcn_1p9: regulator-wcn-1p9 { - compatible = "regulator-fixed"; - - regulator-name = "VREG_WCN_1P9"; - regulator-min-microvolt = <1900000>; - regulator-max-microvolt = <1900000>; - - vin-supply = <&vreg_wcn_3p3>; - }; - vreg_wcn_3p3: regulator-wcn-3p3 { compatible = "regulator-fixed"; @@ -658,83 +649,44 @@ platform { }; }; - usb-1-ss0-sbu-mux { - compatible = "onnn,fsusb42", "gpio-sbu-mux"; + wifi-bt-connector { + compatible = "pcie-m2-e-connector"; + vpcie3v3-supply = <&vreg_wcn_3p3>; - enable-gpios = <&tlmm 168 GPIO_ACTIVE_LOW>; - select-gpios = <&tlmm 167 GPIO_ACTIVE_HIGH>; + w-disable1-gpios = <&tlmm 117 GPIO_ACTIVE_LOW>; + w-disable2-gpios = <&tlmm 116 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&usb_1_ss0_sbu_default>; + pinctrl-0 = <&wcn_wlan_en>, <&wcn_bt_en>; pinctrl-names = "default"; - mode-switch; - orientation-switch; + ports { + #address-cells = <1>; + #size-cells = <0>; - port { - usb_1_ss0_sbu_mux: endpoint { - remote-endpoint = <&pmic_glink_ss0_sbu>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + m2_e_pcie_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&pcie4_port0_ep>; + }; + }; + + port@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + + m2_e_uart_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&uart14_ep>; + }; }; }; }; - wcn7850-pmu { - compatible = "qcom,wcn7850-pmu"; - - vdd-supply = <&vreg_wcn_0p95>; - vddio-supply = <&vreg_l15b_1p8>; - vddaon-supply = <&vreg_wcn_0p95>; - vdddig-supply = <&vreg_wcn_0p95>; - vddrfa1p2-supply = <&vreg_wcn_1p9>; - vddrfa1p8-supply = <&vreg_wcn_1p9>; - - bt-enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>; - wlan-enable-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>; - - pinctrl-0 = <&wcn_bt_en>, <&wcn_wlan_en>; - pinctrl-names = "default"; - - regulators { - vreg_pmu_rfa_cmn: ldo0 { - regulator-name = "vreg_pmu_rfa_cmn"; - }; - - vreg_pmu_aon_0p59: ldo1 { - regulator-name = "vreg_pmu_aon_0p59"; - }; - - vreg_pmu_wlcx_0p8: ldo2 { - regulator-name = "vreg_pmu_wlcx_0p8"; - }; - - vreg_pmu_wlmx_0p85: ldo3 { - regulator-name = "vreg_pmu_wlmx_0p85"; - }; - - vreg_pmu_btcmx_0p85: ldo4 { - regulator-name = "vreg_pmu_btcmx_0p85"; - }; - - vreg_pmu_rfa_0p8: ldo5 { - regulator-name = "vreg_pmu_rfa_0p8"; - }; - - vreg_pmu_rfa_1p2: ldo6 { - regulator-name = "vreg_pmu_rfa_1p2"; - }; - - vreg_pmu_rfa_1p8: ldo7 { - regulator-name = "vreg_pmu_rfa_1p8"; - }; - - vreg_pmu_pcie_0p9: ldo8 { - regulator-name = "vreg_pmu_pcie_0p9"; - }; - - vreg_pmu_pcie_1p8: ldo9 { - regulator-name = "vreg_pmu_pcie_1p8"; - }; - }; - }; }; &i2c1 { @@ -745,7 +697,7 @@ typec-mux@8 { compatible = "parade,ps8830"; reg = <0x08>; - clocks = <&rpmhcc RPMH_RF_CLK5>; + clocks = <&clk_rtmr2_xo>; vdd-supply = <&vreg_rtmr2_1p15>; vdd33-supply = <&vreg_rtmr2_3p3>; @@ -793,6 +745,63 @@ retimer_ss2_con_sbu_out: endpoint { }; }; +&i2c3 { + clock-frequency = <400000>; + + status = "okay"; + + typec-mux@8 { + compatible = "parade,ps8830"; + reg = <0x08>; + + clocks = <&clk_rtmr0_xo>; + + vdd-supply = <&vreg_rtmr0_1p15>; + vdd33-supply = <&vreg_rtmr0_3p3>; + vdd33-cap-supply = <&vreg_rtmr0_3p3>; + vddar-supply = <&vreg_rtmr0_1p15>; + vddat-supply = <&vreg_rtmr0_1p15>; + vddio-supply = <&vreg_rtmr0_1p8>; + + reset-gpios = <&pm8550_gpios 10 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&rtmr0_default>; + pinctrl-names = "default"; + + orientation-switch; + retimer-switch; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + retimer_ss0_ss_out: endpoint { + remote-endpoint = <&pmic_glink_ss0_ss_in>; + }; + }; + + port@1 { + reg = <1>; + + retimer_ss0_ss_in: endpoint { + remote-endpoint = <&usb_1_ss0_qmpphy_out>; + }; + }; + + port@2 { + reg = <2>; + + retimer_ss0_con_sbu_out: endpoint { + remote-endpoint = <&pmic_glink_ss0_con_sbu_in>; + }; + }; + }; + }; +}; + &i2c5 { clock-frequency = <400000>; @@ -860,7 +869,7 @@ typec-mux@8 { compatible = "parade,ps8830"; reg = <0x8>; - clocks = <&rpmhcc RPMH_RF_CLK4>; + clocks = <&clk_rtmr1_xo>; vdd-supply = <&vreg_rtmr1_1p15>; vdd33-supply = <&vreg_rtmr1_3p3>; @@ -1024,21 +1033,10 @@ &pcie3_port0 { &pcie4_port0 { reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>; wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>; +}; - wifi@0 { - compatible = "pci17cb,1107"; - reg = <0x10000 0x0 0x0 0x0 0x0>; - - vddaon-supply = <&vreg_pmu_aon_0p59>; - vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; - vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; - vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; - vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; - vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; - vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; - vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; - vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; - }; +&pcie4_port0_ep { + remote-endpoint = <&m2_e_pcie_ep>; }; &pcie5 { @@ -1458,30 +1456,6 @@ usb2_pwr_3p3_reg_en: usb2-pwr-3p3-reg-en-state { bias-disable; }; - usb_1_ss0_sbu_default: usb-1-ss0-sbu-state { - mode-pins { - pins = "gpio166"; - function = "gpio"; - bias-disable; - drive-strength = <2>; - output-high; - }; - - oe-n-pins { - pins = "gpio168"; - function = "gpio"; - bias-disable; - drive-strength = <2>; - }; - - sel-pins { - pins = "gpio167"; - function = "gpio"; - bias-disable; - drive-strength = <2>; - }; - }; - wcd_default: wcd-reset-n-active-state { pins = "gpio191"; function = "gpio"; @@ -1530,19 +1504,10 @@ wcn_usb_sw_n: wcn-usb-sw-n-state { &uart14 { status = "okay"; +}; - bluetooth { - compatible = "qcom,wcn7850-bt"; - max-speed = <3200000>; - - vddaon-supply = <&vreg_pmu_aon_0p59>; - vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; - vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; - vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; - vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; - vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; - vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; - }; +&uart14_ep { + remote-endpoint = <&m2_e_uart_ep>; }; &uart21 { @@ -1578,7 +1543,7 @@ &usb_1_ss0_hsphy { }; &usb_1_ss0_qmpphy_out { - remote-endpoint = <&pmic_glink_ss0_ss_in>; + remote-endpoint = <&retimer_ss0_ss_in>; }; &usb_1_ss1_dwc3_hs {
diff --git a/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi b/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi index bc70fe5..f139f3a 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa-iot-som.dtsi
@@ -478,6 +478,27 @@ &remoteproc_cdsp { status = "okay"; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { gpio-reserved-ranges = <34 2>; /* TPM LP & INT */
diff --git a/arch/arm64/boot/dts/qcom/hamoa-lenovo-ideacentre-mini-01q8x10.dts b/arch/arm64/boot/dts/qcom/hamoa-lenovo-ideacentre-mini-01q8x10.dts index 2848250..75ce8b0 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-lenovo-ideacentre-mini-01q8x10.dts +++ b/arch/arm64/boot/dts/qcom/hamoa-lenovo-ideacentre-mini-01q8x10.dts
@@ -902,6 +902,27 @@ wcd_tx: codec@0,3 { }; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d>; + vdda-qreftx0-0p9-supply = <&vreg_l3j>; + vdda-qreftx0-1p2-supply = <&vreg_l2j>; + vdda-qreftx1-0p9-supply = <&vreg_l3j>; + vdda-qreftx1-1p2-supply = <&vreg_l3e>; + vdda-refgen0-0p9-supply = <&vreg_l3i>; + vdda-refgen0-1p2-supply = <&vreg_l3e>; + vdda-refgen2-0p9-supply = <&vreg_l3j>; + vdda-refgen2-1p2-supply = <&vreg_l2j>; +}; + &tlmm { gpio-reserved-ranges = <44 4>, /* SPI11 (TPM) */ <76 4>, /* SPI19 (TZ Protected) */
diff --git a/arch/arm64/boot/dts/qcom/hamoa-pmics.dtsi b/arch/arm64/boot/dts/qcom/hamoa-pmics.dtsi index 17d754d..7fad4a9 100644 --- a/arch/arm64/boot/dts/qcom/hamoa-pmics.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa-pmics.dtsi
@@ -288,6 +288,7 @@ pmk8550_vadc: adc@9000 { #address-cells = <1>; #size-cells = <0>; #io-channel-cells = <1>; + #thermal-sensor-cells = <1>; pinctrl-0 = <&sys_therm_0_gpio3>, <&sys_therm_1_gpio4>; pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/qcom/hamoa.dtsi b/arch/arm64/boot/dts/qcom/hamoa.dtsi index 8a96ea1..48f47aa 100644 --- a/arch/arm64/boot/dts/qcom/hamoa.dtsi +++ b/arch/arm64/boot/dts/qcom/hamoa.dtsi
@@ -19,7 +19,6 @@ #include <dt-bindings/mailbox/qcom-ipcc.h> #include <dt-bindings/phy/phy-qcom-qmp.h> #include <dt-bindings/power/qcom,rpmhpd.h> -#include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/soc/qcom,gpr.h> #include <dt-bindings/soc/qcom,rpmh-rsc.h> #include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h> @@ -2033,6 +2032,11 @@ &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, pinctrl-names = "default"; status = "disabled"; + + port { + uart14_ep: endpoint { + }; + }; }; i2c15: i2c@a9c000 { @@ -2108,7 +2112,7 @@ &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>, }; }; - gpi_dma0: dma-controller@b00000 { + gpi_dma0: dma-controller@b00000 { compatible = "qcom,x1e80100-gpi-dma", "qcom,sm6350-gpi-dma"; reg = <0 0x00b00000 0 0x60000>; @@ -2833,11 +2837,13 @@ usb_1_ss0_qmpphy: phy@fd5000 { clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>, <&rpmhcc RPMH_CXO_CLK>, <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>, - <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; + <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>, + <&gcc GCC_USB4_0_PHY_P2RR2P_PIPE_CLK>; clock-names = "aux", "ref", "com_aux", - "usb3_pipe"; + "usb3_pipe", + "p2rr2p_pipe"; power-domains = <&gcc GCC_USB_0_PHY_GDSC>; @@ -2904,11 +2910,13 @@ usb_1_ss1_qmpphy: phy@fda000 { clocks = <&gcc GCC_USB3_SEC_PHY_AUX_CLK>, <&tcsr TCSR_USB4_1_CLKREF_EN>, <&gcc GCC_USB3_SEC_PHY_COM_AUX_CLK>, - <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>; + <&gcc GCC_USB3_SEC_PHY_PIPE_CLK>, + <&gcc GCC_USB4_1_PHY_P2RR2P_PIPE_CLK>; clock-names = "aux", "ref", "com_aux", - "usb3_pipe"; + "usb3_pipe", + "p2rr2p_pipe"; power-domains = <&gcc GCC_USB_1_PHY_GDSC>; @@ -2975,11 +2983,13 @@ usb_1_ss2_qmpphy: phy@fdf000 { clocks = <&gcc GCC_USB3_TERT_PHY_AUX_CLK>, <&tcsr TCSR_USB4_2_CLKREF_EN>, <&gcc GCC_USB3_TERT_PHY_COM_AUX_CLK>, - <&gcc GCC_USB3_TERT_PHY_PIPE_CLK>; + <&gcc GCC_USB3_TERT_PHY_PIPE_CLK>, + <&gcc GCC_USB4_2_PHY_P2RR2P_PIPE_CLK>; clock-names = "aux", "ref", "com_aux", - "usb3_pipe"; + "usb3_pipe", + "p2rr2p_pipe"; power-domains = <&gcc GCC_USB_2_PHY_GDSC>; @@ -3082,6 +3092,7 @@ aggre1_noc: interconnect@16e0000 { qcom,bcm-voters = <&apps_bcm_voter>; #interconnect-cells = <2>; + clocks = <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>; }; aggre2_noc: interconnect@1700000 { @@ -3118,6 +3129,8 @@ usb_north_anoc: interconnect@1760000 { qcom,bcm-voters = <&apps_bcm_voter>; #interconnect-cells = <2>; + clocks = <&gcc GCC_AGGRE_USB2_PRIM_AXI_CLK>, + <&gcc GCC_AGGRE_USB3_MP_AXI_CLK>; }; usb_south_anoc: interconnect@1770000 { @@ -3127,6 +3140,12 @@ usb_south_anoc: interconnect@1770000 { qcom,bcm-voters = <&apps_bcm_voter>; #interconnect-cells = <2>; + clocks = <&gcc GCC_AGGRE_USB3_PRIM_AXI_CLK>, + <&gcc GCC_AGGRE_USB3_SEC_AXI_CLK>, + <&gcc GCC_AGGRE_USB3_TERT_AXI_CLK>, + <&gcc GCC_AGGRE_USB4_0_AXI_CLK>, + <&gcc GCC_AGGRE_USB4_1_AXI_CLK>, + <&gcc GCC_AGGRE_USB4_2_AXI_CLK>; }; mmss_noc: interconnect@1780000 { @@ -3702,7 +3721,7 @@ pcie4: pcie@1c08000 { <0 0x7c100000 0 0x100000>, <0 0x01c0b000 0 0x1000>; reg-names = "parf", - "dbi", + "dbi", "elbi", "atu", "config", @@ -3784,6 +3803,7 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, status = "disabled"; pcie4_port0: pcie@0 { + compatible = "pciclass,0604"; device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; @@ -3793,6 +3813,11 @@ pcie4_port0: pcie@0 { #address-cells = <3>; #size-cells = <2>; ranges; + + port { + pcie4_port0_ep: endpoint { + }; + }; }; }; @@ -3984,7 +4009,6 @@ tcsr: clock-controller@1fc0000 { reg = <0 0x01fc0000 0 0x30000>; clocks = <&rpmhcc RPMH_CXO_CLK>; #clock-cells = <1>; - #reset-cells = <1>; }; gpu: gpu@3d00000 {
diff --git a/arch/arm64/boot/dts/qcom/hawi-ipcc.h b/arch/arm64/boot/dts/qcom/hawi-ipcc.h new file mode 100644 index 0000000..7659357 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/hawi-ipcc.h
@@ -0,0 +1,61 @@ +/* SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef __DTS_HAWI_MAILBOX_IPCC_H +#define __DTS_HAWI_MAILBOX_IPCC_H + +/* Physical client IDs */ +#define IPCC_MPROC_AOP 0 +#define IPCC_MPROC_TZ 1 +#define IPCC_MPROC_MPSS 2 +#define IPCC_MPROC_LPASS 3 +#define IPCC_MPROC_SDC 4 +#define IPCC_MPROC_CDSP 5 +#define IPCC_MPROC_APSS 6 +#define IPCC_MPROC_SOCCP 12 +#define IPCC_MPROC_DCP 13 +#define IPCC_MPROC_QECP 14 +#define IPCC_MPROC_SPSS 15 +#define IPCC_MPROC_TME 16 + +#define IPCC_COMPUTE_L0_LPASS 1 +#define IPCC_COMPUTE_L0_CDSP 2 +#define IPCC_COMPUTE_L0_APSS 3 +#define IPCC_COMPUTE_L0_GPU 4 +#define IPCC_COMPUTE_L0_CVP 8 +#define IPCC_COMPUTE_L0_CAM 9 +#define IPCC_COMPUTE_L0_CAM1 10 +#define IPCC_COMPUTE_L0_DCP 11 +#define IPCC_COMPUTE_L0_VPU 12 +#define IPCC_COMPUTE_L0_SOCCP 16 + +#define IPCC_COMPUTE_L1_LPASS 1 +#define IPCC_COMPUTE_L1_CDSP 2 +#define IPCC_COMPUTE_L1_APSS 3 +#define IPCC_COMPUTE_L1_GPU 4 +#define IPCC_COMPUTE_L1_CVP 8 +#define IPCC_COMPUTE_L1_CAM 9 +#define IPCC_COMPUTE_L1_CAM1 10 +#define IPCC_COMPUTE_L1_DCP 11 +#define IPCC_COMPUTE_L1_VPU 12 +#define IPCC_COMPUTE_L1_SOCCP 16 + +#define IPCC_PERIPH_CDSP 2 +#define IPCC_PERIPH_APSS 3 +#define IPCC_PERIPH_PCIE0 4 +#define IPCC_PERIPH_PCIE1 15 + +#define IPCC_FENCE_LPASS 1 +#define IPCC_FENCE_CDSP 2 +#define IPCC_FENCE_APSS 3 +#define IPCC_FENCE_GPU 4 +#define IPCC_FENCE_CVP 8 +#define IPCC_FENCE_CAM 9 +#define IPCC_FENCE_CAM1 10 +#define IPCC_FENCE_DCP 11 +#define IPCC_FENCE_VPU 20 +#define IPCC_FENCE_SOCCP 24 + +#endif
diff --git a/arch/arm64/boot/dts/qcom/hawi-mtp.dts b/arch/arm64/boot/dts/qcom/hawi-mtp.dts new file mode 100644 index 0000000..c38e5fa --- /dev/null +++ b/arch/arm64/boot/dts/qcom/hawi-mtp.dts
@@ -0,0 +1,997 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/pinctrl/qcom,pmic-gpio.h> +#include <dt-bindings/regulator/qcom,rpmh-regulator.h> + +#include "hawi.dtsi" + +#include "pmd8028-kaanapali.dtsi" /* SPMI1: SID-4 */ +#include "pmh0101.dtsi" /* SPMI0: SID-1 */ +#include "pmh0104-hawi.dtsi" /* SPMI0: SID-2 SPMI1: SID-9 */ +#include "pmh0110-kaanapali.dtsi" /* SPMI0: SID-3/5/6/8 */ +#include "pmih0108-kaanapali.dtsi" /* SPMI1: SID-7 */ +#include "pmk8850.dtsi" /* SPMI0: SID-0 */ +#include "pmr735d-kaanapali.dtsi" /* SPMI1: SID-A */ +#include "pm8010-kaanapali.dtsi" /* SPMI1: SID-C/D */ + +/ { + model = "Qualcomm Technologies, Inc. Hawi MTP"; + compatible = "qcom,hawi-mtp", "qcom,hawi"; + chassis-type = "handset"; + + aliases { + serial0 = &uart7; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + clocks { + bi_tcxo_ao_div2: bi-tcxo-ao-div2-clk { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + + clocks = <&rpmhcc RPMH_CXO_CLK_A>; + clock-mult = <1>; + clock-div = <2>; + }; + + bi_tcxo_div2: bi-tcxo-div2-clk { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-mult = <1>; + clock-div = <2>; + }; + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + clock-frequency = <32764>; + #clock-cells = <0>; + }; + + xo_board: xo-board { + compatible = "fixed-clock"; + clock-frequency = <76800000>; + #clock-cells = <0>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&key_vol_up_default>; + pinctrl-names = "default"; + + key-volume-up { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + gpios = <&tlmm 101 GPIO_ACTIVE_LOW>; + debounce-interval = <15>; + linux,can-disable; + wakeup-source; + }; + }; + + pmic-glink { + compatible = "qcom,hawi-pmic-glink", + "qcom,kaanapali-pmic-glink", + "qcom,pmic-glink"; + #address-cells = <1>; + #size-cells = <0>; + + connector@0 { + compatible = "usb-c-connector"; + reg = <0>; + + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in: endpoint { + remote-endpoint = <&usb_1_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in: endpoint { + remote-endpoint = <&usb_dp_qmpphy_out>; + }; + }; + + port@2 { + reg = <2>; + + pmic_glink_dp_out: endpoint { + }; + }; + }; + }; + }; + + sdcard_vdd_3p0: sdcard-vdd-3p0 { + compatible = "regulator-fixed"; + + regulator-name = "sdc-vdd123"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-enable-ramp-delay = <1500>; + + gpio = <&pmh0104_c_e0_gpios 5 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&sd_card_eldo_en>; + pinctrl-names = "default"; + + vin-supply = <&vreg_bob1>; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pmh0101-rpmh-regulators"; + qcom,pmic-id = "B_E0"; + + vreg_bob1: bob1 { + regulator-name = "vreg_bob1"; + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <4000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_bob2: bob2 { + regulator-name = "vreg_bob2"; + regulator-min-microvolt = <2704000>; + regulator-max-microvolt = <3552000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1b_1p8: ldo1 { + regulator-name = "vreg_l1b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l2b_3p0: ldo2 { + regulator-name = "vreg_l2b_3p0"; + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l4b_1p8: ldo4 { + regulator-name = "vreg_l4b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l5b_3p1: ldo5 { + regulator-name = "vreg_l5b_3p1"; + regulator-min-microvolt = <3104000>; + regulator-max-microvolt = <3104000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l6b_1p8: ldo6 { + regulator-name = "vreg_l6b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l7b_1p8: ldo7 { + regulator-name = "vreg_l7b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l8b_1p8: ldo8 { + regulator-name = "vreg_l8b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l9b_2p5: ldo9 { + regulator-name = "vreg_l9b_2p5"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <2504000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l10b_1p8: ldo10 { + regulator-name = "vreg_l10b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l11b_1p2: ldo11 { + regulator-name = "vreg_l11b_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l12b_1p8: ldo12 { + regulator-name = "vreg_l12b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l13b_3p0: ldo13 { + regulator-name = "vreg_l13b_3p0"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l14b_3p2: ldo14 { + regulator-name = "vreg_l14b_3p2"; + regulator-min-microvolt = <3200000>; + regulator-max-microvolt = <3200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l15b_1p8: ldo15 { + regulator-name = "vreg_l15b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l16b_2p9: ldo16 { + regulator-name = "vreg_l16b_2p9"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3600000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l17b_2p5: ldo17 { + regulator-name = "vreg_l17b_2p5"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <2504000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l18b_1p2: ldo18 { + regulator-name = "vreg_l18b_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + }; + + regulators-1 { + compatible = "qcom,pmh0104-rpmh-regulators"; + qcom,pmic-id = "C_E0"; + + vreg_s1c_0p5: smps1 { + regulator-name = "vreg_s1c_0p5"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <572000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s3c_1p2: smps3 { + regulator-name = "vreg_s3c_1p2"; + regulator-min-microvolt = <1224000>; + regulator-max-microvolt = <1372000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s4c_1p8: smps4 { + regulator-name = "vreg_s4c_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-2 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "D_E0"; + + vreg_s9d_1p0: smps9 { + regulator-name = "vreg_s9d_1p0"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1d_0p9: ldo1 { + regulator-name = "vreg_l1d_0p9"; + regulator-min-microvolt = <824000>; + regulator-max-microvolt = <952000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l2d_0p9: ldo2 { + regulator-name = "vreg_l2d_0p9"; + regulator-min-microvolt = <824000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l3d_1p2: ldo3 { + regulator-name = "vreg_l3d_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1256000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l4d_0p8: ldo4 { + regulator-name = "vreg_l4d_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + }; + + regulators-3 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "F_E0"; + + vreg_s7f_0p9: smps7 { + regulator-name = "vreg_s7f_0p9"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <972000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s8f_0p8: smps8 { + regulator-name = "vreg_s8f_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1f_1p2: ldo1 { + regulator-name = "vreg_l1f_1p2"; + regulator-min-microvolt = <744000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l2f_1p2: ldo2 { + regulator-name = "vreg_l2f_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l3f_0p9: ldo3 { + regulator-name = "vreg_l3f_0p9"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l4f_0p8: ldo4 { + regulator-name = "vreg_l4f_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + }; + + regulators-4 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "G_E0"; + + vreg_l1g_1p2: ldo1 { + regulator-name = "vreg_l1g_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l2g_1p8: ldo2 { + regulator-name = "vreg_l2g_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l3g_1p2: ldo3 { + regulator-name = "vreg_l3g_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l4g_1p2: ldo4 { + regulator-name = "vreg_l4g_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + }; + + regulators-5 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "I_E0"; + + vreg_l1i_0p8: ldo1 { + regulator-name = "vreg_l1i_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l2i_0p8: ldo2 { + regulator-name = "vreg_l2i_0p8"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <1104000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l3i_1p2: ldo3 { + regulator-name = "vreg_l3i_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_AUTO>; + }; + }; + + regulators-6 { + compatible = "qcom,pmh0104-rpmh-regulators"; + qcom,pmic-id = "J_E1"; + + vreg_s1j_0p8: smps1 { + regulator-name = "vreg_s1j_0p8"; + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s2j_0p8: smps2 { + regulator-name = "vreg_s2j_0p8"; + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s3j_1p2: smps3 { + regulator-name = "vreg_s3j_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1300000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s4j_0p7: smps4 { + regulator-name = "vreg_s4j_0p7"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-7 { + compatible = "qcom,pmr735d-rpmh-regulators"; + qcom,pmic-id = "K_E1"; + + vreg_l1k_0p7: ldo1 { + regulator-name = "vreg_l1k_0p7"; + regulator-min-microvolt = <496000>; + regulator-max-microvolt = <1104000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2k_0p7: ldo2 { + regulator-name = "vreg_l2k_0p7"; + regulator-min-microvolt = <696000>; + regulator-max-microvolt = <1000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3k_1p2: ldo3 { + regulator-name = "vreg_l3k_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1256000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4k_1p0: ldo4 { + regulator-name = "vreg_l4k_1p0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5k_0p9: ldo5 { + regulator-name = "vreg_l5k_0p9"; + regulator-min-microvolt = <696000>; + regulator-max-microvolt = <1000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6k_1p7: ldo6 { + regulator-name = "vreg_l6k_1p7"; + regulator-min-microvolt = <1696000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7k_0p7: ldo7 { + regulator-name = "vreg_l7k_0p7"; + regulator-min-microvolt = <696000>; + regulator-max-microvolt = <848000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-8 { + compatible = "qcom,pm8010-rpmh-regulators"; + qcom,pmic-id = "M_E1"; + + vreg_l1m_1p0: ldo1 { + regulator-name = "vreg_l1m_1p0"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1056000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2m_1p0: ldo2 { + regulator-name = "vreg_l2m_1p0"; + regulator-min-microvolt = <1096000>; + regulator-max-microvolt = <1104000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3m_2p8: ldo3 { + regulator-name = "vreg_l3m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2900000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4m_2p8: ldo4 { + regulator-name = "vreg_l4m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2896000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5m_2p8: ldo5 { + regulator-name = "vreg_l5m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2896000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6m_2p8: ldo6 { + regulator-name = "vreg_l6m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2896000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7m_2p2: ldo7 { + regulator-name = "vreg_l7m_2p2"; + regulator-min-microvolt = <2200000>; + regulator-max-microvolt = <2296000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-9 { + compatible = "qcom,pm8010-rpmh-regulators"; + qcom,pmic-id = "N_E1"; + + vreg_l1n_0p8: ldo1 { + regulator-name = "vreg_l1n_0p8"; + regulator-min-microvolt = <720000>; + regulator-max-microvolt = <896000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2n_1p2: ldo2 { + regulator-name = "vreg_l2n_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3n_1p8: ldo3 { + regulator-name = "vreg_l3n_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4n_1p8: ldo4 { + regulator-name = "vreg_l4n_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5n_3p3: ldo5 { + regulator-name = "vreg_l5n_3p3"; + regulator-min-microvolt = <3296000>; + regulator-max-microvolt = <3304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6n_2p8: ldo6 { + regulator-name = "vreg_l6n_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7n_3p3: ldo7 { + regulator-name = "vreg_l7n_3p3"; + regulator-min-microvolt = <3296000>; + regulator-max-microvolt = <3304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; +}; + +&pcie0 { + status = "okay"; +}; + +&pcie0_phy { + vdda-phy-supply = <&vreg_l1i_0p8>; + vdda-pll-supply = <&vreg_l3d_1p2>; + + status = "okay"; +}; + +&pcie0_port0 { + wake-gpios = <&tlmm 104 GPIO_ACTIVE_LOW>; + reset-gpios = <&tlmm 102 GPIO_ACTIVE_LOW>; +}; + +&pcie1 { + status = "okay"; +}; + +&pcie1_phy { + vdda-phy-supply = <&vreg_l1i_0p8>; + vdda-pll-supply = <&vreg_l3d_1p2>; + + status = "okay"; +}; + +&pcie1_port0 { + wake-gpios = <&tlmm 222 GPIO_ACTIVE_LOW>; + reset-gpios = <&tlmm 220 GPIO_ACTIVE_LOW>; +}; + +&pmh0101_flash { + status = "okay"; + + led-0 { + function = LED_FUNCTION_FLASH; + function-enumerator = <0>; + color = <LED_COLOR_ID_YELLOW>; + led-sources = <1>, <4>; + led-max-microamp = <500000>; + flash-max-microamp = <2000000>; + flash-max-timeout-us = <1280000>; + }; + + led-1 { + function = LED_FUNCTION_FLASH; + function-enumerator = <1>; + color = <LED_COLOR_ID_WHITE>; + led-sources = <2>, <3>; + led-max-microamp = <500000>; + flash-max-microamp = <2000000>; + flash-max-timeout-us = <1280000>; + }; +}; + +&pmh0101_pwm { + status = "okay"; + + multi-led { + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_STATUS; + + #address-cells = <1>; + #size-cells = <0>; + + led@1 { + reg = <1>; + color = <LED_COLOR_ID_RED>; + }; + + led@2 { + reg = <2>; + color = <LED_COLOR_ID_GREEN>; + }; + + led@3 { + reg = <3>; + color = <LED_COLOR_ID_BLUE>; + }; + }; +}; + +&pmh0104_c_e0_gpios { + sd_card_eldo_en: sd-card-eldo-en-state { + pins = "gpio5"; + function = "normal"; + input-disable; + output-low; + power-source = <0>; + qcom,drive-strength = <PMIC_GPIO_STRENGTH_HIGH>; + }; +}; + +&pmih0108_e1_eusb2_repeater { + vdd18-supply = <&vreg_l15b_1p8>; + vdd3-supply = <&vreg_l5b_3p1>; +}; + +&pon_resin { + linux,code = <KEY_VOLUMEDOWN>; + + status = "okay"; +}; + +&remoteproc_adsp { + firmware-name = "qcom/hawi/adsp.mbn", + "qcom/hawi/adsp_dtb.mbn"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/hawi/cdsp.mbn", + "qcom/hawi/cdsp_dtb.mbn"; + + status = "okay"; +}; + +&remoteproc_mpss { + firmware-name = "qcom/hawi/modem.mbn", + "qcom/hawi/modem_dtb.mbn"; + + status = "okay"; +}; + +&remoteproc_soccp { + firmware-name = "qcom/hawi/soccp.mbn", + "qcom/hawi/soccp_dtb.mbn"; +}; + +&sdhc_2 { + cd-gpios = <&tlmm 55 GPIO_ACTIVE_LOW>; + + vmmc-supply = <&sdcard_vdd_3p0>; + vqmmc-supply = <&vreg_l16b_2p9>; + + bus-width = <4>; + no-sdio; + no-mmc; + + pinctrl-0 = <&sdc2_default>; + pinctrl-1 = <&sdc2_sleep>; + pinctrl-names = "default", "sleep"; + + status = "okay"; +}; + +&tlmm { + gpio-reserved-ranges = <36 4>, /* NFC eSE SPI */ + <74 1>, /* eSE */ + <119 2>, /* SoCCP */ + <144 2>; /* CXM UART */ + + key_vol_up_default: key-vol-up-default-state { + pins = "gpio101"; + function = "gpio"; + output-disable; + bias-pull-up; + }; +}; + +&uart7 { + status = "okay"; +}; + +&ufs_mem_hc { + reset-gpios = <&tlmm 226 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l9b_2p5>; + vcc-max-microamp = <1200000>; + + vccq-supply = <&vreg_l4g_1p2>; + vccq-max-microamp = <1200000>; + + status = "okay"; +}; + +&ufs_mem_phy { + vdda-phy-supply = <&vreg_l3f_0p9>; + vdda-pll-supply = <&vreg_l3d_1p2>; + + status = "okay"; +}; + +&usb_1 { + dr_mode = "otg"; + usb-role-switch; + + status = "okay"; +}; + +&usb_1_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in>; +}; + +&usb_1_hsphy { + vdd-supply = <&vreg_l4f_0p8>; + vdda12-supply = <&vreg_l3d_1p2>; + + phys = <&pmih0108_e1_eusb2_repeater>; + + status = "okay"; +}; + +&usb_dp_qmpphy { + vdda-phy-supply = <&vreg_l4f_0p8>; + vdda-pll-supply = <&vreg_l3d_1p2>; + + status = "okay"; +}; + +&usb_dp_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in>; +};
diff --git a/arch/arm64/boot/dts/qcom/hawi.dtsi b/arch/arm64/boot/dts/qcom/hawi.dtsi new file mode 100644 index 0000000..6b0a0ff --- /dev/null +++ b/arch/arm64/boot/dts/qcom/hawi.dtsi
@@ -0,0 +1,6844 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include <dt-bindings/clock/qcom,hawi-camcc.h> +#include <dt-bindings/clock/qcom,hawi-gcc.h> +#include <dt-bindings/clock/qcom,hawi-gpucc.h> +#include <dt-bindings/clock/qcom,hawi-tcsrcc.h> +#include <dt-bindings/clock/qcom,hawi-videocc.h> +#include <dt-bindings/clock/qcom,kaanapali-cambistmclkcc.h> +#include <dt-bindings/clock/qcom,kaanapali-gxclkctl.h> +#include <dt-bindings/clock/qcom,rpmh.h> +#include <dt-bindings/dma/qcom-gpi.h> +#include <dt-bindings/interconnect/qcom,hawi-rpmh.h> +#include <dt-bindings/interconnect/qcom,icc.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/mailbox/qcom-ipcc.h> +#include <dt-bindings/phy/phy-qcom-qmp.h> +#include <dt-bindings/power/qcom,rpmhpd.h> +#include <dt-bindings/power/qcom-rpmpd.h> +#include <dt-bindings/soc/qcom,rpmh-rsc.h> + +#include "hawi-ipcc.h" + +/ { + interrupt-parent = <&intc>; + + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu6: cpu@0 { + device_type = "cpu"; + compatible = "qcom,oryon-3-0"; + reg = <0x0 0x0>; + enable-method = "psci"; + next-level-cache = <&l2_0>; + power-domains = <&cpu_pd6>, <&scmi_perf 0>; + power-domain-names = "psci", "perf"; + #cooling-cells = <2>; + }; + + cpu7: cpu@100 { + device_type = "cpu"; + compatible = "qcom,oryon-3-0"; + reg = <0x0 0x100>; + enable-method = "psci"; + next-level-cache = <&l2_0>; + power-domains = <&cpu_pd7>, <&scmi_perf 0>; + power-domain-names = "psci", "perf"; + #cooling-cells = <2>; + }; + + cpu3: cpu@200 { + device_type = "cpu"; + compatible = "qcom,oryon-3-1"; + reg = <0x0 0x200>; + enable-method = "psci"; + next-level-cache = <&l2_0>; + power-domains = <&cpu_pd3>, <&scmi_perf 2>; + power-domain-names = "psci", "perf"; + #cooling-cells = <2>; + }; + + cpu0: cpu@300 { + device_type = "cpu"; + compatible = "qcom,oryon-3-2"; + reg = <0x0 0x300>; + enable-method = "psci"; + next-level-cache = <&l2_0>; + power-domains = <&cpu_pd0>, <&scmi_perf 1>; + power-domain-names = "psci", "perf"; + #cooling-cells = <2>; + + l2_0: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; + }; + }; + + cpu4: cpu@400 { + device_type = "cpu"; + compatible = "qcom,oryon-3-1"; + reg = <0x0 0x400>; + enable-method = "psci"; + next-level-cache = <&l2_0>; + power-domains = <&cpu_pd4>, <&scmi_perf 2>; + power-domain-names = "psci", "perf"; + #cooling-cells = <2>; + }; + + cpu1: cpu@500 { + device_type = "cpu"; + compatible = "qcom,oryon-3-2"; + reg = <0x0 0x500>; + enable-method = "psci"; + next-level-cache = <&l2_0>; + power-domains = <&cpu_pd1>, <&scmi_perf 1>; + power-domain-names = "psci", "perf"; + #cooling-cells = <2>; + }; + + cpu5: cpu@600 { + device_type = "cpu"; + compatible = "qcom,oryon-3-1"; + reg = <0x0 0x600>; + enable-method = "psci"; + next-level-cache = <&l2_0>; + power-domains = <&cpu_pd5>, <&scmi_perf 2>; + power-domain-names = "psci", "perf"; + #cooling-cells = <2>; + }; + + cpu2: cpu@700 { + device_type = "cpu"; + compatible = "qcom,oryon-3-2"; + reg = <0x0 0x700>; + enable-method = "psci"; + next-level-cache = <&l2_0>; + power-domains = <&cpu_pd2>, <&scmi_perf 1>; + power-domain-names = "psci", "perf"; + #cooling-cells = <2>; + }; + + cpu-map { + cluster0 { + core0 { + cpu = <&cpu0>; + }; + + core1 { + cpu = <&cpu1>; + }; + + core2 { + cpu = <&cpu2>; + }; + }; + + cluster1 { + core0 { + cpu = <&cpu3>; + }; + + core1 { + cpu = <&cpu4>; + }; + + core2 { + cpu = <&cpu5>; + }; + }; + + cluster2 { + core0 { + cpu = <&cpu6>; + }; + + core1 { + cpu = <&cpu7>; + }; + }; + }; + + domain-idle-states { + cluster_cl5: cluster-sleep-0 { + compatible = "domain-idle-state"; + arm,psci-suspend-param = <0x01000054>; + entry-latency-us = <2150>; + exit-latency-us = <1983>; + min-residency-us = <17845>; + }; + + domain_ss3: domain-sleep-0 { + compatible = "domain-idle-state"; + arm,psci-suspend-param = <0x0200c354>; + entry-latency-us = <2800>; + exit-latency-us = <4400>; + min-residency-us = <19012>; + }; + }; + + idle-states { + entry-method = "psci"; + + cluster0_1_c4: cpu-sleep-0 { + compatible = "arm,idle-state"; + idle-state-name = "retention"; + arm,psci-suspend-param = <0x00000004>; + entry-latency-us = <93>; + exit-latency-us = <129>; + min-residency-us = <1925>; + }; + + cluster2_c4: cpu-sleep-1 { + compatible = "arm,idle-state"; + idle-state-name = "retention"; + entry-latency-us = <172>; + exit-latency-us = <130>; + min-residency-us = <2356>; + arm,psci-suspend-param = <0x00000004>; + }; + }; + }; + + firmware { + scm { + compatible = "qcom,scm-hawi", "qcom,scm"; + qcom,dload-mode = <&tcsr 0x2000>; + interconnects = <&aggre_noc MASTER_CRYPTO QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + sram = <&minidump_config>; + }; + + scmi { + compatible = "arm,scmi"; + mboxes = <&pdp0_mbox 0>, <&pdp0_mbox 1>; + mbox-names = "tx", "rx"; + shmem = <&pdp_tx>, <&pdp_rx>; + #address-cells = <1>; + #size-cells = <0>; + + scmi_perf: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + }; + }; + + clk_virt: interconnect-0 { + compatible = "qcom,hawi-clk-virt"; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + mc_virt: interconnect-1 { + compatible = "qcom,hawi-mc-virt"; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + memory@a0000000 { + device_type = "memory"; + /* We expect the bootloader to fill in the size */ + reg = <0x0 0xa0000000 0x0 0x0>; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + + cpu_pd0: power-domain-cpu0 { + #power-domain-cells = <0>; + power-domains = <&cluster_pd>; + domain-idle-states = <&cluster0_1_c4>; + }; + + cpu_pd1: power-domain-cpu1 { + #power-domain-cells = <0>; + power-domains = <&cluster_pd>; + domain-idle-states = <&cluster0_1_c4>; + }; + + cpu_pd2: power-domain-cpu2 { + #power-domain-cells = <0>; + power-domains = <&cluster_pd>; + domain-idle-states = <&cluster0_1_c4>; + }; + + cpu_pd3: power-domain-cpu3 { + #power-domain-cells = <0>; + power-domains = <&cluster_pd>; + domain-idle-states = <&cluster0_1_c4>; + }; + + cpu_pd4: power-domain-cpu4 { + #power-domain-cells = <0>; + power-domains = <&cluster_pd>; + domain-idle-states = <&cluster0_1_c4>; + }; + + cpu_pd5: power-domain-cpu5 { + #power-domain-cells = <0>; + power-domains = <&cluster_pd>; + domain-idle-states = <&cluster0_1_c4>; + }; + + cpu_pd6: power-domain-cpu6 { + #power-domain-cells = <0>; + power-domains = <&cluster_pd>; + domain-idle-states = <&cluster2_c4>; + }; + + cpu_pd7: power-domain-cpu7 { + #power-domain-cells = <0>; + power-domains = <&cluster_pd>; + domain-idle-states = <&cluster2_c4>; + }; + + cluster_pd: power-domain-cluster { + #power-domain-cells = <0>; + domain-idle-states = <&cluster_cl5>, + <&domain_ss3>; + }; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + cpucp_slc_mem_sub: cpucp@81230000 { + reg = <0x0 0x81230000 0x0 0x1000>; + no-map; + }; + + aop_cmd_db_mem: aop-cmd-db@81c60000 { + compatible = "qcom,cmd-db"; + reg = <0x0 0x81c60000 0x0 0x20000>; + no-map; + }; + + pdp_ns_shared_mem: pdp-ns-shared@81f00000 { + reg = <0x0 0x81f00000 0x0 0x100000>; + no-map; + }; + + smem_mem: smem@82700000 { + compatible = "qcom,smem"; + reg = <0x0 0x82700000 0x0 0x400000>; + hwlocks = <&tcsr_mutex 3>; + no-map; + }; + + dsm_partition_1_mem: dsm-partition-1@83500000 { + reg = <0x0 0x83500000 0x0 0x5180000>; + no-map; + }; + + dsm_partition_2_mem: dsm-partition-2@88680000 { + reg = <0x0 0x88680000 0x0 0x1700000>; + no-map; + }; + + mpss_mem: mpss@89e00000 { + reg = <0x0 0x89e00000 0x0 0xe600000>; + no-map; + }; + + q6_mpss_dtb_mem: q6-mpss-dtb@98400000 { + reg = <0x0 0x98400000 0x0 0x80000>; + no-map; + }; + + ipa_fw_mem: ipa-fw@99580000 { + reg = <0x0 0x99580000 0x0 0x10000>; + no-map; + }; + + ipa_gsi_mem: ipa-gsi@99590000 { + reg = <0x0 0x99590000 0x0 0xc000>; + no-map; + }; + + gpu_microcode_mem: gpu-microcode@9959c000 { + reg = <0x0 0x9959c000 0x0 0x4000>; + no-map; + }; + + camera_mem: camera@99600000 { + reg = <0x0 0x99600000 0x0 0x800000>; + no-map; + }; + + camera_2_mem: camera-2@99e00000 { + reg = <0x0 0x99e00000 0x0 0x800000>; + no-map; + }; + + video_mem: video@9a600000 { + reg = <0x0 0x9a600000 0x0 0x800000>; + no-map; + }; + + cvp_mem: cvp@9ae00000 { + reg = <0x0 0x9ae00000 0x0 0x800000>; + no-map; + }; + + cdsp_mem: cdsp@9b900000 { + reg = <0x0 0x9b900000 0x0 0x2000000>; + no-map; + }; + + q6_cdsp_dtb_mem: q6-cdsp-dtb@9d900000 { + reg = <0x0 0x9d900000 0x0 0x80000>; + no-map; + }; + + dcp_dtb_mem: dcp-dtb@a0000000 { + reg = <0x0 0xa0000000 0x0 0x80000>; + no-map; + }; + + dcp_mem: dcp@a0080000 { + reg = <0x0 0xa0080000 0x0 0x400000>; + no-map; + }; + + soccp_mem: soccp@a0480000 { + reg = <0x0 0xa0480000 0x0 0x500000>; + no-map; + }; + + soccp_dtb_mem: soccp-dtb@a0980000 { + reg = <0x0 0xa0980000 0x0 0x40000>; + no-map; + }; + + q6_adsp_dtb_mem: q6-adsp-dtb@a1380000 { + reg = <0x0 0xa1380000 0x0 0x80000>; + no-map; + }; + + adspslpi_mem: adspslpi@a1400000 { + reg = <0x0 0xa1400000 0x0 0x5f00000>; + no-map; + }; + + mpss_crashdump_overlay_mem: mpss-crashdump-overlay@bd500000 { + reg = <0x0 0xbd500000 0x0 0xf00000>; + no-map; + }; + }; + + smp2p-adsp { + compatible = "qcom,smp2p"; + + interrupts-extended = <&ipcc IPCC_MPROC_LPASS + IPCC_MPROC_SIGNAL_SMP2P + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_LPASS + IPCC_MPROC_SIGNAL_SMP2P>; + + qcom,smem = <443>, <429>; + qcom,local-pid = <0>; + qcom,remote-pid = <2>; + + smp2p_adsp_out: master-kernel { + qcom,entry-name = "master-kernel"; + #qcom,smem-state-cells = <1>; + }; + + smp2p_adsp_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + smp2p-cdsp { + compatible = "qcom,smp2p"; + + interrupts-extended = <&ipcc IPCC_MPROC_CDSP + IPCC_MPROC_SIGNAL_SMP2P + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_CDSP + IPCC_MPROC_SIGNAL_SMP2P>; + + qcom,smem = <94>, <432>; + qcom,local-pid = <0>; + qcom,remote-pid = <5>; + + smp2p_cdsp_out: master-kernel { + qcom,entry-name = "master-kernel"; + #qcom,smem-state-cells = <1>; + }; + + smp2p_cdsp_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + smp2p-modem { + compatible = "qcom,smp2p"; + + interrupts-extended = <&ipcc IPCC_MPROC_MPSS + IPCC_MPROC_SIGNAL_SMP2P + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_MPSS + IPCC_MPROC_SIGNAL_SMP2P>; + + qcom,smem = <435>, <428>; + + qcom,local-pid = <0>; + qcom,remote-pid = <1>; + + smp2p_modem_out: master-kernel { + qcom,entry-name = "master-kernel"; + #qcom,smem-state-cells = <1>; + }; + + smp2p_modem_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + smp2p-soccp { + compatible = "qcom,smp2p"; + + interrupts-extended = <&ipcc IPCC_MPROC_SOCCP + IPCC_MPROC_SIGNAL_SMP2P + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_SOCCP + IPCC_MPROC_SIGNAL_SMP2P>; + + qcom,smem = <617>, <616>; + qcom,local-pid = <0>; + qcom,remote-pid = <19>; + + soccp_smp2p_out: master-kernel { + qcom,entry-name = "master-kernel"; + #qcom,smem-state-cells = <1>; + }; + + soccp_smp2p_in: slave-kernel { + qcom,entry-name = "slave-kernel"; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; + + soc@0 { + compatible = "simple-bus"; + + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>; + ranges = <0x0 0x0 0x0 0x0 0x10 0x0>; + + gcc: clock-controller@100000 { + compatible = "qcom,hawi-gcc"; + reg = <0x0 0x00100000 0x0 0x1f4200>; + + clocks = <&bi_tcxo_div2>, + <&bi_tcxo_ao_div2>, + <&sleep_clk>, + <&pcie0_phy>, + <&pcie1_phy>, + <&ufs_mem_phy 0>, + <&ufs_mem_phy 1>, + <&ufs_mem_phy 2>, + <&usb_dp_qmpphy QMP_USB43DP_USB3_PIPE_CLK>; + + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + gpi_dma2: dma-controller@800000 { + compatible = "qcom,hawi-gpi-dma", "qcom,sm6350-gpi-dma"; + reg = <0x0 0x00800000 0x0 0x60000>; + + interrupts = <GIC_ESPI 343 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 344 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 345 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 346 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 347 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 912 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 913 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 914 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 915 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 916 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 917 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 918 IRQ_TYPE_LEVEL_HIGH>; + + dma-channels = <12>; + dma-channel-mask = <0x1f>; + #dma-cells = <3>; + + iommus = <&apps_smmu 0x36 0x0>; + dma-coherent; + }; + + qupv3_2: geniqup@8c0000 { + compatible = "qcom,geni-se-qup"; + reg = <0x0 0x008c0000 0x0 0x2000>; + + clocks = <&gcc GCC_QUPV3_WRAP_2_M_AHB_CLK>, + <&gcc GCC_QUPV3_WRAP_2_S_AHB_CLK>; + clock-names = "m-ahb", + "s-ahb"; + + iommus = <&apps_smmu 0x23 0x0>; + + dma-coherent; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + i2c8: i2c@880000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00880000 0x0 0x4000>; + + interrupts = <GIC_ESPI 417 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP2_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma2 0 0 QCOM_GPI_I2C>, + <&gpi_dma2 1 0 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c8_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi8: spi@880000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00880000 0x0 0x4000>; + + interrupts = <GIC_ESPI 417 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP2_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma2 0 0 QCOM_GPI_SPI>, + <&gpi_dma2 1 0 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi8_data_clk>, <&qup_spi8_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart8: serial@880000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00880000 0x0 0x4000>; + + interrupts = <GIC_ESPI 417 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP2_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart8_default>, <&qup_uart8_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c9: i2c@884000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00884000 0x0 0x4000>; + + interrupts = <GIC_ESPI 418 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP2_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma2 0 1 QCOM_GPI_I2C>, + <&gpi_dma2 1 1 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c9_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi9: spi@884000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00884000 0x0 0x4000>; + + interrupts = <GIC_ESPI 418 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP2_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma2 0 1 QCOM_GPI_SPI>, + <&gpi_dma2 1 1 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi9_data_clk>, <&qup_spi9_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart9: serial@884000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00884000 0x0 0x4000>; + + interrupts = <GIC_ESPI 418 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP2_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart9_default>, <&qup_uart9_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c10: i2c@888000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00888000 0x0 0x4000>; + + interrupts = <GIC_ESPI 419 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP2_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma2 0 2 QCOM_GPI_I2C>, + <&gpi_dma2 1 2 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c10_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi10: spi@888000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00888000 0x0 0x4000>; + + interrupts = <GIC_ESPI 419 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP2_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma2 0 2 QCOM_GPI_SPI>, + <&gpi_dma2 1 2 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi10_data_clk>, <&qup_spi10_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart10: serial@888000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00888000 0x0 0x4000>; + + interrupts = <GIC_ESPI 419 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP2_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart10_default>, <&qup_uart10_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c11: i2c@88c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x0088c000 0x0 0x4000>; + + interrupts = <GIC_ESPI 420 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma2 0 3 QCOM_GPI_I2C>, + <&gpi_dma2 1 3 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c11_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi11: spi@88c000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x0088c000 0x0 0x4000>; + + interrupts = <GIC_ESPI 420 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma2 0 3 QCOM_GPI_SPI>, + <&gpi_dma2 1 3 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi11_data_clk>, <&qup_spi11_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart11: serial@88c000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x0088c000 0x0 0x4000>; + + interrupts = <GIC_ESPI 420 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart11_default>, <&qup_uart11_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c12: i2c@890000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00890000 0x0 0x4000>; + + interrupts = <GIC_ESPI 421 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP2_S4_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma2 0 4 QCOM_GPI_I2C>, + <&gpi_dma2 1 4 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c12_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart12: serial@890000 { + compatible = "qcom,geni-debug-uart"; + reg = <0x0 0x00890000 0x0 0x4000>; + + interrupts = <GIC_ESPI 421 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP2_S4_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart12_default>; + pinctrl-names = "default"; + + status = "disabled"; + }; + }; + + i2c_master_hub: geniqup@9c0000 { + compatible = "qcom,geni-se-i2c-master-hub"; + reg = <0x0 0x009c0000 0x0 0x2000>; + + clocks = <&gcc GCC_QUPV3_I2C_S_AHB_CLK>; + clock-names = "s-ahb"; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + status = "disabled"; + + i2c_hub_0: i2c@980000 { + compatible = "qcom,geni-i2c-master-hub"; + reg = <0x0 0x00980000 0x0 0x4000>; + + interrupts = <GIC_ESPI 528 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_I2C_S0_CLK>, + <&gcc GCC_QUPV3_I2C_CORE_CLK>; + clock-names = "se", + "core"; + + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&hub_i2c0_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c_hub_1: i2c@984000 { + compatible = "qcom,geni-i2c-master-hub"; + reg = <0x0 0x00984000 0x0 0x4000>; + + interrupts = <GIC_ESPI 529 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_I2C_S1_CLK>, + <&gcc GCC_QUPV3_I2C_CORE_CLK>; + clock-names = "se", + "core"; + + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&hub_i2c1_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c_hub_2: i2c@988000 { + compatible = "qcom,geni-i2c-master-hub"; + reg = <0x0 0x00988000 0x0 0x4000>; + + interrupts = <GIC_ESPI 530 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_I2C_S2_CLK>, + <&gcc GCC_QUPV3_I2C_CORE_CLK>; + clock-names = "se", + "core"; + + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&hub_i2c2_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c_hub_3: i2c@98c000 { + compatible = "qcom,geni-i2c-master-hub"; + reg = <0x0 0x0098c000 0x0 0x4000>; + + interrupts = <GIC_ESPI 531 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_I2C_S3_CLK>, + <&gcc GCC_QUPV3_I2C_CORE_CLK>; + clock-names = "se", + "core"; + + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&hub_i2c3_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + i2c_hub_4: i2c@990000 { + compatible = "qcom,geni-i2c-master-hub"; + reg = <0x0 0x00990000 0x0 0x4000>; + + interrupts = <GIC_ESPI 532 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_I2C_S4_CLK>, + <&gcc GCC_QUPV3_I2C_CORE_CLK>; + clock-names = "se", + "core"; + + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_I2C QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&hub_i2c4_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + }; + + gpi_dma1: dma-controller@a00000 { + compatible = "qcom,hawi-gpi-dma", "qcom,sm6350-gpi-dma"; + reg = <0x0 0x00a00000 0x0 0x60000>; + + interrupts = <GIC_ESPI 900 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 901 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 902 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 903 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 904 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 905 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 906 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 907 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 908 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 909 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 910 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 911 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 944 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 945 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 946 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 947 IRQ_TYPE_LEVEL_HIGH>; + + dma-channels = <16>; + dma-channel-mask = <0x7f>; + #dma-cells = <3>; + + iommus = <&apps_smmu 0xb6 0x0>; + dma-coherent; + }; + + qupv3_1: geniqup@ac0000 { + compatible = "qcom,geni-se-qup"; + reg = <0x0 0x00ac0000 0x0 0x2000>; + + clocks = <&gcc GCC_QUPV3_WRAP_1_M_AXI_CLK>, + <&gcc GCC_QUPV3_WRAP_1_S_AHB_CLK>; + clock-names = "m-ahb", + "s-ahb"; + + iommus = <&apps_smmu 0xa3 0x0>; + + dma-coherent; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + i2c0: i2c@a80000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a80000 0x0 0x4000>; + + interrupts = <GIC_ESPI 892 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma1 0 0 QCOM_GPI_I2C>, + <&gpi_dma1 1 0 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c0_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi0: spi@a80000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a80000 0x0 0x4000>; + + interrupts = <GIC_ESPI 892 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma1 0 0 QCOM_GPI_SPI>, + <&gpi_dma1 1 0 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi0_data_clk>, <&qup_spi0_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart0: serial@a80000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00a80000 0x0 0x4000>; + + interrupts = <GIC_ESPI 892 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart0_default>, <&qup_uart0_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c1: i2c@a84000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a84000 0x0 0x4000>; + + interrupts = <GIC_ESPI 893 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma1 0 1 QCOM_GPI_I2C>, + <&gpi_dma1 1 1 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c1_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi1: spi@a84000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a84000 0x0 0x4000>; + + interrupts = <GIC_ESPI 893 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma1 0 1 QCOM_GPI_SPI>, + <&gpi_dma1 1 1 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi1_data_clk>, <&qup_spi1_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart1: serial@a84000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00a84000 0x0 0x4000>; + + interrupts = <GIC_ESPI 893 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart1_default>, <&qup_uart1_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c2: i2c@a88000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a88000 0x0 0x4000>; + + interrupts = <GIC_ESPI 894 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma1 0 2 QCOM_GPI_I2C>, + <&gpi_dma1 1 2 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c2_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi2: spi@a88000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a88000 0x0 0x4000>; + + interrupts = <GIC_ESPI 894 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma1 0 2 QCOM_GPI_SPI>, + <&gpi_dma1 1 2 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi2_data_clk>, <&qup_spi2_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart2: serial@a88000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00a88000 0x0 0x4000>; + + interrupts = <GIC_ESPI 894 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart2_default>, <&qup_uart2_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c3: i2c@a8c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a8c000 0x0 0x4000>; + + interrupts = <GIC_ESPI 895 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma1 0 3 QCOM_GPI_I2C>, + <&gpi_dma1 1 3 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c3_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi3: spi@a8c000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a8c000 0x0 0x4000>; + + interrupts = <GIC_ESPI 895 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma1 0 3 QCOM_GPI_SPI>, + <&gpi_dma1 1 3 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi3_data_clk>, <&qup_spi3_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart3: serial@a8c000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00a8c000 0x0 0x4000>; + + interrupts = <GIC_ESPI 895 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart3_default>, <&qup_uart3_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c4: i2c@a90000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a90000 0x0 0x4000>; + + interrupts = <GIC_ESPI 896 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma1 0 4 QCOM_GPI_I2C>, + <&gpi_dma1 1 4 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c4_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi4: spi@a90000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a90000 0x0 0x4000>; + + interrupts = <GIC_ESPI 896 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma1 0 4 QCOM_GPI_SPI>, + <&gpi_dma1 1 4 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi4_data_clk>, <&qup_spi4_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart4: serial@a90000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00a90000 0x0 0x4000>; + + interrupts = <GIC_ESPI 896 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart4_default>, <&qup_uart4_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c5: i2c@a94000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a94000 0x0 0x4000>; + + interrupts = <GIC_ESPI 897 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma1 0 5 QCOM_GPI_I2C>, + <&gpi_dma1 1 5 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c5_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi5: spi@a94000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a94000 0x0 0x4000>; + + interrupts = <GIC_ESPI 897 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma1 0 5 QCOM_GPI_SPI>, + <&gpi_dma1 1 5 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi5_data_clk>, <&qup_spi5_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart5: serial@a94000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00a94000 0x0 0x4000>; + + interrupts = <GIC_ESPI 897 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S5_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart5_default>, <&qup_uart5_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c6: i2c@a98000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a98000 0x0 0x4000>; + + interrupts = <GIC_ESPI 898 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma1 0 6 QCOM_GPI_I2C>, + <&gpi_dma1 1 6 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c6_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi6: spi@a98000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a98000 0x0 0x4000>; + + interrupts = <GIC_ESPI 898 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma1 0 6 QCOM_GPI_SPI>, + <&gpi_dma1 1 6 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi6_data_clk>, <&qup_spi6_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart6: serial@a98000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00a98000 0x0 0x4000>; + + interrupts = <GIC_ESPI 898 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S6_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart6_default>, <&qup_uart6_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + uart7: serial@a9c000 { + compatible = "qcom,geni-debug-uart"; + reg = <0x0 0x00a9c000 0x0 0x4000>; + + interrupts = <GIC_ESPI 899 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP1_S7_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart7_default>; + pinctrl-names = "default"; + + status = "disabled"; + }; + }; + + remoteproc_soccp: remoteproc@d00000 { + compatible = "qcom,hawi-soccp-pas", "qcom,kaanapali-soccp-pas"; + reg = <0x0 0x00d00000 0x0 0x200000>; + + interrupts-extended = <&intc GIC_ESPI 231 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 0 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 1 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 2 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 3 IRQ_TYPE_EDGE_RISING>, + <&soccp_smp2p_in 9 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack", + "pong"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MX>; + power-domain-names = "cx", + "mx"; + + memory-region = <&soccp_mem>, + <&soccp_dtb_mem>; + + qcom,smem-states = <&soccp_smp2p_out 0>, + <&soccp_smp2p_out 8>; + qcom,smem-state-names = "stop", + "ping"; + + glink-edge { + interrupts-extended = <&ipcc IPCC_MPROC_SOCCP + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_SOCCP + IPCC_MPROC_SIGNAL_GLINK_QMP>; + + qcom,remote-pid = <19>; + label = "soccp"; + }; + }; + + aggre_noc: interconnect@f00000 { + compatible = "qcom,hawi-aggre1-noc"; + reg = <0x0 0x00f00000 0x0 0x54400>; + #interconnect-cells = <2>; + clocks = <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>, + <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>, + <&rpmhcc RPMH_IPA_CLK>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + usb_1_hsphy: phy@fe3000 { + compatible = "qcom,hawi-m31-eusb2-phy", "qcom,sm8750-m31-eusb2-phy"; + reg = <0x0 0x00fe3000 0x0 0x29c>; + + clocks = <&tcsrcc TCSR_USB2_CLKREF_EN>; + clock-names = "ref"; + + resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>; + + #phy-cells = <0>; + + status = "disabled"; + }; + + usb_dp_qmpphy: phy@fe8000 { + compatible = "qcom,hawi-qmp-usb3-dp-phy"; + reg = <0x0 0x00fe8000 0x0 0x4000>; + + clocks = <&gcc GCC_USB3_PRIM_PHY_AUX_CLK>, + <&tcsrcc TCSR_USB3_CLKREF_EN>, + <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>, + <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; + clock-names = "aux", + "ref", + "com_aux", + "usb3_pipe"; + + resets = <&gcc GCC_USB3_PHY_PRIM_BCR>, + <&gcc GCC_USB3_DP_PHY_PRIM_BCR>; + reset-names = "phy", + "common"; + + power-domains = <&gcc GCC_USB3_PHY_GDSC>; + + #clock-cells = <1>; + #phy-cells = <1>; + + orientation-switch; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_dp_qmpphy_out: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb_dp_qmpphy_usb_ss_in: endpoint { + remote-endpoint = <&usb_1_dwc3_ss>; + }; + }; + + port@2 { + reg = <2>; + + usb_dp_qmpphy_dp_in: endpoint { + }; + }; + }; + }; + + rng@10c3000 { + compatible = "qcom,hawi-trng", "qcom,trng"; + reg = <0x0 0x010c3000 0x0 0x1000>; + }; + + ipcc: mailbox@1106000 { + compatible = "qcom,hawi-ipcc", "qcom,ipcc"; + reg = <0x0 0x01106000 0x0 0x1000>; + + interrupts = <GIC_ESPI 310 IRQ_TYPE_LEVEL_HIGH>; + interrupt-controller; + #interrupt-cells = <3>; + + #mbox-cells = <2>; + }; + + cnoc_main: interconnect@1500000 { + compatible = "qcom,hawi-cnoc-main"; + reg = <0x0 0x01500000 0x0 0x20000>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + system_noc: interconnect@1680000 { + compatible = "qcom,hawi-system-noc"; + reg = <0x0 0x01680000 0x0 0x20080>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + pcie_anoc: interconnect@16c0000 { + compatible = "qcom,hawi-pcie-anoc"; + reg = <0x0 0x016c0000 0x0 0x12400>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + clocks = <&gcc GCC_AGGRE_NOC_PCIE_AXI_CLK>, + <&gcc GCC_CFG_NOC_PCIE_ANOC_AHB_CLK>; + }; + + cambistmclkcc: clock-controller@1760000 { + compatible = "qcom,hawi-cambistmclkcc", + "qcom,kaanapali-cambistmclkcc"; + reg = <0x0 0x01760000 0x0 0x6000>; + + clocks = <&gcc GCC_CAM_BIST_MCLK_AHB_CLK>, + <&bi_tcxo_div2>, + <&bi_tcxo_ao_div2>, + <&sleep_clk>; + + power-domains = <&rpmhpd RPMHPD_MMCX>, + <&rpmhpd RPMHPD_MX>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + + #clock-cells = <1>; + #reset-cells = <1>; + }; + + mmss_noc: interconnect@1780000 { + compatible = "qcom,hawi-mmss-noc"; + reg = <0x0 0x01780000 0x0 0x5f800>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + gpi_dma3: dma-controller@1900000 { + compatible = "qcom,hawi-gpi-dma", "qcom,sm6350-gpi-dma"; + reg = <0x0 0x01900000 0x0 0x60000>; + + interrupts = <GIC_ESPI 652 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 653 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 654 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 655 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 656 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 657 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 658 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 659 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 660 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 661 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 662 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 663 IRQ_TYPE_LEVEL_HIGH>; + + dma-channels = <12>; + dma-channel-mask = <0x1f>; + #dma-cells = <3>; + + iommus = <&apps_smmu 0xd6 0x0>; + dma-coherent; + }; + + qupv3_3: geniqup@19c0000 { + compatible = "qcom,geni-se-qup"; + reg = <0x0 0x019c0000 0x0 0x2000>; + + clocks = <&gcc GCC_QUPV3_WRAP_3_M_AHB_CLK>, + <&gcc GCC_QUPV3_WRAP_3_S_AHB_CLK>; + clock-names = "m-ahb", + "s-ahb"; + + iommus = <&apps_smmu 0xc3 0x0>; + + dma-coherent; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + i2c13: i2c@1980000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01980000 0x0 0x4000>; + + interrupts = <GIC_ESPI 437 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP3_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_3 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma3 0 0 QCOM_GPI_I2C>, + <&gpi_dma3 1 0 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c13_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart13: serial@1980000 { + compatible = "qcom,geni-debug-uart"; + reg = <0x0 0x01980000 0x0 0x4000>; + + interrupts = <GIC_ESPI 437 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP3_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart13_default>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c14: i2c@1984000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01984000 0x0 0x4000>; + + interrupts = <GIC_ESPI 647 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP3_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_3 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma3 0 1 QCOM_GPI_I2C>, + <&gpi_dma3 1 1 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c14_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi14: spi@1984000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x01984000 0x0 0x4000>; + + interrupts = <GIC_ESPI 647 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP3_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma3 0 1 QCOM_GPI_SPI>, + <&gpi_dma3 1 1 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi14_data_clk>, <&qup_spi14_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart14: serial@1984000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x01984000 0x0 0x4000>; + + interrupts = <GIC_ESPI 647 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP3_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart14_default>, <&qup_uart14_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c15: i2c@1988000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01988000 0x0 0x4000>; + + interrupts = <GIC_ESPI 648 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP3_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_3 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma3 0 2 QCOM_GPI_I2C>, + <&gpi_dma3 1 2 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c15_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi15: spi@1988000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x01988000 0x0 0x4000>; + + interrupts = <GIC_ESPI 648 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP3_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma3 0 2 QCOM_GPI_SPI>, + <&gpi_dma3 1 2 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi15_data_clk>, <&qup_spi15_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart15: serial@1988000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x01988000 0x0 0x4000>; + + interrupts = <GIC_ESPI 648 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP3_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart15_default>, <&qup_uart15_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c16: i2c@198c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x0198c000 0x0 0x4000>; + + interrupts = <GIC_ESPI 649 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP3_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_3 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma3 0 3 QCOM_GPI_I2C>, + <&gpi_dma3 1 3 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c16_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi16: spi@198c000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x0198c000 0x0 0x4000>; + + interrupts = <GIC_ESPI 649 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP3_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma3 0 3 QCOM_GPI_SPI>, + <&gpi_dma3 1 3 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi16_data_clk>, <&qup_spi16_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart16: serial@198c000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x0198c000 0x0 0x4000>; + + interrupts = <GIC_ESPI 649 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP3_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart16_default>, <&qup_uart16_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c17: i2c@1990000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01990000 0x0 0x4000>; + + interrupts = <GIC_ESPI 650 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP3_S4_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_3 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma3 0 4 QCOM_GPI_I2C>, + <&gpi_dma3 1 4 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c17_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi17: spi@1990000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x01990000 0x0 0x4000>; + + interrupts = <GIC_ESPI 650 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP3_S4_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma3 0 4 QCOM_GPI_SPI>, + <&gpi_dma3 1 4 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi17_data_clk>, <&qup_spi17_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart17: serial@1990000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x01990000 0x0 0x4000>; + + interrupts = <GIC_ESPI 650 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP3_S4_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart17_default>, <&qup_uart17_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + uart18: serial@1994000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x01994000 0x0 0x4000>; + + interrupts = <GIC_ESPI 651 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP3_S5_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_3 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart18_default>, <&qup_uart18_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + }; + + gpi_dma4: dma-controller@1a00000 { + compatible = "qcom,hawi-gpi-dma", "qcom,sm6350-gpi-dma"; + reg = <0x0 0x01a00000 0x0 0x60000>; + + interrupts = <GIC_ESPI 568 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 569 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 570 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 571 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 572 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 573 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 574 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 575 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 576 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 577 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 578 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 579 IRQ_TYPE_LEVEL_HIGH>; + + dma-channels = <12>; + dma-channel-mask = <0x1f>; + #dma-cells = <3>; + + iommus = <&apps_smmu 0x136 0x0>; + dma-coherent; + }; + + qupv3_4: geniqup@1ac0000 { + compatible = "qcom,geni-se-qup"; + reg = <0x0 0x01ac0000 0x0 0x2000>; + + clocks = <&gcc GCC_QUPV3_WRAP_4_M_AHB_CLK>, + <&gcc GCC_QUPV3_WRAP_4_S_AHB_CLK>; + clock-names = "m-ahb", + "s-ahb"; + + iommus = <&apps_smmu 0x123 0x0>; + + dma-coherent; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + i2c19: i2c@1a80000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01a80000 0x0 0x4000>; + + interrupts = <GIC_ESPI 920 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP4_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_4 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma4 0 0 QCOM_GPI_I2C>, + <&gpi_dma4 1 0 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c19_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi19: spi@1a80000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x01a80000 0x0 0x4000>; + + interrupts = <GIC_ESPI 920 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP4_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma4 0 0 QCOM_GPI_SPI>, + <&gpi_dma4 1 0 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi19_data_clk>, <&qup_spi19_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart19: serial@1a80000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x01a80000 0x0 0x4000>; + + interrupts = <GIC_ESPI 920 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP4_S0_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart19_default>, <&qup_uart19_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c20: i2c@1a84000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01a84000 0x0 0x4000>; + + interrupts = <GIC_ESPI 921 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP4_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_4 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma4 0 1 QCOM_GPI_I2C>, + <&gpi_dma4 1 1 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c20_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi20: spi@1a84000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x01a84000 0x0 0x4000>; + + interrupts = <GIC_ESPI 921 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP4_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma4 0 1 QCOM_GPI_SPI>, + <&gpi_dma4 1 1 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi20_data_clk>, <&qup_spi20_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart20: serial@1a84000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x01a84000 0x0 0x4000>; + + interrupts = <GIC_ESPI 921 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP4_S1_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart20_default>, <&qup_uart20_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c21: i2c@1a88000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01a88000 0x0 0x4000>; + + interrupts = <GIC_ESPI 922 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP4_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_4 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma4 0 2 QCOM_GPI_I2C>, + <&gpi_dma4 1 2 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c21_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi21: spi@1a88000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x01a88000 0x0 0x4000>; + + interrupts = <GIC_ESPI 922 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP4_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + dmas = <&gpi_dma4 0 2 QCOM_GPI_SPI>, + <&gpi_dma4 1 2 QCOM_GPI_SPI>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_spi21_data_clk>, <&qup_spi21_cs>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart21: serial@1a88000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x01a88000 0x0 0x4000>; + + interrupts = <GIC_ESPI 922 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP4_S2_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart21_default>, <&qup_uart21_cts_rts>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c22: i2c@1a8c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01a8c000 0x0 0x4000>; + + interrupts = <GIC_ESPI 923 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP4_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_4 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma4 0 3 QCOM_GPI_I2C>, + <&gpi_dma4 1 3 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c22_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart22: serial@1a8c000 { + compatible = "qcom,geni-debug-uart"; + reg = <0x0 0x01a8c000 0x0 0x4000>; + + interrupts = <GIC_ESPI 923 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP4_S3_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart22_default>; + pinctrl-names = "default"; + + status = "disabled"; + }; + + i2c23: i2c@1a90000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x01a90000 0x0 0x4000>; + + interrupts = <GIC_ESPI 924 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP4_S4_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&aggre_noc MASTER_QUP_4 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + + dmas = <&gpi_dma4 0 4 QCOM_GPI_I2C>, + <&gpi_dma4 1 4 QCOM_GPI_I2C>; + dma-names = "tx", + "rx"; + + pinctrl-0 = <&qup_i2c23_data_clk>; + pinctrl-names = "default"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart23: serial@1a90000 { + compatible = "qcom,geni-debug-uart"; + reg = <0x0 0x01a90000 0x0 0x4000>; + + interrupts = <GIC_ESPI 924 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_QUPV3_WRAP4_S4_CLK>; + clock-names = "se"; + + interconnects = <&clk_virt MASTER_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_4 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_4 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", + "qup-config"; + + pinctrl-0 = <&qup_uart23_default>; + pinctrl-names = "default"; + + status = "disabled"; + }; + }; + + pcie0: pcie@1c00000 { + device_type = "pci"; + compatible = "qcom,hawi-pcie"; + reg = <0x0 0x01c00000 0x0 0x3000>, + <0x0 0x40000000 0x0 0xf1d>, + <0x0 0x40000f20 0x0 0xa8>, + <0x0 0x40001000 0x0 0x1000>, + <0x0 0x40100000 0x0 0x100000>, + <0x0 0x01c03000 0x0 0x1000>; + reg-names = "parf", + "dbi", + "elbi", + "atu", + "config", + "mhi"; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x100000>, + <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x23d00000>; + + interrupts = <GIC_ESPI 205 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 206 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 207 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 208 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 209 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 210 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 211 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 212 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 204 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + + clocks = <&gcc GCC_PCIE_0_AUX_CLK>, + <&gcc GCC_PCIE_0_CFG_AHB_CLK>, + <&gcc GCC_PCIE_0_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_0_SLV_AXI_CLK>, + <&gcc GCC_PCIE_0_SLV_Q2A_AXI_CLK>, + <&gcc GCC_AGGRE_NOC_PCIE_AXI_CLK>, + <&gcc GCC_CNOC_PCIE_SF_AXI_CLK>; + clock-names = "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a", + "noc_aggr", + "cnoc_sf_axi"; + + resets = <&gcc GCC_PCIE_0_BCR>, + <&gcc GCC_PCIE_0_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; + + interconnects = <&pcie_anoc MASTER_PCIE_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &cnoc_main SLAVE_PCIE_0 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "pcie-mem", + "cpu-pcie"; + + power-domains = <&gcc GCC_PCIE_0_GDSC>; + + eq-presets-8gts = /bits/ 16 <0x5555 0x5555>; + + operating-points-v2 = <&pcie0_opp_table>; + + iommu-map = <0 &apps_smmu 0x1000 0x0 0x1>, + <0x100 &apps_smmu 0x1001 0x0 0x1>; + + interrupt-map = <0 0 0 1 &intc 0 0 GIC_ESPI 213 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc 0 0 GIC_ESPI 214 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc 0 0 GIC_ESPI 215 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc 0 0 GIC_ESPI 216 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map-mask = <0 0 0 0x7>; + #interrupt-cells = <1>; + + msi-map = <0x0 &gic_its 0x1000 0x1>, + <0x100 &gic_its 0x1001 0x1>; + msi-map-mask = <0xff00>; + linux,pci-domain = <0>; + bus-range = <0x00 0xff>; + + pinctrl-0 = <&pcie0_default_state>; + pinctrl-names = "default"; + + dma-coherent; + + status = "disabled"; + + pcie0_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* 2.5 GT/s */ + opp-2500000 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_low_svs_d1>; + opp-peak-kBps = <250000 1>; + }; + + /* 5.0 GT/s */ + opp-5000000 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs_d1>; + opp-peak-kBps = <500000 1>; + }; + + /* 8.0 GT/s */ + opp-8000000 { + opp-hz = /bits/ 64 <8000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <984500 1>; + }; + + /* 10 GT/s */ + opp-10000000 { + opp-hz = /bits/ 64 <10000000>; + required-opps = <&rpmhpd_opp_low_svs_d1>; + opp-peak-kBps = <1000000 1>; + }; + + /* 16 GT/s */ + opp-16000000 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <1969000 1>; + }; + }; + + pcie0_port0: pcie@0 { + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + + phys = <&pcie0_phy>; + }; + }; + + pcie0_phy: phy@1c06000 { + compatible = "qcom,hawi-qmp-gen3x2-pcie-phy"; + reg = <0x0 0x01c06000 0x0 0x2000>; + + clocks = <&gcc GCC_PCIE_0_PHY_AUX_CLK>, + <&gcc GCC_PCIE_0_CFG_AHB_CLK>, + <&tcsrcc TCSR_PCIE_0_CLKREF_EN>, + <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_0_PIPE_CLK>, + <&gcc GCC_PCIE_0_PIPE_DIV2_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "rchng", + "pipe", + "pipediv2"; + + assigned-clocks = <&gcc GCC_PCIE_0_PHY_RCHNG_CLK>; + assigned-clock-rates = <100000000>; + + resets = <&gcc GCC_PCIE_0_PHY_BCR>, + <&gcc GCC_PCIE_0_NOCSR_COM_PHY_BCR>; + reset-names = "phy", + "phy_nocsr"; + + power-domains = <&gcc GCC_PCIE_0_PHY_GDSC>; + + #clock-cells = <0>; + clock-output-names = "pcie0_pipe_clk"; + + #phy-cells = <0>; + + status = "disabled"; + }; + + pcie1: pcie@1c18000 { + device_type = "pci"; + compatible = "qcom,hawi-pcie"; + reg = <0x0 0x01c18000 0x0 0x3000>, + <0x0 0x64000000 0x0 0xf1d>, + <0x0 0x64000f20 0x0 0xa8>, + <0x0 0x64001000 0x0 0x1000>, + <0x0 0x64100000 0x0 0x100000>, + <0x0 0x01c1b000 0x0 0x1000>; + reg-names = "parf", + "dbi", + "elbi", + "atu", + "config", + "mhi"; + #address-cells = <3>; + #size-cells = <2>; + ranges = <0x01000000 0x0 0x00000000 0x0 0x64200000 0x0 0x100000>, + <0x02000000 0x0 0x64300000 0x0 0x64300000 0x0 0x1bd00000>; + + interrupts = <GIC_ESPI 98 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 99 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 100 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 101 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 102 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 103 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 104 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 105 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 95 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + + clocks = <&gcc GCC_PCIE_1_AUX_CLK>, + <&gcc GCC_PCIE_1_CFG_AHB_CLK>, + <&gcc GCC_PCIE_1_MSTR_AXI_CLK>, + <&gcc GCC_PCIE_1_SLV_AXI_CLK>, + <&gcc GCC_PCIE_1_SLV_Q2A_AXI_CLK>, + <&gcc GCC_AGGRE_NOC_PCIE_AXI_CLK>, + <&gcc GCC_CNOC_PCIE_SF_AXI_CLK>; + clock-names = "aux", + "cfg", + "bus_master", + "bus_slave", + "slave_q2a", + "noc_aggr", + "cnoc_sf_axi"; + + resets = <&gcc GCC_PCIE_1_BCR>, + <&gcc GCC_PCIE_1_LINK_DOWN_BCR>; + reset-names = "pci", + "link_down"; + + interconnects = <&pcie_anoc MASTER_PCIE_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &cnoc_main SLAVE_PCIE_1 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "pcie-mem", + "cpu-pcie"; + + power-domains = <&gcc GCC_PCIE_1_GDSC>; + + eq-presets-8gts = /bits/ 16 <0x5555 0x5555>; + + operating-points-v2 = <&pcie1_opp_table>; + + iommu-map = <0 &apps_smmu 0x1080 0x0 0x1>, + <0x100 &apps_smmu 0x1081 0x0 0x1>; + + interrupt-map = <0 0 0 1 &intc 0 0 GIC_ESPI 106 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &intc 0 0 GIC_ESPI 107 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &intc 0 0 GIC_ESPI 108 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &intc 0 0 GIC_ESPI 109 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map-mask = <0 0 0 0x7>; + #interrupt-cells = <1>; + + msi-map = <0x0 &gic_its 0x1080 0x1>, + <0x100 &gic_its 0x1081 0x1>; + msi-map-mask = <0xff00>; + linux,pci-domain = <1>; + bus-range = <0x00 0xff>; + + pinctrl-0 = <&pcie1_default_state>; + pinctrl-names = "default"; + + dma-coherent; + + status = "disabled"; + + pcie1_opp_table: opp-table { + compatible = "operating-points-v2"; + + /* 2.5 GT/s */ + opp-2500000 { + opp-hz = /bits/ 64 <2500000>; + required-opps = <&rpmhpd_opp_low_svs_d1>; + opp-peak-kBps = <250000 1>; + }; + + /* 5.0 GT/s */ + opp-5000000 { + opp-hz = /bits/ 64 <5000000>; + required-opps = <&rpmhpd_opp_low_svs_d1>; + opp-peak-kBps = <500000 1>; + }; + + /* 8.0 GT/s */ + opp-8000000 { + opp-hz = /bits/ 64 <8000000>; + required-opps = <&rpmhpd_opp_low_svs>; + opp-peak-kBps = <984500 1>; + }; + + /* 16 GT/s */ + opp-16000000 { + opp-hz = /bits/ 64 <16000000>; + required-opps = <&rpmhpd_opp_svs>; + opp-peak-kBps = <1969000 1>; + }; + }; + + pcie1_port0: pcie@0 { + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + + phys = <&pcie1_phy>; + }; + }; + + pcie1_phy: phy@1c1e000 { + compatible = "qcom,hawi-qmp-gen4x1-pcie-phy"; + reg = <0x0 0x01c1e000 0x0 0x2000>; + + clocks = <&gcc GCC_PCIE_1_PHY_AUX_CLK>, + <&gcc GCC_PCIE_1_CFG_AHB_CLK>, + <&tcsrcc TCSR_PCIE_1_CLKREF_EN>, + <&gcc GCC_PCIE_1_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_1_PIPE_CLK>, + <&gcc GCC_PCIE_1_PIPE_DIV2_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "rchng", + "pipe", + "pipediv2"; + + assigned-clocks = <&gcc GCC_PCIE_1_PHY_RCHNG_CLK>; + assigned-clock-rates = <100000000>; + + resets = <&gcc GCC_PCIE_1_PHY_BCR>, + <&gcc GCC_PCIE_1_NOCSR_COM_PHY_BCR>; + reset-names = "phy", + "phy_nocsr"; + + power-domains = <&gcc GCC_PCIE_1_PHY_GDSC>; + + #clock-cells = <0>; + clock-output-names = "pcie1_pipe_clk"; + + #phy-cells = <0>; + + status = "disabled"; + }; + + sdhc_2: mmc@1c44000 { + compatible = "qcom,hawi-sdhci", "qcom,sdhci-msm-v5"; + reg = <0x0 0x01c44000 0x0 0x1000>; + + interrupts = <GIC_ESPI 271 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 287 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "hc_irq", "pwr_irq"; + + clocks = <&gcc GCC_SDCC2_AHB_CLK>, + <&gcc GCC_SDCC2_APPS_CLK>, + <&rpmhcc RPMH_CXO_CLK>; + + clock-names = "iface", "core", "xo"; + + interconnects = <&aggre_noc MASTER_SDCC_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_SDCC_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + + interconnect-names = "sdhc-ddr", "cpu-sdhc"; + + power-domains = <&rpmhpd RPMHPD_CX>; + operating-points-v2 = <&sdhc2_opp_table>; + + iommus = <&apps_smmu 0x140 0x0>; + dma-coherent; + + resets = <&gcc GCC_SDCC2_BCR>; + + bus-width = <4>; + max-sd-hs-hz = <37500000>; + + qcom,dll-config = <0x0007442c>; + qcom,ddr-config = <0x80040868>; + + status = "disabled"; + + sdhc2_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + opp-peak-kBps = <160000 100000>; + opp-avg-kBps = <50000 0>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-202000000 { + opp-hz = /bits/ 64 <202000000>; + opp-peak-kBps = <200000 120000>; + opp-avg-kBps = <104000 0>; + required-opps = <&rpmhpd_opp_svs_l1>; + }; + }; + }; + + ufs_mem_phy: phy@1d80000 { + compatible = "qcom,hawi-qmp-ufs-phy"; + reg = <0x0 0x01d80000 0x0 0x4000>; + + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_UFS_PHY_PHY_AUX_CLK>, + <&tcsrcc TCSR_UFS_CLKREF_EN>; + + clock-names = "ref", + "ref_aux", + "qref"; + + resets = <&ufs_mem_hc 0>; + reset-names = "ufsphy"; + + power-domains = <&gcc GCC_UFS_MEM_PHY_GDSC>; + + #clock-cells = <1>; + #phy-cells = <0>; + + status = "disabled"; + }; + + ufs_mem_hc: ufshc@1d84000 { + compatible = "qcom,hawi-ufshc", + "qcom,ufshc", + "jedec,ufs-2.0"; + reg = <0x0 0x01d84000 0x0 0x3000>; + + interrupts = <GIC_ESPI 329 IRQ_TYPE_LEVEL_HIGH>; + + clocks = <&gcc GCC_UFS_PHY_AXI_CLK>, + <&gcc GCC_AGGRE_UFS_PHY_AXI_CLK>, + <&gcc GCC_UFS_PHY_AHB_CLK>, + <&gcc GCC_UFS_PHY_UNIPRO_5_CORE_CLK>, + <&rpmhcc RPMH_LN_BB_CLK3>, + <&gcc GCC_UFS_PHY_TX_SYMBOL_0_CLK>, + <&gcc GCC_UFS_PHY_RX_SYMBOL_0_CLK>, + <&gcc GCC_UFS_PHY_RX_SYMBOL_1_CLK>; + + clock-names = "core_clk", + "bus_aggr_clk", + "iface_clk", + "core_clk_unipro", + "ref_clk", + "tx_lane0_sync_clk", + "rx_lane0_sync_clk", + "rx_lane1_sync_clk"; + + operating-points-v2 = <&ufshc_opp_table>; + + resets = <&gcc GCC_UFS_PHY_BCR>; + reset-names = "rst"; + + interconnects = <&aggre_noc MASTER_UFS_MEM QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_UFS_MEM_CFG QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "ufs-ddr", + "cpu-ufs"; + + power-domains = <&gcc GCC_UFS_PHY_GDSC>; + required-opps = <&rpmhpd_opp_nom>; + + iommus = <&apps_smmu 0x60 0x0>; + dma-coherent; + + lanes-per-direction = <2>; + limit-hs-gear = <5>; + + phys = <&ufs_mem_phy>; + phy-names = "ufsphy"; + + qcom,ice = <&ice>; + + #reset-cells = <1>; + + status = "disabled"; + + ufshc_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <100000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-450000000 { + opp-hz = /bits/ 64 <403000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <403000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; + }; + + ice: crypto@1d88000 { + compatible = "qcom,hawi-inline-crypto-engine", + "qcom,inline-crypto-engine"; + reg = <0x0 0x01d88000 0x0 0x18000>; + + clocks = <&gcc GCC_UFS_PHY_ICE_CORE_CLK>, + <&gcc GCC_UFS_PHY_AHB_CLK>; + clock-names = "core", + "iface"; + + power-domains = <&gcc GCC_UFS_PHY_GDSC>; + }; + + videocc: clock-controller@20f0000 { + compatible = "qcom,hawi-videocc"; + reg = <0x0 0x020f0000 0x0 0x10000>; + clocks = <&bi_tcxo_div2>, + <&gcc GCC_VIDEO_AHB_CLK>; + + power-domains = <&rpmhpd RPMHPD_MMCX>, + <&rpmhpd RPMHPD_MXC>; + required-opps = <&rpmhpd_opp_low_svs_d2>, + <&rpmhpd_opp_low_svs_d2>; + + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + apps_smmu: iommu@2e00000 { + compatible = "qcom,hawi-smmu-500", "qcom,smmu-500", "arm,mmu-500"; + reg = <0x0 0x02e00000 0x0 0x100000>; + + interrupts = <GIC_ESPI 128 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 161 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 162 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 163 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 164 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 165 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 166 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 167 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 168 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 169 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 170 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 171 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 172 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 173 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 174 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 175 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 176 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 177 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 178 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 179 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 180 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 181 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 182 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 245 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 246 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 247 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 248 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 249 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 250 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 251 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 252 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 253 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 254 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 255 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 256 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 379 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 380 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 381 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 382 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 383 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 384 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 385 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 386 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 387 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 388 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 389 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 390 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 391 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 392 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 393 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 394 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 395 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 396 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 397 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 398 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 399 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 400 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 401 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 402 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 403 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 404 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 405 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 406 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 407 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 408 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 409 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 459 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 460 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 461 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 462 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 463 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 464 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 465 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 466 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 467 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 468 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 469 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 470 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 471 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 472 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 473 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 482 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 483 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 476 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 485 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 771 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 487 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 488 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 489 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 754 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 755 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 756 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 757 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 758 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 759 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 760 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 761 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 474 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 552 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 553 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 554 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 555 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 556 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 557 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 558 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 559 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 560 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 561 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 562 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 563 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 564 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 565 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 566 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 567 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 928 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 929 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 930 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 931 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 932 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 933 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 934 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 935 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 936 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 937 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 938 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 939 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 940 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 941 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 942 IRQ_TYPE_LEVEL_HIGH>; + + #iommu-cells = <2>; + #global-interrupts = <1>; + + dma-coherent; + }; + + stdst_noc: interconnect@3000000 { + compatible = "qcom,hawi-stdst-main"; + reg = <0x0 0x03000000 0x0 0x10000>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + config_noc: interconnect@3010000 { + compatible = "qcom,hawi-stdst-cfg"; + reg = <0x0 0x03010000 0x0 0xb1000>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + tcsr: syscon@3a70000 { + compatible = "qcom,hawi-tcsr", "syscon"; + reg = <0x0 0x03a70000 0x0 0x10000>; + }; + + tcsr_mutex: hwlock@3ad3000 { + compatible = "qcom,tcsr-mutex"; + reg = <0x0 0x03ad3000 0x0 0x20000>; + #hwlock-cells = <1>; + }; + + tcsrcc: clock-controller@3b13040 { + compatible = "qcom,hawi-tcsrcc", "syscon"; + reg = <0x0 0x03b13040 0x0 0x50>; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + + #clock-cells = <1>; + #reset-cells = <1>; + }; + + gxclkctl: clock-controller@3d64000 { + compatible = "qcom,hawi-gxclkctl", + "qcom,kaanapali-gxclkctl"; + reg = <0x0 0x03d64000 0x0 0x6000>; + + power-domains = <&rpmhpd RPMHPD_GFX>, + <&rpmhpd RPMHPD_GMXC>, + <&gpucc GPU_CC_CX_GDSC>; + + #power-domain-cells = <1>; + }; + + gpucc: clock-controller@3d90000 { + compatible = "qcom,hawi-gpucc"; + reg = <0x0 0x03d90000 0x0 0x9800>; + + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MX>, + <&rpmhpd RPMHPD_GMXC>; + required-opps = <&rpmhpd_opp_low_svs_d3>, + <&rpmhpd_opp_low_svs_d3>, + <&rpmhpd_opp_low_svs_d3>; + clocks = <&bi_tcxo_div2>, + <&gcc GCC_GPU_GPLL0_CLK_SRC>, + <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>; + + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + adreno_smmu: iommu@3da0000 { + compatible = "qcom,hawi-smmu-500", "qcom,adreno-smmu", + "qcom,smmu-500", "arm,mmu-500"; + reg = <0x0 0x03da0000 0x0 0x40000>; + #iommu-cells = <2>; + #global-interrupts = <1>; + interrupts = <GIC_ESPI 738 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 742 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 743 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 744 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 745 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 746 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 747 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 748 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 749 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 750 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 751 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 752 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 486 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 540 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 638 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 639 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 640 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 641 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 724 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 726 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 729 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 730 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 731 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 733 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 734 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 764 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gpucc GPU_CC_GPU_SMMU_VOTE_CLK>; + clock-names = "hlos"; + power-domains = <&gpucc GPU_CC_CX_GDSC>; + dma-coherent; + }; + + remoteproc_mpss: remoteproc@4000000 { + compatible = "qcom,hawi-mpss-pas", "qcom,sm8650-mpss-pas"; + reg = <0x0 0x04000000 0x0 0x10000>; + + interrupts-extended = <&intc GIC_ESPI 328 IRQ_TYPE_EDGE_RISING>, + <&smp2p_modem_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_modem_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_modem_in 2 IRQ_TYPE_EDGE_RISING>, + <&smp2p_modem_in 3 IRQ_TYPE_EDGE_RISING>, + <&smp2p_modem_in 7 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack", + "shutdown-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + interconnects = <&mc_virt MASTER_LLCC QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MSS>; + power-domain-names = "cx", + "mss"; + + memory-region = <&mpss_mem>, <&q6_mpss_dtb_mem>, <&dsm_partition_1_mem>, + <&dsm_partition_2_mem>, <&mpss_crashdump_overlay_mem>; + + qcom,qmp = <&aoss_qmp>; + + qcom,smem-states = <&smp2p_modem_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + + glink-edge { + interrupts-extended = <&ipcc IPCC_MPROC_MPSS + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_MPSS + IPCC_MPROC_SIGNAL_GLINK_QMP>; + + qcom,remote-pid = <1>; + label = "mpss"; + }; + }; + + remoteproc_adsp: remoteproc@7000000 { + compatible = "qcom,hawi-adsp-pas", "qcom,sm8550-adsp-pas"; + reg = <0x0 0x07000000 0x0 0x10000>; + + interrupts-extended = <&pdc 6 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 2 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 3 IRQ_TYPE_EDGE_RISING>, + <&smp2p_adsp_in 7 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack", + "shutdown-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + interconnects = <&lpass_lpicx_noc MASTER_LPASS_PROC QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + + power-domains = <&rpmhpd RPMHPD_LCX>, + <&rpmhpd RPMHPD_LMX>; + power-domain-names = "lcx", + "lmx"; + + memory-region = <&adspslpi_mem>, <&q6_adsp_dtb_mem>; + + qcom,qmp = <&aoss_qmp>; + + qcom,smem-states = <&smp2p_adsp_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + + glink-edge { + interrupts-extended = <&ipcc IPCC_MPROC_LPASS + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_LPASS + IPCC_MPROC_SIGNAL_GLINK_QMP>; + + qcom,remote-pid = <2>; + label = "lpass"; + + fastrpc { + compatible = "qcom,hawi-fastrpc", "qcom,kaanapali-fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "adsp"; + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + + iommus = <&apps_smmu 0x0c03 0x80>, + <&apps_smmu 0x0c43 0x20>; + dma-coherent; + }; + + compute-cb@4 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <4>; + + iommus = <&apps_smmu 0x0c04 0x80>, + <&apps_smmu 0x0c44 0x20>; + dma-coherent; + }; + + compute-cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + + iommus = <&apps_smmu 0x0c05 0x80>, + <&apps_smmu 0x0c45 0x20>; + dma-coherent; + }; + + compute-cb@6 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <6>; + + iommus = <&apps_smmu 0x0c06 0x80>, + <&apps_smmu 0x0c46 0x20>; + dma-coherent; + }; + + compute-cb@7 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <7>; + + iommus = <&apps_smmu 0x0c07 0x80>, + <&apps_smmu 0x0c47 0x20>; + dma-coherent; + }; + + compute-cb@8 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <8>; + + iommus = <&apps_smmu 0x0c08 0x80>, + <&apps_smmu 0x0c48 0x20>; + dma-coherent; + }; + }; + }; + }; + + lpass_lpiaon_noc: interconnect@7c00000 { + compatible = "qcom,hawi-lpass-lpiaon-noc"; + reg = <0x0 0x07c00000 0x0 0x19080>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + lpass_lpicx_noc: interconnect@7c20000 { + compatible = "qcom,hawi-lpass-lpicx-noc"; + reg = <0x0 0x07c20000 0x0 0x46080>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + lpass_ag_noc: interconnect@8f40000 { + compatible = "qcom,hawi-lpass-ag-noc"; + reg = <0x0 0x08f40000 0x0 0xc080>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + camcc: clock-controller@956d000 { + compatible = "qcom,hawi-camcc"; + reg = <0x0 0x0956d000 0x0 0x80000>; + + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&bi_tcxo_div2>, + <&bi_tcxo_ao_div2>, + <&sleep_clk>; + + power-domains = <&rpmhpd RPMHPD_MMCX>, + <&rpmhpd RPMHPD_MXC>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + + interconnects = <&mmss_noc MASTER_CAMNOC_HF QCOM_ICC_TAG_ALWAYS + &mmss_noc SLAVE_MNOC_HF_MEM_NOC QCOM_ICC_TAG_ALWAYS>; + + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + usb_1: usb@a600000 { + compatible = "qcom,hawi-dwc3", "qcom,snps-dwc3"; + reg = <0x0 0x0a600000 0x0 0xfc100>; + + clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>, + <&gcc GCC_USB30_PRIM_MASTER_CLK>, + <&gcc GCC_AGGRE_STARDUSTNOC_USB3_PRIM_AXI_CLK>, + <&gcc GCC_USB30_PRIM_SLEEP_CLK>, + <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>; + clock-names = "cfg_noc", + "core", + "iface", + "sleep", + "mock_utmi"; + + assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_PRIM_MASTER_CLK>; + assigned-clock-rates = <19200000>, <200000000>; + + interrupts-extended = <&intc GIC_ESPI 196 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_ESPI 194 IRQ_TYPE_LEVEL_HIGH>, + <&intc GIC_ESPI 195 IRQ_TYPE_LEVEL_HIGH>, + <&pdc 14 IRQ_TYPE_EDGE_BOTH>, + <&pdc 15 IRQ_TYPE_EDGE_BOTH>, + <&pdc 17 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "dwc_usb3", + "pwr_event", + "hs_phy_irq", + "dp_hs_phy_irq", + "dm_hs_phy_irq", + "ss_phy_irq"; + + power-domains = <&gcc GCC_USB30_PRIM_GDSC>; + required-opps = <&rpmhpd_opp_nom>; + + resets = <&gcc GCC_USB30_PRIM_BCR>; + + interconnects = <&aggre_noc MASTER_USB3 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_USB3 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "usb-ddr", + "apps-usb"; + iommus = <&apps_smmu 0x40 0x0>; + + phys = <&usb_1_hsphy>, <&usb_dp_qmpphy QMP_USB43DP_USB3_PHY>; + phy-names = "usb2-phy", "usb3-phy"; + + snps,hird-threshold = /bits/ 8 <0x0>; + snps,usb2-gadget-lpm-disable; + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + snps,dis-u1-entry-quirk; + snps,dis-u2-entry-quirk; + snps,is-utmi-l1-suspend; + snps,usb3_lpm_capable; + snps,usb2-lpm-disable; + snps,has-lpm-erratum; + tx-fifo-resize; + dma-coherent; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_1_dwc3_hs: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb_1_dwc3_ss: endpoint { + remote-endpoint = <&usb_dp_qmpphy_usb_ss_in>; + }; + }; + }; + }; + + pdc: interrupt-controller@b220000 { + compatible = "qcom,hawi-pdc", "qcom,pdc"; + reg = <0x0 0x0b220000 0x0 0x10000>, + <0x0 0x179600f0 0x0 0xf4>; + + qcom,pdc-ranges = <0 256 196>; + #interrupt-cells = <2>; + interrupt-parent = <&intc>; + interrupt-controller; + }; + + tsens0: thermal-sensor@c22b000 { + compatible = "qcom,hawi-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c22b000 0x0 0x1000>, + <0x0 0x0c222000 0x0 0x1000>; + interrupts = <GIC_SPI 282 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 484 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <12>; + #thermal-sensor-cells = <1>; + }; + + tsens1: thermal-sensor@c22c000 { + compatible = "qcom,hawi-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c22c000 0x0 0x1000>, + <0x0 0x0c223000 0x0 0x1000>; + interrupts = <GIC_SPI 283 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 485 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <7>; + #thermal-sensor-cells = <1>; + }; + + tsens2: thermal-sensor@c22d000 { + compatible = "qcom,hawi-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c22d000 0x0 0x1000>, + <0x0 0x0c224000 0x0 0x1000>; + interrupts = <GIC_SPI 284 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <6>; + #thermal-sensor-cells = <1>; + }; + + tsens3: thermal-sensor@c22e000 { + compatible = "qcom,hawi-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c22e000 0x0 0x1000>, + <0x0 0x0c225000 0x0 0x1000>; + interrupts = <GIC_SPI 285 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <9>; + #thermal-sensor-cells = <1>; + }; + + tsens4: thermal-sensor@c22f000 { + compatible = "qcom,hawi-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c22f000 0x0 0x1000>, + <0x0 0x0c226000 0x0 0x1000>; + interrupts = <GIC_SPI 323 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 527 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <9>; + #thermal-sensor-cells = <1>; + }; + + tsens5: thermal-sensor@c230000 { + compatible = "qcom,hawi-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c230000 0x0 0x1000>, + <0x0 0x0c227000 0x0 0x1000>; + interrupts = <GIC_SPI 324 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 528 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <11>; + #thermal-sensor-cells = <1>; + }; + + tsens6: thermal-sensor@c231000 { + compatible = "qcom,hawi-tsens", "qcom,tsens-v2"; + reg = <0x0 0x0c231000 0x0 0x1000>, + <0x0 0x0c228000 0x0 0x1000>; + interrupts = <GIC_SPI 325 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 529 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <8>; + #thermal-sensor-cells = <1>; + }; + + aoss_qmp: power-management@c300000 { + compatible = "qcom,hawi-aoss-qmp", "qcom,aoss-qmp"; + reg = <0x0 0x0c300000 0x0 0x400>; + + interrupts-extended = <&ipcc IPCC_MPROC_AOP + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_AOP + IPCC_MPROC_SIGNAL_GLINK_QMP>; + + #clock-cells = <0>; + }; + + arbiter@c400000 { + compatible = "qcom,hawi-spmi-pmic-arb", + "qcom,glymur-spmi-pmic-arb"; + reg = <0x0 0x0c400000 0x0 0x3000>, + <0x0 0xc900000 0x0 0x400000>, + <0x0 0xc4c0000 0x0 0x400000>, + <0x0 0xc403000 0x0 0x8000>; + reg-names = "core", + "chnls", + "obsrvr", + "chnl_map"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + qcom,channel = <0>; + qcom,ee = <0>; + + spmi_bus0: spmi@c426000 { + reg = <0x0 0x0c426000 0x0 0x4000>, + <0x0 0xc8c0000 0x0 0x10000>, + <0x0 0xc42a000 0x0 0x8000>; + reg-names = "cnfg", + "intr", + "chnl_owner"; + interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "periph_irq"; + interrupt-controller; + #interrupt-cells = <4>; + #address-cells = <2>; + #size-cells = <0>; + }; + + spmi_bus1: spmi@c437000 { + reg = <0x0 0x0c437000 0x0 0x4000>, + <0x0 0xc8d0000 0x0 0x10000>, + <0x0 0xc43b000 0x0 0x8000>; + reg-names = "cnfg", + "intr", + "chnl_owner"; + interrupts-extended = <&pdc 3 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "periph_irq"; + interrupt-controller; + #interrupt-cells = <4>; + #address-cells = <2>; + #size-cells = <0>; + }; + }; + + tlmm: pinctrl@f100000 { + compatible = "qcom,hawi-tlmm"; + reg = <0x0 0x0f100000 0x0 0x102000>; + interrupts = <GIC_ESPI 272 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&tlmm 0 0 227>; + interrupt-controller; + #interrupt-cells = <2>; + wakeup-parent = <&pdc>; + + qup_i2c8_data_clk: qup-i2c8-data-clk-state { + /* SDA, SCL */ + pins = "gpio0", "gpio1"; + function = "qup2_se0"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi8_data_clk: qup-spi8-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio0", "gpio1", "gpio2"; + function = "qup2_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart8_cts_rts: qup-uart8-cts-rts-state { + /* CTS, RTS */ + pins = "gpio0", "gpio1"; + function = "qup2_se0"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart8_default: qup-uart8-default-state { + /* TX, RX */ + pins = "gpio2", "gpio3"; + function = "qup2_se0"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi8_cs: qup-spi8-cs-state { + pins = "gpio3"; + function = "qup2_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_i2c9_data_clk: qup-i2c9-data-clk-state { + /* SDA, SCL */ + pins = "gpio4", "gpio5"; + function = "qup2_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi9_data_clk: qup-spi9-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio4", "gpio5", "gpio6"; + function = "qup2_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart9_cts_rts: qup-uart9-cts-rts-state { + /* CTS, RTS */ + pins = "gpio4", "gpio5"; + function = "qup2_se1"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart9_default: qup-uart9-default-state { + /* TX, RX */ + pins = "gpio6", "gpio7"; + function = "qup2_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi9_cs: qup-spi9-cs-state { + pins = "gpio7"; + function = "qup2_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_i2c14_data_clk: qup-i2c14-data-clk-state { + /* SDA, SCL */ + pins = "gpio8", "gpio9"; + function = "qup3_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi14_data_clk: qup-spi14-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio8", "gpio9", "gpio10"; + function = "qup3_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart14_cts_rts: qup-uart14-cts-rts-state { + /* CTS, RTS */ + pins = "gpio8", "gpio9"; + function = "qup3_se1"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart14_default: qup-uart14-default-state { + /* TX, RX */ + pins = "gpio10", "gpio11"; + function = "qup3_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi14_cs: qup-spi14-cs-state { + pins = "gpio11"; + function = "qup3_se1"; + drive-strength = <6>; + bias-pull-up; + }; + + qup_i2c15_data_clk: qup-i2c15-data-clk-state { + /* SDA, SCL */ + pins = "gpio12", "gpio13"; + function = "qup3_se2"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi15_data_clk: qup-spi15-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio12", "gpio13", "gpio14"; + function = "qup3_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart15_cts_rts: qup-uart15-cts-rts-state { + /* CTS, RTS */ + pins = "gpio12", "gpio13"; + function = "qup3_se2"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart15_default: qup-uart15-default-state { + /* TX, RX */ + pins = "gpio14", "gpio15"; + function = "qup3_se2"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi15_cs: qup-spi15-cs-state { + pins = "gpio15"; + function = "qup3_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_i2c16_data_clk: qup-i2c16-data-clk-state { + /* SDA, SCL */ + pins = "gpio16", "gpio17"; + function = "qup3_se3"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi16_data_clk: qup-spi16-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio16", "gpio17", "gpio18"; + function = "qup3_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart16_cts_rts: qup-uart16-cts-rts-state { + /* CTS, RTS */ + pins = "gpio16", "gpio17"; + function = "qup3_se3"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart16_default: qup-uart16-default-state { + /* TX, RX */ + pins = "gpio18", "gpio19"; + function = "qup3_se3"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi16_cs: qup-spi16-cs-state { + pins = "gpio19"; + function = "qup3_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_i2c17_data_clk: qup-i2c17-data-clk-state { + /* SDA, SCL */ + pins = "gpio20", "gpio21"; + function = "qup3_se4"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi17_data_clk: qup-spi17-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio20", "gpio21", "gpio22"; + function = "qup3_se4"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart17_cts_rts: qup-uart17-cts-rts-state { + /* CTS, RTS */ + pins = "gpio20", "gpio21"; + function = "qup3_se4"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart17_default: qup-uart17-default-state { + /* TX, RX */ + pins = "gpio22", "gpio23"; + function = "qup3_se4"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi17_cs: qup-spi17-cs-state { + pins = "gpio23"; + function = "qup3_se4"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart18_cts_rts: qup-uart18-cts-rts-state { + /* CTS, RTS */ + pins = "gpio24", "gpio25"; + function = "qup3_se5"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart18_default: qup-uart18-default-state { + /* TX, RX */ + pins = "gpio26", "gpio27"; + function = "qup3_se5"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c20_data_clk: qup-i2c20-data-clk-state { + /* SDA, SCL */ + pins = "gpio28", "gpio29"; + function = "qup4_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi20_data_clk: qup-spi20-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio28", "gpio29", "gpio30"; + function = "qup4_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart20_cts_rts: qup-uart20-cts-rts-state { + /* CTS, RTS */ + pins = "gpio28", "gpio29"; + function = "qup4_se1"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart20_default: qup-uart20-default-state { + /* TX, RX */ + pins = "gpio30", "gpio31"; + function = "qup4_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi20_cs: qup-spi20-cs-state { + pins = "gpio31"; + function = "qup4_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_i2c21_data_clk: qup-i2c21-data-clk-state { + /* SDA, SCL */ + pins = "gpio32", "gpio33"; + function = "qup4_se2"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi21_data_clk: qup-spi21-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio32", "gpio33", "gpio34"; + function = "qup4_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart21_cts_rts: qup-uart21-cts-rts-state { + /* CTS, RTS */ + pins = "gpio32", "gpio33"; + function = "qup4_se2"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart21_default: qup-uart21-default-state { + /* TX, RX */ + pins = "gpio34", "gpio35"; + function = "qup4_se2"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi21_cs: qup-spi21-cs-state { + pins = "gpio35"; + function = "qup4_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_i2c4_data_clk: qup-i2c4-data-clk-state { + /* SDA, SCL */ + pins = "gpio36", "gpio37"; + function = "qup1_se4"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi4_data_clk: qup-spi4-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio36", "gpio37", "gpio38"; + function = "qup1_se4"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart4_cts_rts: qup-uart4-cts-rts-state { + /* CTS, RTS */ + pins = "gpio36", "gpio37"; + function = "qup1_se4"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart4_default: qup-uart4-default-state { + /* TX, RX */ + pins = "gpio38", "gpio39"; + function = "qup1_se4"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi4_cs: qup-spi4-cs-state { + pins = "gpio39"; + function = "qup1_se4"; + drive-strength = <6>; + bias-disable; + }; + + qup_i2c2_data_clk: qup-i2c2-data-clk-state { + /* SDA, SCL */ + pins = "gpio40", "gpio41"; + function = "qup1_se2"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi2_data_clk: qup-spi2-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio40", "gpio41", "gpio42"; + function = "qup1_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart2_cts_rts: qup-uart2-cts-rts-state { + /* CTS, RTS */ + pins = "gpio40", "gpio41"; + function = "qup1_se2"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart2_default: qup-uart2-default-state { + /* TX, RX */ + pins = "gpio42", "gpio43"; + function = "qup1_se2"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi2_cs: qup-spi2-cs-state { + pins = "gpio43"; + function = "qup1_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_i2c3_data_clk: qup-i2c3-data-clk-state { + /* SDA, SCL */ + pins = "gpio44", "gpio45"; + function = "qup1_se3"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi3_data_clk: qup-spi3-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio44", "gpio45", "gpio46"; + function = "qup1_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart3_cts_rts: qup-uart3-cts-rts-state { + /* CTS, RTS */ + pins = "gpio44", "gpio45"; + function = "qup1_se3"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart3_default: qup-uart3-default-state { + /* TX, RX */ + pins = "gpio46", "gpio47"; + function = "qup1_se3"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi3_cs: qup-spi3-cs-state { + pins = "gpio47"; + function = "qup1_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_i2c19_data_clk: qup-i2c19-data-clk-state { + /* SDA, SCL */ + pins = "gpio48", "gpio49"; + function = "qup4_se0"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi19_data_clk: qup-spi19-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio48", "gpio49", "gpio50"; + function = "qup4_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart19_cts_rts: qup-uart19-cts-rts-state { + /* CTS, RTS */ + pins = "gpio48", "gpio49"; + function = "qup4_se0"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart19_default: qup-uart19-default-state { + /* TX, RX */ + pins = "gpio50", "gpio51"; + function = "qup4_se0"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi19_cs: qup-spi19-cs-state { + pins = "gpio51"; + function = "qup4_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_i2c5_data_clk: qup-i2c5-data-clk-state { + /* SDA, SCL */ + pins = "gpio52", "gpio53"; + function = "qup1_se5"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi5_data_clk: qup-spi5-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio52", "gpio53", "gpio54"; + function = "qup1_se5"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart5_cts_rts: qup-uart5-cts-rts-state { + /* CTS, RTS */ + pins = "gpio52", "gpio53"; + function = "qup1_se5"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart5_default: qup-uart5-default-state { + /* TX, RX */ + pins = "gpio54", "gpio55"; + function = "qup1_se5"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi5_cs: qup-spi5-cs-state { + pins = "gpio55"; + function = "qup1_se5"; + drive-strength = <6>; + bias-disable; + }; + + sdc2_default: sdc2-default-state { + clk-pins { + pins = "sdc2_clk"; + drive-strength = <16>; + bias-disable; + }; + + cmd-pins { + pins = "sdc2_cmd"; + drive-strength = <10>; + bias-pull-up; + }; + + data-pins { + pins = "sdc2_data"; + drive-strength = <10>; + bias-pull-up; + }; + + card-detect-pins { + pins = "gpio55"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + sdc2_sleep: sdc2-sleep-state { + clk-pins { + pins = "sdc2_clk"; + drive-strength = <2>; + bias-disable; + }; + + cmd-pins { + pins = "sdc2_cmd"; + drive-strength = <2>; + bias-pull-up; + }; + + data-pins { + pins = "sdc2_data"; + drive-strength = <2>; + bias-pull-up; + }; + + card-detect-pins { + pins = "gpio55"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + qup_i2c6_data_clk: qup-i2c6-data-clk-state { + /* SDA, SCL */ + pins = "gpio56", "gpio57"; + function = "qup1_se6"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi6_data_clk: qup-spi6-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio56", "gpio57", "gpio58"; + function = "qup1_se6"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart6_cts_rts: qup-uart6-cts-rts-state { + /* CTS, RTS */ + pins = "gpio56", "gpio57"; + function = "qup1_se6"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart6_default: qup-uart6-default-state { + /* TX, RX */ + pins = "gpio58", "gpio59"; + function = "qup1_se6"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi6_cs: qup-spi6-cs-state { + pins = "gpio59"; + function = "qup1_se6"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart7_default: qup-uart7-state { + /* TX, RX */ + pins = "gpio62", "gpio63"; + function = "qup1_se7"; + drive-strength = <2>; + bias-disable; + }; + + qup_i2c13_data_clk: qup-i2c13-data-clk-state { + /* SDA, SCL */ + pins = "gpio64", "gpio65"; + function = "qup3_se0_01"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_uart13_default: qup-uart13-default-state { + /* TX, RX */ + pins = "gpio64", "gpio65"; + function = "qup3_se0_23"; + drive-strength = <2>; + bias-pull-up; + }; + + hub_i2c0_data_clk: hub-i2c0-data-clk-state { + /* SDA, SCL */ + pins = "gpio66", "gpio67"; + function = "i2chub0_se0"; + drive-strength = <2>; + bias-pull-up; + }; + + hub_i2c2_data_clk: hub-i2c2-data-clk-state { + /* SDA, SCL */ + pins = "gpio68", "gpio69"; + function = "i2chub0_se2"; + drive-strength = <2>; + bias-pull-up; + }; + + hub_i2c3_data_clk: hub-i2c3-data-clk-state { + /* SDA, SCL */ + pins = "gpio70", "gpio71"; + function = "i2chub0_se3"; + drive-strength = <2>; + bias-pull-up; + }; + + hub_i2c4_data_clk: hub-i2c4-data-clk-state { + /* SDA, SCL */ + pins = "gpio72", "gpio73"; + function = "i2chub0_se4"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c1_data_clk: qup-i2c1-data-clk-state { + /* SDA, SCL */ + pins = "gpio74", "gpio75"; + function = "qup1_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi1_data_clk: qup-spi1-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio74", "gpio75", "gpio76"; + function = "qup1_se1"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart1_cts_rts: qup-uart1-cts-rts-state { + /* CTS, RTS */ + pins = "gpio74", "gpio75"; + function = "qup1_se1"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart1_default: qup-uart1-default-state { + /* TX, RX */ + pins = "gpio76", "gpio77"; + function = "qup1_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi1_cs: qup-spi1-cs-state { + pins = "gpio77"; + function = "qup1_se1"; + drive-strength = <6>; + bias-disable; + }; + + hub_i2c1_data_clk: hub-i2c1-data-clk-state { + /* SDA, SCL */ + pins = "gpio78", "gpio79"; + function = "i2chub0_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c0_data_clk: qup-i2c0-data-clk-state { + /* SDA, SCL */ + pins = "gpio80", "gpio83"; + function = "qup1_se0"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi0_data_clk: qup-spi0-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio80", "gpio83", "gpio82"; + function = "qup1_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart0_cts_rts: qup-uart0-cts-rts-state { + /* CTS, RTS */ + pins = "gpio80", "gpio83"; + function = "qup1_se0"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_spi0_cs: qup-spi0-cs-state { + pins = "gpio81"; + function = "qup1_se0"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart0_default: qup-uart0-default-state { + /* TX, RX */ + pins = "gpio82", "gpio81"; + function = "qup1_se0"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c22_data_clk: qup-i2c22-data-clk-state { + /* SDA, SCL */ + pins = "gpio121", "gpio84"; + function = "qup4_se3_01"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_uart22_default: qup-uart22-default-state { + /* TX, RX */ + pins = "gpio121", "gpio84"; + function = "qup4_se3_23"; + drive-strength = <2>; + bias-pull-up; + }; + + pcie0_default_state: pcie0-default-state { + perst-n-pins { + pins = "gpio102"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + clkreq-n-pins { + pins = "gpio103"; + function = "pcie0_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + wake-n-pins { + pins = "gpio104"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + qup_i2c10_data_clk: qup-i2c10-data-clk-state { + /* SDA, SCL */ + pins = "gpio117", "gpio118"; + function = "qup2_se2"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi10_data_clk: qup-spi10-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio117", "gpio118", "gpio119"; + function = "qup2_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart10_cts_rts: qup-uart10-cts-rts-state { + /* CTS, RTS */ + pins = "gpio117", "gpio118"; + function = "qup2_se2"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart10_default: qup-uart10-default-state { + /* TX, RX */ + pins = "gpio119", "gpio120"; + function = "qup2_se2"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi10_cs: qup-spi10-cs-state { + pins = "gpio120"; + function = "qup2_se2"; + drive-strength = <6>; + bias-disable; + }; + + qup_i2c11_data_clk: qup-i2c11-data-clk-state { + /* SDA, SCL */ + pins = "gpio122", "gpio123"; + function = "qup2_se3"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi11_data_clk: qup-spi11-data-clk-state { + /* MISO, MOSI, CLK */ + pins = "gpio122", "gpio123", "gpio124"; + function = "qup2_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_uart11_cts_rts: qup-uart11-cts-rts-state { + /* CTS, RTS */ + pins = "gpio122", "gpio123"; + function = "qup2_se3"; + drive-strength = <2>; + bias-pull-down; + }; + + qup_uart11_default: qup-uart11-default-state { + /* TX, RX */ + pins = "gpio124", "gpio125"; + function = "qup2_se3"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi11_cs: qup-spi11-cs-state { + pins = "gpio125"; + function = "qup2_se3"; + drive-strength = <6>; + bias-disable; + }; + + qup_i2c23_data_clk: qup-i2c23-data-clk-state { + /* SDA, SCL */ + pins = "gpio161", "gpio162"; + function = "qup4_se4_01"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_uart23_default: qup-uart23-default-state { + /* TX, RX */ + pins = "gpio161", "gpio162"; + function = "qup4_se4_23"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c12_data_clk: qup-i2c12-data-clk-state { + /* SDA, SCL */ + pins = "gpio208", "gpio209"; + function = "qup2_se4_01"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_uart12_default: qup-uart12-default-state { + /* TX, RX */ + pins = "gpio208", "gpio209"; + function = "qup2_se4_23"; + drive-strength = <2>; + bias-pull-up; + }; + + pcie1_default_state: pcie1-default-state { + perst-n-pins { + pins = "gpio220"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + clkreq-n-pins { + pins = "gpio221"; + function = "pcie1_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + wake-n-pins { + pins = "gpio222"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + }; + + sram@14680000 { + compatible = "qcom,hawi-imem", "mmio-sram"; + reg = <0x0 0x14680000 0x0 0x1000>; + ranges = <0x0 0x0 0x14680000 0x1000>; + + no-memory-wc; + + #address-cells = <1>; + #size-cells = <1>; + + minidump_config: minidump-sram@1c { + reg = <0x1c 0x4>; + }; + + pil-sram@94c { + compatible = "qcom,pil-reloc-info"; + reg = <0x94c 0xc8>; + }; + }; + + intc: interrupt-controller@17000000 { + compatible = "arm,gic-v3"; + reg = <0x0 0x17000000 0x0 0x10000>, + <0x0 0x17080000 0x0 0x200000>; + + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + + #interrupt-cells = <3>; + interrupt-controller; + + #redistributor-regions = <1>; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + gic_its: msi-controller@17040000 { + compatible = "arm,gic-v3-its"; + reg = <0x0 0x17040000 0x0 0x20000>; + + msi-controller; + #msi-cells = <1>; + }; + }; + + watchdog@17600000 { + compatible = "qcom,apss-wdt-hawi", "qcom,kpss-wdt"; + reg = <0x0 0x17600000 0x0 0x1000>; + clocks = <&sleep_clk>; + interrupts = <GIC_SPI 0 IRQ_TYPE_EDGE_RISING>; + }; + + pdp0_mbox: mailbox@17610000 { + compatible = "qcom,hawi-cpucp-mbox", "qcom,x1e80100-cpucp-mbox"; + reg = <0x0 0x17610000 0x0 0x8000>, + <0x0 0x19990000 0x0 0x8000>; + interrupts = <GIC_SPI 34 IRQ_TYPE_LEVEL_HIGH>; + #mbox-cells = <1>; + }; + + timer@17810000 { + compatible = "arm,armv7-timer-mem"; + reg = <0x0 0x17810000 0x0 0x1000>; + + #address-cells = <2>; + #size-cells = <1>; + ranges = <0x0 0x0 0x0 0x0 0x20000000>; + + frame@17811000 { + reg = <0x0 0x17811000 0x1000>, + <0x0 0x17812000 0x1000>; + frame-number = <0>; + interrupts = <GIC_SPI 8 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 6 IRQ_TYPE_LEVEL_HIGH>; + }; + + frame@17813000 { + reg = <0x0 0x17813000 0x1000>; + frame-number = <1>; + interrupts = <GIC_SPI 9 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + frame@17815000 { + reg = <0x0 0x17815000 0x1000>; + frame-number = <2>; + interrupts = <GIC_SPI 10 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + frame@17817000 { + reg = <0x0 0x17817000 0x1000>; + frame-number = <3>; + interrupts = <GIC_SPI 11 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + frame@17819000 { + reg = <0x0 0x17819000 0x1000>; + frame-number = <4>; + interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + frame@1781b000 { + reg = <0x0 0x1781b000 0x1000>; + frame-number = <5>; + interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + frame@1781d000 { + reg = <0x0 0x1781d000 0x1000>; + frame-number = <6>; + interrupts = <GIC_SPI 14 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + }; + + apps_rsc: rsc@18900000 { + compatible = "qcom,rpmh-rsc"; + reg = <0x0 0x18900000 0x0 0x10000>, + <0x0 0x18910000 0x0 0x10000>, + <0x0 0x18920000 0x0 0x10000>; + reg-names = "drv-0", + "drv-1", + "drv-2"; + interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>; + + power-domains = <&cluster_pd>; + label = "apps_rsc"; + + qcom,tcs-offset = <0xd00>; + qcom,drv-id = <2>; + qcom,tcs-config = <ACTIVE_TCS 3>, + <SLEEP_TCS 2>, + <WAKE_TCS 2>, + <CONTROL_TCS 0>; + + apps_bcm_voter: bcm-voter { + compatible = "qcom,bcm-voter"; + }; + + rpmhcc: clock-controller { + compatible = "qcom,hawi-rpmh-clk"; + #clock-cells = <1>; + clocks = <&xo_board>; + clock-names = "xo"; + }; + + rpmhpd: power-controller { + compatible = "qcom,hawi-rpmhpd"; + + operating-points-v2 = <&rpmhpd_opp_table>; + + #power-domain-cells = <1>; + + rpmhpd_opp_table: opp-table { + compatible = "operating-points-v2"; + + rpmhpd_opp_ret: opp-16 { + opp-level = <RPMH_REGULATOR_LEVEL_RETENTION>; + }; + + rpmhpd_opp_low_svs_d3_0: opp-49 { + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D3_0>; + }; + + rpmhpd_opp_low_svs_d3: opp-50 { + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D3>; + }; + + rpmhpd_opp_low_svs_d2_1: opp-51 { + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2_1>; + }; + + rpmhpd_opp_low_svs_d2: opp-52 { + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2>; + }; + + rpmhpd_opp_low_svs_d1_1: opp-54 { + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1_1>; + }; + + rpmhpd_opp_low_svs_d1_0: opp-55 { + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1_0>; + }; + + rpmhpd_opp_low_svs_d1: opp-56 { + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>; + }; + + rpmhpd_opp_low_svs_d0_0: opp-59 { + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D0_0>; + }; + + rpmhpd_opp_low_svs_d0: opp-60 { + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D0>; + }; + + rpmhpd_opp_low_svs: opp-64 { + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>; + }; + + rpmhpd_opp_low_svs_l0: opp-76 { + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L0>; + }; + + rpmhpd_opp_low_svs_l1: opp-80 { + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L1>; + }; + + rpmhpd_opp_low_svs_l2: opp-96 { + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L2>; + }; + + rpmhpd_opp_svs: opp-128 { + opp-level = <RPMH_REGULATOR_LEVEL_SVS>; + }; + + rpmhpd_opp_svs_l0: opp-144 { + opp-level = <RPMH_REGULATOR_LEVEL_SVS_L0>; + }; + + rpmhpd_opp_svs_l1: opp-192 { + opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>; + }; + + rpmhpd_opp_svs_l2: opp-224 { + opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2>; + }; + + rpmhpd_opp_svs_l2_0: opp-225 { + opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2_0>; + }; + + rpmhpd_opp_nom: opp-256 { + opp-level = <RPMH_REGULATOR_LEVEL_NOM>; + }; + + rpmhpd_opp_nom_l1: opp-320 { + opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>; + }; + + rpmhpd_opp_nom_l2: opp-336 { + opp-level = <RPMH_REGULATOR_LEVEL_NOM_L2>; + }; + + rpmhpd_opp_turbo: opp-384 { + opp-level = <RPMH_REGULATOR_LEVEL_TURBO>; + }; + + rpmhpd_opp_turbo_l0: opp-400 { + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L0>; + }; + + rpmhpd_opp_turbo_l1: opp-416 { + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>; + }; + + rpmhpd_opp_turbo_l1_0: opp-417 { + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1_0>; + }; + + rpmhpd_opp_turbo_l1_1: opp-418 { + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1_1>; + }; + + rpmhpd_opp_turbo_l1_2: opp-419 { + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1_2>; + }; + + rpmhpd_opp_turbo_l2: opp-432 { + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L2>; + }; + + rpmhpd_opp_turbo_l3: opp-448 { + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L3>; + }; + + rpmhpd_opp_turbo_l3_0: opp-449 { + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L3_0>; + }; + + rpmhpd_opp_turbo_l3_1: opp-450 { + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L3_1>; + }; + + rpmhpd_opp_turbo_l3_2: opp-451 { + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L3_2>; + }; + + rpmhpd_opp_turbo_l4: opp-452 { + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L4>; + }; + + rpmhpd_opp_turbo_l5: opp-456 { + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L5>; + }; + + rpmhpd_opp_super_turbo_no_cpr: opp-480 { + opp-level = <RPMH_REGULATOR_LEVEL_SUPER_TURBO_NO_CPR>; + }; + }; + }; + }; + + efuse@221c8000 { + compatible = "qcom,hawi-qfprom", "qcom,qfprom"; + reg = <0x0 0x221c8000 0x0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + gpu_speed_bin: gpu-speed-bin@142 { + reg = <0x142 0x2>; + bits = <3 9>; + }; + }; + + nsp_noc: interconnect@260c0000 { + compatible = "qcom,hawi-nsp-noc"; + reg = <0x0 0x260c0000 0x0 0x21280>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + remoteproc_cdsp: remoteproc@26300000 { + compatible = "qcom,hawi-cdsp-pas"; + reg = <0x0 0x26300000 0x0 0x10000>; + + interrupts-extended = <&intc GIC_ESPI 642 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 0 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 1 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 2 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 3 IRQ_TYPE_EDGE_RISING>, + <&smp2p_cdsp_in 7 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "wdog", + "fatal", + "ready", + "handover", + "stop-ack", + "shutdown-ack"; + + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-names = "xo"; + + interconnects = <&nsp_noc MASTER_CDSP_PROC QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MXC>, + <&rpmhpd RPMHPD_NSP>; + power-domain-names = "cx", + "mxc", + "nsp"; + + memory-region = <&cdsp_mem>, <&q6_cdsp_dtb_mem>; + + qcom,qmp = <&aoss_qmp>; + + qcom,smem-states = <&smp2p_cdsp_out 0>; + qcom,smem-state-names = "stop"; + + status = "disabled"; + + glink-edge { + interrupts-extended = <&ipcc IPCC_MPROC_CDSP + IPCC_MPROC_SIGNAL_GLINK_QMP + IRQ_TYPE_EDGE_RISING>; + + mboxes = <&ipcc IPCC_MPROC_CDSP + IPCC_MPROC_SIGNAL_GLINK_QMP>; + + qcom,remote-pid = <5>; + label = "cdsp"; + + fastrpc { + compatible = "qcom,hawi-fastrpc", "qcom,kaanapali-fastrpc"; + qcom,glink-channels = "fastrpcglink-apps-dsp"; + label = "cdsp"; + #address-cells = <1>; + #size-cells = <0>; + + compute-cb@1 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <1>; + + iommus = <&apps_smmu 0x0801 0x40>, + <&apps_smmu 0x15c1 0x0>; + dma-coherent; + }; + + compute-cb@2 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <2>; + + iommus = <&apps_smmu 0x0802 0x40>, + <&apps_smmu 0x15c2 0x0>; + dma-coherent; + }; + + compute-cb@3 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <3>; + + iommus = <&apps_smmu 0x0803 0x40>, + <&apps_smmu 0x15c3 0x0>; + dma-coherent; + }; + + compute-cb@4 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <4>; + + iommus = <&apps_smmu 0x0804 0x40>, + <&apps_smmu 0x15c4 0x0>; + dma-coherent; + }; + + compute-cb@5 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <5>; + + iommus = <&apps_smmu 0x0805 0x40>, + <&apps_smmu 0x15c5 0x0>; + dma-coherent; + }; + + compute-cb@6 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <6>; + + iommus = <&apps_smmu 0x0806 0x40>, + <&apps_smmu 0x15c6 0x0>; + dma-coherent; + }; + + compute-cb@7 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <7>; + + iommus = <&apps_smmu 0x0807 0x40>, + <&apps_smmu 0x15c7 0x0>; + dma-coherent; + }; + + compute-cb@8 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <8>; + + iommus = <&apps_smmu 0x0808 0x40>, + <&apps_smmu 0x15c8 0x0>; + dma-coherent; + }; + + compute-cb@9 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <9>; + + iommus = <&apps_smmu 0x0809 0x40>, + <&apps_smmu 0x15c9 0x0>; + dma-coherent; + }; + + compute-cb@12 { + compatible = "qcom,fastrpc-compute-cb"; + reg = <12>; + + iommus = <&apps_smmu 0x080c 0x40>, + <&apps_smmu 0x15cc 0x0>; + dma-coherent; + }; + }; + }; + }; + + pmu@31081000 { + compatible = "qcom,hawi-llcc-bwmon", "qcom,sc7280-llcc-bwmon"; + reg = <0x0 0x31081000 0x0 0x1000>; + + interrupts = <GIC_ESPI 145 IRQ_TYPE_LEVEL_HIGH>; + + interconnects = <&mc_virt MASTER_LLCC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>; + + operating-points-v2 = <&llcc_bwmon_opp_table>; + + llcc_bwmon_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-0 { + opp-peak-kBps = <13128000>; + }; + + opp-1 { + opp-peak-kBps = <32472000>; + }; + + opp-2 { + opp-peak-kBps = <37320000>; + }; + + opp-3 { + opp-peak-kBps = <40992000>; + }; + + opp-4 { + opp-peak-kBps = <50208000>; + }; + + opp-5 { + opp-peak-kBps = <65664000>; + }; + + opp-6 { + opp-peak-kBps = <76488000>; + }; + + opp-7 { + opp-peak-kBps = <88464000>; + }; + + opp-8 { + opp-peak-kBps = <101376000>; + }; + + opp-9 { + opp-peak-kBps = <114720000>; + }; + + opp-10 { + opp-peak-kBps = <127992000>; + }; + }; + }; + + pmu@310b7500 { + compatible = "qcom,hawi-cpu-bwmon", "qcom,sdm845-bwmon"; + reg = <0x0 0x310b7500 0x0 0x600>; + + interrupts = <GIC_ESPI 645 IRQ_TYPE_LEVEL_HIGH>; + + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &gem_noc SLAVE_LLCC QCOM_ICC_TAG_ACTIVE_ONLY>; + + operating-points-v2 = <&cpu_bwmon_opp_table>; + + cpu_bwmon_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-0 { + opp-peak-kBps = <12516000>; + }; + + opp-1 { + opp-peak-kBps = <17574000>; + }; + + opp-2 { + opp-peak-kBps = <35586000>; + }; + + opp-3 { + opp-peak-kBps = <39090000>; + }; + + opp-4 { + opp-peak-kBps = <47880000>; + }; + + opp-5 { + opp-peak-kBps = <62622000>; + }; + + opp-6 { + opp-peak-kBps = <73542000>; + }; + + opp-7 { + opp-peak-kBps = <84360000>; + }; + + opp-8 { + opp-peak-kBps = <96678000>; + }; + }; + }; + + gem_noc: interconnect@31100000 { + compatible = "qcom,hawi-gem-noc"; + reg = <0x0 0x31100000 0x0 0x160200>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + llclpi_noc: interconnect@31310000 { + compatible = "qcom,hawi-llclpi-noc"; + reg = <0x0 0x31310000 0x0 0x17200>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + system-cache-controller@31800000 { + compatible = "qcom,hawi-llcc"; + reg = <0x0 0x31800000 0x0 0x200000>, + <0x0 0x32800000 0x0 0x200000>, + <0x0 0x31c00000 0x0 0x200000>, + <0x0 0x32c00000 0x0 0x200000>, + <0x0 0x34800000 0x0 0x200000>, + <0x0 0x34c00000 0x0 0x200000>; + reg-names = "llcc0_base", + "llcc1_base", + "llcc2_base", + "llcc3_base", + "llcc_broadcast_base", + "llcc_broadcast_and_base"; + + interrupts = <GIC_ESPI 330 IRQ_TYPE_LEVEL_HIGH>; + memory-region = <&cpucp_slc_mem_sub>; + }; + + sram: sram@81f08000 { + compatible = "mmio-sram"; + reg = <0x0 0x81f08000 0x0 0x200>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x0 0x81f08000 0x200>; + + pdp_rx: scp-sram-section@0 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x80>; + }; + + pdp_tx: scp-sram-section@80 { + compatible = "arm,scmi-shmem"; + reg = <0x80 0x80>; + }; + }; + }; + + thermal-zones { + camera-0-thermal { + thermal-sensors = <&tsens6 4>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + camera-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + camera-1-thermal { + thermal-sensors = <&tsens6 5>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + camera-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-0-thermal { + thermal-sensors = <&tsens2 0>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-0-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-1-thermal { + thermal-sensors = <&tsens2 1>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-0-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-0-2-thermal { + thermal-sensors = <&tsens2 2>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-0-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-1-0-thermal { + thermal-sensors = <&tsens2 3>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-1-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-1-1-thermal { + thermal-sensors = <&tsens2 4>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-1-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-1-2-thermal { + thermal-sensors = <&tsens2 5>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-1-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-2-0-thermal { + thermal-sensors = <&tsens0 6>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-2-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-2-1-thermal { + thermal-sensors = <&tsens0 7>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-2-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-3-0-thermal { + thermal-sensors = <&tsens0 0>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-3-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-3-1-thermal { + thermal-sensors = <&tsens0 1>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-3-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-4-0-thermal { + thermal-sensors = <&tsens0 8>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-4-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-4-1-thermal { + thermal-sensors = <&tsens0 9>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-4-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-5-0-thermal { + thermal-sensors = <&tsens0 2>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-5-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-5-1-thermal { + thermal-sensors = <&tsens0 3>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-5-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-6-0-thermal { + thermal-sensors = <&tsens0 10>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-6-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-6-1-thermal { + thermal-sensors = <&tsens0 11>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-6-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-7-0-thermal { + thermal-sensors = <&tsens0 4>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-7-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu-7-1-thermal { + thermal-sensors = <&tsens0 5>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpu-7-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpullc-0-thermal { + thermal-sensors = <&tsens1 0>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpullc-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpullc-1-thermal { + thermal-sensors = <&tsens1 1>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + cpullc-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + ddr-thermal { + thermal-sensors = <&tsens6 7>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + ddr-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpu-0-0-thermal { + thermal-sensors = <&tsens5 0>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpu-0-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpu-0-1-thermal { + thermal-sensors = <&tsens5 1>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpu-0-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpu-0-2-thermal { + thermal-sensors = <&tsens5 2>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + gpu-0-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpu-1-0-thermal { + thermal-sensors = <&tsens5 3>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + gpu-1-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpu-1-1-thermal { + thermal-sensors = <&tsens5 4>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + gpu-1-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpu-1-2-thermal { + thermal-sensors = <&tsens5 5>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + gpu-1-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpu-2-0-thermal { + thermal-sensors = <&tsens5 6>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + gpu-2-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpu-2-1-thermal { + thermal-sensors = <&tsens5 7>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + gpu-2-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpu-2-2-thermal { + thermal-sensors = <&tsens5 8>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + gpu-2-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-0-thermal { + thermal-sensors = <&tsens5 9>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + gpuss-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-1-thermal { + thermal-sensors = <&tsens5 10>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + gpuss-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + mdmss-0-thermal { + thermal-sensors = <&tsens6 0>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + mdmss-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + mdmss-1-thermal { + thermal-sensors = <&tsens6 1>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + mdmss-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + mdmss-2-thermal { + thermal-sensors = <&tsens6 2>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + mdmss-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + mdmss-3-thermal { + thermal-sensors = <&tsens6 3>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + mdmss-3-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspllv-0-0-thermal { + thermal-sensors = <&tsens3 5>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspllv-0-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspllv-0-1-thermal { + thermal-sensors = <&tsens3 6>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspllv-0-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspllv-1-0-thermal { + thermal-sensors = <&tsens3 7>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspllv-1-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspllv-1-1-thermal { + thermal-sensors = <&tsens3 8>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspllv-1-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspmxu0-0-0-thermal { + thermal-sensors = <&tsens4 1>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspmxu0-0-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspmxu0-0-1-thermal { + thermal-sensors = <&tsens4 2>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspmxu0-0-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspmxu0-1-0-thermal { + thermal-sensors = <&tsens4 3>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspmxu0-1-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspmxu0-1-1-thermal { + thermal-sensors = <&tsens4 4>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspmxu0-1-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspmxu1-0-0-thermal { + thermal-sensors = <&tsens4 5>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspmxu1-0-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspmxu1-0-1-thermal { + thermal-sensors = <&tsens4 6>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspmxu1-0-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspmxu1-1-0-thermal { + thermal-sensors = <&tsens4 7>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspmxu1-1-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspmxu1-1-1-thermal { + thermal-sensors = <&tsens4 8>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspmxu1-1-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspmxutop-thermal { + thermal-sensors = <&tsens4 0>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspmxutop-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspq6-thermal { + thermal-sensors = <&tsens3 0>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspq6-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspvxu-0-thermal { + thermal-sensors = <&tsens3 1>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspvxu-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspvxu-1-thermal { + thermal-sensors = <&tsens3 2>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspvxu-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspvxu-2-thermal { + thermal-sensors = <&tsens3 3>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspvxu-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + nspvxu-3-thermal { + thermal-sensors = <&tsens3 4>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + nspvxu-3-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-0-thermal { + thermal-sensors = <&tsens1 2>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + qmx-0-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-1-thermal { + thermal-sensors = <&tsens1 3>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + qmx-1-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-2-thermal { + thermal-sensors = <&tsens1 4>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + qmx-2-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-3-thermal { + thermal-sensors = <&tsens1 5>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + qmx-3-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + qmx-4-thermal { + thermal-sensors = <&tsens1 6>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <5000>; + type = "hot"; + }; + + qmx-4-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + video-thermal { + thermal-sensors = <&tsens6 6>; + + trips { + trip-point0 { + temperature = <120000>; + hysteresis = <2000>; + type = "hot"; + }; + + video-critical { + temperature = <125000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + + interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, + <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, + <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, + <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; + }; +};
diff --git a/arch/arm64/boot/dts/qcom/ipq5018-rdp432-c2.dts b/arch/arm64/boot/dts/qcom/ipq5018-rdp432-c2.dts index 33eef92..34d4a08 100644 --- a/arch/arm64/boot/dts/qcom/ipq5018-rdp432-c2.dts +++ b/arch/arm64/boot/dts/qcom/ipq5018-rdp432-c2.dts
@@ -30,6 +30,16 @@ &blsp1_uart1 { status = "okay"; }; +&mdio1 { + clock-frequency = <6250000>; + + status = "okay"; + + ethernet-phy@1c { + reg = <0x1c>; + }; +}; + &pcie0 { pinctrl-0 = <&pcie0_default>; pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/qcom/ipq5018.dtsi b/arch/arm64/boot/dts/qcom/ipq5018.dtsi index 4fc627b..fe1ed24 100644 --- a/arch/arm64/boot/dts/qcom/ipq5018.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq5018.dtsi
@@ -222,8 +222,7 @@ mdio0: mdio@88000 { clocks = <&gcc GCC_MDIO0_AHB_CLK>; clock-names = "gcc_mdio_ahb_clk"; - - status = "disabled"; + clock-frequency = <6250000>; ge_phy: ethernet-phy@7 { compatible = "ethernet-phy-id004d.d0c0"; @@ -241,6 +240,8 @@ mdio1: mdio@90000 { reg = <0x00090000 0x64>; #address-cells = <1>; #size-cells = <0>; + pinctrl-0 = <&mdio_pins>; + pinctrl-names = "default"; clocks = <&gcc GCC_MDIO1_AHB_CLK>; clock-names = "gcc_mdio_ahb_clk"; @@ -421,6 +422,22 @@ tlmm: pinctrl@1000000 { interrupt-controller; #interrupt-cells = <2>; + mdio_pins: mdio-state { + mdc-pins { + pins = "gpio36"; + function = "mdc"; + drive-strength = <8>; + bias-pull-up; + }; + + mdio-pins { + pins = "gpio37"; + function = "mdio"; + drive-strength = <8>; + bias-pull-up; + }; + }; + uart1_pins: uart1-state { pins = "gpio31", "gpio32", "gpio33", "gpio34"; function = "blsp1_uart1";
diff --git a/arch/arm64/boot/dts/qcom/ipq5332-rdp-common.dtsi b/arch/arm64/boot/dts/qcom/ipq5332-rdp-common.dtsi index 3bbf748..6f5b193 100644 --- a/arch/arm64/boot/dts/qcom/ipq5332-rdp-common.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq5332-rdp-common.dtsi
@@ -141,5 +141,7 @@ flash@0 { nand-ecc-engine = <&qpic_nand>; nand-ecc-strength = <4>; nand-ecc-step-size = <512>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; }; };
diff --git a/arch/arm64/boot/dts/qcom/ipq5424-rdp466.dts b/arch/arm64/boot/dts/qcom/ipq5424-rdp466.dts index be86572..793afc3 100644 --- a/arch/arm64/boot/dts/qcom/ipq5424-rdp466.dts +++ b/arch/arm64/boot/dts/qcom/ipq5424-rdp466.dts
@@ -261,6 +261,8 @@ flash@0 { nand-ecc-engine = <&qpic_nand>; nand-ecc-strength = <4>; nand-ecc-step-size = <512>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; }; };
diff --git a/arch/arm64/boot/dts/qcom/ipq5424.dtsi b/arch/arm64/boot/dts/qcom/ipq5424.dtsi index 702061e..23f851e 100644 --- a/arch/arm64/boot/dts/qcom/ipq5424.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq5424.dtsi
@@ -624,6 +624,7 @@ watchdog@f410000 { reg = <0 0x0f410000 0 0x1000>; interrupts = <GIC_SPI 0 IRQ_TYPE_EDGE_RISING>; clocks = <&sleep_clk>; + sram = <&restart_reason>; }; qusb_phy_1: phy@71000 { @@ -730,6 +731,21 @@ ssphy_0: phy@7d000 { status = "disabled"; }; + sram@8600000 { + compatible = "qcom,ipq5424-imem", "mmio-sram"; + reg = <0 0x08600000 0 0x1c000>; + ranges = <0 0 0x08600000 0x1c000>; + + no-memory-wc; + + #address-cells = <1>; + #size-cells = <1>; + + restart_reason: restartreason-sram@7b0 { + reg = <0x7b0 0x4>; + }; + }; + usb3: usb3@8af8800 { compatible = "qcom,ipq5424-dwc3", "qcom,dwc3"; reg = <0 0x08af8800 0 0x400>;
diff --git a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi index 62877b4..8613852 100644 --- a/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq9574-rdp-common.dtsi
@@ -249,6 +249,8 @@ flash@0 { nand-ecc-engine = <&qpic_nand>; nand-ecc-strength = <4>; nand-ecc-step-size = <512>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; }; };
diff --git a/arch/arm64/boot/dts/qcom/ipq9574.dtsi b/arch/arm64/boot/dts/qcom/ipq9574.dtsi index 5a5bda5..771a5958 100644 --- a/arch/arm64/boot/dts/qcom/ipq9574.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq9574.dtsi
@@ -428,7 +428,7 @@ gcc: clock-controller@1800000 { <&pcie1_phy>, <&pcie2_phy>, <&pcie3_phy>, - <0>; + <&usb_0_qmpphy>; #clock-cells = <1>; #reset-cells = <1>; #interconnect-cells = <1>; @@ -471,6 +471,7 @@ sdhc_1: mmc@7804000 { <&xo_board_clk>, <&gcc GCC_SDCC1_ICE_CORE_CLK>; clock-names = "iface", "core", "xo", "ice"; + resets = <&gcc GCC_SDCC_BCR>; non-removable; supports-cqe; pinctrl-0 = <&sdc_default_state>;
diff --git a/arch/arm64/boot/dts/qcom/ipq9650-rdp488.dts b/arch/arm64/boot/dts/qcom/ipq9650-rdp488.dts index 6871f3d..f6411a5 100644 --- a/arch/arm64/boot/dts/qcom/ipq9650-rdp488.dts +++ b/arch/arm64/boot/dts/qcom/ipq9650-rdp488.dts
@@ -5,6 +5,8 @@ /dts-v1/; +#include <dt-bindings/gpio/gpio.h> + #include "ipq9650.dtsi" / { @@ -20,6 +22,54 @@ chosen { }; }; +&pcie1 { + pinctrl-0 = <&pcie1_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie1_phy { + status = "okay"; +}; + +&pcie1_port0 { + reset-gpios = <&tlmm 28 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 29 GPIO_ACTIVE_LOW>; +}; + +&pcie2 { + pinctrl-0 = <&pcie2_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie2_phy { + status = "okay"; +}; + +&pcie2_port0 { + reset-gpios = <&tlmm 52 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 53 GPIO_ACTIVE_LOW>; +}; + +&pcie3 { + pinctrl-0 = <&pcie3_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie3_phy { + status = "okay"; +}; + +&pcie3_port0 { + reset-gpios = <&tlmm 41 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 42 GPIO_ACTIVE_LOW>; +}; + &sdhc { max-frequency = <192000000>; bus-width = <4>; @@ -36,6 +86,75 @@ &sleep_clk { }; &tlmm { + pcie1_default_state: pcie1-default-state { + clkreq-n-pins { + pins = "gpio27"; + function = "pcie1_clk_req_n"; + drive-strength = <8>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio28"; + function = "gpio"; + drive-strength = <8>; + bias-pull-down; + }; + + wake-n-pins { + pins = "gpio29"; + function = "pcie1_wake"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + pcie2_default_state: pcie2-default-state { + clkreq-n-pins { + pins = "gpio51"; + function = "pcie2_clk_req_n"; + drive-strength = <8>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio52"; + function = "gpio"; + drive-strength = <8>; + bias-pull-down; + }; + + wake-n-pins { + pins = "gpio53"; + function = "pcie2_wake"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + pcie3_default_state: pcie3-default-state { + clkreq-n-pins { + pins = "gpio40"; + function = "pcie3_clk_req_n"; + drive-strength = <8>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio41"; + function = "gpio"; + drive-strength = <8>; + bias-pull-down; + }; + + wake-n-pins { + pins = "gpio42"; + function = "pcie3_wake"; + drive-strength = <8>; + bias-pull-up; + }; + }; + qup_uart1_default_state: qup-uart1-default-state { pins = "gpio43", "gpio44"; function = "qup_se6";
diff --git a/arch/arm64/boot/dts/qcom/ipq9650.dtsi b/arch/arm64/boot/dts/qcom/ipq9650.dtsi index 3d3b317..3f18438 100644 --- a/arch/arm64/boot/dts/qcom/ipq9650.dtsi +++ b/arch/arm64/boot/dts/qcom/ipq9650.dtsi
@@ -5,6 +5,7 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/clock/qcom,ipq9650-gcc.h> +#include <dt-bindings/interconnect/qcom,ipq9650.h> #include <dt-bindings/reset/qcom,ipq9650-gcc.h> / { @@ -200,6 +201,160 @@ soc@0 { dma-ranges = <0 0 0 0 0x10 0>; ranges = <0 0 0 0 0x10 0>; + refgen_pcie: regulator@6c000 { + compatible = "qcom,ipq9650-refgen-regulator"; + reg = <0x0 0x0006c000 0x0 0x84>; + clocks = <&gcc GCC_REFGEN_PCIE_CORE_CLK>, + <&gcc GCC_REFGEN_PCIE_HCLK>; + clock-names = "core", + "hclk"; + }; + + pcie0_phy: phy@84000 { + compatible = "qcom,ipq9650-qmp-gen3x1-pcie-phy"; + reg = <0x0 0x00084000 0x0 0x1000>; + + clocks = <&gcc GCC_PCIE0_AUX_CLK>, + <&gcc GCC_PCIE0_AHB_CLK>, + <&gcc GCC_PCIE0_PIPE_CLK>; + clock-names = "aux", + "cfg_ahb", + "pipe"; + + assigned-clocks = <&gcc GCC_PCIE0_AUX_CLK>; + assigned-clock-rates = <20000000>; + + resets = <&gcc GCC_PCIE0_PHY_BCR>, + <&gcc GCC_PCIE0PHY_PHY_BCR>; + reset-names = "phy", + "common"; + + refgen-supply = <&refgen_pcie>; + + clock-output-names = "pcie0_pipe_clk"; + #clock-cells = <0>; + + #phy-cells = <0>; + + status = "disabled"; + }; + + pcie4_phy: phy@8c000 { + compatible = "qcom,ipq9650-qmp-gen3x1-pcie-phy"; + reg = <0x0 0x0008c000 0x0 0x1000>; + + clocks = <&gcc GCC_PCIE4_AUX_CLK>, + <&gcc GCC_PCIE4_AHB_CLK>, + <&gcc GCC_PCIE4_PIPE_CLK>; + clock-names = "aux", + "cfg_ahb", + "pipe"; + + assigned-clocks = <&gcc GCC_PCIE4_AUX_CLK>; + assigned-clock-rates = <20000000>; + + resets = <&gcc GCC_PCIE4_PHY_BCR>, + <&gcc GCC_PCIE4PHY_PHY_BCR>; + reset-names = "phy", + "common"; + + refgen-supply = <&refgen_pcie>; + + clock-output-names = "pcie4_pipe_clk"; + #clock-cells = <0>; + + #phy-cells = <0>; + + status = "disabled"; + }; + + pcie3_phy: phy@b4000 { + compatible = "qcom,ipq9650-qmp-gen3x2-pcie-phy"; + reg = <0x0 0x000b4000 0x0 0x2000>; + + clocks = <&gcc GCC_PCIE3_AUX_CLK>, + <&gcc GCC_PCIE3_AHB_CLK>, + <&gcc GCC_PCIE3_PIPE_CLK>; + clock-names = "aux", + "cfg_ahb", + "pipe"; + + assigned-clocks = <&gcc GCC_PCIE3_AUX_CLK>; + assigned-clock-rates = <20000000>; + + resets = <&gcc GCC_PCIE3_PHY_BCR>, + <&gcc GCC_PCIE3PHY_PHY_BCR>; + reset-names = "phy", + "common"; + + refgen-supply = <&refgen_pcie>; + + clock-output-names = "pcie3_pipe_clk"; + #clock-cells = <0>; + + #phy-cells = <0>; + + status = "disabled"; + }; + + pcie1_phy: phy@f4000 { + compatible = "qcom,ipq9650-qmp-gen3x2-pcie-phy"; + reg = <0x0 0x000f4000 0x0 0x2000>; + + clocks = <&gcc GCC_PCIE1_AUX_CLK>, + <&gcc GCC_PCIE1_AHB_CLK>, + <&gcc GCC_PCIE1_PIPE_CLK>; + clock-names = "aux", + "cfg_ahb", + "pipe"; + + assigned-clocks = <&gcc GCC_PCIE1_AUX_CLK>; + assigned-clock-rates = <20000000>; + + resets = <&gcc GCC_PCIE1_PHY_BCR>, + <&gcc GCC_PCIE1PHY_PHY_BCR>; + reset-names = "phy", + "common"; + + refgen-supply = <&refgen_pcie>; + + clock-output-names = "pcie1_pipe_clk"; + #clock-cells = <0>; + + #phy-cells = <0>; + + status = "disabled"; + }; + + pcie2_phy: phy@fc000 { + compatible = "qcom,ipq9650-qmp-gen3x2-pcie-phy"; + reg = <0x0 0x000fc000 0x0 0x2000>; + + clocks = <&gcc GCC_PCIE2_AUX_CLK>, + <&gcc GCC_PCIE2_AHB_CLK>, + <&gcc GCC_PCIE2_PIPE_CLK>; + clock-names = "aux", + "cfg_ahb", + "pipe"; + + assigned-clocks = <&gcc GCC_PCIE2_AUX_CLK>; + assigned-clock-rates = <20000000>; + + resets = <&gcc GCC_PCIE2_PHY_BCR>, + <&gcc GCC_PCIE2PHY_PHY_BCR>; + reset-names = "phy", + "common"; + + refgen-supply = <&refgen_pcie>; + + clock-output-names = "pcie2_pipe_clk"; + #clock-cells = <0>; + + #phy-cells = <0>; + + status = "disabled"; + }; + tlmm: pinctrl@1000000 { compatible = "qcom,ipq9650-tlmm"; reg = <0x0 0x01000000 0x0 0x300000>; @@ -216,15 +371,16 @@ gcc: clock-controller@1800000 { reg = <0x0 0x01800000 0x0 0x40000>; clocks = <&xo_board>, <&sleep_clk>, - <0>, - <0>, - <0>, - <0>, - <0>, + <&pcie0_phy>, + <&pcie1_phy>, + <&pcie2_phy>, + <&pcie3_phy>, + <&pcie4_phy>, <0>, <0>; #clock-cells = <1>; #reset-cells = <1>; + #interconnect-cells = <1>; }; tcsr_mutex: hwlock@1917000 { @@ -371,6 +527,506 @@ frame@f42d000 { status = "disabled"; }; }; + + pcie3: pcie@30000000 { + compatible = "qcom,pcie-ipq9650", "qcom,pcie-ipq9574"; + reg = <0x0 0x30000000 0x0 0xf1d>, + <0x0 0x30000f20 0x0 0xa8>, + <0x0 0x30001000 0x0 0x1000>, + <0x0 0x000b0000 0x0 0x3000>, + <0x0 0x30100000 0x0 0x1000>, + <0x0 0x000b6000 0x0 0x1000>; + reg-names = "dbi", + "elbi", + "atu", + "parf", + "config", + "mhi"; + device_type = "pci"; + linux,pci-domain = <3>; + #address-cells = <3>; + #size-cells = <2>; + + ranges = <0x01000000 0x0 0x00000000 0x0 0x30200000 0x0 0x00100000>, + <0x02000000 0x0 0x30300000 0x0 0x30300000 0x0 0x0fd00000>; + + msi-map = <0x0 &intc 0x0 0x1000>; + + interrupts = <GIC_SPI 496 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 497 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 498 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 499 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 500 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 501 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 502 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 503 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 504 IRQ_TYPE_LEVEL_HIGH 0>; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0x0 0x0 0x0 0x7>; + interrupt-map = <0 0 0 1 &intc GIC_SPI 505 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 2 &intc GIC_SPI 506 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 3 &intc GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 4 &intc GIC_SPI 508 IRQ_TYPE_LEVEL_HIGH 0>; + + clocks = <&gcc GCC_PCIE3_AXI_M_CLK>, + <&gcc GCC_PCIE3_AXI_S_CLK>, + <&gcc GCC_PCIE3_AXI_S_BRIDGE_CLK>, + <&gcc GCC_PCIE3_RCHNG_CLK>, + <&gcc GCC_PCIE3_AHB_CLK>, + <&gcc GCC_PCIE3_AUX_CLK>; + clock-names = "axi_m", + "axi_s", + "axi_bridge", + "rchng", + "ahb", + "aux"; + + resets = <&gcc GCC_PCIE3_PIPE_CLK_ARES>, + <&gcc GCC_PCIE3_CORE_STICKY_RESET>, + <&gcc GCC_PCIE3_AXI_S_STICKY_RESET>, + <&gcc GCC_PCIE3_AXI_S_CLK_ARES>, + <&gcc GCC_PCIE3_AXI_M_STICKY_RESET>, + <&gcc GCC_PCIE3_AXI_M_CLK_ARES>, + <&gcc GCC_PCIE3_AUX_CLK_ARES>, + <&gcc GCC_PCIE3_AHB_CLK_ARES>; + reset-names = "pipe", + "sticky", + "axi_s_sticky", + "axi_s", + "axi_m_sticky", + "axi_m", + "aux", + "ahb"; + + interconnects = <&gcc MASTER_ANOC_PCIE3 &gcc SLAVE_ANOC_PCIE3>, + <&gcc MASTER_CNOC_PCIE3 &gcc SLAVE_CNOC_PCIE3>; + interconnect-names = "pcie-mem", "cpu-pcie"; + + status = "disabled"; + + pcie3_port0: pcie@0 { + compatible = "pciclass,0604"; + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + phys = <&pcie3_phy>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; + }; + + pcie2: pcie@40000000 { + compatible = "qcom,pcie-ipq9650", "qcom,pcie-ipq9574"; + reg = <0x0 0x40000000 0x0 0xf1d>, + <0x0 0x40000f20 0x0 0xa8>, + <0x0 0x40001000 0x0 0x1000>, + <0x0 0x000f8000 0x0 0x3000>, + <0x0 0x40100000 0x0 0x1000>, + <0x0 0x000fe000 0x0 0x1000>; + reg-names = "dbi", + "elbi", + "atu", + "parf", + "config", + "mhi"; + device_type = "pci"; + linux,pci-domain = <2>; + #address-cells = <3>; + #size-cells = <2>; + + ranges = <0x01000000 0x0 0x00000000 0x0 0x40200000 0x0 0x00100000>, + <0x02000000 0x0 0x40300000 0x0 0x40300000 0x0 0x0fd00000>; + + msi-map = <0x0 &intc 0x0 0x1000>; + + interrupts = <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 474 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 475 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 477 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 478 IRQ_TYPE_LEVEL_HIGH 0>; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc GIC_SPI 479 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 2 &intc GIC_SPI 480 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 3 &intc GIC_SPI 481 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 4 &intc GIC_SPI 482 IRQ_TYPE_LEVEL_HIGH 0>; + + clocks = <&gcc GCC_PCIE2_AXI_M_CLK>, + <&gcc GCC_PCIE2_AXI_S_CLK>, + <&gcc GCC_PCIE2_AXI_S_BRIDGE_CLK>, + <&gcc GCC_PCIE2_RCHNG_CLK>, + <&gcc GCC_PCIE2_AHB_CLK>, + <&gcc GCC_PCIE2_AUX_CLK>; + clock-names = "axi_m", + "axi_s", + "axi_bridge", + "rchng", + "ahb", + "aux"; + + resets = <&gcc GCC_PCIE2_PIPE_CLK_ARES>, + <&gcc GCC_PCIE2_CORE_STICKY_RESET>, + <&gcc GCC_PCIE2_AXI_S_STICKY_RESET>, + <&gcc GCC_PCIE2_AXI_S_CLK_ARES>, + <&gcc GCC_PCIE2_AXI_M_STICKY_RESET>, + <&gcc GCC_PCIE2_AXI_M_CLK_ARES>, + <&gcc GCC_PCIE2_AUX_CLK_ARES>, + <&gcc GCC_PCIE2_AHB_CLK_ARES>; + reset-names = "pipe", + "sticky", + "axi_s_sticky", + "axi_s", + "axi_m_sticky", + "axi_m", + "aux", + "ahb"; + + interconnects = <&gcc MASTER_ANOC_PCIE2 &gcc SLAVE_ANOC_PCIE2>, + <&gcc MASTER_CNOC_PCIE2 &gcc SLAVE_CNOC_PCIE2>; + interconnect-names = "pcie-mem", "cpu-pcie"; + + status = "disabled"; + + pcie2_port0: pcie@0 { + compatible = "pciclass,0604"; + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + phys = <&pcie2_phy>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; + }; + + pcie1: pcie@50000000 { + compatible = "qcom,pcie-ipq9650", "qcom,pcie-ipq9574"; + reg = <0x0 0x50000000 0x0 0xf1d>, + <0x0 0x50000f20 0x0 0xa8>, + <0x0 0x50001000 0x0 0x1000>, + <0x0 0x000f0000 0x0 0x3000>, + <0x0 0x50100000 0x0 0x1000>, + <0x0 0x000f6000 0x0 0x1000>; + reg-names = "dbi", + "elbi", + "atu", + "parf", + "config", + "mhi"; + device_type = "pci"; + linux,pci-domain = <1>; + #address-cells = <3>; + #size-cells = <2>; + + ranges = <0x01000000 0x0 0x00000000 0x0 0x50200000 0x0 0x00100000>, + <0x02000000 0x0 0x50300000 0x0 0x50300000 0x0 0x0fd00000>; + + msi-map = <0x0 &intc 0x0 0x1000>; + + interrupts = <GIC_SPI 455 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH 0>; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 2 &intc GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 3 &intc GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 4 &intc GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH 0>; + + clocks = <&gcc GCC_PCIE1_AXI_M_CLK>, + <&gcc GCC_PCIE1_AXI_S_CLK>, + <&gcc GCC_PCIE1_AXI_S_BRIDGE_CLK>, + <&gcc GCC_PCIE1_RCHNG_CLK>, + <&gcc GCC_PCIE1_AHB_CLK>, + <&gcc GCC_PCIE1_AUX_CLK>; + clock-names = "axi_m", + "axi_s", + "axi_bridge", + "rchng", + "ahb", + "aux"; + + resets = <&gcc GCC_PCIE1_PIPE_CLK_ARES>, + <&gcc GCC_PCIE1_CORE_STICKY_RESET>, + <&gcc GCC_PCIE1_AXI_S_STICKY_RESET>, + <&gcc GCC_PCIE1_AXI_S_CLK_ARES>, + <&gcc GCC_PCIE1_AXI_M_STICKY_RESET>, + <&gcc GCC_PCIE1_AXI_M_CLK_ARES>, + <&gcc GCC_PCIE1_AUX_CLK_ARES>, + <&gcc GCC_PCIE1_AHB_CLK_ARES>; + reset-names = "pipe", + "sticky", + "axi_s_sticky", + "axi_s", + "axi_m_sticky", + "axi_m", + "aux", + "ahb"; + + interconnects = <&gcc MASTER_ANOC_PCIE1 &gcc SLAVE_ANOC_PCIE1>, + <&gcc MASTER_CNOC_PCIE1 &gcc SLAVE_CNOC_PCIE1>; + interconnect-names = "pcie-mem", "cpu-pcie"; + + status = "disabled"; + + pcie1_port0: pcie@0 { + compatible = "pciclass,0604"; + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + phys = <&pcie1_phy>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; + }; + + pcie4: pcie@60000000 { + compatible = "qcom,pcie-ipq9650", "qcom,pcie-ipq9574"; + reg = <0x0 0x60000000 0x0 0xf1d>, + <0x0 0x60000f20 0x0 0xa8>, + <0x0 0x60001000 0x0 0x1000>, + <0x0 0x00088000 0x0 0x3000>, + <0x0 0x60100000 0x0 0x1000>, + <0x0 0x0008e000 0x0 0x1000>; + reg-names = "dbi", + "elbi", + "atu", + "parf", + "config", + "mhi"; + device_type = "pci"; + linux,pci-domain = <4>; + #address-cells = <3>; + #size-cells = <2>; + + ranges = <0x01000000 0x0 0x00000000 0x0 0x60200000 0x0 0x00100000>, + <0x02000000 0x0 0x60300000 0x0 0x60300000 0x0 0x0fd00000>; + + msi-map = <0x0 &intc 0x0 0x1000>; + + interrupts = <GIC_SPI 511 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 512 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 513 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 514 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 515 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 516 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 517 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 518 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 519 IRQ_TYPE_LEVEL_HIGH 0>; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc GIC_SPI 520 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 2 &intc GIC_SPI 521 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 3 &intc GIC_SPI 522 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 4 &intc GIC_SPI 523 IRQ_TYPE_LEVEL_HIGH 0>; + + clocks = <&gcc GCC_PCIE4_AXI_M_CLK>, + <&gcc GCC_PCIE4_AXI_S_CLK>, + <&gcc GCC_PCIE4_AXI_S_BRIDGE_CLK>, + <&gcc GCC_PCIE4_RCHNG_CLK>, + <&gcc GCC_PCIE4_AHB_CLK>, + <&gcc GCC_PCIE4_AUX_CLK>; + clock-names = "axi_m", + "axi_s", + "axi_bridge", + "rchng", + "ahb", + "aux"; + + resets = <&gcc GCC_PCIE4_PIPE_CLK_ARES>, + <&gcc GCC_PCIE4_CORE_STICKY_RESET>, + <&gcc GCC_PCIE4_AXI_S_STICKY_RESET>, + <&gcc GCC_PCIE4_AXI_S_CLK_ARES>, + <&gcc GCC_PCIE4_AXI_M_STICKY_RESET>, + <&gcc GCC_PCIE4_AXI_M_CLK_ARES>, + <&gcc GCC_PCIE4_AUX_CLK_ARES>, + <&gcc GCC_PCIE4_AHB_CLK_ARES>; + reset-names = "pipe", + "sticky", + "axi_s_sticky", + "axi_s", + "axi_m_sticky", + "axi_m", + "aux", + "ahb"; + + interconnects = <&gcc MASTER_ANOC_PCIE4 &gcc SLAVE_ANOC_PCIE4>, + <&gcc MASTER_CNOC_PCIE4 &gcc SLAVE_CNOC_PCIE4>; + interconnect-names = "pcie-mem", "cpu-pcie"; + + status = "disabled"; + + pcie4_port0: pcie@0 { + compatible = "pciclass,0604"; + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + phys = <&pcie4_phy>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; + }; + + pcie0: pcie@70000000 { + compatible = "qcom,pcie-ipq9650", "qcom,pcie-ipq9574"; + reg = <0x0 0x70000000 0x0 0xf1d>, + <0x0 0x70000f20 0x0 0xa8>, + <0x0 0x70001000 0x0 0x1000>, + <0x0 0x00080000 0x0 0x3000>, + <0x0 0x70100000 0x0 0x1000>, + <0x0 0x00086000 0x0 0x1000>; + reg-names = "dbi", + "elbi", + "atu", + "parf", + "config", + "mhi"; + device_type = "pci"; + linux,pci-domain = <0>; + #address-cells = <3>; + #size-cells = <2>; + + ranges = <0x01000000 0x0 0x00000000 0x0 0x70200000 0x0 0x00100000>, + <0x02000000 0x0 0x70300000 0x0 0x70300000 0x0 0x0fd00000>; + + msi-map = <0x0 &intc 0x0 0x1000>; + + interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 426 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 431 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 432 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 433 IRQ_TYPE_LEVEL_HIGH 0>; + interrupt-names = "msi0", + "msi1", + "msi2", + "msi3", + "msi4", + "msi5", + "msi6", + "msi7", + "global"; + + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &intc GIC_SPI 434 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 2 &intc GIC_SPI 435 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 3 &intc GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH 0>, + <0 0 0 4 &intc GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH 0>; + + clocks = <&gcc GCC_PCIE0_AXI_M_CLK>, + <&gcc GCC_PCIE0_AXI_S_CLK>, + <&gcc GCC_PCIE0_AXI_S_BRIDGE_CLK>, + <&gcc GCC_PCIE0_RCHNG_CLK>, + <&gcc GCC_PCIE0_AHB_CLK>, + <&gcc GCC_PCIE0_AUX_CLK>; + clock-names = "axi_m", + "axi_s", + "axi_bridge", + "rchng", + "ahb", + "aux"; + + resets = <&gcc GCC_PCIE0_PIPE_CLK_ARES>, + <&gcc GCC_PCIE0_CORE_STICKY_RESET>, + <&gcc GCC_PCIE0_AXI_S_STICKY_RESET>, + <&gcc GCC_PCIE0_AXI_S_CLK_ARES>, + <&gcc GCC_PCIE0_AXI_M_STICKY_RESET>, + <&gcc GCC_PCIE0_AXI_M_CLK_ARES>, + <&gcc GCC_PCIE0_AUX_CLK_ARES>, + <&gcc GCC_PCIE0_AHB_CLK_ARES>; + reset-names = "pipe", + "sticky", + "axi_s_sticky", + "axi_s", + "axi_m_sticky", + "axi_m", + "aux", + "ahb"; + + interconnects = <&gcc MASTER_ANOC_PCIE0 &gcc SLAVE_ANOC_PCIE0>, + <&gcc MASTER_CNOC_PCIE0 &gcc SLAVE_CNOC_PCIE0>; + interconnect-names = "pcie-mem", "cpu-pcie"; + + status = "disabled"; + + pcie0_port0: pcie@0 { + compatible = "pciclass,0604"; + device_type = "pci"; + reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + phys = <&pcie0_phy>; + + #address-cells = <3>; + #size-cells = <2>; + ranges; + }; + }; }; timer {
diff --git a/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts b/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts index 6d81738..9eb02fd 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts +++ b/arch/arm64/boot/dts/qcom/kaanapali-mtp.dts
@@ -908,6 +908,14 @@ vreg_l7n_3p3: ldo7 { }; }; +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/kaanapali/gen80200_zap.mbn"; +}; + &lpass_vamacro { pinctrl-0 = <&dmic01_default>, <&dmic23_default>; pinctrl-names = "default"; @@ -976,7 +984,7 @@ &pcie0_phy { }; &pcie_port0 { - wake-gpios = <&tlmm 104 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 104 GPIO_ACTIVE_LOW>; reset-gpios = <&tlmm 102 GPIO_ACTIVE_LOW>; wifi@0 {
diff --git a/arch/arm64/boot/dts/qcom/kaanapali-qrd.dts b/arch/arm64/boot/dts/qcom/kaanapali-qrd.dts index abd3e9f..f6b0222 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali-qrd.dts +++ b/arch/arm64/boot/dts/qcom/kaanapali-qrd.dts
@@ -736,6 +736,14 @@ vreg_l7n_3p3: ldo7 { }; }; +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/kaanapali/gen80200_zap.mbn"; +}; + &pmh0101_flash { status = "okay";
diff --git a/arch/arm64/boot/dts/qcom/kaanapali.dtsi b/arch/arm64/boot/dts/qcom/kaanapali.dtsi index 131fd2a..e48a179 100644 --- a/arch/arm64/boot/dts/qcom/kaanapali.dtsi +++ b/arch/arm64/boot/dts/qcom/kaanapali.dtsi
@@ -26,6 +26,7 @@ #include <dt-bindings/soc/qcom,gpr.h> #include <dt-bindings/soc/qcom,rpmh-rsc.h> #include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h> +#include <dt-bindings/thermal/thermal.h> #include "kaanapali-ipcc.h" @@ -552,6 +553,8 @@ gcc: clock-controller@100000 { <&ufs_mem_phy 2>, <0>; + power-domains = <&rpmhpd RPMHPD_CX>; + #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; @@ -1866,7 +1869,7 @@ &clk_virt SLAVE_QUP_CORE_3 QCOM_ICC_TAG_ALWAYS>, status = "disabled"; }; - i2c16: i2c@198c000 { + i2c16: i2c@198c000 { compatible = "qcom,geni-i2c"; reg = <0x0 0x0198c000 0x0 0x4000>; interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>; @@ -2678,6 +2681,246 @@ videocc: clock-controller@20f0000 { #power-domain-cells = <1>; }; + gpu: gpu@3d00000 { + compatible = "qcom,adreno-44050a01", "qcom,adreno"; + reg = <0x0 0x03d00000 0x0 0x6c000>, + <0x0 0x03d9e000 0x0 0x2000>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem"; + + interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>; + + iommus = <&adreno_smmu 0 0x0>, + <&adreno_smmu 1 0x0>; + + operating-points-v2 = <&gpu_opp_table>; + + qcom,gmu = <&gmu>; + #cooling-cells = <2>; + + nvmem-cells = <&gpu_speed_bin>; + nvmem-cell-names = "speed_bin"; + + interconnects = <&gem_noc MASTER_GFX3D QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "gfx-mem"; + + gpu_zap_shader: zap-shader { + memory-region = <&gpu_microcode_mem>; + }; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2-adreno", + "operating-points-v2"; + + opp-160000000 { + opp-hz = /bits/ 64 <160000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D3>; + opp-peak-kBps = <2136718>; + opp-supported-hw = <0x0f>; + /* ACD is disabled */ + }; + + opp-191000000 { + opp-hz = /bits/ 64 <191000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2_1>; + opp-peak-kBps = <2136718>; + opp-supported-hw = <0x0f>; + /* ACD is disabled */ + }; + + opp-222000000 { + opp-hz = /bits/ 64 <222000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2>; + opp-peak-kBps = <2136718>; + opp-supported-hw = <0x0f>; + /* ACD is disabled */ + }; + + opp-282000000 { + opp-hz = /bits/ 64 <282000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1_1>; + opp-peak-kBps = <5285156>; + opp-supported-hw = <0x0f>; + qcom,opp-acd-level = <0xca2e5ffd>; + }; + + opp-342000000 { + opp-hz = /bits/ 64 <342000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>; + opp-peak-kBps = <5285156>; + opp-supported-hw = <0x0f>; + qcom,opp-acd-level = <0xe22a5ffd>; + }; + + opp-382000000 { + opp-hz = /bits/ 64 <382000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D0>; + opp-peak-kBps = <5285156>; + opp-supported-hw = <0x0f>; + qcom,opp-acd-level = <0xa22c5ffd>; + }; + + opp-422000000 { + opp-hz = /bits/ 64 <422000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>; + opp-peak-kBps = <6074218>; + opp-supported-hw = <0x0f>; + qcom,opp-acd-level = <0xa22c5ffd>; + }; + + opp-461000000 { + opp-hz = /bits/ 64 <461000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L0>; + opp-peak-kBps = <6074218>; + opp-supported-hw = <0x0f>; + qcom,opp-acd-level = <0xe82e5ffd>; + }; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L1>; + opp-peak-kBps = <6074218>; + opp-supported-hw = <0x0f>; + qcom,opp-acd-level = <0xe82c5ffd>; + }; + + opp-578000000 { + opp-hz = /bits/ 64 <578000000>; + opp-level = <RPMH_REGULATOR_LEVEL_SVS>; + opp-peak-kBps = <6074218>; + opp-supported-hw = <0x0f>; + qcom,opp-acd-level = <0xc02c5ffd>; + }; + + opp-646000000 { + opp-hz = /bits/ 64 <646000000>; + opp-level = <RPMH_REGULATOR_LEVEL_SVS_L0>; + opp-peak-kBps = <8171875>; + opp-supported-hw = <0x0f>; + qcom,opp-acd-level = <0xc02c5ffd>; + }; + + opp-726000000 { + opp-hz = /bits/ 64 <726000000>; + opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>; + opp-peak-kBps = <8171875>; + opp-supported-hw = <0x0f>; + qcom,opp-acd-level = <0x882f5ffd>; + }; + + opp-826000000 { + opp-hz = /bits/ 64 <826000000>; + opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2>; + opp-peak-kBps = <12449218>; + opp-supported-hw = <0x0f>; + qcom,opp-acd-level = <0xa82c5ffd>; + }; + + opp-902000000 { + opp-hz = /bits/ 64 <902000000>; + opp-level = <RPMH_REGULATOR_LEVEL_NOM>; + opp-peak-kBps = <12449218>; + opp-supported-hw = <0x0f>; + qcom,opp-acd-level = <0xa82b5ffd>; + }; + + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-level = <RPMH_REGULATOR_LEVEL_TURBO>; + opp-peak-kBps = <12449218>; + opp-supported-hw = <0x0f>; + qcom,opp-acd-level = <0x882a5ffd>; + }; + + opp-1050000000 { + opp-hz = /bits/ 64 <1050000000>; + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>; + opp-peak-kBps = <20832031>; + opp-supported-hw = <0x0f>; + qcom,opp-acd-level = <0x88295ffd>; + }; + + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L3>; + opp-peak-kBps = <20832031>; + opp-supported-hw = <0x07>; + qcom,opp-acd-level = <0xa02e5ffd>; + }; + + opp-1300000000 { + opp-hz = /bits/ 64 <1300000000>; + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L4>; + opp-peak-kBps = <20832031>; + opp-supported-hw = <0x03>; + qcom,opp-acd-level = <0x802d5ffd>; + }; + }; + }; + + gmu: gmu@3d6c000 { + compatible = "qcom,adreno-gmu-840.1", "qcom,adreno-gmu"; + + reg = <0x0 0x03d6c000 0x0 0x68000>; + reg-names = "gmu"; + + interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "hfi", "gmu"; + + clocks = <&gpucc GPU_CC_AHB_CLK>, + <&gpucc GPU_CC_CX_GMU_CLK>, + <&gpucc GPU_CC_CXO_CLK>, + <&gcc GCC_GPU_GEMNOC_GFX_CLK>, + <&gpucc GPU_CC_HUB_CX_INT_CLK>; + clock-names = "ahb", + "gmu", + "cxo", + "memnoc", + "hub"; + + power-domains = <&gpucc GPU_CC_CX_GDSC>, + <&gxclkctl GX_CLKCTL_GX_GDSC>; + power-domain-names = "cx", + "gx"; + + iommus = <&adreno_smmu 5 0x0>; + + qcom,qmp = <&aoss_qmp>; + + operating-points-v2 = <&gmu_opp_table>; + + gmu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-475000000 { + opp-hz = /bits/ 64 <475000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>; + }; + + opp-575000000 { + opp-hz = /bits/ 64 <575000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>; + }; + + opp-700000000 { + opp-hz = /bits/ 64 <700000000>; + opp-level = <RPMH_REGULATOR_LEVEL_SVS>; + }; + + opp-725000000 { + opp-hz = /bits/ 64 <725000000>; + opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>; + }; + + opp-750000000 { + opp-hz = /bits/ 64 <750000000>; + opp-level = <RPMH_REGULATOR_LEVEL_NOM>; + }; + }; + }; + gxclkctl: clock-controller@3d64000 { compatible = "qcom,kaanapali-gxclkctl"; reg = <0x0 0x03d64000 0x0 0x6000>; @@ -2702,6 +2945,46 @@ gpucc: clock-controller@3d90000 { #power-domain-cells = <1>; }; + adreno_smmu: iommu@3da0000 { + compatible = "qcom,kaanapali-smmu-500", + "qcom,adreno-smmu", + "qcom,smmu-500", + "arm,mmu-500"; + reg = <0x0 0x03da0000 0x0 0x40000>; + #iommu-cells = <2>; + #global-interrupts = <1>; + interrupts = <GIC_SPI 674 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 678 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 679 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 680 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 681 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 682 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 683 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 684 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 685 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 686 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 687 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 688 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 574 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 575 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 576 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 577 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 660 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 662 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 665 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 666 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 667 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 669 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 670 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 700 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gpucc GPU_CC_GPU_SMMU_VOTE_CLK>; + clock-names = "hlos"; + power-domains = <&gpucc GPU_CC_CX_GDSC>; + dma-coherent; + }; + remoteproc_adsp: remoteproc@6800000 { compatible = "qcom,kaanapali-adsp-pas", "qcom,sm8550-adsp-pas"; reg = <0x0 0x06800000 0x0 0x10000>; @@ -4360,11 +4643,11 @@ qup_spi21_data_clk: qup-spi21-data-clk-state { }; qup_uart7_default: qup-uart7-state { - /* TX, RX */ - pins = "gpio62", "gpio63"; - function = "qup1_se7"; - drive-strength = <2>; - bias-disable; + /* TX, RX */ + pins = "gpio62", "gpio63"; + function = "qup1_se7"; + drive-strength = <2>; + bias-disable; }; qup_uart18_default: qup-uart18-default-state { @@ -5970,6 +6253,18 @@ rpmhpd_opp_super_turbo_no_cpr: opp-480 { }; }; + efuse@221c8000 { + compatible = "qcom,kaanapali-qfprom", "qcom,qfprom"; + reg = <0x0 0x221c8000 0x0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + gpu_speed_bin: gpu-speed-bin@142 { + reg = <0x142 0x2>; + bits = <3 9>; + }; + }; + nsp_noc: interconnect@260c0000 { compatible = "qcom,kaanapali-nsp-noc"; reg = <0x0 0x260c0000 0x0 0x21280>; @@ -6903,9 +7198,17 @@ nsphmx-3-critical { }; gpuss-0-thermal { + polling-delay-passive = <10>; + thermal-sensors = <&tsens5 0>; trips { + gpuss_0_alert0: gpuss-0-alert0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + gpuss-0-hot { temperature = <120000>; hysteresis = <5000>; @@ -6918,12 +7221,27 @@ gpuss-0-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss_0_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss-1-thermal { + polling-delay-passive = <10>; + thermal-sensors = <&tsens5 1>; trips { + gpuss_1_alert0: gpuss-1-alert0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + gpuss-1-hot { temperature = <120000>; hysteresis = <5000>; @@ -6936,12 +7254,27 @@ gpuss-1-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss_1_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss-2-thermal { + polling-delay-passive = <10>; + thermal-sensors = <&tsens5 2>; trips { + gpuss_2_alert0: gpuss-2-alert0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + gpuss-2-hot { temperature = <120000>; hysteresis = <5000>; @@ -6954,12 +7287,27 @@ gpuss-2-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss_2_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss-3-thermal { + polling-delay-passive = <10>; + thermal-sensors = <&tsens5 3>; trips { + gpuss_3_alert0: gpuss-3-alert0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + gpuss-3-hot { temperature = <120000>; hysteresis = <5000>; @@ -6972,12 +7320,27 @@ gpuss-3-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss_3_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss-4-thermal { + polling-delay-passive = <10>; + thermal-sensors = <&tsens5 4>; trips { + gpuss_4_alert0: gpuss-4-alert0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + gpuss-4-hot { temperature = <120000>; hysteresis = <5000>; @@ -6990,12 +7353,27 @@ gpuss-4-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss_4_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss-5-thermal { + polling-delay-passive = <10>; + thermal-sensors = <&tsens5 5>; trips { + gpuss_5_alert0: gpuss-5-alert0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + gpuss-5-hot { temperature = <120000>; hysteresis = <5000>; @@ -7008,12 +7386,27 @@ gpuss-5-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss_5_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss-6-thermal { + polling-delay-passive = <10>; + thermal-sensors = <&tsens5 6>; trips { + gpuss_6_alert0: gpuss-6-alert0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + gpuss-6-hot { temperature = <120000>; hysteresis = <5000>; @@ -7026,12 +7419,27 @@ gpuss-6-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss_6_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss-7-thermal { + polling-delay-passive = <10>; + thermal-sensors = <&tsens5 7>; trips { + gpuss_7_alert0: gpuss-7-alert0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + gpuss-7-hot { temperature = <120000>; hysteresis = <5000>; @@ -7044,12 +7452,27 @@ gpuss-7-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss_7_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss-8-thermal { + polling-delay-passive = <10>; + thermal-sensors = <&tsens5 8>; trips { + gpuss_8_alert0: gpuss-8-alert0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + gpuss-8-hot { temperature = <120000>; hysteresis = <5000>; @@ -7062,12 +7485,27 @@ gpuss-8-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss_8_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss-9-thermal { + polling-delay-passive = <10>; + thermal-sensors = <&tsens5 9>; trips { + gpuss_9_alert0: gpuss-9-alert0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + gpuss-9-hot { temperature = <120000>; hysteresis = <5000>; @@ -7080,12 +7518,27 @@ gpuss-9-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss_9_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss-10-thermal { + polling-delay-passive = <10>; + thermal-sensors = <&tsens5 10>; trips { + gpuss_10_alert0: gpuss-10-alert0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + gpuss-10-hot { temperature = <120000>; hysteresis = <5000>; @@ -7098,6 +7551,13 @@ gpuss-10-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss_10_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; ddr-thermal {
diff --git a/arch/arm64/boot/dts/qcom/kodiak.dtsi b/arch/arm64/boot/dts/qcom/kodiak.dtsi index f2da370..8c75236 100644 --- a/arch/arm64/boot/dts/qcom/kodiak.dtsi +++ b/arch/arm64/boot/dts/qcom/kodiak.dtsi
@@ -1054,6 +1054,8 @@ sdhc_1: mmc@7c4000 { qcom,dll-config = <0x0007642c>; qcom,ddr-config = <0x80040868>; + qcom,ice = <&sdhc_ice>; + mmc-ddr-1_8v; mmc-hs200-1_8v; mmc-hs400-1_8v; @@ -1080,6 +1082,17 @@ opp-384000000 { }; }; + sdhc_ice: crypto@7c8000 { + compatible = "qcom,sc7280-inline-crypto-engine", + "qcom,inline-crypto-engine"; + reg = <0x0 0x007c8000 0x0 0x18000>; + clocks = <&gcc GCC_SDCC1_ICE_CORE_CLK>, + <&gcc GCC_SDCC1_AHB_CLK>; + clock-names = "core", + "iface"; + power-domains = <&rpmhpd SC7280_CX>; + }; + gpi_dma0: dma-controller@900000 { #dma-cells = <3>; compatible = "qcom,sc7280-gpi-dma", "qcom,sm6350-gpi-dma"; @@ -5852,6 +5865,697 @@ tlmm: pinctrl@f100000 { gpio-ranges = <&tlmm 0 0 175>; wakeup-parent = <&pdc>; + qup_i2c0_data_clk: qup-i2c0-data-clk-state { + pins = "gpio0", "gpio1"; + function = "qup00"; + }; + + qup_spi0_data_clk: qup-spi0-data-clk-state { + pins = "gpio0", "gpio1", "gpio2"; + function = "qup00"; + }; + + qup_uart0_cts: qup-uart0-cts-state { + pins = "gpio0"; + function = "qup00"; + }; + + qup_uart0_rts: qup-uart0-rts-state { + pins = "gpio1"; + function = "qup00"; + }; + + qup_uart0_tx: qup-uart0-tx-state { + pins = "gpio2"; + function = "qup00"; + }; + + qup_spi0_cs: qup-spi0-cs-state { + pins = "gpio3"; + function = "qup00"; + }; + + qup_spi0_cs_gpio: qup-spi0-cs-gpio-state { + pins = "gpio3"; + function = "gpio"; + }; + + qup_uart0_rx: qup-uart0-rx-state { + pins = "gpio3"; + function = "qup00"; + }; + + qup_i2c1_data_clk: qup-i2c1-data-clk-state { + pins = "gpio4", "gpio5"; + function = "qup01"; + }; + + qup_spi1_data_clk: qup-spi1-data-clk-state { + pins = "gpio4", "gpio5", "gpio6"; + function = "qup01"; + }; + + qup_uart1_cts: qup-uart1-cts-state { + pins = "gpio4"; + function = "qup01"; + }; + + qup_uart1_rts: qup-uart1-rts-state { + pins = "gpio5"; + function = "qup01"; + }; + + qup_uart1_tx: qup-uart1-tx-state { + pins = "gpio6"; + function = "qup01"; + }; + + qup_spi1_cs: qup-spi1-cs-state { + pins = "gpio7"; + function = "qup01"; + }; + + qup_spi1_cs_gpio: qup-spi1-cs-gpio-state { + pins = "gpio7"; + function = "gpio"; + }; + + qup_uart1_rx: qup-uart1-rx-state { + pins = "gpio7"; + function = "qup01"; + }; + + qup_i2c2_data_clk: qup-i2c2-data-clk-state { + pins = "gpio8", "gpio9"; + function = "qup02"; + }; + + qup_spi2_data_clk: qup-spi2-data-clk-state { + pins = "gpio8", "gpio9", "gpio10"; + function = "qup02"; + }; + + qup_uart2_cts: qup-uart2-cts-state { + pins = "gpio8"; + function = "qup02"; + }; + + qup_uart2_rts: qup-uart2-rts-state { + pins = "gpio9"; + function = "qup02"; + }; + + qup_uart2_tx: qup-uart2-tx-state { + pins = "gpio10"; + function = "qup02"; + }; + + qup_spi2_cs: qup-spi2-cs-state { + pins = "gpio11"; + function = "qup02"; + }; + + qup_spi2_cs_gpio: qup-spi2-cs-gpio-state { + pins = "gpio11"; + function = "gpio"; + }; + + qup_uart2_rx: qup-uart2-rx-state { + pins = "gpio11"; + function = "qup02"; + }; + + qspi_data0: qspi-data0-state { + pins = "gpio12"; + function = "qspi_data"; + }; + + qup_i2c3_data_clk: qup-i2c3-data-clk-state { + pins = "gpio12", "gpio13"; + function = "qup03"; + }; + + qup_spi3_data_clk: qup-spi3-data-clk-state { + pins = "gpio12", "gpio13", "gpio14"; + function = "qup03"; + }; + + qup_uart3_cts: qup-uart3-cts-state { + pins = "gpio12"; + function = "qup03"; + }; + + qspi_data1: qspi-data1-state { + pins = "gpio13"; + function = "qspi_data"; + }; + + qup_uart3_rts: qup-uart3-rts-state { + pins = "gpio13"; + function = "qup03"; + }; + + qspi_clk: qspi-clk-state { + pins = "gpio14"; + function = "qspi_clk"; + }; + + qup_uart3_tx: qup-uart3-tx-state { + pins = "gpio14"; + function = "qup03"; + }; + + qspi_cs0: qspi-cs0-state { + pins = "gpio15"; + function = "qspi_cs"; + }; + + qup_spi3_cs: qup-spi3-cs-state { + pins = "gpio15"; + function = "qup03"; + }; + + qup_spi3_cs_gpio: qup-spi3-cs-gpio-state { + pins = "gpio15"; + function = "gpio"; + }; + + qup_uart3_rx: qup-uart3-rx-state { + pins = "gpio15"; + function = "qup03"; + }; + + qspi_data23: qspi-data23-state { + pins = "gpio16", "gpio17"; + function = "qspi_data"; + }; + + qup_i2c4_data_clk: qup-i2c4-data-clk-state { + pins = "gpio16", "gpio17"; + function = "qup04"; + }; + + qup_spi4_data_clk: qup-spi4-data-clk-state { + pins = "gpio16", "gpio17", "gpio18"; + function = "qup04"; + }; + + qup_uart4_cts: qup-uart4-cts-state { + pins = "gpio16"; + function = "qup04"; + }; + + qup_uart4_rts: qup-uart4-rts-state { + pins = "gpio17"; + function = "qup04"; + }; + + qup_uart4_tx: qup-uart4-tx-state { + pins = "gpio18"; + function = "qup04"; + }; + + qspi_cs1: qspi-cs1-state { + pins = "gpio19"; + function = "qspi_cs"; + }; + + qup_spi4_cs: qup-spi4-cs-state { + pins = "gpio19"; + function = "qup04"; + }; + + qup_spi4_cs_gpio: qup-spi4-cs-gpio-state { + pins = "gpio19"; + function = "gpio"; + }; + + qup_uart4_rx: qup-uart4-rx-state { + pins = "gpio19"; + function = "qup04"; + }; + + qup_i2c5_data_clk: qup-i2c5-data-clk-state { + pins = "gpio20", "gpio21"; + function = "qup05"; + }; + + qup_spi5_data_clk: qup-spi5-data-clk-state { + pins = "gpio20", "gpio21", "gpio22"; + function = "qup05"; + }; + + qup_uart5_tx: qup-uart5-tx-state { + pins = "gpio22"; + function = "qup05"; + }; + + qup_spi5_cs: qup-spi5-cs-state { + pins = "gpio23"; + function = "qup05"; + }; + + qup_spi5_cs_gpio: qup-spi5-cs-gpio-state { + pins = "gpio23"; + function = "gpio"; + }; + + qup_uart5_rx: qup-uart5-rx-state { + pins = "gpio23"; + function = "qup05"; + }; + + qup_i2c6_data_clk: qup-i2c6-data-clk-state { + pins = "gpio24", "gpio25"; + function = "qup06"; + }; + + qup_spi6_data_clk: qup-spi6-data-clk-state { + pins = "gpio24", "gpio25", "gpio26"; + function = "qup06"; + }; + + qup_uart6_cts: qup-uart6-cts-state { + pins = "gpio24"; + function = "qup06"; + }; + + qup_uart6_rts: qup-uart6-rts-state { + pins = "gpio25"; + function = "qup06"; + }; + + qup_uart6_tx: qup-uart6-tx-state { + pins = "gpio26"; + function = "qup06"; + }; + + qup_spi6_cs: qup-spi6-cs-state { + pins = "gpio27"; + function = "qup06"; + }; + + qup_spi6_cs_gpio: qup-spi6-cs-gpio-state { + pins = "gpio27"; + function = "gpio"; + }; + + qup_uart6_rx: qup-uart6-rx-state { + pins = "gpio27"; + function = "qup06"; + }; + + qup_i2c7_data_clk: qup-i2c7-data-clk-state { + pins = "gpio28", "gpio29"; + function = "qup07"; + }; + + qup_spi7_data_clk: qup-spi7-data-clk-state { + pins = "gpio28", "gpio29", "gpio30"; + function = "qup07"; + }; + + qup_uart7_cts: qup-uart7-cts-state { + pins = "gpio28"; + function = "qup07"; + }; + + qup_uart7_rts: qup-uart7-rts-state { + pins = "gpio29"; + function = "qup07"; + }; + + qup_uart7_tx: qup-uart7-tx-state { + pins = "gpio30"; + function = "qup07"; + }; + + qup_spi7_cs: qup-spi7-cs-state { + pins = "gpio31"; + function = "qup07"; + }; + + qup_spi7_cs_gpio: qup-spi7-cs-gpio-state { + pins = "gpio31"; + function = "gpio"; + }; + + qup_uart7_rx: qup-uart7-rx-state { + pins = "gpio31"; + function = "qup07"; + }; + + qup_i2c8_data_clk: qup-i2c8-data-clk-state { + pins = "gpio32", "gpio33"; + function = "qup10"; + }; + + qup_spi8_data_clk: qup-spi8-data-clk-state { + pins = "gpio32", "gpio33", "gpio34"; + function = "qup10"; + }; + + qup_uart8_cts: qup-uart8-cts-state { + pins = "gpio32"; + function = "qup10"; + }; + + qup_uart8_rts: qup-uart8-rts-state { + pins = "gpio33"; + function = "qup10"; + }; + + qup_uart8_tx: qup-uart8-tx-state { + pins = "gpio34"; + function = "qup10"; + }; + + qup_spi8_cs: qup-spi8-cs-state { + pins = "gpio35"; + function = "qup10"; + }; + + qup_spi8_cs_gpio: qup-spi8-cs-gpio-state { + pins = "gpio35"; + function = "gpio"; + }; + + qup_uart8_rx: qup-uart8-rx-state { + pins = "gpio35"; + function = "qup10"; + }; + + qup_i2c9_data_clk: qup-i2c9-data-clk-state { + pins = "gpio36", "gpio37"; + function = "qup11"; + }; + + qup_spi9_data_clk: qup-spi9-data-clk-state { + pins = "gpio36", "gpio37", "gpio38"; + function = "qup11"; + }; + + qup_uart9_cts: qup-uart9-cts-state { + pins = "gpio36"; + function = "qup11"; + }; + + qup_uart9_rts: qup-uart9-rts-state { + pins = "gpio37"; + function = "qup11"; + }; + + qup_uart9_tx: qup-uart9-tx-state { + pins = "gpio38"; + function = "qup11"; + }; + + qup_spi9_cs: qup-spi9-cs-state { + pins = "gpio39"; + function = "qup11"; + }; + + qup_spi9_cs_gpio: qup-spi9-cs-gpio-state { + pins = "gpio39"; + function = "gpio"; + }; + + qup_uart9_rx: qup-uart9-rx-state { + pins = "gpio39"; + function = "qup11"; + }; + + qup_i2c10_data_clk: qup-i2c10-data-clk-state { + pins = "gpio40", "gpio41"; + function = "qup12"; + }; + + qup_spi10_data_clk: qup-spi10-data-clk-state { + pins = "gpio40", "gpio41", "gpio42"; + function = "qup12"; + }; + + qup_uart10_cts: qup-uart10-cts-state { + pins = "gpio40"; + function = "qup12"; + }; + + qup_uart10_rts: qup-uart10-rts-state { + pins = "gpio41"; + function = "qup12"; + }; + + qup_uart10_tx: qup-uart10-tx-state { + pins = "gpio42"; + function = "qup12"; + }; + + qup_spi10_cs: qup-spi10-cs-state { + pins = "gpio43"; + function = "qup12"; + }; + + qup_spi10_cs_gpio: qup-spi10-cs-gpio-state { + pins = "gpio43"; + function = "gpio"; + }; + + qup_uart10_rx: qup-uart10-rx-state { + pins = "gpio43"; + function = "qup12"; + }; + + qup_i2c11_data_clk: qup-i2c11-data-clk-state { + pins = "gpio44", "gpio45"; + function = "qup13"; + }; + + qup_spi11_data_clk: qup-spi11-data-clk-state { + pins = "gpio44", "gpio45", "gpio46"; + function = "qup13"; + }; + + qup_uart11_cts: qup-uart11-cts-state { + pins = "gpio44"; + function = "qup13"; + }; + + qup_uart11_rts: qup-uart11-rts-state { + pins = "gpio45"; + function = "qup13"; + }; + + qup_uart11_tx: qup-uart11-tx-state { + pins = "gpio46"; + function = "qup13"; + }; + + dp_hot_plug_det: dp-hot-plug-det-state { + pins = "gpio47"; + function = "dp_hot"; + }; + + qup_spi11_cs: qup-spi11-cs-state { + pins = "gpio47"; + function = "qup13"; + }; + + qup_spi11_cs_gpio: qup-spi11-cs-gpio-state { + pins = "gpio47"; + function = "gpio"; + }; + + qup_uart11_rx: qup-uart11-rx-state { + pins = "gpio47"; + function = "qup13"; + }; + + qup_i2c12_data_clk: qup-i2c12-data-clk-state { + pins = "gpio48", "gpio49"; + function = "qup14"; + }; + + qup_spi12_data_clk: qup-spi12-data-clk-state { + pins = "gpio48", "gpio49", "gpio50"; + function = "qup14"; + }; + + qup_uart12_cts: qup-uart12-cts-state { + pins = "gpio48"; + function = "qup14"; + }; + + qup_uart12_rts: qup-uart12-rts-state { + pins = "gpio49"; + function = "qup14"; + }; + + qup_uart12_tx: qup-uart12-tx-state { + pins = "gpio50"; + function = "qup14"; + }; + + qup_spi12_cs: qup-spi12-cs-state { + pins = "gpio51"; + function = "qup14"; + }; + + qup_spi12_cs_gpio: qup-spi12-cs-gpio-state { + pins = "gpio51"; + function = "gpio"; + }; + + qup_uart12_rx: qup-uart12-rx-state { + pins = "gpio51"; + function = "qup14"; + }; + + qup_i2c13_data_clk: qup-i2c13-data-clk-state { + pins = "gpio52", "gpio53"; + function = "qup15"; + }; + + qup_spi13_data_clk: qup-spi13-data-clk-state { + pins = "gpio52", "gpio53", "gpio54"; + function = "qup15"; + }; + + qup_uart13_cts: qup-uart13-cts-state { + pins = "gpio52"; + function = "qup15"; + }; + + qup_uart13_rts: qup-uart13-rts-state { + pins = "gpio53"; + function = "qup15"; + }; + + qup_uart13_tx: qup-uart13-tx-state { + pins = "gpio54"; + function = "qup15"; + }; + + qup_spi13_cs: qup-spi13-cs-state { + pins = "gpio55"; + function = "qup15"; + }; + + qup_spi13_cs_gpio: qup-spi13-cs-gpio-state { + pins = "gpio55"; + function = "gpio"; + }; + + qup_uart13_rx: qup-uart13-rx-state { + pins = "gpio55"; + function = "qup15"; + }; + + qup_i2c14_data_clk: qup-i2c14-data-clk-state { + pins = "gpio56", "gpio57"; + function = "qup16"; + }; + + qup_spi14_data_clk: qup-spi14-data-clk-state { + pins = "gpio56", "gpio57", "gpio58"; + function = "qup16"; + }; + + qup_uart14_cts: qup-uart14-cts-state { + pins = "gpio56"; + function = "qup16"; + }; + + qup_uart14_rts: qup-uart14-rts-state { + pins = "gpio57"; + function = "qup16"; + }; + + qup_uart14_tx: qup-uart14-tx-state { + pins = "gpio58"; + function = "qup16"; + }; + + qup_spi14_cs: qup-spi14-cs-state { + pins = "gpio59"; + function = "qup16"; + }; + + qup_spi14_cs_gpio: qup-spi14-cs-gpio-state { + pins = "gpio59"; + function = "gpio"; + }; + + qup_uart14_rx: qup-uart14-rx-state { + pins = "gpio59"; + function = "qup16"; + }; + + edp_hot_plug_det: edp-hot-plug-det-state { + pins = "gpio60"; + function = "edp_hot"; + }; + + qup_i2c15_data_clk: qup-i2c15-data-clk-state { + pins = "gpio60", "gpio61"; + function = "qup17"; + }; + + qup_spi15_data_clk: qup-spi15-data-clk-state { + pins = "gpio60", "gpio61", "gpio62"; + function = "qup17"; + }; + + qup_uart15_cts: qup-uart15-cts-state { + pins = "gpio60"; + function = "qup17"; + }; + + qup_uart15_rts: qup-uart15-rts-state { + pins = "gpio61"; + function = "qup17"; + }; + + qup_uart15_tx: qup-uart15-tx-state { + pins = "gpio62"; + function = "qup17"; + }; + + qup_spi15_cs: qup-spi15-cs-state { + pins = "gpio63"; + function = "qup17"; + }; + + qup_spi15_cs_gpio: qup-spi15-cs-gpio-state { + pins = "gpio63"; + function = "gpio"; + }; + + qup_uart15_rx: qup-uart15-rx-state { + pins = "gpio63"; + function = "qup17"; + }; + + cam_mclk0_default: cam-mclk0-default-state { + pins = "gpio64"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + cam_mclk1_default: cam-mclk1-default-state { + pins = "gpio65"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + cam_mclk2_default: cam-mclk2-default-state { + pins = "gpio66"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + cam_mclk3_default: cam-mclk3-default-state { pins = "gpio67"; function = "cam_mclk"; @@ -5859,6 +6563,13 @@ cam_mclk3_default: cam-mclk3-default-state { bias-disable; }; + cam_mclk4_default: cam-mclk4-default-state { + pins = "gpio68"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + cci0_default: cci0-default-state { pins = "gpio69", "gpio70"; function = "cci_i2c"; @@ -5915,24 +6626,21 @@ cci3_sleep: cci3-sleep-state { bias-pull-down; }; - dp_hot_plug_det: dp-hot-plug-det-state { - pins = "gpio47"; - function = "dp_hot"; + pcie1_clkreq_n: pcie1-clkreq-n-state { + pins = "gpio79"; + function = "pcie1_clkreqn"; }; - edp_hot_plug_det: edp-hot-plug-det-state { - pins = "gpio60"; - function = "edp_hot"; + pcie0_clkreq_n: pcie0-clkreq-n-state { + pins = "gpio88"; + function = "pcie0_clkreqn"; }; - mi2s0_data0: mi2s0-data0-state { - pins = "gpio98"; - function = "mi2s0_data0"; - }; - - mi2s0_data1: mi2s0-data1-state { - pins = "gpio99"; - function = "mi2s0_data1"; + cam_mclk5_default: cam-mclk5-default-state { + pins = "gpio93"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; }; mi2s0_mclk: mi2s0-mclk-state { @@ -5945,696 +6653,36 @@ mi2s0_sclk: mi2s0-sclk-state { function = "mi2s0_sck"; }; + mi2s0_data0: mi2s0-data0-state { + pins = "gpio98"; + function = "mi2s0_data0"; + }; + + mi2s0_data1: mi2s0-data1-state { + pins = "gpio99"; + function = "mi2s0_data1"; + }; + mi2s0_ws: mi2s0-ws-state { pins = "gpio100"; function = "mi2s0_ws"; }; - mi2s1_data0: mi2s1-data0-state { - pins = "gpio107"; - function = "mi2s1_data0"; - }; - mi2s1_sclk: mi2s1-sclk-state { pins = "gpio106"; function = "mi2s1_sck"; }; + mi2s1_data0: mi2s1-data0-state { + pins = "gpio107"; + function = "mi2s1_data0"; + }; + mi2s1_ws: mi2s1-ws-state { pins = "gpio108"; function = "mi2s1_ws"; }; - pcie0_clkreq_n: pcie0-clkreq-n-state { - pins = "gpio88"; - function = "pcie0_clkreqn"; - }; - - pcie1_clkreq_n: pcie1-clkreq-n-state { - pins = "gpio79"; - function = "pcie1_clkreqn"; - }; - - qspi_clk: qspi-clk-state { - pins = "gpio14"; - function = "qspi_clk"; - }; - - qspi_cs0: qspi-cs0-state { - pins = "gpio15"; - function = "qspi_cs"; - }; - - qspi_cs1: qspi-cs1-state { - pins = "gpio19"; - function = "qspi_cs"; - }; - - qspi_data0: qspi-data0-state { - pins = "gpio12"; - function = "qspi_data"; - }; - - qspi_data1: qspi-data1-state { - pins = "gpio13"; - function = "qspi_data"; - }; - - qspi_data23: qspi-data23-state { - pins = "gpio16", "gpio17"; - function = "qspi_data"; - }; - - qup_i2c0_data_clk: qup-i2c0-data-clk-state { - pins = "gpio0", "gpio1"; - function = "qup00"; - }; - - qup_i2c1_data_clk: qup-i2c1-data-clk-state { - pins = "gpio4", "gpio5"; - function = "qup01"; - }; - - qup_i2c2_data_clk: qup-i2c2-data-clk-state { - pins = "gpio8", "gpio9"; - function = "qup02"; - }; - - qup_i2c3_data_clk: qup-i2c3-data-clk-state { - pins = "gpio12", "gpio13"; - function = "qup03"; - }; - - qup_i2c4_data_clk: qup-i2c4-data-clk-state { - pins = "gpio16", "gpio17"; - function = "qup04"; - }; - - qup_i2c5_data_clk: qup-i2c5-data-clk-state { - pins = "gpio20", "gpio21"; - function = "qup05"; - }; - - qup_i2c6_data_clk: qup-i2c6-data-clk-state { - pins = "gpio24", "gpio25"; - function = "qup06"; - }; - - qup_i2c7_data_clk: qup-i2c7-data-clk-state { - pins = "gpio28", "gpio29"; - function = "qup07"; - }; - - qup_i2c8_data_clk: qup-i2c8-data-clk-state { - pins = "gpio32", "gpio33"; - function = "qup10"; - }; - - qup_i2c9_data_clk: qup-i2c9-data-clk-state { - pins = "gpio36", "gpio37"; - function = "qup11"; - }; - - qup_i2c10_data_clk: qup-i2c10-data-clk-state { - pins = "gpio40", "gpio41"; - function = "qup12"; - }; - - qup_i2c11_data_clk: qup-i2c11-data-clk-state { - pins = "gpio44", "gpio45"; - function = "qup13"; - }; - - qup_i2c12_data_clk: qup-i2c12-data-clk-state { - pins = "gpio48", "gpio49"; - function = "qup14"; - }; - - qup_i2c13_data_clk: qup-i2c13-data-clk-state { - pins = "gpio52", "gpio53"; - function = "qup15"; - }; - - qup_i2c14_data_clk: qup-i2c14-data-clk-state { - pins = "gpio56", "gpio57"; - function = "qup16"; - }; - - qup_i2c15_data_clk: qup-i2c15-data-clk-state { - pins = "gpio60", "gpio61"; - function = "qup17"; - }; - - qup_spi0_data_clk: qup-spi0-data-clk-state { - pins = "gpio0", "gpio1", "gpio2"; - function = "qup00"; - }; - - qup_spi0_cs: qup-spi0-cs-state { - pins = "gpio3"; - function = "qup00"; - }; - - qup_spi0_cs_gpio: qup-spi0-cs-gpio-state { - pins = "gpio3"; - function = "gpio"; - }; - - qup_spi1_data_clk: qup-spi1-data-clk-state { - pins = "gpio4", "gpio5", "gpio6"; - function = "qup01"; - }; - - qup_spi1_cs: qup-spi1-cs-state { - pins = "gpio7"; - function = "qup01"; - }; - - qup_spi1_cs_gpio: qup-spi1-cs-gpio-state { - pins = "gpio7"; - function = "gpio"; - }; - - qup_spi2_data_clk: qup-spi2-data-clk-state { - pins = "gpio8", "gpio9", "gpio10"; - function = "qup02"; - }; - - qup_spi2_cs: qup-spi2-cs-state { - pins = "gpio11"; - function = "qup02"; - }; - - qup_spi2_cs_gpio: qup-spi2-cs-gpio-state { - pins = "gpio11"; - function = "gpio"; - }; - - qup_spi3_data_clk: qup-spi3-data-clk-state { - pins = "gpio12", "gpio13", "gpio14"; - function = "qup03"; - }; - - qup_spi3_cs: qup-spi3-cs-state { - pins = "gpio15"; - function = "qup03"; - }; - - qup_spi3_cs_gpio: qup-spi3-cs-gpio-state { - pins = "gpio15"; - function = "gpio"; - }; - - qup_spi4_data_clk: qup-spi4-data-clk-state { - pins = "gpio16", "gpio17", "gpio18"; - function = "qup04"; - }; - - qup_spi4_cs: qup-spi4-cs-state { - pins = "gpio19"; - function = "qup04"; - }; - - qup_spi4_cs_gpio: qup-spi4-cs-gpio-state { - pins = "gpio19"; - function = "gpio"; - }; - - qup_spi5_data_clk: qup-spi5-data-clk-state { - pins = "gpio20", "gpio21", "gpio22"; - function = "qup05"; - }; - - qup_spi5_cs: qup-spi5-cs-state { - pins = "gpio23"; - function = "qup05"; - }; - - qup_spi5_cs_gpio: qup-spi5-cs-gpio-state { - pins = "gpio23"; - function = "gpio"; - }; - - qup_spi6_data_clk: qup-spi6-data-clk-state { - pins = "gpio24", "gpio25", "gpio26"; - function = "qup06"; - }; - - qup_spi6_cs: qup-spi6-cs-state { - pins = "gpio27"; - function = "qup06"; - }; - - qup_spi6_cs_gpio: qup-spi6-cs-gpio-state { - pins = "gpio27"; - function = "gpio"; - }; - - qup_spi7_data_clk: qup-spi7-data-clk-state { - pins = "gpio28", "gpio29", "gpio30"; - function = "qup07"; - }; - - qup_spi7_cs: qup-spi7-cs-state { - pins = "gpio31"; - function = "qup07"; - }; - - qup_spi7_cs_gpio: qup-spi7-cs-gpio-state { - pins = "gpio31"; - function = "gpio"; - }; - - qup_spi8_data_clk: qup-spi8-data-clk-state { - pins = "gpio32", "gpio33", "gpio34"; - function = "qup10"; - }; - - qup_spi8_cs: qup-spi8-cs-state { - pins = "gpio35"; - function = "qup10"; - }; - - qup_spi8_cs_gpio: qup-spi8-cs-gpio-state { - pins = "gpio35"; - function = "gpio"; - }; - - qup_spi9_data_clk: qup-spi9-data-clk-state { - pins = "gpio36", "gpio37", "gpio38"; - function = "qup11"; - }; - - qup_spi9_cs: qup-spi9-cs-state { - pins = "gpio39"; - function = "qup11"; - }; - - qup_spi9_cs_gpio: qup-spi9-cs-gpio-state { - pins = "gpio39"; - function = "gpio"; - }; - - qup_spi10_data_clk: qup-spi10-data-clk-state { - pins = "gpio40", "gpio41", "gpio42"; - function = "qup12"; - }; - - qup_spi10_cs: qup-spi10-cs-state { - pins = "gpio43"; - function = "qup12"; - }; - - qup_spi10_cs_gpio: qup-spi10-cs-gpio-state { - pins = "gpio43"; - function = "gpio"; - }; - - qup_spi11_data_clk: qup-spi11-data-clk-state { - pins = "gpio44", "gpio45", "gpio46"; - function = "qup13"; - }; - - qup_spi11_cs: qup-spi11-cs-state { - pins = "gpio47"; - function = "qup13"; - }; - - qup_spi11_cs_gpio: qup-spi11-cs-gpio-state { - pins = "gpio47"; - function = "gpio"; - }; - - qup_spi12_data_clk: qup-spi12-data-clk-state { - pins = "gpio48", "gpio49", "gpio50"; - function = "qup14"; - }; - - qup_spi12_cs: qup-spi12-cs-state { - pins = "gpio51"; - function = "qup14"; - }; - - qup_spi12_cs_gpio: qup-spi12-cs-gpio-state { - pins = "gpio51"; - function = "gpio"; - }; - - qup_spi13_data_clk: qup-spi13-data-clk-state { - pins = "gpio52", "gpio53", "gpio54"; - function = "qup15"; - }; - - qup_spi13_cs: qup-spi13-cs-state { - pins = "gpio55"; - function = "qup15"; - }; - - qup_spi13_cs_gpio: qup-spi13-cs-gpio-state { - pins = "gpio55"; - function = "gpio"; - }; - - qup_spi14_data_clk: qup-spi14-data-clk-state { - pins = "gpio56", "gpio57", "gpio58"; - function = "qup16"; - }; - - qup_spi14_cs: qup-spi14-cs-state { - pins = "gpio59"; - function = "qup16"; - }; - - qup_spi14_cs_gpio: qup-spi14-cs-gpio-state { - pins = "gpio59"; - function = "gpio"; - }; - - qup_spi15_data_clk: qup-spi15-data-clk-state { - pins = "gpio60", "gpio61", "gpio62"; - function = "qup17"; - }; - - qup_spi15_cs: qup-spi15-cs-state { - pins = "gpio63"; - function = "qup17"; - }; - - qup_spi15_cs_gpio: qup-spi15-cs-gpio-state { - pins = "gpio63"; - function = "gpio"; - }; - - qup_uart0_cts: qup-uart0-cts-state { - pins = "gpio0"; - function = "qup00"; - }; - - qup_uart0_rts: qup-uart0-rts-state { - pins = "gpio1"; - function = "qup00"; - }; - - qup_uart0_tx: qup-uart0-tx-state { - pins = "gpio2"; - function = "qup00"; - }; - - qup_uart0_rx: qup-uart0-rx-state { - pins = "gpio3"; - function = "qup00"; - }; - - qup_uart1_cts: qup-uart1-cts-state { - pins = "gpio4"; - function = "qup01"; - }; - - qup_uart1_rts: qup-uart1-rts-state { - pins = "gpio5"; - function = "qup01"; - }; - - qup_uart1_tx: qup-uart1-tx-state { - pins = "gpio6"; - function = "qup01"; - }; - - qup_uart1_rx: qup-uart1-rx-state { - pins = "gpio7"; - function = "qup01"; - }; - - qup_uart2_cts: qup-uart2-cts-state { - pins = "gpio8"; - function = "qup02"; - }; - - qup_uart2_rts: qup-uart2-rts-state { - pins = "gpio9"; - function = "qup02"; - }; - - qup_uart2_tx: qup-uart2-tx-state { - pins = "gpio10"; - function = "qup02"; - }; - - qup_uart2_rx: qup-uart2-rx-state { - pins = "gpio11"; - function = "qup02"; - }; - - qup_uart3_cts: qup-uart3-cts-state { - pins = "gpio12"; - function = "qup03"; - }; - - qup_uart3_rts: qup-uart3-rts-state { - pins = "gpio13"; - function = "qup03"; - }; - - qup_uart3_tx: qup-uart3-tx-state { - pins = "gpio14"; - function = "qup03"; - }; - - qup_uart3_rx: qup-uart3-rx-state { - pins = "gpio15"; - function = "qup03"; - }; - - qup_uart4_cts: qup-uart4-cts-state { - pins = "gpio16"; - function = "qup04"; - }; - - qup_uart4_rts: qup-uart4-rts-state { - pins = "gpio17"; - function = "qup04"; - }; - - qup_uart4_tx: qup-uart4-tx-state { - pins = "gpio18"; - function = "qup04"; - }; - - qup_uart4_rx: qup-uart4-rx-state { - pins = "gpio19"; - function = "qup04"; - }; - - qup_uart5_tx: qup-uart5-tx-state { - pins = "gpio22"; - function = "qup05"; - }; - - qup_uart5_rx: qup-uart5-rx-state { - pins = "gpio23"; - function = "qup05"; - }; - - qup_uart6_cts: qup-uart6-cts-state { - pins = "gpio24"; - function = "qup06"; - }; - - qup_uart6_rts: qup-uart6-rts-state { - pins = "gpio25"; - function = "qup06"; - }; - - qup_uart6_tx: qup-uart6-tx-state { - pins = "gpio26"; - function = "qup06"; - }; - - qup_uart6_rx: qup-uart6-rx-state { - pins = "gpio27"; - function = "qup06"; - }; - - qup_uart7_cts: qup-uart7-cts-state { - pins = "gpio28"; - function = "qup07"; - }; - - qup_uart7_rts: qup-uart7-rts-state { - pins = "gpio29"; - function = "qup07"; - }; - - qup_uart7_tx: qup-uart7-tx-state { - pins = "gpio30"; - function = "qup07"; - }; - - qup_uart7_rx: qup-uart7-rx-state { - pins = "gpio31"; - function = "qup07"; - }; - - qup_uart8_cts: qup-uart8-cts-state { - pins = "gpio32"; - function = "qup10"; - }; - - qup_uart8_rts: qup-uart8-rts-state { - pins = "gpio33"; - function = "qup10"; - }; - - qup_uart8_tx: qup-uart8-tx-state { - pins = "gpio34"; - function = "qup10"; - }; - - qup_uart8_rx: qup-uart8-rx-state { - pins = "gpio35"; - function = "qup10"; - }; - - qup_uart9_cts: qup-uart9-cts-state { - pins = "gpio36"; - function = "qup11"; - }; - - qup_uart9_rts: qup-uart9-rts-state { - pins = "gpio37"; - function = "qup11"; - }; - - qup_uart9_tx: qup-uart9-tx-state { - pins = "gpio38"; - function = "qup11"; - }; - - qup_uart9_rx: qup-uart9-rx-state { - pins = "gpio39"; - function = "qup11"; - }; - - qup_uart10_cts: qup-uart10-cts-state { - pins = "gpio40"; - function = "qup12"; - }; - - qup_uart10_rts: qup-uart10-rts-state { - pins = "gpio41"; - function = "qup12"; - }; - - qup_uart10_tx: qup-uart10-tx-state { - pins = "gpio42"; - function = "qup12"; - }; - - qup_uart10_rx: qup-uart10-rx-state { - pins = "gpio43"; - function = "qup12"; - }; - - qup_uart11_cts: qup-uart11-cts-state { - pins = "gpio44"; - function = "qup13"; - }; - - qup_uart11_rts: qup-uart11-rts-state { - pins = "gpio45"; - function = "qup13"; - }; - - qup_uart11_tx: qup-uart11-tx-state { - pins = "gpio46"; - function = "qup13"; - }; - - qup_uart11_rx: qup-uart11-rx-state { - pins = "gpio47"; - function = "qup13"; - }; - - qup_uart12_cts: qup-uart12-cts-state { - pins = "gpio48"; - function = "qup14"; - }; - - qup_uart12_rts: qup-uart12-rts-state { - pins = "gpio49"; - function = "qup14"; - }; - - qup_uart12_tx: qup-uart12-tx-state { - pins = "gpio50"; - function = "qup14"; - }; - - qup_uart12_rx: qup-uart12-rx-state { - pins = "gpio51"; - function = "qup14"; - }; - - qup_uart13_cts: qup-uart13-cts-state { - pins = "gpio52"; - function = "qup15"; - }; - - qup_uart13_rts: qup-uart13-rts-state { - pins = "gpio53"; - function = "qup15"; - }; - - qup_uart13_tx: qup-uart13-tx-state { - pins = "gpio54"; - function = "qup15"; - }; - - qup_uart13_rx: qup-uart13-rx-state { - pins = "gpio55"; - function = "qup15"; - }; - - qup_uart14_cts: qup-uart14-cts-state { - pins = "gpio56"; - function = "qup16"; - }; - - qup_uart14_rts: qup-uart14-rts-state { - pins = "gpio57"; - function = "qup16"; - }; - - qup_uart14_tx: qup-uart14-tx-state { - pins = "gpio58"; - function = "qup16"; - }; - - qup_uart14_rx: qup-uart14-rx-state { - pins = "gpio59"; - function = "qup16"; - }; - - qup_uart15_cts: qup-uart15-cts-state { - pins = "gpio60"; - function = "qup17"; - }; - - qup_uart15_rts: qup-uart15-rts-state { - pins = "gpio61"; - function = "qup17"; - }; - - qup_uart15_tx: qup-uart15-tx-state { - pins = "gpio62"; - function = "qup17"; - }; - - qup_uart15_rx: qup-uart15-rx-state { - pins = "gpio63"; - function = "qup17"; - }; - sdc1_clk: sdc1-clk-state { pins = "sdc1_clk"; }; @@ -7010,39 +7058,39 @@ rpmhpd: power-controller { rpmhpd_opp_table: opp-table { compatible = "operating-points-v2"; - rpmhpd_opp_ret: opp1 { + rpmhpd_opp_ret: opp-1 { opp-level = <RPMH_REGULATOR_LEVEL_RETENTION>; }; - rpmhpd_opp_low_svs: opp2 { + rpmhpd_opp_low_svs: opp-2 { opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>; }; - rpmhpd_opp_svs: opp3 { + rpmhpd_opp_svs: opp-3 { opp-level = <RPMH_REGULATOR_LEVEL_SVS>; }; - rpmhpd_opp_svs_l1: opp4 { + rpmhpd_opp_svs_l1: opp-4 { opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>; }; - rpmhpd_opp_svs_l2: opp5 { + rpmhpd_opp_svs_l2: opp-5 { opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2>; }; - rpmhpd_opp_nom: opp6 { + rpmhpd_opp_nom: opp-6 { opp-level = <RPMH_REGULATOR_LEVEL_NOM>; }; - rpmhpd_opp_nom_l1: opp7 { + rpmhpd_opp_nom_l1: opp-7 { opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>; }; - rpmhpd_opp_turbo: opp8 { + rpmhpd_opp_turbo: opp-8 { opp-level = <RPMH_REGULATOR_LEVEL_TURBO>; }; - rpmhpd_opp_turbo_l1: opp9 { + rpmhpd_opp_turbo_l1: opp-9 { opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>; }; };
diff --git a/arch/arm64/boot/dts/qcom/lemans-el2.dtso b/arch/arm64/boot/dts/qcom/lemans-el2.dtso index 621ad93..ceaab5f 100644 --- a/arch/arm64/boot/dts/qcom/lemans-el2.dtso +++ b/arch/arm64/boot/dts/qcom/lemans-el2.dtso
@@ -31,9 +31,9 @@ &remoteproc_cdsp1 { }; &remoteproc_gpdsp0 { - iommus = <&apps_smmu 0x38a0 0x0>; + iommus = <&apps_smmu 0x38a0 0x0>; }; &remoteproc_gpdsp1 { - iommus = <&apps_smmu 0x38c0 0x0>; + iommus = <&apps_smmu 0x38c0 0x0>; };
diff --git a/arch/arm64/boot/dts/qcom/lemans-evk-ifp-mezzanine.dtso b/arch/arm64/boot/dts/qcom/lemans-evk-ifp-mezzanine.dtso index 6cfa0bc..e346394 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk-ifp-mezzanine.dtso +++ b/arch/arm64/boot/dts/qcom/lemans-evk-ifp-mezzanine.dtso
@@ -271,27 +271,20 @@ pcie@3,0 { ranges; bus-range = <0x5 0xff>; - pcie@0,0 { + dev@0,0 { reg = <0x50000 0x0 0x0 0x0 0x0>; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - ranges; }; - pcie@0,1 { + dev@0,1 { reg = <0x50100 0x0 0x0 0x0 0x0>; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - ranges; }; }; }; }; &serdes1 { - phy-supply = <&vreg_l5a>; + vdda-0p9-supply = <&vreg_l4a>; + vdda-1p2-supply = <&vreg_l1c>; status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/lemans-evk.dts b/arch/arm64/boot/dts/qcom/lemans-evk.dts index a45485b..23cf20f 100644 --- a/arch/arm64/boot/dts/qcom/lemans-evk.dts +++ b/arch/arm64/boot/dts/qcom/lemans-evk.dts
@@ -839,9 +839,6 @@ &mdss0_dp1_phy { }; &pcie0 { - perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>; - pinctrl-0 = <&pcie0_default_state>; pinctrl-names = "default"; @@ -856,9 +853,6 @@ &pcie0_phy { }; &pcie1 { - perst-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 5 GPIO_ACTIVE_HIGH>; - pinctrl-0 = <&pcie1_default_state>; pinctrl-names = "default"; @@ -872,7 +866,14 @@ &pcie1_phy { status = "okay"; }; +&pcie1_port0 { + reset-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 5 GPIO_ACTIVE_LOW>; +}; + &pcieport0 { + reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 0 GPIO_ACTIVE_LOW>; port { pcieport0_ep: endpoint { remote-endpoint = <&m2_e_pcie_ep>; @@ -978,7 +979,8 @@ &sdhc { }; &serdes0 { - phy-supply = <&vreg_l5a>; + vdda-0p9-supply = <&vreg_l4a>; + vdda-1p2-supply = <&vreg_l1c>; status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/lemans-pmics.dtsi b/arch/arm64/boot/dts/qcom/lemans-pmics.dtsi index 500f715..4c85305 100644 --- a/arch/arm64/boot/dts/qcom/lemans-pmics.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans-pmics.dtsi
@@ -88,6 +88,58 @@ trip1 { }; }; }; + + pm8775-mbg0-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmm8654au_0_mbg_temp>; + + trips { + trip0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + pm8775-mbg1-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmm8654au_1_mbg_temp>; + + trips { + trip0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + pm8775-mbg2-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmm8654au_2_mbg_temp>; + + trips { + trip0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + pm8775-mbg3-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmm8654au_3_mbg_temp>; + + trips { + trip0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; }; reboot-mode { @@ -189,6 +241,22 @@ reboot_reason: reboot-reason@48 { }; }; + pmm8654au_sail_0: pmic@1 { + compatible = "qcom,pmm8654au", "qcom,spmi-pmic"; + reg = <0x1 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmm8654au_0_mbg_temp: temperature-sensor@d700 { + compatible = "qcom,pm8775-mbg-tm"; + reg = <0xd700>; + io-channels = <&pmm8654au_0_adc ADC5_GEN3_DIE_TEMP(0)>; + io-channel-names = "thermal"; + interrupts-extended = <&spmi_bus 0x1 0xd7 0x0 IRQ_TYPE_EDGE_RISING>; + #thermal-sensor-cells = <0>; + }; + }; + pmm8654au_1: pmic@2 { compatible = "qcom,pmm8654au", "qcom,spmi-pmic"; reg = <0x2 SPMI_USID>; @@ -236,6 +304,22 @@ pmm8654au_1_gpios: gpio@8800 { }; }; + pmm8654au_sail_1: pmic@3 { + compatible = "qcom,pmm8654au", "qcom,spmi-pmic"; + reg = <0x3 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmm8654au_1_mbg_temp: temperature-sensor@d700 { + compatible = "qcom,pm8775-mbg-tm"; + reg = <0xd700>; + io-channels = <&pmm8654au_1_adc ADC5_GEN3_DIE_TEMP(2)>; + io-channel-names = "thermal"; + interrupts-extended = <&spmi_bus 0x3 0xd7 0x0 IRQ_TYPE_EDGE_RISING>; + #thermal-sensor-cells = <0>; + }; + }; + pmm8654au_2: pmic@4 { compatible = "qcom,pmm8654au", "qcom,spmi-pmic"; reg = <0x4 SPMI_USID>; @@ -283,6 +367,22 @@ pmm8654au_2_gpios: gpio@8800 { }; }; + pmm8654au_sail_2: pmic@5 { + compatible = "qcom,pmm8654au", "qcom,spmi-pmic"; + reg = <0x5 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmm8654au_2_mbg_temp: temperature-sensor@d700 { + compatible = "qcom,pm8775-mbg-tm"; + reg = <0xd700>; + io-channels = <&pmm8654au_2_adc ADC5_GEN3_DIE_TEMP(4)>; + io-channel-names = "thermal"; + interrupts-extended = <&spmi_bus 0x5 0xd7 0x0 IRQ_TYPE_EDGE_RISING>; + #thermal-sensor-cells = <0>; + }; + }; + pmm8654au_3: pmic@6 { compatible = "qcom,pmm8654au", "qcom,spmi-pmic"; reg = <0x6 SPMI_USID>; @@ -329,4 +429,20 @@ pmm8654au_3_gpios: gpio@8800 { #interrupt-cells = <2>; }; }; + + pmm8654au_sail_3: pmic@7 { + compatible = "qcom,pmm8654au", "qcom,spmi-pmic"; + reg = <0x7 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmm8654au_3_mbg_temp: temperature-sensor@d700 { + compatible = "qcom,pm8775-mbg-tm"; + reg = <0xd700>; + io-channels = <&pmm8654au_3_adc ADC5_GEN3_DIE_TEMP(6)>; + io-channel-names = "thermal"; + interrupts-extended = <&spmi_bus 0x7 0xd7 0x0 IRQ_TYPE_EDGE_RISING>; + #thermal-sensor-cells = <0>; + }; + }; };
diff --git a/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi b/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi index 144f117..22f764b 100644 --- a/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans-ride-common.dtsi
@@ -856,12 +856,16 @@ &qup_uart17_rx { }; &serdes0 { - phy-supply = <&vreg_l5a>; + vdda-0p9-supply = <&vreg_l4a>; + vdda-1p2-supply = <&vreg_l1c>; + status = "okay"; }; &serdes1 { - phy-supply = <&vreg_l5a>; + vdda-0p9-supply = <&vreg_l4a>; + vdda-1p2-supply = <&vreg_l1c>; + status = "okay"; }; @@ -961,9 +965,6 @@ wake-pins { }; &pcie0 { - perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&pcie0_default_state>; @@ -971,9 +972,6 @@ &pcie0 { }; &pcie1 { - perst-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 5 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&pcie1_default_state>; @@ -994,7 +992,14 @@ &pcie1_phy { status = "okay"; }; +&pcie1_port0 { + reset-gpios = <&tlmm 4 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 5 GPIO_ACTIVE_LOW>; +}; + &pcieport0 { + reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 0 GPIO_ACTIVE_LOW>; wifi@0 { compatible = "pci17cb,1101"; reg = <0x10000 0x0 0x0 0x0 0x0>;
diff --git a/arch/arm64/boot/dts/qcom/lemans.dtsi b/arch/arm64/boot/dts/qcom/lemans.dtsi index 695eae1..1fdb72f 100644 --- a/arch/arm64/boot/dts/qcom/lemans.dtsi +++ b/arch/arm64/boot/dts/qcom/lemans.dtsi
@@ -1030,7 +1030,7 @@ gpu_speed_bin: gpu-speed-bin@240c { }; }; - gpi_dma2: dma-controller@800000 { + gpi_dma2: dma-controller@800000 { compatible = "qcom,sa8775p-gpi-dma", "qcom,sm6350-gpi-dma"; reg = <0x0 0x00800000 0x0 0x60000>; #dma-cells = <3>; @@ -1563,7 +1563,7 @@ &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, }; - gpi_dma0: dma-controller@900000 { + gpi_dma0: dma-controller@900000 { compatible = "qcom,sa8775p-gpi-dma", "qcom,sm6350-gpi-dma"; reg = <0x0 0x00900000 0x0 0x60000>; #dma-cells = <3>; @@ -2024,7 +2024,7 @@ &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, }; }; - gpi_dma1: dma-controller@a00000 { + gpi_dma1: dma-controller@a00000 { compatible = "qcom,sa8775p-gpi-dma", "qcom,sm6350-gpi-dma"; reg = <0x0 0x00a00000 0x0 0x60000>; #dma-cells = <3>; @@ -2517,7 +2517,7 @@ &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, }; }; - gpi_dma3: dma-controller@b00000 { + gpi_dma3: dma-controller@b00000 { compatible = "qcom,sa8775p-gpi-dma", "qcom,sm6350-gpi-dma"; reg = <0x0 0x00b00000 0x0 0x58000>; #dma-cells = <3>; @@ -2753,9 +2753,6 @@ pcie0: pcie@1c00000 { power-domains = <&gcc PCIE_0_GDSC>; - phys = <&pcie0_phy>; - phy-names = "pciephy"; - eq-presets-8gts = /bits/ 16 <0x5555 0x5555>; eq-presets-16gts = /bits/ 8 <0x55 0x55>; @@ -2767,6 +2764,8 @@ pcieport0: pcie@0 { reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie0_phy>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -2927,19 +2926,18 @@ pcie1: pcie@1c10000 { power-domains = <&gcc PCIE_1_GDSC>; - phys = <&pcie1_phy>; - phy-names = "pciephy"; - eq-presets-8gts = /bits/ 16 <0x5555 0x5555 0x5555 0x5555>; eq-presets-16gts = /bits/ 8 <0x55 0x55 0x55 0x55>; status = "disabled"; - pcie@0 { + pcie1_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie1_phy>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -7168,11 +7166,11 @@ rpmhpd_opp_min_svs: opp-1 { opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>; }; - rpmhpd_opp_low_svs: opp2 { + rpmhpd_opp_low_svs: opp-2 { opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>; }; - rpmhpd_opp_svs: opp3 { + rpmhpd_opp_svs: opp-3 { opp-level = <RPMH_REGULATOR_LEVEL_SVS>; };
diff --git a/arch/arm64/boot/dts/qcom/mahua-crd.dts b/arch/arm64/boot/dts/qcom/mahua-crd.dts index fa52290..17e40f2 100644 --- a/arch/arm64/boot/dts/qcom/mahua-crd.dts +++ b/arch/arm64/boot/dts/qcom/mahua-crd.dts
@@ -20,6 +20,11 @@ / { compatible = "qcom,mahua-crd", "qcom,mahua"; }; +&pcie3b_phy { + vdda-phy-supply = <&vreg_l3c_e1_0p89>; + vdda-pll-supply = <&vreg_l2c_e1_1p14>; +}; + &tcsr { vdda-qrefrpt0-0p9-supply = <&vreg_l2f_e1_0p83>; vdda-qrefrpt1-0p9-supply = <&vreg_l2f_e1_0p83>;
diff --git a/arch/arm64/boot/dts/qcom/mahua-lenovo-thinkpad-t14s-gen7-lcd.dts b/arch/arm64/boot/dts/qcom/mahua-lenovo-thinkpad-t14s-gen7-lcd.dts new file mode 100644 index 0000000..26d6d82 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/mahua-lenovo-thinkpad-t14s-gen7-lcd.dts
@@ -0,0 +1,1272 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +/dts-v1/; + +#include "mahua.dtsi" + +#include "pmcx0102.dtsi" +#include "pmh0101.dtsi" +#include "pmh0110-glymur.dtsi" +#include "pmh0104-glymur.dtsi" +#include "pmk8850.dtsi" +#include "smb2370.dtsi" + +#include <dt-bindings/input/gpio-keys.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/pinctrl/qcom,pmic-gpio.h> + +/* PMICs tied to Glymur's cluster2 are absent on Mahua. */ +/delete-node/ &pmcx0102_d_e0; +/delete-node/ &pmcx0102_d0_thermal; +/delete-node/ &pmh0104_i_e0; +/delete-node/ &pmh0104_i0_thermal; +/delete-node/ &pmh0104_j_e0; +/delete-node/ &pmh0104_j0_thermal; + +/ { + model = "Lenovo ThinkPad T14s Gen 7 (LCD)"; + compatible = "lenovo,thinkpad-t14s-gen7-lcd", "lenovo,thinkpad-t14s-gen7", + "qcom,mahua"; + + aliases { + i2c0 = &i2c0; + i2c5 = &i2c5; + + serial0 = &uart21; + serial1 = &uart14; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + clocks { + xo_board: xo-board { + compatible = "fixed-clock"; + clock-frequency = <38400000>; + #clock-cells = <0>; + }; + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + clock-frequency = <32000>; + #clock-cells = <0>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&hall_int_n_default>; + pinctrl-names = "default"; + + switch-lid { + label = "lid"; + gpios = <&tlmm 92 GPIO_ACTIVE_LOW>; + linux,input-type = <EV_SW>; + linux,code = <SW_LID>; + wakeup-source; + wakeup-event-action = <EV_ACT_DEASSERTED>; + }; + }; + + pmic-glink { + compatible = "qcom,glymur-pmic-glink", + "qcom,pmic-glink"; + #address-cells = <1>; + #size-cells = <0>; + + /* Left-side USB-C port */ + connector@0 { + compatible = "usb-c-connector"; + reg = <0>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in: endpoint { + remote-endpoint = <&usb_0_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in: endpoint { + remote-endpoint = <&usb_0_qmpphy_out>; + }; + }; + }; + }; + + /* Right-side USB-C port */ + connector@1 { + compatible = "usb-c-connector"; + reg = <1>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in1: endpoint { + remote-endpoint = <&usb_1_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in1: endpoint { + remote-endpoint = <&usb_1_qmpphy_out>; + }; + }; + }; + }; + }; + + vreg_edp_3p3: regulator-edp-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_EDP_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 70 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&edp_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_edp_bl: regulator-edp-bl { + compatible = "regulator-fixed"; + + regulator-name = "VREG_EDP_BL"; + regulator-min-microvolt = <3600000>; + regulator-max-microvolt = <3600000>; + + gpio = <&tlmm 19 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&edp_bl_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + regulator-always-on; + }; + + vreg_misc_3p3: regulator-misc-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_MISC_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pmh0110_f_e0_gpios 6 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&misc_3p3_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + regulator-always-on; + }; + + vreg_nvme: regulator-nvme { + compatible = "regulator-fixed"; + + regulator-name = "VREG_NVME_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&pmh0101_gpios 14 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&nvme_reg_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_wcn_0p95: regulator-wcn-0p95 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_0P95"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <950000>; + + vin-supply = <&vreg_wcn_3p3>; + }; + + vreg_wcn_3p3: regulator-wcn-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 94 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&wcn_sw_en>; + pinctrl-names = "default"; + + regulator-boot-on; + }; + + vreg_wwan: regulator-wwan { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WWAN_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 246 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&wwan_reg_en>; + pinctrl-names = "default"; + }; + + reserved-memory { + linux,cma { + compatible = "shared-dma-pool"; + size = <0x0 0x10000000>; + reusable; + linux,cma-default; + }; + }; + + sound { + compatible = "qcom,glymur-sndcard"; + model = "Lenovo-ThinkPad-T14s-Gen-7"; + audio-routing = "SpkrLeft IN", "WSA WSA_SPK1 OUT", + "SpkrRight IN", "WSA WSA_SPK2 OUT", + "VA DMIC0", "vdd-micb", + "VA DMIC1", "vdd-micb"; + + wsa-dai-link { + link-name = "WSA Playback"; + + cpu { + sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>; + }; + + codec { + sound-dai = <&left_spkr>, <&right_spkr>, + <&swr0 0>, <&lpass_wsamacro 0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + va-dai-link { + link-name = "VA Capture"; + + cpu { + sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>; + }; + + codec { + sound-dai = <&lpass_vamacro 0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + displayport-0-dai-link { + link-name = "DisplayPort0 Playback"; + + cpu { + sound-dai = <&q6apmbedai DISPLAY_PORT_RX_0>; + }; + + codec { + sound-dai = <&mdss_dp0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + displayport-1-dai-link { + link-name = "DisplayPort1 Playback"; + + cpu { + sound-dai = <&q6apmbedai DISPLAY_PORT_RX_1>; + }; + + codec { + sound-dai = <&mdss_dp1>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + }; + + wcn7850-pmu { + compatible = "qcom,wcn7850-pmu"; + + vdd-supply = <&vreg_wcn_0p95>; + vddio-supply = <&vreg_l15b_e0_1p8>; + vddaon-supply = <&vreg_l15b_e0_1p8>; + vdddig-supply = <&vreg_l15b_e0_1p8>; + vddrfa1p2-supply = <&vreg_l15b_e0_1p8>; + vddrfa1p8-supply = <&vreg_l15b_e0_1p8>; + + wlan-enable-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>; + bt-enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&wcn_wlan_bt_en>; + pinctrl-names = "default"; + + regulators { + vreg_pmu_rfa_cmn: ldo0 { + regulator-name = "vreg_pmu_rfa_cmn"; + }; + + vreg_pmu_aon_0p59: ldo1 { + regulator-name = "vreg_pmu_aon_0p59"; + }; + + vreg_pmu_wlcx_0p8: ldo2 { + regulator-name = "vreg_pmu_wlcx_0p8"; + }; + + vreg_pmu_wlmx_0p85: ldo3 { + regulator-name = "vreg_pmu_wlmx_0p85"; + }; + + vreg_pmu_btcmx_0p85: ldo4 { + regulator-name = "vreg_pmu_btcmx_0p85"; + }; + + vreg_pmu_rfa_0p8: ldo5 { + regulator-name = "vreg_pmu_rfa_0p8"; + }; + + vreg_pmu_rfa_1p2: ldo6 { + regulator-name = "vreg_pmu_rfa_1p2"; + }; + + vreg_pmu_rfa_1p8: ldo7 { + regulator-name = "vreg_pmu_rfa_1p8"; + }; + + vreg_pmu_pcie_0p9: ldo8 { + regulator-name = "vreg_pmu_pcie_0p9"; + }; + + vreg_pmu_pcie_1p8: ldo9 { + regulator-name = "vreg_pmu_pcie_1p8"; + }; + }; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pmh0101-rpmh-regulators"; + qcom,pmic-id = "B_E0"; + + vreg_bob1_e0: bob1 { + regulator-name = "vreg_bob1_e0"; + regulator-min-microvolt = <2200000>; + regulator-max-microvolt = <4224000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_bob2_e0: bob2 { + regulator-name = "vreg_bob2_e0"; + regulator-min-microvolt = <2540000>; + regulator-max-microvolt = <3600000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + }; + + vreg_l1b_e0_1p8: ldo1 { + regulator-name = "vreg_l1b_e0_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2b_e0_2p9: ldo2 { + regulator-name = "vreg_l2b_e0_2p9"; + regulator-min-microvolt = <2904000>; + regulator-max-microvolt = <2904000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7b_e0_2p79: ldo7 { + regulator-name = "vreg_l7b_e0_2p79"; + regulator-min-microvolt = <2790000>; + regulator-max-microvolt = <2792000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l8b_e0_3p3: ldo8 { + regulator-name = "vreg_l8b_e0_3p3"; + regulator-min-microvolt = <1504000>; + regulator-max-microvolt = <3304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l9b_e0_2p9: ldo9 { + regulator-name = "vreg_l9b_e0_2p9"; + regulator-min-microvolt = <2704000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l10b_e0_1p8: ldo10 { + regulator-name = "vreg_l10b_e0_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l11b_e0_1p2: ldo11 { + regulator-name = "vreg_l11b_e0_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l12b_e0_1p2: ldo12 { + regulator-name = "vreg_l12b_e0_1p2"; + regulator-min-microvolt = <1144000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l15b_e0_1p8: ldo15 { + regulator-name = "vreg_l15b_e0_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; + }; + + vreg_l17b_e0_2p4: ldo17 { + regulator-name = "vreg_l17b_e0_2p4"; + regulator-min-microvolt = <2400000>; + regulator-max-microvolt = <2700000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l18b_e0_1p2: ldo18 { + regulator-name = "vreg_l18b_e0_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; + }; + }; + + regulators-1 { + compatible = "qcom,pmcx0102-rpmh-regulators"; + qcom,pmic-id = "C_E1"; + + vreg_l1c_e1_0p82: ldo1 { + regulator-name = "vreg_l1c_e1_0p82"; + regulator-min-microvolt = <832000>; + regulator-max-microvolt = <832000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2c_e1_1p14: ldo2 { + regulator-name = "vreg_l2c_e1_1p14"; + regulator-min-microvolt = <1144000>; + regulator-max-microvolt = <1144000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3c_e1_0p89: ldo3 { + regulator-name = "vreg_l3c_e1_0p89"; + regulator-min-microvolt = <890000>; + regulator-max-microvolt = <980000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4c_e1_0p72: ldo4 { + regulator-name = "vreg_l4c_e1_0p72"; + regulator-min-microvolt = <720000>; + regulator-max-microvolt = <720000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-2 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "F_E0"; + + vreg_s7f_e0_1p32: smps7 { + regulator-name = "vreg_s7f_e0_1p32"; + regulator-min-microvolt = <1320000>; + regulator-max-microvolt = <1352000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s8f_e0_0p95: smps8 { + regulator-name = "vreg_s8f_e0_0p95"; + regulator-min-microvolt = <952000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s9f_e0_1p9: smps9 { + regulator-name = "vreg_s9f_e0_1p9"; + regulator-min-microvolt = <1900000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2f_e0_0p94: ldo2 { + regulator-name = "vreg_l2f_e0_0p94"; + regulator-min-microvolt = <936000>; + regulator-max-microvolt = <936000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3f_e0_0p91: ldo3 { + regulator-name = "vreg_l3f_e0_0p91"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4f_e0_0p3: ldo4 { + regulator-name = "vreg_l4f_e0_0p3"; + regulator-min-microvolt = <1080000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-3 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "F_E1"; + + vreg_s7f_e1_0p3: smps7 { + regulator-name = "vreg_s7f_e1_0p3"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1f_e1_0p88: ldo1 { + regulator-name = "vreg_l1f_e1_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2f_e1_0p9: ldo2 { + regulator-name = "vreg_l2f_e1_0p9"; + regulator-min-microvolt = <904000>; + regulator-max-microvolt = <904000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4f_e1_1p2: ldo4 { + regulator-name = "vreg_l4f_e1_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-4 { + compatible = "qcom,pmh0110-rpmh-regulators"; + qcom,pmic-id = "H_E0"; + + vreg_l1h_e0_0p94: ldo1 { + regulator-name = "vreg_l1h_e0_0p94"; + regulator-min-microvolt = <936000>; + regulator-max-microvolt = <936000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2h_e0_0p72: ldo2 { + regulator-name = "vreg_l2h_e0_0p72"; + regulator-min-microvolt = <832000>; + regulator-max-microvolt = <832000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3h_e0_0p32: ldo3 { + regulator-name = "vreg_l3h_e0_0p32"; + regulator-min-microvolt = <320000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4h_e0_1p2: ldo4 { + regulator-name = "vreg_l4h_e0_1p2"; + regulator-min-microvolt = <1080000>; + regulator-max-microvolt = <1320000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; +}; + +/* GPU/GMU not fully functional yet on this platform. */ +&gmu { + status = "disabled"; +}; + +&gpu { + status = "disabled"; +}; + +&i2c0 { + clock-frequency = <400000>; + + status = "okay"; + + touchpad@2c { + compatible = "hid-over-i2c"; + reg = <0x2c>; + + hid-descr-addr = <0x20>; + interrupts-extended = <&tlmm 3 IRQ_TYPE_LEVEL_LOW>; + + vdd-supply = <&vreg_misc_3p3>; + vddl-supply = <&vreg_l15b_e0_1p8>; + + pinctrl-0 = <&tpad_default>; + pinctrl-names = "default"; + + wakeup-source; + }; + + keyboard@3a { + compatible = "hid-over-i2c"; + reg = <0x3a>; + + hid-descr-addr = <0x1>; + interrupts-extended = <&tlmm 67 IRQ_TYPE_LEVEL_LOW>; + + vdd-supply = <&vreg_misc_3p3>; + vddl-supply = <&vreg_l15b_e0_1p8>; + + pinctrl-0 = <&kybd_default>; + pinctrl-names = "default"; + + wakeup-source; + }; +}; + +&i2c5 { + clock-frequency = <400000>; + + status = "okay"; + + ptn3222_0: redriver@43 { + compatible = "nxp,ptn3222"; + reg = <0x43>; + + reset-gpios = <&tlmm 25 GPIO_ACTIVE_LOW>; + + vdd3v3-supply = <&vreg_l8b_e0_3p3>; + vdd1v8-supply = <&vreg_l15b_e0_1p8>; + + #phy-cells = <0>; + }; + + ptn3222_1: redriver@4b { + compatible = "nxp,ptn3222"; + reg = <0x4b>; + + reset-gpios = <&tlmm 184 GPIO_ACTIVE_LOW>; + + vdd3v3-supply = <&vreg_l8b_e0_3p3>; + vdd1v8-supply = <&vreg_l15b_e0_1p8>; + + #phy-cells = <0>; + }; + + ptn3222_cam: redriver@47 { + compatible = "nxp,ptn3222"; + reg = <0x47>; + + reset-gpios = <&tlmm 184 GPIO_ACTIVE_LOW>; + + vdd3v3-supply = <&vreg_l8b_e0_3p3>; + vdd1v8-supply = <&vreg_l15b_e0_1p8>; + + #phy-cells = <0>; + }; + + ptn3222_fpr: redriver@4f { + compatible = "nxp,ptn3222"; + reg = <0x4f>; + + reset-gpios = <&tlmm 40 GPIO_ACTIVE_LOW>; + + vdd3v3-supply = <&vreg_l8b_e0_3p3>; + vdd1v8-supply = <&vreg_l15b_e0_1p8>; + + #phy-cells = <0>; + }; +}; + +&lpass_vamacro { + pinctrl-0 = <&dmic01_default>; + pinctrl-names = "default"; + qcom,dmic-sample-rate = <4800000>; + vdd-micb-supply = <&vreg_l1b_e0_1p8>; +}; + +&mdss { + status = "okay"; +}; + +&mdss_dp0 { + status = "okay"; +}; + +&mdss_dp0_out { + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; +}; + +&mdss_dp1 { + status = "okay"; +}; + +&mdss_dp1_out { + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; +}; + +&mdss_dp3 { + /delete-property/ #sound-dai-cells; + + pinctrl-0 = <&edp0_hpd_default>; + pinctrl-names = "default"; + + status = "okay"; + + aux-bus { + panel { + compatible = "edp-panel"; + enable-gpios = <&tlmm 18 GPIO_ACTIVE_HIGH>; + power-supply = <&vreg_edp_3p3>; + + pinctrl-0 = <&edp_bl_en>; + pinctrl-names = "default"; + + port { + edp_panel_in: endpoint { + remote-endpoint = <&mdss_dp3_out>; + }; + }; + }; + }; +}; + +&mdss_dp3_out { + data-lanes = <0 1 2 3>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; + + remote-endpoint = <&edp_panel_in>; +}; + +&mdss_dp3_phy { + vdda-phy-supply = <&vreg_l2f_e1_0p9>; + vdda-pll-supply = <&vreg_l4f_e1_1p2>; + + status = "okay"; +}; + +/* PCIe4: on-board WLAN (WCN7850) */ +&pcie4 { + pinctrl-0 = <&pcie4_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie4_phy { + vdda-phy-supply = <&vreg_l1c_e1_0p82>; + vdda-pll-supply = <&vreg_l4f_e1_1p2>; + + status = "okay"; +}; + +&pcie4_port0 { + reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>; + + wifi@0 { + compatible = "pci17cb,1107"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; + vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; + }; +}; + +/* PCIe5: primary M.2 2280 NVMe */ +&pcie5 { + vddpe-3v3-supply = <&vreg_nvme>; + + pinctrl-0 = <&pcie5_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie5_phy { + vdda-phy-supply = <&vreg_l2f_e0_0p94>; + vdda-pll-supply = <&vreg_l4h_e0_1p2>; + + status = "okay"; +}; + +&pcie5_port0 { + reset-gpios = <&tlmm 152 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 154 GPIO_ACTIVE_LOW>; +}; + +/* PCIe6: optional WWAN M.2 3042 */ +&pcie6 { + vddpe-3v3-supply = <&vreg_wwan>; + + pinctrl-0 = <&pcie6_default>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie6_phy { + vdda-phy-supply = <&vreg_l1c_e1_0p82>; + vdda-pll-supply = <&vreg_l4f_e1_1p2>; + + status = "okay"; +}; + +&pcie6_port0 { + reset-gpios = <&tlmm 149 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 151 GPIO_ACTIVE_LOW>; +}; + +&pmh0101_gpios { + nvme_reg_en: nvme-reg-en-state { + pins = "gpio14"; + function = "normal"; + bias-disable; + }; +}; + +&pmh0110_f_e0_gpios { + misc_3p3_reg_en: misc-3p3-reg-en-state { + pins = "gpio6"; + function = "normal"; + bias-disable; + input-disable; + output-enable; + drive-push-pull; + power-source = <1>; /* 1.8 V */ + qcom,drive-strength = <PMIC_GPIO_STRENGTH_LOW>; + }; +}; + +&pmk8850_rtc { + qcom,no-alarm; +}; + +&remoteproc_adsp { + firmware-name = "qcom/glymur/LENOVO/22A8/qcadsp8480.mbn", + "qcom/glymur/LENOVO/22A8/adsp_dtbs.elf"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/glymur/LENOVO/22A8/qccdsp8480.mbn", + "qcom/glymur/LENOVO/22A8/cdsp_dtbs.elf"; + + status = "okay"; +}; + +&swr0 { + status = "okay"; + + /* WSA8845, Left */ + left_spkr: speaker@0,0 { + compatible = "sdw20217020400"; + reg = <0 0>; + reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "SpkrLeft"; + vdd-1p8-supply = <&vreg_l15b_e0_1p8>; + vdd-io-supply = <&vreg_l18b_e0_1p2>; + qcom,port-mapping = <1 2 3 7 12 14>; + }; + + /* WSA8845, Right */ + right_spkr: speaker@0,1 { + compatible = "sdw20217020400"; + reg = <0 1>; + reset-gpios = <&lpass_tlmm 12 GPIO_ACTIVE_LOW>; + #sound-dai-cells = <0>; + sound-name-prefix = "SpkrRight"; + vdd-1p8-supply = <&vreg_l15b_e0_1p8>; + vdd-io-supply = <&vreg_l18b_e0_1p2>; + qcom,port-mapping = <4 5 6 7 13 15>; + }; +}; + +&smb2370_j_e2_eusb2_repeater { + vdd18-supply = <&vreg_l15b_e0_1p8>; + vdd3-supply = <&vreg_l7b_e0_2p79>; +}; + +&smb2370_k_e2_eusb2_repeater { + vdd18-supply = <&vreg_l15b_e0_1p8>; + vdd3-supply = <&vreg_l7b_e0_2p79>; +}; + +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l2f_e1_0p9>; + vdda-qrefrpt1-0p9-supply = <&vreg_l2f_e1_0p9>; + vdda-qrefrpt2-0p9-supply = <&vreg_l2f_e1_0p9>; + vdda-qrefrpt3-0p9-supply = <&vreg_l2h_e0_0p72>; + vdda-qrefrpt4-0p9-supply = <&vreg_l2h_e0_0p72>; + vdda-qrefrpt5-0p9-supply = <&vreg_l2h_e0_0p72>; + vdda-qrefrx0-0p9-supply = <&vreg_l2f_e1_0p9>; + vdda-qrefrx1-0p9-supply = <&vreg_l2f_e1_0p9>; + vdda-qrefrx2-0p9-supply = <&vreg_l2f_e1_0p9>; + vdda-qrefrx3-0p9-supply = <&vreg_l2h_e0_0p72>; + vdda-qrefrx4-0p9-supply = <&vreg_l2h_e0_0p72>; + vdda-qrefrx5-0p9-supply = <&vreg_l3f_e0_0p91>; + vdda-qreftx0-0p9-supply = <&vreg_l3f_e0_0p91>; + vdda-qreftx0-1p2-supply = <&vreg_l4h_e0_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l1f_e1_0p88>; + vdda-refgen3-0p9-supply = <&vreg_l2f_e0_0p94>; + vdda-refgen3-1p2-supply = <&vreg_l4h_e0_1p2>; + vdda-refgen4-0p9-supply = <&vreg_l1f_e1_0p88>; + vdda-refgen4-1p2-supply = <&vreg_l4f_e1_1p2>; +}; + +&tlmm { + gpio-reserved-ranges = <4 4>, /* EC TZ Secure I3C */ + <10 2>, /* OOB UART */ + <27 1>, /* TZ trigger */ + <44 4>, /* TPM */ + <139 1>; /* TZ trigger */ + + edp_bl_en: edp-bl-en-state { + pins = "gpio18"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + edp_bl_reg_en: edp-bl-reg-en-state { + pins = "gpio19"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + edp_reg_en: edp-reg-en-state { + pins = "gpio70"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + edp0_hpd_default: edp0-hpd-default-state { + pins = "gpio119"; + function = "edp0_hot"; + bias-disable; + }; + + hall_int_n_default: hall-int-n-state { + pins = "gpio92"; + function = "gpio"; + bias-disable; + }; + + kybd_default: kybd-default-state { + pins = "gpio67"; + function = "gpio"; + bias-disable; + }; + + pcie4_default: pcie4-default-state { + clkreq-n-pins { + pins = "gpio147"; + function = "pcie4_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio146"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio148"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie5_default: pcie5-default-state { + clkreq-n-pins { + pins = "gpio153"; + function = "pcie5_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio152"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio154"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + pcie6_default: pcie6-default-state { + clkreq-n-pins { + pins = "gpio150"; + function = "pcie6_clk_req_n"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-n-pins { + pins = "gpio149"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wake-n-pins { + pins = "gpio151"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + tpad_default: tpad-default-state { + pins = "gpio3"; + function = "gpio"; + bias-disable; + }; + + wcn_wlan_bt_en: wcn-wlan-bt-en-state { + pins = "gpio116", "gpio117"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wcn_sw_en: wcn-sw-en-state { + pins = "gpio94"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + wwan_reg_en: wwan-reg-en-state { + pins = "gpio246"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; +}; + +&uart14 { + status = "okay"; + + bluetooth { + compatible = "qcom,wcn7850-bt"; + max-speed = <3200000>; + + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + }; +}; + +&usb_0 { + status = "okay"; +}; + +&usb_0_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in>; +}; + +&usb_0_hsphy { + vdd-supply = <&vreg_l3f_e0_0p91>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + phys = <&smb2370_j_e2_eusb2_repeater>; + + status = "okay"; +}; + +&usb_0_qmpphy { + vdda-phy-supply = <&vreg_l3f_e0_0p91>; + vdda-pll-supply = <&vreg_l4h_e0_1p2>; + refgen-supply = <&vreg_l2f_e0_0p94>; + + status = "okay"; +}; + +&usb_0_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in>; +}; + +&usb_1 { + status = "okay"; +}; + +&usb_1_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in1>; +}; + +&usb_1_hsphy { + vdd-supply = <&vreg_l3f_e0_0p91>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + phys = <&smb2370_k_e2_eusb2_repeater>; + + status = "okay"; +}; + +&usb_1_qmpphy { + vdda-phy-supply = <&vreg_l1h_e0_0p94>; + vdda-pll-supply = <&vreg_l4h_e0_1p2>; + refgen-supply = <&vreg_l2f_e0_0p94>; + + status = "okay"; +}; + +&usb_1_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in1>; +}; + +&usb_mp { + status = "okay"; +}; + +&usb_mp_hsphy0 { + vdd-supply = <&vreg_l2h_e0_0p72>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + phys = <&ptn3222_0>; + + status = "okay"; +}; + +&usb_mp_hsphy1 { + vdd-supply = <&vreg_l2h_e0_0p72>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + phys = <&ptn3222_1>; +//USB-A.. + status = "okay"; +}; + +&usb_mp_qmpphy0 { + vdda-phy-supply = <&vreg_l2h_e0_0p72>; + vdda-pll-supply = <&vreg_l4h_e0_1p2>; + refgen-supply = <&vreg_l4f_e1_1p2>; + + status = "okay"; +}; + +&usb_mp_qmpphy1 { + vdda-phy-supply = <&vreg_l2h_e0_0p72>; + vdda-pll-supply = <&vreg_l4h_e0_1p2>; + refgen-supply = <&vreg_l4f_e1_1p2>; + + status = "okay"; +}; + +&usb_hs { + dr_mode = "host"; + + status = "okay"; +}; + +&usb_hs_phy { + vdd-supply = <&vreg_l2h_e0_0p72>; + vdda12-supply = <&vreg_l4h_e0_1p2>; + + phys = <&ptn3222_cam>; + + status = "okay"; +}; + +&usb_2 { + dr_mode = "host"; + maximum-speed = "high-speed"; + + /delete-property/ usb-role-switch; + phys = <&usb_2_hsphy>; + phy-names = "usb2-phy"; + + status = "okay"; +}; + +&usb_2_hsphy { + vdd-supply = <&vreg_l4c_e1_0p72>; + vdda12-supply = <&vreg_l4f_e1_1p2>; + + phys = <&ptn3222_fpr>; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/qcom/mahua.dtsi b/arch/arm64/boot/dts/qcom/mahua.dtsi index e6c0597..a59c5ed 100644 --- a/arch/arm64/boot/dts/qcom/mahua.dtsi +++ b/arch/arm64/boot/dts/qcom/mahua.dtsi
@@ -22,6 +22,8 @@ /delete-node/ &cpu_pd16; /delete-node/ &cpu_pd17; /delete-node/ &cti_wpss; +/delete-node/ &pcie3_phy; +/delete-node/ &pcie3a; /delete-node/ &thermal_aoss_6; /delete-node/ &thermal_aoss_7; /delete-node/ &thermal_cpu_2_0_0; @@ -79,6 +81,52 @@ &config_noc { compatible = "qcom,mahua-cnoc-cfg"; }; +&gcc { + clocks = <&rpmhcc RPMH_CXO_CLK>, /* Board XO source */ + <&rpmhcc RPMH_CXO_CLK_A>, /* Board XO_A source */ + <&sleep_clk>, /* Sleep */ + <0>, /* USB 0 Phy DP0 GMUX */ + <0>, /* USB 0 Phy DP1 GMUX */ + <0>, /* USB 0 Phy PCIE PIPEGMUX */ + <0>, /* USB 0 Phy PIPEGMUX */ + <0>, /* USB 0 Phy SYS PCIE PIPEGMUX */ + <0>, /* USB 1 Phy DP0 GMUX 2 */ + <0>, /* USB 1 Phy DP1 GMUX 2 */ + <0>, /* USB 1 Phy PCIE PIPEGMUX */ + <0>, /* USB 1 Phy PIPEGMUX */ + <0>, /* USB 1 Phy SYS PCIE PIPEGMUX */ + <0>, /* USB 2 Phy DP0 GMUX 2 */ + <0>, /* USB 2 Phy DP1 GMUX 2 */ + <0>, /* USB 2 Phy PCIE PIPEGMUX */ + <0>, /* USB 2 Phy PIPEGMUX */ + <0>, /* USB 2 Phy SYS PCIE PIPEGMUX */ + <0>, /* PCIe 3a pipe */ + <&pcie3b_phy>, /* PCIe 3b pipe */ + <&pcie4_phy>, /* PCIe 4 */ + <&pcie5_phy>, /* PCIe 5 */ + <&pcie6_phy>, /* PCIe 6 */ + <0>, /* QUSB4 0 PHY RX 0 */ + <0>, /* QUSB4 0 PHY RX 1 */ + <0>, /* QUSB4 1 PHY RX 0 */ + <0>, /* QUSB4 1 PHY RX 1 */ + <0>, /* QUSB4 2 PHY RX 0 */ + <0>, /* QUSB4 2 PHY RX 1 */ + <0>, /* UFS PHY RX Symbol 0 */ + <0>, /* UFS PHY RX Symbol 1 */ + <0>, /* UFS PHY TX Symbol 0 */ + <&usb_0_qmpphy QMP_USB43DP_USB3_PIPE_CLK>, + <&usb_1_qmpphy QMP_USB43DP_USB3_PIPE_CLK>, + <&usb_2_qmpphy QMP_USB43DP_USB3_PIPE_CLK>, + <&usb_mp_qmpphy0>, /* USB3 UNI PHY pipe 0 */ + <&usb_mp_qmpphy1>, /* USB3 UNI PHY pipe 1 */ + <0>, /* USB4 PHY 0 pcie pipe */ + <0>, /* USB4 PHY 0 Max pipe */ + <0>, /* USB4 PHY 1 pcie pipe */ + <0>, /* USB4 PHY 1 Max pipe */ + <0>, /* USB4 PHY 2 pcie */ + <0>; /* USB4 PHY 2 Max */ +}; + &hsc_noc { compatible = "qcom,mahua-hscnoc"; }; @@ -115,6 +163,10 @@ &oobm_ss_noc { compatible = "qcom,mahua-oobm-ss-noc", "qcom,glymur-oobm-ss-noc"; }; +&pcie3b_port0 { + phys = <&pcie3b_phy>; +}; + &pcie5_phy { clocks = <&gcc GCC_PCIE_PHY_5_AUX_CLK>, <&gcc GCC_PCIE_5_CFG_AHB_CLK>, @@ -143,6 +195,43 @@ &pcie_west_slv_noc { compatible = "qcom,mahua-pcie-west-slv-noc"; }; +&soc { + pcie3b_phy: phy@1b90000 { + compatible = "qcom,glymur-qmp-gen5x4-pcie-phy"; + reg = <0x0 0x01b90000 0x0 0x10000>; + + clocks = <&gcc GCC_PCIE_PHY_3B_AUX_CLK>, + <&gcc GCC_PCIE_3B_CFG_AHB_CLK>, + <&tcsr TCSR_PCIE_3_CLKREF_EN>, + <&gcc GCC_PCIE_3B_PHY_RCHNG_CLK>, + <&gcc GCC_PCIE_3B_PIPE_CLK>, + <&gcc GCC_PCIE_3B_PIPE_DIV2_CLK>; + clock-names = "aux", + "cfg_ahb", + "ref", + "rchng", + "pipe", + "pipediv2"; + + resets = <&gcc GCC_PCIE_3B_PHY_BCR>, + <&gcc GCC_PCIE_3B_NOCSR_COM_PHY_BCR>; + reset-names = "phy", + "phy_nocsr"; + + assigned-clocks = <&gcc GCC_PCIE_3B_PHY_RCHNG_CLK>; + assigned-clock-rates = <100000000>; + + power-domains = <&gcc GCC_PCIE_3B_PHY_GDSC>; + + #clock-cells = <0>; + clock-output-names = "pcie3b_pipe_clk"; + + #phy-cells = <0>; + + status = "disabled"; + }; +}; + &system_noc { compatible = "qcom,mahua-system-noc", "qcom,glymur-system-noc"; };
diff --git a/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts b/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts index bb3b67e..acdcd3f 100644 --- a/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts +++ b/arch/arm64/boot/dts/qcom/milos-fairphone-fp6.dts
@@ -24,6 +24,7 @@ / { aliases { serial0 = &uart5; + serial1 = &uart11; }; gpio-keys { @@ -225,6 +226,67 @@ trip1 { }; }; }; + + wcn6750-pmu { + compatible = "qcom,wcn6755-pmu", "qcom,wcn6750-pmu"; + + vddaon-supply = <&vreg_s3b>; + vddasd-supply = <&vreg_l7b>; + vddpmu-supply = <&vreg_s3b>; + vddrfa0p8-supply = <&vreg_s3b>; + vddrfa1p2-supply = <&vreg_s2b>; + vddrfa1p7-supply = <&vreg_s1b>; + vddrfa2p2-supply = <&vreg_s1j>; + + bt-enable-gpios = <&tlmm 53 GPIO_ACTIVE_HIGH>; + + clocks = <&rpmhcc RPMH_RF_CLK1>; + + pinctrl-0 = <&bluetooth_enable_default>, <&pmk8550_sleep_clk_default>; + pinctrl-names = "default"; + + regulators { + vreg_pmu_rfa_cmn: ldo0 { + regulator-name = "vreg_pmu_rfa_cmn"; + }; + + vreg_pmu_aon_0p59: ldo1 { + regulator-name = "vreg_pmu_aon_0p59"; + }; + + vreg_pmu_wlcx_0p8: ldo2 { + regulator-name = "vreg_pmu_wlcx_0p8"; + }; + + vreg_pmu_wlmx_0p85: ldo3 { + regulator-name = "vreg_pmu_wlmx_0p85"; + }; + + vreg_pmu_btcmx_0p85: ldo4 { + regulator-name = "vreg_pmu_btcmx_0p85"; + }; + + vreg_pmu_rfa_0p8: ldo5 { + regulator-name = "vreg_pmu_rfa_0p8"; + }; + + vreg_pmu_rfa_1p2: ldo6 { + regulator-name = "vreg_pmu_rfa_1p2"; + }; + + vreg_pmu_rfa_1p7: ldo7 { + regulator-name = "vreg_pmu_rfa_1p7"; + }; + + vreg_pmu_pcie_0p9: ldo8 { + regulator-name = "vreg_pmu_pcie_0p9"; + }; + + vreg_pmu_pcie_1p8: ldo9 { + regulator-name = "vreg_pmu_pcie_1p8"; + }; + }; + }; }; &apps_rsc { @@ -723,6 +785,17 @@ &pmiv0104_eusb2_repeater { qcom,tune-usb2-preem = /bits/ 8 <0x6>; }; +&pmk8550_gpios { + pmk8550_sleep_clk_default: sleep-clk-default-state { + pins = "gpio5"; + function = "func1"; + input-disable; + output-enable; + bias-disable; + power-source = <0>; + }; +}; + &pmr735b_gpios { s1j_enable_default: s1j-enable-default-state { pins = "gpio1"; @@ -771,6 +844,39 @@ &pon_resin { status = "okay"; }; +&qup_uart11_cts { + /* + * Configure a bias-bus-hold on CTS to lower power + * usage when Bluetooth is turned off. Bus hold will + * maintain a low power state regardless of whether + * the Bluetooth module drives the pin in either + * direction or leaves the pin fully unpowered. + */ + bias-bus-hold; +}; + +&qup_uart11_rts { + /* We'll drive RTS, so no pull */ + drive-strength = <2>; + bias-disable; +}; + +&qup_uart11_rx { + /* + * Configure a pull-up on RX. This is needed to avoid + * garbage data when the TX pin of the Bluetooth module is + * in tri-state (module powered off or not driving the + * signal yet). + */ + bias-pull-up; +}; + +&qup_uart11_tx { + /* We'll drive TX, so no pull */ + drive-strength = <2>; + bias-disable; +}; + &qupv3_id_0 { status = "okay"; }; @@ -834,6 +940,59 @@ &tlmm { <13 1>, /* NC */ <63 2>; /* WLAN UART */ + qup_uart11_sleep_cts: qup-uart11-sleep-cts-state { + pins = "gpio48"; + function = "gpio"; + /* + * Configure a bias-bus-hold on CTS to lower power + * usage when Bluetooth is turned off. Bus hold will + * maintain a low power state regardless of whether + * the Bluetooth module drives the pin in either + * direction or leaves the pin fully unpowered. + */ + bias-bus-hold; + }; + + qup_uart11_sleep_rts: qup-uart11-sleep-rts-state { + pins = "gpio49"; + function = "gpio"; + /* + * Configure pull-down on RTS. As RTS is active low + * signal, pull it low to indicate the BT SoC that it + * can wakeup the system anytime from suspend state by + * pulling RX low (by sending wakeup bytes). + */ + bias-pull-down; + }; + + qup_uart11_sleep_tx: qup-uart11-sleep-tx-state { + pins = "gpio50"; + function = "gpio"; + /* + * Configure pull-up on TX when it isn't actively driven + * to prevent BT SoC from receiving garbage during sleep. + */ + bias-pull-up; + }; + + qup_uart11_sleep_rx: qup-uart11-sleep-rx-state { + pins = "gpio51"; + function = "gpio"; + /* + * Configure a pull-up on RX. This is needed to avoid + * garbage data when the TX pin of the Bluetooth module + * is floating which may cause spurious wakeups. + */ + bias-pull-up; + }; + + bluetooth_enable_default: bluetooth-enable-default-state { + pins = "gpio53"; + function = "gpio"; + output-low; + bias-disable; + }; + sdc2_card_det_n: sdc2-card-det-state { pins = "gpio65"; function = "gpio"; @@ -874,6 +1033,32 @@ &uart5 { status = "okay"; }; +&uart11 { + /delete-property/ interrupts; + interrupts-extended = <&intc GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH 0>, + <&tlmm 51 IRQ_TYPE_EDGE_FALLING>; + + pinctrl-1 = <&qup_uart11_sleep_cts>, + <&qup_uart11_sleep_rts>, + <&qup_uart11_sleep_tx>, + <&qup_uart11_sleep_rx>; + pinctrl-names = "default", + "sleep"; + + status = "okay"; + + bluetooth { + compatible = "qcom,wcn6755-bt", "qcom,wcn6750-bt"; + + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddbtcmx-supply = <&vreg_pmu_btcmx_0p85>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p7-supply = <&vreg_pmu_rfa_1p7>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + }; +}; + &ufs_mem_hc { reset-gpios = <&tlmm 167 GPIO_ACTIVE_LOW>; @@ -913,3 +1098,9 @@ &usb_1_hsphy { status = "okay"; }; + +&wifi { + qcom,calibration-variant = "Fairphone_Gen_6"; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/qcom/milos.dtsi b/arch/arm64/boot/dts/qcom/milos.dtsi index aad8bf6..ed994c2 100644 --- a/arch/arm64/boot/dts/qcom/milos.dtsi +++ b/arch/arm64/boot/dts/qcom/milos.dtsi
@@ -15,10 +15,10 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interconnect/qcom,icc.h> #include <dt-bindings/interconnect/qcom,milos-rpmh.h> +#include <dt-bindings/interconnect/qcom,osm-l3.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/mailbox/qcom-ipcc.h> #include <dt-bindings/power/qcom,rpmhpd.h> -#include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/soc/qcom,gpr.h> #include <dt-bindings/soc/qcom,rpmh-rsc.h> #include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h> @@ -66,6 +66,13 @@ cpu0: cpu@0 { qcom,freq-domain = <&cpufreq_hw 0>; + operating-points-v2 = <&cpu0_opp_table>; + + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&epss_l3 MASTER_EPSS_L3_APPS + &epss_l3 SLAVE_EPSS_L3_SHARED>; + #cooling-cells = <2>; l2_0: l2-cache { @@ -99,6 +106,13 @@ cpu1: cpu@100 { qcom,freq-domain = <&cpufreq_hw 0>; + operating-points-v2 = <&cpu0_opp_table>; + + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&epss_l3 MASTER_EPSS_L3_APPS + &epss_l3 SLAVE_EPSS_L3_SHARED>; + #cooling-cells = <2>; }; @@ -119,6 +133,13 @@ cpu2: cpu@200 { qcom,freq-domain = <&cpufreq_hw 0>; + operating-points-v2 = <&cpu0_opp_table>; + + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&epss_l3 MASTER_EPSS_L3_APPS + &epss_l3 SLAVE_EPSS_L3_SHARED>; + #cooling-cells = <2>; l2_2: l2-cache { @@ -146,6 +167,13 @@ cpu3: cpu@300 { qcom,freq-domain = <&cpufreq_hw 0>; + operating-points-v2 = <&cpu0_opp_table>; + + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&epss_l3 MASTER_EPSS_L3_APPS + &epss_l3 SLAVE_EPSS_L3_SHARED>; + #cooling-cells = <2>; }; @@ -166,6 +194,13 @@ cpu4: cpu@400 { qcom,freq-domain = <&cpufreq_hw 1>; + operating-points-v2 = <&cpu4_opp_table>; + + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&epss_l3 MASTER_EPSS_L3_APPS + &epss_l3 SLAVE_EPSS_L3_SHARED>; + #cooling-cells = <2>; l2_4: l2-cache { @@ -193,6 +228,13 @@ cpu5: cpu@500 { qcom,freq-domain = <&cpufreq_hw 1>; + operating-points-v2 = <&cpu4_opp_table>; + + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&epss_l3 MASTER_EPSS_L3_APPS + &epss_l3 SLAVE_EPSS_L3_SHARED>; + #cooling-cells = <2>; l2_5: l2-cache { @@ -220,6 +262,13 @@ cpu6: cpu@600 { qcom,freq-domain = <&cpufreq_hw 1>; + operating-points-v2 = <&cpu4_opp_table>; + + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&epss_l3 MASTER_EPSS_L3_APPS + &epss_l3 SLAVE_EPSS_L3_SHARED>; + #cooling-cells = <2>; l2_6: l2-cache { @@ -247,6 +296,13 @@ cpu7: cpu@700 { qcom,freq-domain = <&cpufreq_hw 2>; + operating-points-v2 = <&cpu7_opp_table>; + + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>, + <&epss_l3 MASTER_EPSS_L3_APPS + &epss_l3 SLAVE_EPSS_L3_SHARED>; + #cooling-cells = <2>; l2_7: l2-cache { @@ -395,6 +451,281 @@ memory@0 { reg = <0 0 0 0>; }; + cpu0_opp_table: opp-table-cpu0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-441600000 { + opp-hz = /bits/ 64 <441600000>; + opp-peak-kBps = <(547000 * 4) (364800 * 32)>; + }; + + opp-595200000 { + opp-hz = /bits/ 64 <595200000>; + opp-peak-kBps = <(547000 * 4) (556800 * 32)>; + }; + + opp-787200000 { + opp-hz = /bits/ 64 <787200000>; + opp-peak-kBps = <(547000 * 4) (710400 * 32)>; + }; + + opp-902400000 { + opp-hz = /bits/ 64 <902400000>; + opp-peak-kBps = <(547000 * 4) (806400 * 32)>; + }; + + opp-1017600000 { + opp-hz = /bits/ 64 <1017600000>; + opp-peak-kBps = <(547000 * 4) (998400 * 32)>; + }; + + opp-1113600000 { + opp-hz = /bits/ 64 <1113600000>; + opp-peak-kBps = <(547000 * 4) (998400 * 32)>; + }; + + opp-1228800000 { + opp-hz = /bits/ 64 <1228800000>; + opp-peak-kBps = <(768000 * 4) (1094400 * 32)>; + }; + + opp-1344000000 { + opp-hz = /bits/ 64 <1344000000>; + opp-peak-kBps = <(768000 * 4) (1209600 * 32)>; + }; + + opp-1497600000 { + opp-hz = /bits/ 64 <1497600000>; + opp-peak-kBps = <(768000 * 4) (1363200 * 32)>; + }; + + opp-1593600000 { + opp-hz = /bits/ 64 <1593600000>; + /* TODO: ddr4 = 1017000, ddr5 = 1555000 */ + opp-peak-kBps = <(1555000 * 4) (1363200 * 32)>; + }; + + opp-1708800000 { + opp-hz = /bits/ 64 <1708800000>; + /* TODO: ddr4 = 1017000, ddr5 = 1555000 */ + opp-peak-kBps = <(1555000 * 4) (1497600 * 32)>; + }; + + opp-1804800000 { + opp-hz = /bits/ 64 <1804800000>; + /* TODO: ddr4 = 1017000, ddr5 = 1555000 */ + opp-peak-kBps = <(1555000 * 4) (1516800 * 32)>; + }; + + opp-2054400000 { + opp-hz = /bits/ 64 <2054400000>; + /* TODO: ddr4 = 1017000, ddr5 = 1555000 */ + opp-peak-kBps = <(1555000 * 4) (1804800 * 32)>; + }; + }; + + cpu4_opp_table: opp-table-cpu4 { + compatible = "operating-points-v2"; + opp-shared; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + opp-peak-kBps = <(547000 * 4) (364800 * 32)>; + }; + + opp-633600000 { + opp-hz = /bits/ 64 <633600000>; + opp-peak-kBps = <(547000 * 4) (556800 * 32)>; + }; + + opp-787200000 { + opp-hz = /bits/ 64 <787200000>; + opp-peak-kBps = <(547000 * 4) (556800 * 32)>; + }; + + opp-940800000 { + opp-hz = /bits/ 64 <940800000>; + opp-peak-kBps = <(547000 * 4) (556800 * 32)>; + }; + + opp-1056000000 { + opp-hz = /bits/ 64 <1056000000>; + /* TODO: ddr4 = 1017000, ddr5 = 768000 */ + opp-peak-kBps = <(768000 * 4) (710400 * 32)>; + }; + + opp-1190400000 { + opp-hz = /bits/ 64 <1190400000>; + /* TODO: ddr4 = 1017000, ddr5 = 768000 */ + opp-peak-kBps = <(768000 * 4) (710400 * 32)>; + }; + + opp-1286400000 { + opp-hz = /bits/ 64 <1286400000>; + /* TODO: ddr4 = 1708000, ddr5 = 1555000 */ + opp-peak-kBps = <(1555000 * 4) (902400 * 32)>; + }; + + opp-1401600000 { + opp-hz = /bits/ 64 <1401600000>; + /* TODO: ddr4 = 1708000, ddr5 = 1555000 */ + opp-peak-kBps = <(1555000 * 4) (1209600 * 32)>; + }; + + opp-1497600000 { + opp-hz = /bits/ 64 <1497600000>; + /* TODO: ddr4 = 1708000, ddr5 = 1555000 */ + opp-peak-kBps = <(1555000 * 4) (1209600 * 32)>; + }; + + opp-1612800000 { + opp-hz = /bits/ 64 <1612800000>; + /* TODO: ddr4 = 1708000, ddr5 = 1555000 */ + opp-peak-kBps = <(1555000 * 4) (1363200 * 32)>; + }; + + opp-1708800000 { + opp-hz = /bits/ 64 <1708800000>; + opp-peak-kBps = <(1708000 * 4) (1363200 * 32)>; + }; + + opp-1824000000 { + opp-hz = /bits/ 64 <1824000000>; + opp-peak-kBps = <(1708000 * 4) (1497600 * 32)>; + }; + + opp-1920000000 { + opp-hz = /bits/ 64 <1920000000>; + /* TODO: ddr4 = 1708000, ddr5 = 2092000 */ + opp-peak-kBps = <(2092000 * 4) (1497600 * 32)>; + }; + + opp-2016000000 { + opp-hz = /bits/ 64 <2016000000>; + /* TODO: ddr4 = 1708000, ddr5 = 2092000 */ + opp-peak-kBps = <(2092000 * 4) (1497600 * 32)>; + }; + + opp-2073600000 { + opp-hz = /bits/ 64 <2073600000>; + /* TODO: ddr4 = 1708000, ddr5 = 2092000 */ + opp-peak-kBps = <(2092000 * 4) (1497600 * 32)>; + }; + + opp-2208000000 { + opp-hz = /bits/ 64 <2208000000>; + /* TODO: ddr4 = 1708000, ddr5 = 2092000 */ + opp-peak-kBps = <(2092000 * 4) (1516800 * 32)>; + }; + + opp-2400000000 { + opp-hz = /bits/ 64 <2400000000>; + /* TODO: ddr4 = 1708000, ddr5 = 3196000 */ + opp-peak-kBps = <(3196000 * 4) (1516800 * 32)>; + }; + + opp-2707200000 { + opp-hz = /bits/ 64 <2707200000>; + /* TODO: ddr4 = 1708000, ddr5 = 3196000 */ + opp-peak-kBps = <(3196000 * 4) (1804800 * 32)>; + }; + }; + + cpu7_opp_table: opp-table-cpu7 { + compatible = "operating-points-v2"; + opp-shared; + + opp-480000000 { + opp-hz = /bits/ 64 <480000000>; + opp-peak-kBps = <(547000 * 4) (364800 * 32)>; + }; + + opp-633600000 { + opp-hz = /bits/ 64 <633600000>; + opp-peak-kBps = <(547000 * 4) (556800 * 32)>; + }; + + opp-787200000 { + opp-hz = /bits/ 64 <787200000>; + opp-peak-kBps = <(547000 * 4) (806400 * 32)>; + }; + + opp-960000000 { + opp-hz = /bits/ 64 <960000000>; + opp-peak-kBps = <(547000 * 4) (806400 * 32)>; + }; + + opp-1094400000 { + opp-hz = /bits/ 64 <1094400000>; + /* TODO: ddr4 = 1017000, ddr5 = 768000 */ + opp-peak-kBps = <(768000 * 4) (998400 * 32)>; + }; + + opp-1209600000 { + opp-hz = /bits/ 64 <1209600000>; + /* TODO: ddr4 = 1017000, ddr5 = 768000 */ + opp-peak-kBps = <(768000 * 4) (998400 * 32)>; + }; + + opp-1324800000 { + opp-hz = /bits/ 64 <1324800000>; + opp-peak-kBps = <(1555000 * 4) (998400 * 32)>; + }; + + opp-1459200000 { + opp-hz = /bits/ 64 <1459200000>; + opp-peak-kBps = <(1555000 * 4) (1209600 * 32)>; + }; + + opp-1651200000 { + opp-hz = /bits/ 64 <1651200000>; + opp-peak-kBps = <(1708000 * 4) (1209600 * 32)>; + }; + + opp-1766400000 { + opp-hz = /bits/ 64 <1766400000>; + /* TODO: ddr4 = 1708000, ddr5 = 2092000 */ + opp-peak-kBps = <(2092000 * 4) (1363200 * 32)>; + }; + + opp-1900800000 { + opp-hz = /bits/ 64 <1900800000>; + /* TODO: ddr4 = 2092000, ddr5 = 3196000 */ + opp-peak-kBps = <(3196000 * 4) (1497600 * 32)>; + }; + + opp-2208000000 { + opp-hz = /bits/ 64 <2208000000>; + /* TODO: ddr4 = 2092000, ddr5 = 3196000 */ + opp-peak-kBps = <(3196000 * 4) (1497600 * 32)>; + }; + + opp-2304000000 { + opp-hz = /bits/ 64 <2304000000>; + /* TODO: ddr4 = 2092000, ddr5 = 3196000 */ + opp-peak-kBps = <(3196000 * 4) (1516800 * 32)>; + }; + + opp-2496000000 { + opp-hz = /bits/ 64 <2496000000>; + /* TODO: ddr4 = 2092000, ddr5 = 3196000 */ + opp-peak-kBps = <(3196000 * 4) (1516800 * 32)>; + }; + + opp-2707200000 { + opp-hz = /bits/ 64 <2707200000>; + /* TODO: ddr4 = 2092000, ddr5 = 3196000 */ + opp-peak-kBps = <(3196000 * 4) (1804800 * 32)>; + }; + + opp-2918400000 { + opp-hz = /bits/ 64 <2918400000>; + /* TODO: ddr4 = 2092000, ddr5 = 3196000 */ + opp-peak-kBps = <(3196000 * 4) (1804800 * 32)>; + }; + }; + pmu-a520 { compatible = "arm,cortex-a520-pmu"; interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW &ppi_cluster0>; @@ -1949,6 +2280,11 @@ videocc: clock-controller@aaf0000 { <&sleep_clk>, <&gcc GCC_VIDEO_AHB_CLK>; + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MX>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; @@ -2031,6 +2367,11 @@ camcc: clock-controller@adb0000 { interconnects = <&mmss_noc MASTER_CAMNOC_HF QCOM_ICC_TAG_ALWAYS &mmss_noc SLAVE_MNOC_HF_MEM_NOC QCOM_ICC_TAG_ALWAYS>; + power-domains = <&rpmhpd RPMHPD_CX>, + <&rpmhpd RPMHPD_MX>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; @@ -2340,7 +2681,6 @@ spmi_bus: spmi@c400000 { qcom,ee = <0>; qcom,channel = <0>; - qcom,bus-id = <0>; interrupt-controller; #interrupt-cells = <4>; @@ -2413,19 +2753,27 @@ qup_i2c7_data_clk: qup-i2c7-data-clk-state { }; qup_uart11_cts_rts: qup-uart11-cts-rts-state { - /* CTS, RTS */ - pins = "gpio48", "gpio49"; - function = "qup1_se4"; - drive-strength = <2>; - bias-pull-down; + qup_uart11_cts: cts-pins { + pins = "gpio48"; + function = "qup1_se4"; + }; + + qup_uart11_rts: rts-pins { + pins = "gpio49"; + function = "qup1_se4"; + }; }; qup_uart11_default: qup-uart11-default-state { - /* TX, RX */ - pins = "gpio50", "gpio51"; - function = "qup1_se4"; - drive-strength = <2>; - bias-pull-up; + qup_uart11_tx: tx-pins { + pins = "gpio50"; + function = "qup1_se4"; + }; + + qup_uart11_rx: rx-pins { + pins = "gpio51"; + function = "qup1_se4"; + }; }; sdc2_default: sdc2-default-state { @@ -2764,6 +3112,52 @@ gic_its: msi-controller@17140000 { }; }; + wifi: wifi@17110040 { + compatible = "qcom,wcn6755-wifi", "qcom,wcn6750-wifi"; + reg = <0x0 0x17110040 0x0 0x0>; + + iommus = <&apps_smmu 0x1400 0x1>; + + interrupts = <GIC_SPI 768 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 769 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 770 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 771 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 772 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 773 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 774 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 775 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 776 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 777 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 778 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 779 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 780 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 781 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 782 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 783 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 784 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 785 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 786 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 787 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 788 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 789 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 790 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 791 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 792 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 793 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 794 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 795 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 796 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 797 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 798 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 799 IRQ_TYPE_EDGE_RISING 0>; + + qcom,rproc = <&remoteproc_wpss>; + qcom,smem-states = <&smp2p_wlan_out 0>; + qcom,smem-state-names = "wlan-smp2p-out"; + + status = "disabled"; + }; + timer@17420000 { compatible = "arm,armv7-timer-mem"; reg = <0x0 0x17420000 0x0 0x1000>; @@ -2925,6 +3319,18 @@ rpmhpd_opp_turbo_l1: opp-416 { }; }; + epss_l3: interconnect@17d90000 { + compatible = "qcom,milos-epss-l3", "qcom,epss-l3"; + reg = <0x0 0x17d90000 0x0 0x1000>; + + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&gcc GCC_GPLL0>; + clock-names = "xo", + "alternate"; + + #interconnect-cells = <1>; + }; + cpufreq_hw: cpufreq@17d91000 { compatible = "qcom,milos-cpufreq-epss", "qcom,cpufreq-epss"; reg = <0x0 0x17d91000 0x0 0x1000>, @@ -2950,6 +3356,55 @@ cpufreq_hw: cpufreq@17d91000 { #clock-cells = <1>; }; + pmu@24091000 { + compatible = "qcom,milos-cpu-bwmon", "qcom,sc7280-llcc-bwmon"; + reg = <0x0 0x24091000 0x0 0x1000>; + + interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH 0>; + + interconnects = <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ACTIVE_ONLY>; + + operating-points-v2 = <&llcc_bwmon_opp_table>; + + llcc_bwmon_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-0 { + opp-peak-kBps = <2086000>; + }; + + opp-1 { + opp-peak-kBps = <2929000>; + }; + + opp-2 { + /* TODO: ddr4 = 3879000 */ + opp-peak-kBps = <5931000>; + }; + + opp-3 { + /* TODO: ddr4 = 5163000 */ + opp-peak-kBps = <6515000>; + }; + + opp-4 { + /* TODO: ddr4 = 5931000 */ + opp-peak-kBps = <7980000>; + }; + + opp-5 { + /* TODO: ddr4 = 6515000 */ + opp-peak-kBps = <10437000>; + }; + + opp-6 { + /* TODO: ddr4 = 7980000 */ + opp-peak-kBps = <12191000>; + }; + }; + }; + gem_noc: interconnect@24100000 { compatible = "qcom,milos-gem-noc"; reg = <0x0 0x24100000 0x0 0xff080>;
diff --git a/arch/arm64/boot/dts/qcom/monaco-ac-evk.dts b/arch/arm64/boot/dts/qcom/monaco-ac-evk.dts new file mode 100644 index 0000000..6f3c3ff --- /dev/null +++ b/arch/arm64/boot/dts/qcom/monaco-ac-evk.dts
@@ -0,0 +1,938 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/pwm/pwm.h> +#include <dt-bindings/sound/qcom,q6afe.h> +#include <dt-bindings/regulator/qcom,rpmh-regulator.h> + +#include "monaco.dtsi" +#include "monaco-pmics.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. Monaco-ac EVK"; + compatible = "qcom,monaco-evk", "qcom,qcs8300"; + + aliases { + ethernet0 = ðernet0; + i2c1 = &i2c1; + serial0 = &uart7; + serial2 = &uart6; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + connector-2 { + compatible = "gpio-usb-b-connector", "usb-b-connector"; + label = "micro-USB"; + type = "micro"; + + id-gpios = <&pmm8620au_0_gpios 9 GPIO_ACTIVE_HIGH>; + vbus-gpios = <&expander6 7 GPIO_ACTIVE_HIGH>; + vbus-supply = <&usb2_vbus>; + + pinctrl-0 = <&usb2_id>; + pinctrl-names = "default"; + + port { + usb2_con_hs_ep: endpoint { + remote-endpoint = <&usb_2_dwc3_hs>; + }; + }; + }; + + dmic: audio-codec-0 { + compatible = "dmic-codec"; + #sound-dai-cells = <0>; + num-channels = <1>; + }; + + max98357a: audio-codec-1 { + compatible = "maxim,max98357a"; + #sound-dai-cells = <0>; + }; + + dp-connector-0 { + compatible = "dp-connector"; + label = "DP0"; + type = "mini"; + + port { + dp0_connector_in: endpoint { + remote-endpoint = <<8713sx_dp0_out>; + }; + }; + }; + + dp-connector-1 { + compatible = "dp-connector"; + label = "DP1"; + type = "mini"; + + port { + dp1_connector_in: endpoint { + remote-endpoint = <<8713sx_dp1_out>; + }; + }; + }; + + usb2_vbus: regulator-usb2-vbus { + compatible = "regulator-fixed"; + regulator-name = "usb2_vbus"; + gpio = <&pmm8650au_1_gpios 7 GPIO_ACTIVE_HIGH>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + enable-active-high; + }; + + sound { + compatible = "qcom,qcs8275-sndcard"; + model = "MONACO-EVK"; + + pinctrl-0 = <&hs0_mi2s_active>, <&mi2s1_active>; + pinctrl-names = "default"; + + hs0-mi2s-playback-dai-link { + link-name = "HS0 MI2S Playback"; + + codec { + sound-dai = <&max98357a>; + }; + + cpu { + sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + sec-mi2s-capture-dai-link { + link-name = "Secondary MI2S Capture"; + + codec { + sound-dai = <&dmic>; + }; + + cpu { + sound-dai = <&q6apmbedai SECONDARY_MI2S_TX>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + }; + + vreg_cam0_2p8: vreg-cam0-2p8 { + compatible = "regulator-fixed"; + regulator-name = "vreg_cam0_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + startup-delay-us = <10000>; + + gpio = <&tlmm 73 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&cam0_avdd_2v8_en_default>; + pinctrl-names = "default"; + }; + + vreg_cam1_2p8: vreg-cam1-2p8 { + compatible = "regulator-fixed"; + regulator-name = "vreg_cam1_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + startup-delay-us = <10000>; + + gpio = <&tlmm 74 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&cam1_avdd_2v8_en_default>; + pinctrl-names = "default"; + }; + + vreg_cam2_2p8: vreg-cam2-2p8 { + compatible = "regulator-fixed"; + regulator-name = "vreg_cam2_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + startup-delay-us = <10000>; + + gpio = <&tlmm 75 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&cam2_avdd_2v8_en_default>; + pinctrl-names = "default"; + }; + + /* This comes from a PMIC handled within the SAIL domain */ + vreg_s2s: vreg-s2s { + compatible = "regulator-fixed"; + regulator-name = "vreg_s2s"; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pmm8654au-rpmh-regulators"; + qcom,pmic-id = "a"; + + vreg_l3a: ldo3 { + regulator-name = "vreg_l3a"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4a: ldo4 { + regulator-name = "vreg_l4a"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5a: ldo5 { + regulator-name = "vreg_l5a"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6a: ldo6 { + regulator-name = "vreg_l6a"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7a: ldo7 { + regulator-name = "vreg_l7a"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l8a: ldo8 { + regulator-name = "vreg_l8a"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l9a: ldo9 { + regulator-name = "vreg_l9a"; + regulator-min-microvolt = <2970000>; + regulator-max-microvolt = <3072000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_HPM>; + }; + vreg_s4a: smps4 { + regulator-name = "vreg_s4a"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s9a: smps9 { + regulator-name = "vreg_s9a"; + regulator-min-microvolt = <1352000>; + regulator-max-microvolt = <1352000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-1 { + compatible = "qcom,pmm8654au-rpmh-regulators"; + qcom,pmic-id = "c"; + + vreg_s5c: smps5 { + regulator-name = "vreg_s5c"; + regulator-min-microvolt = <1104000>; + regulator-max-microvolt = <1104000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1c: ldo1 { + regulator-name = "vreg_l1c"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <512000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2c: ldo2 { + regulator-name = "vreg_l2c"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <904000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4c: ldo4 { + regulator-name = "vreg_l4c"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7c: ldo7 { + regulator-name = "vreg_l7c"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l8c: ldo8 { + regulator-name = "vreg_l8c"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l9c: ldo9 { + regulator-name = "vreg_l9c"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_HPM>; + }; + }; +}; + +ðernet0 { + phy-mode = "2500base-x"; + phy-handle = <&hsgmii_phy0>; + + pinctrl-0 = <ðernet0_default>; + pinctrl-names = "default"; + + snps,mtl-rx-config = <&mtl_rx_setup>; + snps,mtl-tx-config = <&mtl_tx_setup>; + nvmem-cells = <&mac_addr0>; + nvmem-cell-names = "mac-address"; + + status = "okay"; + + mdio { + compatible = "snps,dwmac-mdio"; + #address-cells = <1>; + #size-cells = <0>; + + hsgmii_phy0: ethernet-phy@1c { + compatible = "ethernet-phy-id004d.d101"; + reg = <0x1c>; + reset-gpios = <&tlmm 31 GPIO_ACTIVE_LOW>; + reset-assert-us = <11000>; + reset-deassert-us = <70000>; + }; + }; + + mtl_rx_setup: rx-queues-config { + snps,rx-queues-to-use = <4>; + snps,rx-sched-sp; + + queue0 { + snps,dcb-algorithm; + snps,map-to-dma-channel = <0x0>; + snps,route-up; + snps,priority = <0x1>; + }; + + queue1 { + snps,dcb-algorithm; + snps,map-to-dma-channel = <0x1>; + snps,route-ptp; + }; + + queue2 { + snps,avb-algorithm; + snps,map-to-dma-channel = <0x2>; + snps,route-avcp; + }; + + queue3 { + snps,avb-algorithm; + snps,map-to-dma-channel = <0x3>; + snps,priority = <0xc>; + }; + }; + + mtl_tx_setup: tx-queues-config { + snps,tx-queues-to-use = <4>; + + queue0 { + snps,dcb-algorithm; + }; + + queue1 { + snps,dcb-algorithm; + }; + + queue2 { + snps,avb-algorithm; + snps,send_slope = <0x1000>; + snps,idle_slope = <0x1000>; + snps,high_credit = <0x3e800>; + snps,low_credit = <0xffc18000>; + }; + + queue3 { + snps,avb-algorithm; + snps,send_slope = <0x1000>; + snps,idle_slope = <0x1000>; + snps,high_credit = <0x3e800>; + snps,low_credit = <0xffc18000>; + }; + }; +}; + +&gpi_dma0 { + status = "okay"; +}; + +&gpi_dma1 { + status = "okay"; +}; + +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/qcs8300/a623_zap.mbn"; +}; + +&i2c0 { + status = "okay"; + + bridge@4f { + compatible = "lontium,lt8713sx"; + reg = <0x4f>; + reset-gpios = <&expander5 6 GPIO_ACTIVE_LOW>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + lt8713sx_dp_in: endpoint { + remote-endpoint = <&mdss_dp0_out>; + }; + }; + + port@1 { + reg = <1>; + + lt8713sx_dp0_out: endpoint { + remote-endpoint = <&dp0_connector_in>; + }; + }; + + port@2 { + reg = <2>; + + lt8713sx_dp1_out: endpoint { + remote-endpoint = <&dp1_connector_in>; + }; + }; + }; + }; +}; + +&i2c1 { + pinctrl-0 = <&qup_i2c1_default>; + pinctrl-names = "default"; + + status = "okay"; + + fan_controller: fan@18 { + compatible = "ti,amc6821"; + reg = <0x18>; + #pwm-cells = <2>; + + fan { + pwms = <&fan_controller 40000 PWM_POLARITY_INVERTED>; + }; + }; + + eeprom0: eeprom@50 { + compatible = "atmel,24c256"; + reg = <0x50>; + pagesize = <64>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + mac_addr0: mac-addr@0 { + reg = <0x0 0x6>; + }; + }; + }; +}; + +&i2c15 { + pinctrl-0 = <&qup_i2c15_default>; + pinctrl-names = "default"; + + status = "okay"; + + expander0: gpio@38 { + compatible = "ti,tca9538"; + reg = <0x38>; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 56 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander0_int>; + pinctrl-names = "default"; + }; + + expander1: gpio@39 { + compatible = "ti,tca9538"; + reg = <0x39>; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 16 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander1_int>; + pinctrl-names = "default"; + }; + + expander2: gpio@3a { + compatible = "ti,tca9538"; + reg = <0x3a>; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 95 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander2_int>; + pinctrl-names = "default"; + }; + + expander3: gpio@3b { + compatible = "ti,tca9538"; + reg = <0x3b>; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 24 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander3_int>; + pinctrl-names = "default"; + }; + + expander4: gpio@3c { + compatible = "ti,tca9538"; + reg = <0x3c>; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 96 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander4_int>; + pinctrl-names = "default"; + }; + + expander5: gpio@3d { + compatible = "ti,tca9538"; + reg = <0x3d>; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 3 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander5_int>; + pinctrl-names = "default"; + }; + + expander6: gpio@3e { + compatible = "ti,tca9538"; + reg = <0x3e>; + #gpio-cells = <2>; + gpio-controller; + #interrupt-cells = <2>; + interrupt-controller; + interrupts-extended = <&tlmm 52 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&expander6_int>; + pinctrl-names = "default"; + }; +}; + +&iris { + status = "okay"; +}; + +&mdss { + status = "okay"; +}; + +&mdss_dp0 { + pinctrl-0 = <&dp_hot_plug_det>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&mdss_dp0_out { + data-lanes = <0 1 2 3>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; + remote-endpoint = <<8713sx_dp_in>; +}; + +&mdss_dp0_phy { + vdda-phy-supply = <&vreg_l5a>; + vdda-pll-supply = <&vreg_l4a>; + + status = "okay"; +}; + +&pcie0 { + pinctrl-0 = <&pcie0_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie0_phy { + vdda-phy-supply = <&vreg_l6a>; + vdda-pll-supply = <&vreg_l5a>; + + status = "okay"; +}; + +&pcie1 { + pinctrl-0 = <&pcie1_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie1_phy { + vdda-phy-supply = <&vreg_l6a>; + vdda-pll-supply = <&vreg_l5a>; + + status = "okay"; +}; + +&pcieport0 { + reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>; +}; + +&pcieport1 { + reset-gpios = <&tlmm 23 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; +}; + +&pmm8620au_0_gpios { + usb2_id: usb2-id-state { + pins = "gpio9"; + function = "normal"; + input-enable; + bias-pull-up; + power-source = <0>; + }; +}; + +&qup_i2c0_data_clk { + drive-strength = <2>; + bias-pull-up; +}; + +&qupv3_id_0 { + firmware-name = "qcom/qcs8300/qupv3fw.elf"; + status = "okay"; +}; + +&qupv3_id_1 { + firmware-name = "qcom/qcs8300/qupv3fw.elf"; + status = "okay"; +}; + +&remoteproc_adsp { + firmware-name = "qcom/qcs8300/adsp.mbn"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/qcs8300/cdsp0.mbn"; + + status = "okay"; +}; + +&remoteproc_gpdsp { + firmware-name = "qcom/qcs8300/gpdsp0.mbn"; + + status = "okay"; +}; + +&sdhc_1 { + vmmc-supply = <&vreg_l8a>; + vqmmc-supply = <&vreg_s2s>; + + no-sd; + no-sdio; + non-removable; + + status = "okay"; +}; + +&serdes0 { + phy-supply = <&vreg_l4a>; + + status = "okay"; +}; + +&spi10 { + status = "okay"; + + tpm@0 { + compatible = "st,st33htpm-spi", "tcg,tpm_tis-spi"; + reg = <0>; + spi-max-frequency = <20000000>; + }; +}; + +&tlmm { + pcie0_default_state: pcie0-default-state { + wake-pins { + pins = "gpio0"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + clkreq-pins { + pins = "gpio1"; + function = "pcie0_clkreq"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-pins { + pins = "gpio2"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + ethernet0_default: ethernet0-default-state { + ethernet0_mdc: ethernet0-mdc-pins { + pins = "gpio5"; + function = "emac0_mdc"; + drive-strength = <16>; + bias-pull-up; + }; + + ethernet0_mdio: ethernet0-mdio-pins { + pins = "gpio6"; + function = "emac0_mdio"; + drive-strength = <16>; + bias-pull-up; + }; + }; + + expander5_int: expander5-int-state { + pins = "gpio3"; + function = "gpio"; + bias-pull-up; + }; + + expander1_int: expander1-int-state { + pins = "gpio16"; + function = "gpio"; + bias-pull-up; + }; + + qup_i2c1_default: qup-i2c1-state { + pins = "gpio19", "gpio20"; + function = "qup0_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + pcie1_default_state: pcie1-default-state { + wake-pins { + pins = "gpio21"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + clkreq-pins { + pins = "gpio22"; + function = "pcie1_clkreq"; + drive-strength = <2>; + bias-pull-up; + }; + + perst-pins { + pins = "gpio23"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + expander3_int: expander3-int-state { + pins = "gpio24"; + function = "gpio"; + bias-pull-up; + }; + + expander6_int: expander6-int-state { + pins = "gpio52"; + function = "gpio"; + bias-pull-up; + }; + + expander0_int: expander0-int-state { + pins = "gpio56"; + function = "gpio"; + bias-pull-up; + }; + + cam0_avdd_2v8_en_default: cam0-avdd-2v8-en-state { + pins = "gpio73"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + cam1_avdd_2v8_en_default: cam1-avdd-2v8-en-state { + pins = "gpio74"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + cam2_avdd_2v8_en_default: cam2-avdd-2v8-en-state { + pins = "gpio75"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + qup_i2c15_default: qup-i2c15-state { + pins = "gpio91", "gpio92"; + function = "qup1_se7"; + drive-strength = <2>; + bias-pull-up; + }; + + expander2_int: expander2-int-state { + pins = "gpio95"; + function = "gpio"; + bias-pull-up; + }; + + expander4_int: expander4-int-state { + pins = "gpio96"; + function = "gpio"; + bias-pull-up; + }; +}; + +&uart6 { + status = "okay"; +}; + +&uart7 { + status = "okay"; +}; + +&ufs_mem_hc { + reset-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>; + vcc-supply = <&vreg_l8a>; + vcc-max-microamp = <1100000>; + vccq-supply = <&vreg_l4c>; + vccq-max-microamp = <1200000>; + + status = "okay"; +}; + +&ufs_mem_phy { + vdda-phy-supply = <&vreg_l4a>; + vdda-pll-supply = <&vreg_l5a>; + + status = "okay"; +}; + +&usb_1 { + dr_mode = "peripheral"; + + status = "okay"; +}; + +&usb_1_hsphy { + vdda-pll-supply = <&vreg_l7a>; + vdda18-supply = <&vreg_l7c>; + vdda33-supply = <&vreg_l9a>; + + status = "okay"; +}; + +&usb_qmpphy { + vdda-phy-supply = <&vreg_l7a>; + vdda-pll-supply = <&vreg_l5a>; + + status = "okay"; +}; + +&usb_2 { + status = "okay"; +}; + +&usb_2_dwc3_hs { + remote-endpoint = <&usb2_con_hs_ep>; +}; + +&usb_2_hsphy { + vdda-pll-supply = <&vreg_l7a>; + vdda18-supply = <&vreg_l7c>; + vdda33-supply = <&vreg_l9a>; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts b/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts index 299d0da..940a037 100644 --- a/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts +++ b/arch/arm64/boot/dts/qcom/monaco-arduino-monza.dts
@@ -7,6 +7,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> #include <dt-bindings/pwm/pwm.h> #include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h> @@ -32,6 +33,14 @@ gpio-keys { pinctrl-0 = <&gpio_keys_default>; pinctrl-names = "default"; + button-sleep { + label = "Sleep Key"; + linux,code = <KEY_SLEEP>; + gpios = <&tlmm 69 GPIO_ACTIVE_HIGH>; + debounce-interval = <60>; + wakeup-source; + }; + button-home { label = "Home Key"; linux,code = <KEY_HOMEPAGE>; @@ -176,6 +185,109 @@ &cci1 { }; &cci1_i2c1 { + led-controller@22 { + compatible = "nxp,pca9635"; + reg = <0x22>; + #address-cells = <1>; + #size-cells = <0>; + + multi-led@0 { + reg = <0>; + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_INDICATOR; + function-enumerator = <1>; + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = <LED_COLOR_ID_RED>; + }; + + led@1 { + reg = <1>; + color = <LED_COLOR_ID_GREEN>; + }; + + led@2 { + reg = <2>; + color = <LED_COLOR_ID_BLUE>; + }; + }; + + multi-led@1 { + reg = <1>; + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_INDICATOR; + function-enumerator = <2>; + #address-cells = <1>; + #size-cells = <0>; + + led@3 { + reg = <3>; + color = <LED_COLOR_ID_RED>; + }; + + led@4 { + reg = <4>; + color = <LED_COLOR_ID_GREEN>; + }; + + led@5 { + reg = <5>; + color = <LED_COLOR_ID_BLUE>; + }; + }; + + multi-led@2 { + reg = <2>; + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_INDICATOR; + function-enumerator = <3>; + #address-cells = <1>; + #size-cells = <0>; + + led@6 { + reg = <6>; + color = <LED_COLOR_ID_RED>; + }; + + led@7 { + reg = <7>; + color = <LED_COLOR_ID_GREEN>; + }; + + led@8 { + reg = <8>; + color = <LED_COLOR_ID_BLUE>; + }; + }; + + multi-led@3 { + reg = <3>; + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_INDICATOR; + function-enumerator = <4>; + #address-cells = <1>; + #size-cells = <0>; + + led@9 { + reg = <9>; + color = <LED_COLOR_ID_RED>; + }; + + led@a { + reg = <10>; + color = <LED_COLOR_ID_GREEN>; + }; + + led@b { + reg = <11>; + color = <LED_COLOR_ID_BLUE>; + }; + }; + }; + fan_controller: fan-controller@2f { compatible = "microchip,emc2305"; reg = <0x2f>; @@ -452,26 +564,85 @@ &pcieport1 { &thermal_zones { cpuss-0-0-thermal { - polling-delay = <2000>; - trips { - cpuss0_active: cpuss-active { - temperature = <32000>; - hysteresis = <2000>; + cpuss0_active0: cpuss-active0 { + temperature = <50000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss0_active1: cpuss-active1 { + temperature = <60000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss0_active2: cpuss-active2 { + temperature = <70000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss0_active3: cpuss-active3 { + temperature = <80000>; + hysteresis = <4000>; type = "active"; }; }; cooling-maps { - map-active { - trip = <&cpuss0_active>; - cooling-device = <&fan 0 THERMAL_NO_LIMIT>; + map-active0 { + trip = <&cpuss0_active0>; + cooling-device = <&fan 4 4>; + }; + + map-active1 { + trip = <&cpuss0_active1>; + cooling-device = <&fan 6 6>; + }; + + map-active2 { + trip = <&cpuss0_active2>; + cooling-device = <&fan 8 8>; + }; + + map-active3 { + trip = <&cpuss0_active3>; + cooling-device = <&fan 10 THERMAL_NO_LIMIT>; }; }; }; }; &tlmm { + gpio-line-names = "", "", "", "", "", + "", "", "", "", "", + "JMISC_SPI_MISO", "JMISC_SPI_MOSI", "JMISC_SPI_SCK", "JMISC_SPI_CS0", "JMISC_SPI_CS1", + "JMISC_CS2", "", "JHAT_P03_I2C_SDA", "JHAT_P05_I2C_SCL", "JHAT_P27_EEPROM_SDA", + "JHAT_P28_EEPROM_SDL", "", "", "", "", + "JHAT_P21_SPI_MISO", "JHAT_P19_SPI_MOSI", "JHAT_P23_SPI_SCLK", "JHAT_P24_SPI_CE0", "", + "", "MCU_I2C1_SDA", "MCU_I2C1_SDL", "", "", + "", "", "JOMEGA_SPI_SCK", "JOMEGA_SPI_CS", "JOMEGA_SPI_MISO", + "JOMEGA_SPI_MOSI", "", "MCU_PG11", "JCTL_UART_DBG_TX", "JCTL_UART_DBG_RX", + "", "", "MCU_BOOT0", "CYPD_SWCLK", "", + "", "", "FORCE_USB_BOOT", "", "", + "", "", "JMEDIA_SOC_CC0_SDA", "JMEDIA_SOC_CC0_SCL", "JMEDIA_SOC_CC1_SDA", + "JMEDIA_SOC_CC1_SCL", "", "", "MCU_PG12", "", + "FLAT0_P17_GPIO", "", "JMEDIA_SOC_CAM_MCLK0", "JMEDIA_SOC_CAM_MCLK1", "MCU_PG9", + "MCU_PA13_SWDIO", "MCU_PA14_SWCLK", "", "JMISC_SOC_GPIO_0", "JMISC_SOC_GPIO_1", + "FLAT1_P17_GPIO", "", "JHAT_P32_PWM0", "MCU_NRST", "USER_BUTTON", + "JHAT_P31_GPIO", "JHAT_P33_GPIO", "FLAT2_P17_GPIO", "JHAT_P07_GPCLK0", "JHAT_P36_UART_CTS", + "JHAT_P11_UART_RFR", "JHAT_P08_UART_TX", "JHAT_P10_UART_RX", "JHAT_P26_SPI_CE1", "JHAT_P29_GPIO", + "JHAT_P15_GPIO", "", "MCU_PG10", "", "CYPD_SWDIO", + "MCU_PG13", "MCU_PG14", "", "", "", + "", "", "", "", "CYPD_NRES", + "JHAT_P16_GPIO", "JHAT_P18_GPIO", "JHAT_P22_GPIO", "JHAT_P37_GPIO", "JHAT_P13_GPIO", + "", "", "", "", "", + "", "JHAT_P12_PCM_CLK", "JHAT_P35_PCM_FS", "JHAT_P38_PCM_DIN", "JHAT_P40_PCM_DOUT", + "", "", "", "", "", + "", "", "", "", "", + "", "", ""; + pcie0_default_state: pcie0-default-state { wake-pins { pins = "gpio0"; @@ -547,9 +718,17 @@ perst-pins { }; gpio_keys_default: gpio-keys-default-state { - pins = "gpio79"; - function = "gpio"; - bias-disable; + horizontal-button-pins { + pins = "gpio69"; + function = "gpio"; + bias-pull-down; + }; + + vertical-button-pins { + pins = "gpio79"; + function = "gpio"; + bias-disable; + }; }; adv7535_default: adv7535-default-state {
diff --git a/arch/arm64/boot/dts/qcom/monaco-evk-ifp-mezzanine.dtso b/arch/arm64/boot/dts/qcom/monaco-evk-ifp-mezzanine.dtso index ca5bf0f..4f727ff6e 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk-ifp-mezzanine.dtso +++ b/arch/arm64/boot/dts/qcom/monaco-evk-ifp-mezzanine.dtso
@@ -117,20 +117,12 @@ pcie@3,0 { ranges; bus-range = <0x5 0xff>; - pcie@0,0 { + dev@0,0 { reg = <0x50000 0x0 0x0 0x0 0x0>; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - ranges; }; - pcie@0,1 { + dev@0,1 { reg = <0x50100 0x0 0x0 0x0 0x0>; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - ranges; }; }; };
diff --git a/arch/arm64/boot/dts/qcom/monaco-evk.dts b/arch/arm64/boot/dts/qcom/monaco-evk.dts index 9d17ef7..539c9c8 100644 --- a/arch/arm64/boot/dts/qcom/monaco-evk.dts +++ b/arch/arm64/boot/dts/qcom/monaco-evk.dts
@@ -21,6 +21,7 @@ aliases { ethernet0 = ðernet0; i2c1 = &i2c1; serial0 = &uart7; + serial1 = &uart2; serial2 = &uart6; }; @@ -47,6 +48,38 @@ usb2_con_hs_ep: endpoint { }; }; + connector-3 { + compatible = "pcie-m2-e-connector"; + vpcie3v3-supply = <&vreg_wcn_3p3>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + m2_e_pcie_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&pcieport0_ep>; + }; + }; + + port@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + + m2_e_uart_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&uart2_ep>; + }; + }; + }; + }; + dmic: audio-codec-0 { compatible = "dmic-codec"; #sound-dai-cells = <0>; @@ -91,6 +124,17 @@ usb2_vbus: regulator-usb2-vbus { enable-active-high; }; + vreg_wcn_3p3: regulator-wcn-3p3 { + compatible = "regulator-fixed"; + + regulator-name = "VREG_WCN_3P3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-always-on; + regulator-boot-on; + }; + sound { compatible = "qcom,qcs8275-sndcard"; model = "MONACO-EVK"; @@ -643,12 +687,18 @@ &pcie1_phy { &pcieport0 { reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 0 GPIO_ACTIVE_LOW>; + + port { + pcieport0_ep: endpoint { + remote-endpoint = <&m2_e_pcie_ep>; + }; + }; }; &pcieport1 { reset-gpios = <&tlmm 23 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 21 GPIO_ACTIVE_LOW>; }; &pmm8620au_0_gpios { @@ -706,7 +756,8 @@ &sdhc_1 { }; &serdes0 { - phy-supply = <&vreg_l4a>; + vdda-0p9-supply = <&vreg_l4a>; + vdda-1p2-supply = <&vreg_l5a>; status = "okay"; }; @@ -809,7 +860,7 @@ expander3_int: expander3-int-state { bias-pull-up; }; - expander6_int: expander6-int-state { + expander6_int: expander6-int-state { pins = "gpio52"; function = "gpio"; bias-pull-up; @@ -862,6 +913,16 @@ expander4_int: expander4-int-state { }; }; +&uart2 { + status = "okay"; + + port { + uart2_ep: endpoint { + remote-endpoint = <&m2_e_uart_ep>; + }; + }; +}; + &uart6 { status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/monaco-pmics.dtsi b/arch/arm64/boot/dts/qcom/monaco-pmics.dtsi index 6e096b9..361f516 100644 --- a/arch/arm64/boot/dts/qcom/monaco-pmics.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco-pmics.dtsi
@@ -7,6 +7,36 @@ #include <dt-bindings/spmi/spmi.h> #include "qcom-adc5-gen3.h" +/ { + thermal-zones { + pm8775-mbg0-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmm8620au_0_mbg_temp>; + + trips { + trip0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + pm8775-mbg1-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pmm8620au_1_mbg_temp>; + + trips { + trip0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + }; +}; + &spmi_bus { pmm8620au_0: pmic@0 { compatible = "qcom,pmm8654au", "qcom,spmi-pmic"; @@ -53,6 +83,22 @@ pmm8620au_0_gpios: gpio@8800 { }; }; + pmm8620au_sail_0: pmic@1 { + compatible = "qcom,pmm8654au", "qcom,spmi-pmic"; + reg = <0x1 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmm8620au_0_mbg_temp: temperature-sensor@d700 { + compatible = "qcom,pm8775-mbg-tm"; + reg = <0xd700>; + io-channels = <&pmm8620au_0_adc ADC5_GEN3_DIE_TEMP(0)>; + io-channel-names = "thermal"; + interrupts-extended = <&spmi_bus 0x1 0xd7 0x0 IRQ_TYPE_EDGE_RISING>; + #thermal-sensor-cells = <0>; + }; + }; + pmm8650au_1: pmic@2 { compatible = "qcom,pmm8654au", "qcom,spmi-pmic"; reg = <0x2 SPMI_USID>; @@ -90,4 +136,20 @@ pmm8650au_1_gpios: gpio@8800 { #interrupt-cells = <2>; }; }; + + pmm8620au_sail_1: pmic@3 { + compatible = "qcom,pmm8654au", "qcom,spmi-pmic"; + reg = <0x3 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmm8620au_1_mbg_temp: temperature-sensor@d700 { + compatible = "qcom,pm8775-mbg-tm"; + reg = <0xd700>; + io-channels = <&pmm8650au_1_adc ADC5_GEN3_DIE_TEMP(2)>; + io-channel-names = "thermal"; + interrupts-extended = <&spmi_bus 0x3 0xd7 0x0 IRQ_TYPE_EDGE_RISING>; + #thermal-sensor-cells = <0>; + }; + }; };
diff --git a/arch/arm64/boot/dts/qcom/monaco.dtsi b/arch/arm64/boot/dts/qcom/monaco.dtsi index cfe39f9..35fbee6 100644 --- a/arch/arm64/boot/dts/qcom/monaco.dtsi +++ b/arch/arm64/boot/dts/qcom/monaco.dtsi
@@ -18,7 +18,6 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/mailbox/qcom-ipcc.h> #include <dt-bindings/power/qcom,rpmhpd.h> -#include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/soc/qcom,gpr.h> #include <dt-bindings/soc/qcom,rpmh-rsc.h> #include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h> @@ -898,6 +897,7 @@ gcc: clock-controller@100000 { #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; + power-domains = <&rpmhpd RPMHPD_CX>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&sleep_clk>, <&pcie0_phy>, @@ -2394,6 +2394,7 @@ opp-32000000 { }; pcieport0: pcie@0 { + compatible = "pciclass,0604"; device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; @@ -4845,6 +4846,8 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, supports-cqe; dma-coherent; + qcom,ice = <&sdhc_ice>; + mmc-ddr-1_8v; mmc-hs200-1_8v; mmc-hs400-1_8v; @@ -4877,6 +4880,17 @@ opp-384000000 { }; }; + sdhc_ice: crypto@87c8000 { + compatible = "qcom,qcs8300-inline-crypto-engine", + "qcom,inline-crypto-engine"; + reg = <0x0 0x087c8000 0x0 0x18000>; + clocks = <&gcc GCC_SDCC1_ICE_CORE_CLK>, + <&gcc GCC_SDCC1_AHB_CLK>; + clock-names = "core", + "iface"; + power-domains = <&rpmhpd RPMHPD_CX>; + }; + usb_1_hsphy: phy@8904000 { compatible = "qcom,qcs8300-usb-hs-phy", "qcom,usb-snps-hs-7nm-phy";
diff --git a/arch/arm64/boot/dts/qcom/msm8917-xiaomi-riva.dts b/arch/arm64/boot/dts/qcom/msm8917-xiaomi-riva.dts index 4ea4fbd..7c32321 100644 --- a/arch/arm64/boot/dts/qcom/msm8917-xiaomi-riva.dts +++ b/arch/arm64/boot/dts/qcom/msm8917-xiaomi-riva.dts
@@ -5,6 +5,7 @@ /dts-v1/; +#include <dt-bindings/leds/common.h> #include "msm8917-xiaomi-wingtech.dtsi" / { @@ -13,6 +14,10 @@ / { qcom,board-id = <0x1000b 1>, <0x1000b 2>; + chosen { + stdout-path = &blsp1_uart2; + }; + battery: battery { compatible = "simple-battery"; charge-full-design-microamp-hours = <3000000>; @@ -23,6 +28,36 @@ battery: battery { charge-term-current-microamp = <60000>; voltage-min-design-microvolt = <3400000>; }; + + vibrator { + compatible = "gpio-vibrator"; + enable-gpios = <&tlmm 97 GPIO_ACTIVE_HIGH>; + vcc-supply = <&vph_pwr>; + }; +}; + +&blsp1_i2c2 { + status = "okay"; + + led-controller@45 { + compatible = "awinic,aw2013"; + reg = <0x45>; + vcc-supply = <&pm8937_l10>; + vio-supply = <&pm8937_l5>; + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + led-max-microamp = <5000>; + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_WHITE>; + }; + }; +}; + +&blsp1_uart2 { + status = "okay"; }; &blsp2_i2c1 {
diff --git a/arch/arm64/boot/dts/qcom/msm8939-asus-z00t.dts b/arch/arm64/boot/dts/qcom/msm8939-asus-z00t.dts index 90e9662..231a3e9c 100644 --- a/arch/arm64/boot/dts/qcom/msm8939-asus-z00t.dts +++ b/arch/arm64/boot/dts/qcom/msm8939-asus-z00t.dts
@@ -267,6 +267,14 @@ &usb_hs_phy { extcon = <&usb_id>; }; +&venus { + status = "okay"; +}; + +&venus_mem { + status = "okay"; +}; + &wcnss { status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/msm8939-longcheer-l9100.dts b/arch/arm64/boot/dts/qcom/msm8939-longcheer-l9100.dts index 13422a1..48514c3 100644 --- a/arch/arm64/boot/dts/qcom/msm8939-longcheer-l9100.dts +++ b/arch/arm64/boot/dts/qcom/msm8939-longcheer-l9100.dts
@@ -314,6 +314,14 @@ &usb_hs_phy { extcon = <&usb_id>; }; +&venus { + status = "okay"; +}; + +&venus_mem { + status = "okay"; +}; + &wcnss { status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/msm8939.dtsi b/arch/arm64/boot/dts/qcom/msm8939.dtsi index d4d7b0c..013e6a8 100644 --- a/arch/arm64/boot/dts/qcom/msm8939.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8939.dtsi
@@ -1627,6 +1627,32 @@ opp-19200000 { }; }; + venus: video-codec@1d00000 { + compatible = "qcom,msm8939-venus"; + reg = <0x01d00000 0xff000>; + interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gcc GCC_VENUS0_VCODEC0_CLK>, + <&gcc GCC_VENUS0_AHB_CLK>, + <&gcc GCC_VENUS0_AXI_CLK>, + <&gcc GCC_VENUS0_CORE0_VCODEC0_CLK>, + <&gcc GCC_VENUS0_CORE1_VCODEC0_CLK>; + clock-names = "core", + "iface", + "bus", + "vcodec0_core", + "vcodec1_core"; + power-domains = <&gcc VENUS_GDSC>, + <&gcc VENUS_CORE0_GDSC>, + <&gcc VENUS_CORE1_GDSC>; + power-domain-names = "venus", + "vcodec0", + "vcodec1"; + iommus = <&apps_iommu 5>; + memory-region = <&venus_mem>; + + status = "disabled"; + }; + apps_iommu: iommu@1ef0000 { compatible = "qcom,msm8916-iommu", "qcom,msm-iommu-v1"; reg = <0x01ef0000 0x3000>;
diff --git a/arch/arm64/boot/dts/qcom/msm8953-motorola-deen.dts b/arch/arm64/boot/dts/qcom/msm8953-motorola-deen.dts new file mode 100644 index 0000000..4bc407e --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8953-motorola-deen.dts
@@ -0,0 +1,440 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2026 Adam Skladowski <a39skl@gmail.com> + */ + +/dts-v1/; +#include <dt-bindings/usb/pd.h> +#include "msm8953.dtsi" +#include "pm8953.dtsi" +#include "pmi8950.dtsi" + +/delete-node/ &cont_splash_mem; +/delete-node/ &qseecom_mem; + +/ { + model = "Motorola One"; + compatible = "motorola,deen", "qcom,msm8953"; + chassis-type = "handset"; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&gpio_key_default>; + pinctrl-names = "default"; + + key-volume-up { + label = "Volume Up"; + gpios = <&tlmm 85 GPIO_ACTIVE_LOW>; + linux,code = <KEY_VOLUMEUP>; + }; + }; + + reserved-memory { + qseecom_mem: qseecom@84300000 { + reg = <0x0 0x84300000 0x0 0x2000000>; + no-map; + }; + }; + + vph_pwr: regulator-vph-pwr { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-always-on; + regulator-boot-on; + }; + + /* Fake VBUS 5V supply till we wire pmi8950 one */ + fusb302_vbus: regulator-otg-vbus { + compatible = "regulator-fixed"; + regulator-name = "otg-vbus"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + regulator-boot-on; + }; +}; + +&hsusb_phy { + vdd-supply = <&pm8953_l3>; + vdda-phy-dpdm-supply = <&pm8953_l13>; + vdda-pll-supply = <&pm8953_l7>; + + status = "okay"; +}; + +&i2c_1 { + status = "okay"; + + typec-portc@22 { + compatible = "fcs,fusb302"; + reg = <0x22>; + interrupts-extended = <&tlmm 9 IRQ_TYPE_LEVEL_LOW>; + + pinctrl-0 = <&fusb302_int_default>; + pinctrl-names = "default"; + + vbus-supply = <&fusb302_vbus>; + + connector { + compatible = "usb-c-connector"; + label = "USB-C"; + power-role = "dual"; + data-role = "dual"; + op-sink-microwatt = <2000000>; + try-power-role = "sink"; + typec-power-opmode = "default"; + source-pdos = <PDO_FIXED(5000, 500, + PDO_FIXED_DUAL_ROLE | + PDO_FIXED_DATA_SWAP | + PDO_FIXED_USB_COMM)>; + sink-pdos = <PDO_FIXED(5000, 3000, + PDO_FIXED_DUAL_ROLE | + PDO_FIXED_DATA_SWAP | + PDO_FIXED_USB_COMM)>; + + port { + fusb302: endpoint { + remote-endpoint = <&usb_dwc3_hs>; + }; + }; + }; + }; +}; + +&i2c_2 { + status = "okay"; +}; + +&i2c_3 { + status = "okay"; +}; + +&i2c_5 { + status = "okay"; + + pn553: nfc@28 { + compatible = "nxp,pn553", "nxp,nxp-nci-i2c"; + reg = <0x28>; + interrupts-extended = <&tlmm 17 IRQ_TYPE_LEVEL_HIGH>; + + enable-gpios = <&tlmm 16 GPIO_ACTIVE_HIGH>; + firmware-gpios = <&tlmm 62 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&nfc_firm_default &nfc_irq_default &nfc_pwr_default>; + pinctrl-names = "default"; + }; +}; + +&ibb { + qcom,discharge-resistor-kohms = <32>; +}; + +&lpass { + status = "okay"; +}; + +&mdss_dsi0 { + vdda-supply = <&pm8953_s3>; + vddio-supply = <&pm8953_l6>; +}; + +&mdss_dsi0_out { + data-lanes = <0 1 2 3>; +}; + +&mdss_dsi0_phy { + vcca-supply = <&pm8953_l3>; +}; + +&mpss { + pll-supply = <&pm8953_l7>; + + status = "okay"; +}; + +&pm8953_resin { + linux,code = <KEY_VOLUMEDOWN>; + + status = "okay"; +}; + +&pmi8950_wled { + qcom,current-limit-microamp = <25000>; + qcom,num-strings = <2>; + + qcom,cabc; + qcom,external-pfet; +}; + +&q6afedai { + dai@22 { + reg = <QUATERNARY_MI2S_RX>; + qcom,sd-lines = <0>; + }; + + dai@127 { + reg = <QUINARY_MI2S_RX>; + qcom,sd-lines = <1>; + }; +}; + +&rpm_requests { + regulators { + compatible = "qcom,rpm-pm8953-regulators"; + vdd_s1-supply = <&vph_pwr>; + vdd_s2-supply = <&vph_pwr>; + vdd_s3-supply = <&vph_pwr>; + vdd_s4-supply = <&vph_pwr>; + vdd_s5-supply = <&vph_pwr>; + vdd_s6-supply = <&vph_pwr>; + vdd_s7-supply = <&vph_pwr>; + vdd_l1-supply = <&pm8953_s3>; + vdd_l2_l3-supply = <&pm8953_s3>; + vdd_l4_l5_l6_l7_l16_l19-supply = <&pm8953_s4>; + vdd_l8_l11_l12_l13_l14_l15-supply = <&vph_pwr>; + vdd_l9_l10_l17_l18_l22-supply = <&vph_pwr>; + vdd_l23-supply = <&pm8953_s3>; + + pm8953_s1: s1 { + regulator-min-microvolt = <863000>; + regulator-max-microvolt = <1152000>; + }; + + pm8953_s3: s3 { + regulator-min-microvolt = <1224000>; + regulator-max-microvolt = <1224000>; + }; + + pm8953_s4: s4 { + regulator-min-microvolt = <1896000>; + regulator-max-microvolt = <2048000>; + }; + + pm8953_l1: l1 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1100000>; + }; + + pm8953_l2: l2 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + pm8953_l3: l3 { + regulator-min-microvolt = <925000>; + regulator-max-microvolt = <925000>; + regulator-allow-set-load; + }; + + pm8953_l5: l5 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + pm8953_l6: l6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + pm8953_l7: l7 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1900000>; + }; + + pm8953_l8: l8 { + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + }; + + pm8953_l9: l9 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + }; + + pm8953_l10: l10 { + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <2850000>; + }; + + pm8953_l11: l11 { + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + regulator-allow-set-load; + regulator-system-load = <200000>; + }; + + pm8953_l12: l12 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3000000>; + }; + + pm8953_l13: l13 { + regulator-min-microvolt = <3075000>; + regulator-max-microvolt = <3125000>; + }; + + pm8953_l15: l15 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + pm8953_l16: l16 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + pm8953_l17: l17 { + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <2850000>; + }; + + pm8953_l19: l19 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1350000>; + }; + + pm8953_l22: l22 { + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + }; + + pm8953_l23: l23 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + }; +}; + +&sdhc_1 { + vmmc-supply = <&pm8953_l8>; + vqmmc-supply = <&pm8953_l5>; + + status = "okay"; +}; + +&sdhc_2 { + cd-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&sdc2_clk_on &sdc2_cmd_on &sdc2_data_on &sdc2_cd_off>; + pinctrl-1 = <&sdc2_clk_off &sdc2_cmd_off &sdc2_data_off &sdc2_cd_off>; + pinctrl-names = "default", "sleep"; + + vmmc-supply = <&pm8953_l11>; + vqmmc-supply = <&pm8953_l12>; + + status = "okay"; +}; + +&tlmm { + gpio-reserved-ranges = <96 4>; /* Fingerprint SPI */ + + disp_reset_n_active: disp-reset-n-active-state { + pins = "gpio61"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + + disp_reset_n_sleep: disp-reset-n-sleep-state { + pins = "gpio61"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + fusb302_int_default: fusb302-int-default-state { + pins = "gpio9"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + mi2s_sec_act: mi2s-quat-active-state { + pins = "gpio135", "gpio136", "gpio137", "gpio138"; + function = "sec_mi2s"; + drive-strength = <8>; + }; + + mi2s_sec_sus: mi2s-quat-sleep-state { + pins = "gpio135", "gpio136", "gpio137", "gpio138"; + function = "sec_mi2s"; + drive-strength = <2>; + bias-pull-down; + }; + + nfc_firm_default: nfc-firm-state { + pins = "gpio62"; + function = "gpio"; + bias-pull-down; + output-low; + drive-strength = <2>; + }; + + nfc_irq_default: nfc-irq-state { + pins = "gpio17"; + function = "gpio"; + bias-pull-down; + drive-strength = <2>; + }; + + nfc_pwr_default: nfc-pwr-state { + pins = "gpio16"; + function = "gpio"; + bias-pull-down; + output-low; + drive-strength = <2>; + }; + + ts_int_default: ts-int-default-state { + pins = "gpio65"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; + + ts_int_sleep: ts-int-sleep-state { + pins = "gpio65"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + ts_reset_default: ts-reset-default-state { + pins = "gpio64"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; + + ts_reset_sleep: ts-reset-sleep-state { + pins = "gpio64"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; +}; + +&usb3 { + status = "okay"; +}; + +&usb_dwc3_hs { + remote-endpoint = <&fusb302>; +}; + +&wcnss { + vddpx-supply = <&pm8953_l5>; + + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3660b"; + + vdddig-supply = <&pm8953_l5>; + vddpa-supply = <&pm8953_l9>; + vddrfa-supply = <&pm8953_l19>; + vddxo-supply = <&pm8953_l7>; +};
diff --git a/arch/arm64/boot/dts/qcom/msm8976-leeco-s2.dts b/arch/arm64/boot/dts/qcom/msm8976-leeco-s2.dts new file mode 100644 index 0000000..b6c6521 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/msm8976-leeco-s2.dts
@@ -0,0 +1,442 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2026 Adam Skladowski <a39skl@gmail.com> + */ + +/dts-v1/; + +#include "msm8976.dtsi" +#include "pm8950.dtsi" +#include "pm8004.dtsi" +#include "pmi8950.dtsi" +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/gpio-keys.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/input/linux-event-codes.h> +#include <dt-bindings/pinctrl/qcom,pmic-gpio.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/input/ti-drv260x.h> + +/ { + model = "Leeco Le S2"; + compatible = "leeco,s2", "qcom,msm8976"; + chassis-type = "handset"; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&gpio_key_default>; + pinctrl-names = "default"; + + key-volume-up { + label = "Volume Up"; + gpios = <&tlmm 113 GPIO_ACTIVE_LOW>; + linux,code = <KEY_VOLUMEUP>; + }; + }; + + reserved-memory { + /delete-node/ ext-region@85b00000; + + ext_region: memory@84a00000 { + reg = <0x0 0x84a00000 0x0 0x1900000>; + no-map; + }; + }; + + vph_pwr: regulator-vph-pwr { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-always-on; + regulator-boot-on; + }; +}; + +&adreno_gpu { + status = "okay"; +}; + +&blsp1_i2c4 { + status = "okay"; + + touchscreen@4b { + compatible = "syna,rmi4-i2c"; + reg = <0x4b>; + interrupts-extended = <&tlmm 65 IRQ_TYPE_EDGE_FALLING>; + + pinctrl-0 = <&touch_default_state>; + pinctrl-names = "default"; + + reset-gpios = <&tlmm 64 GPIO_ACTIVE_HIGH>; + + vdd-supply = <&pm8950_l17>; + vio-supply = <&pm8950_l6>; + + syna,reset-delay-ms = <100>; + syna,startup-delay-ms = <500>; + + #address-cells = <1>; + #size-cells = <0>; + + rmi4-f01@1 { + reg = <0x01>; + syna,nosleep-mode = <1>; + }; + + rmi4-f12@12 { + reg = <0x12>; + syna,sensor-type = <1>; + syna,clip-x-low = <0>; + syna,clip-x-high = <1080>; + syna,clip-y-low = <0>; + syna,clip-y-high = <1920>; + }; + }; +}; + +&blsp2_i2c2 { + status = "okay"; + + haptics: haptics@5a { + compatible = "ti,drv2604"; + reg = <0x5a>; + enable-gpios = <&tlmm 109 GPIO_ACTIVE_HIGH>; + mode = <DRV260X_LRA_MODE>; + library-sel = <DRV260X_LIB_LRA>; + }; + + tiusb320: typec@47 { + compatible = "ti,tusb320"; + reg = <0x47>; + interrupts-extended = <&tlmm 21 IRQ_TYPE_EDGE_RISING>; + + pinctrl-0 = <&tusb320_int_active>; + pinctrl-names = "default"; + }; +}; + +&blsp2_i2c4 { + status = "okay"; + + led-controller@45 { + compatible = "awinic,aw2013"; + reg = <0x45>; + vcc-supply = <&pm8950_l10>; + + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + led-max-microamp = <5000>; + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_RED>; + }; + + led@1 { + reg = <1>; + led-max-microamp = <5000>; + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_GREEN>; + }; + + led@2 { + reg = <2>; + led-max-microamp = <5000>; + function = LED_FUNCTION_INDICATOR; + color = <LED_COLOR_ID_BLUE>; + }; + }; + + speaker_codec: audio-codec@34 { + compatible = "nxp,tfa9890"; + reg = <0x34>; + vddd-supply = <&pm8950_l5>; + sound-name-prefix = "Speaker"; + #sound-dai-cells = <0>; + }; +}; + +&gcc { + vdd_gfx-supply = <&pm8004_s5>; +}; + +&mdss_dsi0 { + vdd-supply = <&pm8950_l17>; + vdda-supply = <&pm8950_l1>; + vddio-supply = <&pm8950_l6>; +}; + +&mdss_dsi0_out { + data-lanes = <0 1 2 3>; +}; + +&mdss_dsi0_phy { + vddio-supply = <&pm8950_l6>; +}; + +&otg { + extcon = <&tiusb320>; +}; + +&pm8004_lsid5 { + status = "okay"; +}; + +&pm8004_spmi_regulators { + vdd_s2-supply = <&vph_pwr>; + vdd_s5-supply = <&vph_pwr>; + + status = "okay"; + + /* Cluster 1 supply */ + pm8004_s2: s2 { + regulator-name = "VDD_APC1"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1165000>; + regulator-always-on; + regulator-boot-on; + }; + + pm8004_s5: s5 { + regulator-name = "VDD_GFX"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1165000>; + regulator-enable-ramp-delay = <500>; + regulator-always-on; + }; +}; + +&pm8950_spmi_regulators { + vdd_s5-supply = <&vph_pwr>; + + /* Cluster 0 supply */ + pm8950_spmi_s5: s5 { + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1165000>; + regulator-name = "VDD_APC0"; + regulator-always-on; + regulator-boot-on; + }; +}; + +&pm8950_resin { + linux,code = <KEY_VOLUMEDOWN>; + + status = "okay"; +}; + +&pmi8950_wled { + qcom,current-limit-microamp = <20000>; + qcom,enabled-strings = <0 1>; + qcom,ovp-millivolt = <29500>; +}; + +&rpm_requests { + regulators { + compatible = "qcom,rpm-pm8950-regulators"; + + vdd_s1-supply = <&vph_pwr>; + vdd_s2-supply = <&vph_pwr>; + vdd_s3-supply = <&vph_pwr>; + vdd_s4-supply = <&vph_pwr>; + vdd_s6-supply = <&vph_pwr>; + vdd_l1_l19-supply = <&pm8950_s3>; + vdd_l2_l23-supply = <&pm8950_s3>; + vdd_l3-supply = <&pm8950_s3>; + vdd_l5_l6_l7_l16-supply = <&pm8950_s4>; + vdd_l8_l11_l12_l17_l22-supply = <&vph_pwr>; + vdd_l9_l10_l13_l14_l15_l18-supply = <&vph_pwr>; + + pm8950_s3: s3 { + regulator-min-microvolt = <1325000>; + regulator-max-microvolt = <1325000>; + }; + + pm8950_s4: s4 { + regulator-min-microvolt = <2050000>; + regulator-max-microvolt = <2050000>; + }; + + pm8950_l1: l1 { + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1300000>; + }; + + pm8950_l2: l2 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + + pm8950_l3: l3 { + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1100000>; + }; + + pm8950_l5: l5 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + pm8950_l6: l6 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + pm8950_l7: l7 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1900000>; + }; + + pm8950_l8: l8 { + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + }; + + pm8950_l9: l9 { + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3300000>; + }; + + pm8950_l10: l10 { + regulator-min-microvolt = <2850000>; + regulator-max-microvolt = <2850000>; + }; + + pm8950_l11: l11 { + /* TUSB320 power supply */ + regulator-always-on; + regulator-min-microvolt = <2950000>; + regulator-max-microvolt = <2950000>; + }; + + pm8950_l12: l12 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2950000>; + }; + + pm8950_l13: l13 { + regulator-min-microvolt = <3075000>; + regulator-max-microvolt = <3075000>; + }; + + pm8950_l14: l14 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + }; + + pm8950_l15: l15 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + }; + + pm8950_l16: l16 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + pm8950_l17: l17 { + regulator-min-microvolt = <2500000>; + regulator-max-microvolt = <2900000>; + }; + + pm8950_l19: l19 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1350000>; + }; + + pm8950_l22: l22 { + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + }; + + pm8950_l23: l23 { + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + }; + }; +}; + +&sdhc_1 { + vmmc-supply = <&pm8950_l8>; + vqmmc-supply = <&pm8950_l5>; + + status = "okay"; +}; + +&tlmm { + gpio-reserved-ranges = <0 4>, /* Unknown */ + <8 4>; /* Fingerprint SPI */ + + disp_reset_n_active: disp-reset-n-active-state { + pins = "gpio25"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + + disp_reset_n_sleep: disp-reset-n-sleep-state { + pins = "gpio25"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + disp_te_default: disp-te-default-state { + pins = "gpio24"; + function = "mdp_vsync"; + drive-strength = <2>; + bias-pull-down; + }; + + gpio_key_default: gpio-key-default-state { + pins = "gpio113"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + touch_default_state: touch-default-state { + irq-pins { + pins = "gpio65"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; + + reset-pins { + pins = "gpio64"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; + }; + + tusb320_int_active: tusb320-int-active-state { + pins = "gpio21"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; +}; + +&wcnss { + vddpx-supply = <&pm8950_l5>; + + status = "okay"; +}; + +&wcnss_iris { + compatible = "qcom,wcn3680"; + + vddxo-supply = <&pm8950_l7>; + vddrfa-supply = <&pm8950_l19>; + vddpa-supply = <&pm8950_l9>; + vdddig-supply = <&pm8950_l5>; +}; + +&xo_board { + clock-frequency = <19200000>; +}; +
diff --git a/arch/arm64/boot/dts/qcom/msm8976.dtsi b/arch/arm64/boot/dts/qcom/msm8976.dtsi index 80a0a09..20a4368 100644 --- a/arch/arm64/boot/dts/qcom/msm8976.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8976.dtsi
@@ -818,7 +818,7 @@ data-pins { }; }; - wcss_wlan_default: wcss-wlan-default-state { + wcss_wlan_default: wcss-wlan-default-state { wcss-wlan2-pins { pins = "gpio40"; function = "wcss_wlan2";
diff --git a/arch/arm64/boot/dts/qcom/msm8996-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/msm8996-oneplus-common.dtsi index a4dcc88..7a3f8af 100644 --- a/arch/arm64/boot/dts/qcom/msm8996-oneplus-common.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996-oneplus-common.dtsi
@@ -210,12 +210,15 @@ &mss_pil { }; &pcie0 { - perst-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; vddpe-3v3-supply = <&wlan_en>; vdda-supply = <&vreg_l28a_0p925>; status = "okay"; }; +&pcie0_port0 { + reset-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; +}; + &pcie_phy { vdda-phy-supply = <&vreg_l28a_0p925>; vdda-pll-supply = <&vreg_l12a_1p8>;
diff --git a/arch/arm64/boot/dts/qcom/msm8996-sony-xperia-tone.dtsi b/arch/arm64/boot/dts/qcom/msm8996-sony-xperia-tone.dtsi index d55e407..20b5eee 100644 --- a/arch/arm64/boot/dts/qcom/msm8996-sony-xperia-tone.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996-sony-xperia-tone.dtsi
@@ -191,13 +191,16 @@ &mmcc { }; &pcie0 { - perst-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>; vddpe-3v3-supply = <&wlan_en>; vdda-supply = <&pm8994_l28>; status = "okay"; }; +&pcie0_port0 { + reset-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>; +}; + &pcie_phy { vdda-phy-supply = <&pm8994_l28>; vdda-pll-supply = <&pm8994_l12>;
diff --git a/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi b/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi index 77ad613..3c70a9b 100644 --- a/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996-xiaomi-common.dtsi
@@ -278,9 +278,11 @@ &pcie0 { /* Supplied by vdd_3v3, but choose wlan_en to drive enable pin high */ vddpe-3v3-supply = <&wlan_en>; vdda-supply = <&vreg_l28a_0p925>; +}; - perst-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>; +&pcie0_port0 { + reset-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>; }; &pcie_phy {
diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi index 818e566..1267c56 100644 --- a/arch/arm64/boot/dts/qcom/msm8996.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi
@@ -1924,9 +1924,6 @@ pcie0: pcie@600000 { <0x0c100000 0x100000>; reg-names = "parf", "dbi", "elbi","config"; - phys = <&pciephy_0>; - phy-names = "pciephy"; - #address-cells = <3>; #size-cells = <2>; ranges = <0x01000000 0x0 0x00000000 0x0c200000 0x0 0x100000>, @@ -1975,11 +1972,13 @@ pcie0: pcie@600000 { "bus_master", "bus_slave"; - pcie@0 { + pcie0_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pciephy_0>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -2001,9 +2000,6 @@ pcie1: pcie@608000 { reg-names = "parf", "dbi", "elbi","config"; - phys = <&pciephy_1>; - phy-names = "pciephy"; - #address-cells = <3>; #size-cells = <2>; ranges = <0x01000000 0x0 0x00000000 0x0d200000 0x0 0x100000>, @@ -2052,11 +2048,13 @@ pcie1: pcie@608000 { "bus_master", "bus_slave"; - pcie@0 { + pcie1_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pciephy_1>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -2076,9 +2074,6 @@ pcie2: pcie@610000 { reg-names = "parf", "dbi", "elbi","config"; - phys = <&pciephy_2>; - phy-names = "pciephy"; - #address-cells = <3>; #size-cells = <2>; ranges = <0x01000000 0x0 0x00000000 0x0e200000 0x0 0x100000>, @@ -2126,11 +2121,13 @@ pcie2: pcie@610000 { "bus_master", "bus_slave"; - pcie@0 { + pcie2_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pciephy_2>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -2504,18 +2501,18 @@ lpass_q6_smmu: iommu@1600000 { #global-interrupts = <1>; interrupts = <GIC_SPI 404 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>; + <GIC_SPI 226 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 393 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 394 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 395 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 396 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 397 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 398 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 403 IRQ_TYPE_LEVEL_HIGH>; clocks = <&gcc GCC_HLOS1_VOTE_LPASS_ADSP_SMMU_CLK>, <&gcc GCC_HLOS1_VOTE_LPASS_CORE_SMMU_CLK>;
diff --git a/arch/arm64/boot/dts/qcom/msm8998.dtsi b/arch/arm64/boot/dts/qcom/msm8998.dtsi index 5038d00..bd8b69e 100644 --- a/arch/arm64/boot/dts/qcom/msm8998.dtsi +++ b/arch/arm64/boot/dts/qcom/msm8998.dtsi
@@ -928,8 +928,6 @@ pcie0: pcie@1c00000 { #address-cells = <3>; #size-cells = <2>; num-lanes = <1>; - phys = <&pcie_phy>; - phy-names = "pciephy"; status = "disabled"; ranges = <0x01000000 0x0 0x00000000 0x1b200000 0x0 0x100000>, @@ -969,13 +967,15 @@ pcie0: pcie@1c00000 { power-domains = <&gcc PCIE_0_GDSC>; iommu-map = <0x100 &anoc1_smmu 0x1480 1>; - perst-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie_phy>; + reset-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; + #address-cells = <3>; #size-cells = <2>; ranges;
diff --git a/arch/arm64/boot/dts/qcom/nord-embedded.dtsi b/arch/arm64/boot/dts/qcom/nord-embedded.dtsi new file mode 100644 index 0000000..1ab7d9b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/nord-embedded.dtsi
@@ -0,0 +1,1928 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include <dt-bindings/clock/qcom,glymur-videocc.h> +#include <dt-bindings/clock/qcom,nord-camcc.h> +#include <dt-bindings/clock/qcom,nord-dispcc.h> +#include <dt-bindings/clock/qcom,nord-gcc.h> +#include <dt-bindings/clock/qcom,nord-gpucc.h> +#include <dt-bindings/clock/qcom,nord-negcc.h> +#include <dt-bindings/clock/qcom,nord-nwgcc.h> +#include <dt-bindings/clock/qcom,nord-segcc.h> +#include <dt-bindings/clock/qcom,nord-tcsrcc.h> +#include <dt-bindings/clock/qcom,rpmh.h> +#include <dt-bindings/interconnect/qcom,icc.h> +#include <dt-bindings/interconnect/qcom,nord-rpmh.h> +#include <dt-bindings/power/qcom,rpmhpd.h> +#include <dt-bindings/soc/qcom,rpmh-rsc.h> + +#include "nord.dtsi" + +/ { + clk_virt: interconnect-clk-virt { + compatible = "qcom,nord-clk-virt"; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + mc_virt: interconnect-mc-virt { + compatible = "qcom,nord-mc-virt"; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; +}; + +&crypto { + interconnects = <&aggre1_noc_tile MASTER_CRYPTO_CORE0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "memory"; + + status = "okay"; +}; + +&i2c0 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S0_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c0_default>; + pinctrl-names = "default"; +}; + +&i2c1 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S1_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c1_default>; + pinctrl-names = "default"; +}; + +&i2c2 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S2_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c2_default>; + pinctrl-names = "default"; +}; + +&i2c3 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S3_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c3_default>; + pinctrl-names = "default"; +}; + +&i2c4 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S4_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c4_default>; + pinctrl-names = "default"; +}; + +&i2c5 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S5_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c5_default>; + pinctrl-names = "default"; +}; + +&i2c7 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S0_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c7_default>; + pinctrl-names = "default"; +}; + +&i2c8 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S1_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c8_default>; + pinctrl-names = "default"; +}; + +&i2c9 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S2_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c9_default>; + pinctrl-names = "default"; +}; + +&i2c10 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S3_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c10_default>; + pinctrl-names = "default"; +}; + +&i2c11 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S4_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c11_default>; + pinctrl-names = "default"; +}; + +&i2c12 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S5_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c12_default>; + pinctrl-names = "default"; +}; + +&i2c13 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S6_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c13_default>; + pinctrl-names = "default"; +}; + +&i2c14 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S0_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre1_noc_tile MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c14_default>; + pinctrl-names = "default"; +}; + +&i2c16 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S2_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre1_noc_tile MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c16_default>; + pinctrl-names = "default"; +}; + +&i2c17 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S3_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre1_noc_tile MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c17_default>; + pinctrl-names = "default"; +}; + +&i2c18 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S4_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre1_noc_tile MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c18_default>; + pinctrl-names = "default"; +}; + +&i2c19 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S5_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre1_noc_tile MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c19_default>; + pinctrl-names = "default"; +}; + +&i2c20 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S6_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre1_noc_tile MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_i2c20_default>; + pinctrl-names = "default"; +}; + +&qupv3_0 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_M_AHB_CLK>, + <&segcc SE_GCC_QUPV3_WRAP0_S_AHB_CLK>; + clock-names = "m-ahb", + "s-ahb"; +}; + +&qupv3_1 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_M_AHB_CLK>, + <&segcc SE_GCC_QUPV3_WRAP1_S_AHB_CLK>; + clock-names = "m-ahb", + "s-ahb"; +}; + +&qupv3_2 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_M_AHB_CLK>, + <&negcc NE_GCC_QUPV3_WRAP2_S_AHB_CLK>; + clock-names = "m-ahb", + "s-ahb"; +}; + +&spi0 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S0_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi0_default>; + pinctrl-names = "default"; +}; + +&spi1 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S1_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi1_default>; + pinctrl-names = "default"; +}; + +&spi2 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S2_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi2_default>; + pinctrl-names = "default"; +}; + +&spi3 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S3_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi3_default>; + pinctrl-names = "default"; +}; + +&spi4 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S4_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi4_default>; + pinctrl-names = "default"; +}; + +&spi5 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S5_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_0 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi5_default>; + pinctrl-names = "default"; +}; + +&spi7 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S0_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi7_default>; + pinctrl-names = "default"; +}; + +&spi8 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S1_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi8_default>; + pinctrl-names = "default"; +}; + +&spi11 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S4_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi11_default>; + pinctrl-names = "default"; +}; + +&spi12 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S5_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi12_default>; + pinctrl-names = "default"; +}; + +&spi13 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S6_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>, + <&aggre2_noc_tile MASTER_QUP_1 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi13_default>; + pinctrl-names = "default"; +}; + +&spi14 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S0_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre1_noc_tile MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi14_default>; + pinctrl-names = "default"; +}; + +&spi16 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S2_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre1_noc_tile MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi16_default>; + pinctrl-names = "default"; +}; + +&spi17 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S3_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre1_noc_tile MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi17_default>; + pinctrl-names = "default"; +}; + +&spi18 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S4_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre1_noc_tile MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi18_default>; + pinctrl-names = "default"; +}; + +&spi19 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S5_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre1_noc_tile MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi19_default>; + pinctrl-names = "default"; +}; + +&spi20 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S6_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>, + <&aggre1_noc_tile MASTER_QUP_2 QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config", + "qup-memory"; + pinctrl-0 = <&qup_spi20_default>; + pinctrl-names = "default"; +}; + +&soc { + gcc: clock-controller@100000 { + compatible = "qcom,nord-gcc"; + reg = <0x0 0x00100000 0x0 0x1f4200>; + clocks = <&bi_tcxo_div2>, + <&sleep_clk>, + <0>, + <0>, + <0>, + <0>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + cnoc_main: interconnect@1500000 { + compatible = "qcom,nord-cnoc-main"; + reg = <0x0 0x01500000 0x0 0x1d200>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + config_noc: interconnect@1600000 { + compatible = "qcom,nord-cnoc-cfg"; + reg = <0x0 0x01600000 0x0 0xd200>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + system_noc: interconnect@1680000 { + compatible = "qcom,nord-system-noc"; + reg = <0x0 0x01680000 0x0 0x1c080>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + aggre2_noc_tile: interconnect@16c0000 { + compatible = "qcom,nord-aggre2-noc-tile"; + reg = <0x0 0x016c0000 0x0 0x1b400>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + aggre1_noc: interconnect@16e0000 { + compatible = "qcom,nord-aggre1-noc"; + reg = <0x0 0x016e0000 0x0 0x1c400>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + aggre2_noc: interconnect@1700000 { + compatible = "qcom,nord-aggre2-noc"; + reg = <0x0 0x01700000 0x0 0x1b400>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + clocks = <&rpmhcc RPMH_IPA_CLK>; + }; + + aggre1_noc_tile: interconnect@1720000 { + compatible = "qcom,nord-aggre1-noc-tile"; + reg = <0x0 0x01720000 0x0 0x23400>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + clocks = <&negcc NE_GCC_AGGRE_NOC_USB2_AXI_CLK>, + <&negcc NE_GCC_AGGRE_NOC_USB3_PRIM_AXI_CLK>, + <&negcc NE_GCC_AGGRE_NOC_USB3_SEC_AXI_CLK>, + <&negcc NE_GCC_AGGRE_NOC_UFS_PHY_AXI_CLK>; + }; + + mmss_noc: interconnect@1780000 { + compatible = "qcom,nord-mmss-noc"; + reg = <0x0 0x01780000 0x0 0x72800>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + pcie_cfg: interconnect@1ba0000 { + compatible = "qcom,nord-pcie-cfg"; + reg = <0x0 0x01ba0000 0x0 0x7200>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + pcie_data_outbound: interconnect@1bc0000 { + compatible = "qcom,nord-pcie-data-outbound"; + reg = <0x0 0x01bc0000 0x0 0x17000>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + pcie_data_inbound: interconnect@1c00000 { + compatible = "qcom,nord-pcie-data-inbound"; + reg = <0x0 0x01c00000 0x0 0x4b080>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + ufs_mem_phy: phy@1d40000 { + compatible = "qcom,nord-qmp-ufs-phy", + "qcom,sm8650-qmp-ufs-phy"; + reg = <0x0 0x01d40000 0x0 0x2000>; + + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&negcc NE_GCC_UFS_PHY_PHY_AUX_CLK>, + <&tcsrcc TCSR_UFS_CLKREF_EN>; + clock-names = "ref", + "ref_aux", + "qref"; + + resets = <&ufs_mem_hc 0>; + reset-names = "ufsphy"; + + power-domains = <&negcc NE_GCC_UFS_MEM_PHY_GDSC>; + #clock-cells = <1>; + #phy-cells = <0>; + + status = "disabled"; + }; + + ice: crypto@1d48000 { + compatible = "qcom,nord-inline-crypto-engine", + "qcom,inline-crypto-engine"; + reg = <0x0 0x01d48000 0x0 0x18000>; + clocks = <&negcc NE_GCC_UFS_PHY_ICE_CORE_CLK>, + <&negcc NE_GCC_UFS_PHY_AHB_CLK>; + clock-names = "core", + "iface"; + power-domains = <&negcc NE_GCC_UFS_PHY_GDSC>; + }; + + hscnoc: interconnect@2000000 { + compatible = "qcom,nord-hscnoc"; + reg = <0x0 0x02000000 0x0 0xb22000>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + gpucc: clock-controller@3d90000 { + compatible = "qcom,nord-gpucc"; + reg = <0x0 0x03d90000 0x0 0x9800>; + clocks = <&rpmhcc RPMH_CXO_CLK>, + <&nwgcc NW_GCC_GPU_GPLL0_CLK_SRC>, + <&nwgcc NW_GCC_GPU_GPLL0_DIV_CLK_SRC>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + hpass_ag_noc: interconnect@5fc0000 { + compatible = "qcom,nord-hpass-ag-noc"; + reg = <0x0 0x05fc0000 0x0 0x37080>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + negcc: clock-controller@8900000 { + compatible = "qcom,nord-negcc"; + reg = <0x0 0x08900000 0x0 0xf4200>; + clocks = <&bi_tcxo_div2>, + <&sleep_clk>, + <0>, + <0>, + <0>, + <0>, + <0>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + segcc: clock-controller@8a00000 { + compatible = "qcom,nord-segcc"; + reg = <0x0 0x08a00000 0x0 0xf4200>; + clocks = <&bi_tcxo_div2>, + <&sleep_clk>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + nwgcc: clock-controller@8b00000 { + compatible = "qcom,nord-nwgcc"; + reg = <0x0 0x08b00000 0x0 0xf4200>; + clocks = <&bi_tcxo_div2>, + <&sleep_clk>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + dispcc1: clock-controller@8d00000 { + compatible = "qcom,nord-dispcc1"; + reg = <0x0 0x08d00000 0x0 0x20000>; + clocks = <&bi_tcxo_div2>, + <&bi_tcxo_ao_div2>, + <&nwgcc NW_GCC_DISP_1_AHB_CLK>, + <&sleep_clk>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>; + power-domains = <&rpmhpd RPMHPD_MMCX>; + required-opps = <&rpmhpd_opp_min_svs>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + gpu2cc: clock-controller@9890000 { + compatible = "qcom,nord-gpu2cc"; + reg = <0x0 0x09890000 0x0 0xa000>; + clocks = <&bi_tcxo_div2>, + <&negcc NE_GCC_GPU_2_GPLL0_CLK_SRC>, + <&negcc NE_GCC_GPU_2_GPLL0_DIV_CLK_SRC>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + camcc: clock-controller@9ce0000 { + compatible = "qcom,nord-camcc"; + reg = <0x0 0x09ce0000 0x0 0x20000>; + power-domains = <&rpmhpd RPMHPD_MMCX>, + <&rpmhpd RPMHPD_MXC>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + clocks = <&nwgcc NW_GCC_CAMERA_AHB_CLK>, + <&bi_tcxo_div2>, + <&bi_tcxo_ao_div2>, + <&sleep_clk>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + videocc: clock-controller@aaf0000 { + compatible = "qcom,nord-videocc"; + reg = <0x0 0x0aaf0000 0x0 0x10000>; + clocks = <&bi_tcxo_div2>, + <&nwgcc NW_GCC_VIDEO_AHB_CLK>; + power-domains = <&rpmhpd RPMHPD_MMCX>, + <&rpmhpd RPMHPD_MXC>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + dispcc0: clock-controller@af00000 { + compatible = "qcom,nord-dispcc0"; + reg = <0x0 0x0af00000 0x0 0x20000>; + clocks = <&bi_tcxo_div2>, + <&bi_tcxo_ao_div2>, + <&nwgcc NW_GCC_DISP_0_AHB_CLK>, + <&sleep_clk>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>, + <0>; + power-domains = <&rpmhpd RPMHPD_MMCX>; + required-opps = <&rpmhpd_opp_min_svs>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + tcsrcc: clock-controller@f1d9000 { + compatible = "qcom,nord-tcsrcc", + "syscon"; + reg = <0x0 0x0f1d9000 0x0 0xf00c>; + clocks = <&rpmhcc RPMH_CXO_CLK>; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + apps_rsc: rsc@18900000 { + compatible = "qcom,rpmh-rsc"; + reg = <0x0 0x18900000 0x0 0x10000>, + <0x0 0x18910000 0x0 0x10000>, + <0x0 0x18920000 0x0 0x10000>; + reg-names = "drv-0", + "drv-1", + "drv-2"; + interrupts = <GIC_SPI 27 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 28 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 29 IRQ_TYPE_LEVEL_HIGH>; + qcom,tcs-offset = <0xd00>; + qcom,drv-id = <2>; + qcom,tcs-config = <ACTIVE_TCS 3>, + <SLEEP_TCS 2>, + <WAKE_TCS 2>, + <CONTROL_TCS 0>; + label = "apps_rsc"; + power-domains = <&system_pd>; + + apps_bcm_voter: bcm-voter { + compatible = "qcom,bcm-voter"; + }; + + rpmhcc: clock-controller { + compatible = "qcom,nord-rpmh-clk"; + clocks = <&xo_board>; + clock-names = "xo"; + #clock-cells = <1>; + }; + + rpmhpd: power-controller { + compatible = "qcom,nord-rpmhpd"; + #power-domain-cells = <1>; + operating-points-v2 = <&rpmhpd_opp_table>; + + rpmhpd_opp_table: opp-table { + compatible = "operating-points-v2"; + + rpmhpd_opp_ret: opp-0 { + opp-level = <RPMH_REGULATOR_LEVEL_RETENTION>; + }; + + rpmhpd_opp_min_svs: opp-1 { + opp-level = <RPMH_REGULATOR_LEVEL_MIN_SVS>; + }; + + rpmhpd_opp_low_svs: opp-2 { + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>; + }; + + rpmhpd_opp_svs: opp-3 { + opp-level = <RPMH_REGULATOR_LEVEL_SVS>; + }; + + rpmhpd_opp_svs_l1: opp-4 { + opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>; + }; + + rpmhpd_opp_nom: opp-5 { + opp-level = <RPMH_REGULATOR_LEVEL_NOM>; + }; + + rpmhpd_opp_nom_l1: opp-6 { + opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>; + }; + + rpmhpd_opp_nom_l2: opp-7 { + opp-level = <RPMH_REGULATOR_LEVEL_NOM_L2>; + }; + + rpmhpd_opp_turbo: opp-8 { + opp-level = <RPMH_REGULATOR_LEVEL_TURBO>; + }; + + rpmhpd_opp_turbo_l1: opp-9 { + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>; + }; + }; + }; + }; + + nsp_data_noc_0: interconnect@1f200000 { + compatible = "qcom,nord-nsp-data-noc-0"; + reg = <0x0 0x1f200000 0x0 0x2a200>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + nsp_data_noc_1: interconnect@1f600000 { + compatible = "qcom,nord-nsp-data-noc-1"; + reg = <0x0 0x1f600000 0x0 0x2a200>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + nsp_data_noc_2: interconnect@1fa00000 { + compatible = "qcom,nord-nsp-data-noc-2"; + reg = <0x0 0x1fa00000 0x0 0x2a200>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; + + nsp_data_noc_3: interconnect@1fe00000 { + compatible = "qcom,nord-nsp-data-noc-3"; + reg = <0x0 0x1fe00000 0x0 0x2a200>; + #interconnect-cells = <2>; + qcom,bcm-voters = <&apps_bcm_voter>; + }; +}; + +&tlmm { + qup_i2c0_default: qup-i2c0-default-state { + pins = "gpio111", "gpio112"; + function = "qup0_se0"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c1_default: qup-i2c1-default-state { + pins = "gpio111", "gpio112"; + function = "qup0_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c2_default: qup-i2c2-default-state { + pins = "gpio113", "gpio114"; + function = "qup0_se2"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c3_default: qup-i2c3-default-state { + pins = "gpio115", "gpio116"; + function = "qup0_se3"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c4_default: qup-i2c4-default-state { + pins = "gpio117", "gpio118"; + function = "qup0_se4"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c5_default: qup-i2c5-default-state { + pins = "gpio121", "gpio122"; + function = "qup0_se5"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c7_default: qup-i2c7-default-state { + pins = "gpio123", "gpio124"; + function = "qup1_se0"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c8_default: qup-i2c8-default-state { + pins = "gpio125", "gpio126"; + function = "qup1_se1"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c9_default: qup-i2c9-default-state { + pins = "gpio127", "gpio128"; + function = "qup1_se2_01"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c10_default: qup-i2c10-default-state { + pins = "gpio129", "gpio130"; + function = "qup1_se3_01"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c11_default: qup-i2c11-default-state { + pins = "gpio131", "gpio132"; + function = "qup1_se4"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c12_default: qup-i2c12-default-state { + pins = "gpio133", "gpio134"; + function = "qup1_se5"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c13_default: qup-i2c13-default-state { + pins = "gpio137", "gpio138"; + function = "qup1_se6"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c14_default: qup-i2c14-default-state { + pins = "gpio139", "gpio140"; + function = "qup2_se0"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c16_default: qup-i2c16-default-state { + pins = "gpio145", "gpio146"; + function = "qup2_se2"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c17_default: qup-i2c17-default-state { + pins = "gpio150", "gpio151"; + function = "qup2_se3"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c18_default: qup-i2c18-default-state { + pins = "gpio154", "gpio155"; + function = "qup2_se4"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c19_default: qup-i2c19-default-state { + pins = "gpio156", "gpio157"; + function = "qup2_se5"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_i2c20_default: qup-i2c20-default-state { + pins = "gpio158", "gpio159"; + function = "qup2_se6"; + drive-strength = <2>; + bias-pull-up; + }; + + qup_spi0_default: qup-spi0-default-state { + data-pins { + pins = "gpio109", "gpio111", "gpio112"; + function = "qup0_se0"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio110"; + function = "qup0_se0"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_spi1_default: qup-spi1-default-state { + data-pins { + pins = "gpio109", "gpio111", "gpio112"; + function = "qup0_se1"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio110"; + function = "qup0_se1"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_spi2_default: qup-spi2-default-state { + data-pins { + pins = "gpio113", "gpio114", "gpio115"; + function = "qup0_se2"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio116"; + function = "qup0_se2"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_spi3_default: qup-spi3-default-state { + data-pins { + pins = "gpio113", "gpio115", "gpio116"; + function = "qup0_se3"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio114"; + function = "qup0_se3"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_spi4_default: qup-spi4-default-state { + data-pins { + pins = "gpio117", "gpio118", "gpio119"; + function = "qup0_se4"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio120"; + function = "qup0_se4"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_spi5_default: qup-spi5-default-state { + data-pins { + pins = "gpio109", "gpio121", "gpio122"; + function = "qup0_se5"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio110"; + function = "qup0_se5"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_spi7_default: qup-spi7-default-state { + data-pins { + pins = "gpio123", "gpio124", "gpio125"; + function = "qup1_se0"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio126"; + function = "qup1_se0"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_spi8_default: qup-spi8-default-state { + data-pins { + pins = "gpio123", "gpio125", "gpio126"; + function = "qup1_se1"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio124"; + function = "qup1_se1"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_spi11_default: qup-spi11-default-state { + data-pins { + pins = "gpio131", "gpio132", "gpio137"; + function = "qup1_se4"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio138"; + function = "qup1_se4"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_spi12_default: qup-spi12-default-state { + data-pins { + pins = "gpio133", "gpio134", "gpio135"; + function = "qup1_se5"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio136"; + function = "qup1_se5"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_spi13_default: qup-spi13-default-state { + data-pins { + pins = "gpio131", "gpio137", "gpio138"; + function = "qup1_se6"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio132"; + function = "qup1_se6"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_spi14_default: qup-spi14-default-state { + data-pins { + pins = "gpio139", "gpio140", "gpio141"; + function = "qup2_se0"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio142"; + function = "qup2_se0"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_spi16_default: qup-spi16-default-state { + data-pins { + pins = "gpio145", "gpio146", "gpio147"; + function = "qup2_se2"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio148"; + function = "qup2_se2"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_spi17_default: qup-spi17-default-state { + data-pins { + pins = "gpio150", "gpio151", "gpio152"; + function = "qup2_se3"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio153"; + function = "qup2_se3"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_spi18_default: qup-spi18-default-state { + data-pins { + pins = "gpio143", "gpio154", "gpio155"; + function = "qup2_se4"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio144"; + function = "qup2_se4"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_spi19_default: qup-spi19-default-state { + data-pins { + pins = "gpio156", "gpio157", "gpio158"; + function = "qup2_se5"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio159"; + function = "qup2_se5"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_spi20_default: qup-spi20-default-state { + data-pins { + pins = "gpio156", "gpio158", "gpio159"; + function = "qup2_se6"; + drive-strength = <6>; + bias-disable; + }; + + cs-pins { + pins = "gpio157"; + function = "qup2_se6"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart0_default: qup-uart0-default-state { + pins = "gpio109", "gpio110"; + function = "qup0_se0"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart1_default: qup-uart1-default-state { + pins = "gpio109", "gpio110"; + function = "qup0_se1"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart2_default: qup-uart2-default-state { + pins = "gpio115", "gpio116"; + function = "qup0_se2"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart3_default: qup-uart3-default-state { + pins = "gpio113", "gpio114"; + function = "qup0_se3"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart4_default: qup-uart4-default-state { + pins = "gpio119", "gpio120"; + function = "qup0_se4"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart5_default: qup-uart5-default-state { + pins = "gpio109", "gpio110"; + function = "qup0_se5"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart7_default: qup-uart7-default-state { + pins = "gpio125", "gpio126"; + function = "qup1_se0"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart8_default: qup-uart8-default-state { + pins = "gpio123", "gpio124"; + function = "qup1_se1"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart9_default: qup-uart9-default-state { + pins = "gpio127", "gpio128"; + function = "qup1_se2_23"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart10_default: qup-uart10-default-state { + pins = "gpio129", "gpio130"; + function = "qup1_se3_23"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart11_default: qup-uart11-default-state { + pins = "gpio137", "gpio138"; + function = "qup1_se4"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart12_default: qup-uart12-default-state { + pins = "gpio135", "gpio136"; + function = "qup1_se5"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart13_default: qup-uart13-default-state { + pins = "gpio131", "gpio132"; + function = "qup1_se6"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart14_default: qup-uart14-default-state { + pins = "gpio141", "gpio142"; + function = "qup2_se0"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart15_default: qup-uart15-default-state { + pins = "gpio143", "gpio144"; + function = "qup2_se1"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart16_default: qup-uart16-default-state { + pins = "gpio147", "gpio148"; + function = "qup2_se2"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart17_default: qup-uart17-default-state { + pins = "gpio150", "gpio151", "gpio152", "gpio153"; + function = "qup2_se3"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart18_default: qup-uart18-default-state { + pins = "gpio143", "gpio144"; + function = "qup2_se4"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart19_default: qup-uart19-default-state { + pins = "gpio158", "gpio159"; + function = "qup2_se5"; + drive-strength = <2>; + bias-disable; + }; + + qup_uart20_default: qup-uart20-default-state { + pins = "gpio156", "gpio157"; + function = "qup2_se6"; + drive-strength = <2>; + bias-disable; + }; +}; + +&uart0 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S0_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart0_default>; + pinctrl-names = "default"; +}; + +&uart1 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S1_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart1_default>; + pinctrl-names = "default"; +}; + +&uart2 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S2_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart2_default>; + pinctrl-names = "default"; +}; + +&uart3 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S3_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart3_default>; + pinctrl-names = "default"; +}; + +&uart4 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S4_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart4_default>; + pinctrl-names = "default"; +}; + +&uart5 { + clocks = <&segcc SE_GCC_QUPV3_WRAP0_S5_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_0 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_0 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart5_default>; + pinctrl-names = "default"; +}; + +&uart7 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S0_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart7_default>; + pinctrl-names = "default"; +}; + +&uart8 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S1_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart8_default>; + pinctrl-names = "default"; +}; + +&uart9 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S2_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart9_default>; + pinctrl-names = "default"; +}; + +&uart10 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S3_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart10_default>; + pinctrl-names = "default"; +}; + +&uart11 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S4_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart11_default>; + pinctrl-names = "default"; +}; + +&uart12 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S5_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart12_default>; + pinctrl-names = "default"; +}; + +&uart13 { + clocks = <&segcc SE_GCC_QUPV3_WRAP1_S6_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart13_default>; + pinctrl-names = "default"; +}; + +&uart14 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S0_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart14_default>; + pinctrl-names = "default"; +}; + +&uart15 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S1_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart15_default>; + pinctrl-names = "default"; +}; + +&uart16 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S2_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart16_default>; + pinctrl-names = "default"; +}; + +&uart17 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S3_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart17_default>; + pinctrl-names = "default"; +}; + +&uart18 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S4_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart18_default>; + pinctrl-names = "default"; +}; + +&uart19 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S5_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart19_default>; + pinctrl-names = "default"; +}; + +&uart20 { + clocks = <&negcc NE_GCC_QUPV3_WRAP2_S6_CLK>; + clock-names = "se"; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ALWAYS + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "qup-core", + "qup-config"; + pinctrl-0 = <&qup_uart20_default>; + pinctrl-names = "default"; +}; + +&ufs_mem_hc { + clocks = <&negcc NE_GCC_UFS_PHY_AXI_CLK>, + <&negcc NE_GCC_AGGRE_NOC_UFS_PHY_AXI_CLK>, + <&negcc NE_GCC_UFS_PHY_AHB_CLK>, + <&negcc NE_GCC_UFS_PHY_UNIPRO_CORE_CLK>, + <&tcsrcc TCSR_UFS_CLKREF_EN>, + <&negcc NE_GCC_UFS_PHY_TX_SYMBOL_0_CLK>, + <&negcc NE_GCC_UFS_PHY_RX_SYMBOL_0_CLK>, + <&negcc NE_GCC_UFS_PHY_RX_SYMBOL_1_CLK>; + clock-names = "core_clk", + "bus_aggr_clk", + "iface_clk", + "core_clk_unipro", + "ref_clk", + "tx_lane0_sync_clk", + "rx_lane0_sync_clk", + "rx_lane1_sync_clk"; + + resets = <&negcc NE_GCC_UFS_PHY_BCR>; + reset-names = "rst"; + + interconnects = <&aggre1_noc_tile MASTER_UFS_MEM QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, + <&hscnoc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_UFS_MEM_CFG QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "ufs-ddr", + "cpu-ufs"; + + phys = <&ufs_mem_phy>; + phy-names = "ufsphy"; + + power-domains = <&negcc NE_GCC_UFS_PHY_GDSC>; + operating-points-v2 = <&ufs_opp_table>; + required-opps = <&rpmhpd_opp_nom>; + qcom,ice = <&ice>; + #reset-cells = <1>; + + ufs_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <100000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>; + required-opps = <&rpmhpd_opp_low_svs>; + }; + + opp-201500000 { + opp-hz = /bits/ 64 <201500000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <201500000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>; + required-opps = <&rpmhpd_opp_svs>; + }; + + opp-403000000 { + opp-hz = /bits/ 64 <403000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <403000000>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>, + /bits/ 64 <0>; + required-opps = <&rpmhpd_opp_nom>; + }; + }; +};
diff --git a/arch/arm64/boot/dts/qcom/nord-gearvm.dtsi b/arch/arm64/boot/dts/qcom/nord-gearvm.dtsi new file mode 100644 index 0000000..5514f9a --- /dev/null +++ b/arch/arm64/boot/dts/qcom/nord-gearvm.dtsi
@@ -0,0 +1,2848 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include "nord.dtsi" + +&firmware { + scmi0: scmi-0 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem0>; + /* We expect the bootloader to update the IRQ number */ + interrupts = <GIC_SPI 963 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi0_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi0_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi0_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi1: scmi-1 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem1>; + interrupts = <GIC_SPI 964 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi1_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi1_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi1_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi2: scmi-2 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem2>; + interrupts = <GIC_SPI 965 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi2_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi2_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi2_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi3: scmi-3 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem3>; + interrupts = <GIC_SPI 966 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi3_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi3_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi3_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi4: scmi-4 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem4>; + interrupts = <GIC_SPI 967 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi4_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi4_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi4_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi5: scmi-5 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem5>; + interrupts = <GIC_SPI 968 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi5_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi5_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi5_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi6: scmi-6 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem6>; + interrupts = <GIC_SPI 969 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi6_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi6_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi6_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi7: scmi-7 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem7>; + interrupts = <GIC_SPI 970 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi7_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi7_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi7_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi8: scmi-8 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem8>; + interrupts = <GIC_SPI 971 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi8_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi8_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi8_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi9: scmi-9 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem9>; + interrupts = <GIC_SPI 972 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi9_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi9_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi9_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi10: scmi-10 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem10>; + interrupts = <GIC_SPI 973 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi10_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi10_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi10_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi11: scmi-11 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem11>; + interrupts = <GIC_SPI 974 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi11_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi11_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi11_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi12: scmi-12 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem12>; + interrupts = <GIC_SPI 975 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi12_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi12_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi12_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi13: scmi-13 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem13>; + interrupts = <GIC_SPI 976 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi13_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi13_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi13_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi14: scmi-14 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem14>; + interrupts = <GIC_SPI 977 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi14_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi14_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi14_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi15: scmi-15 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem15>; + interrupts = <GIC_SPI 978 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi15_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi15_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi15_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi16: scmi-16 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem16>; + interrupts = <GIC_SPI 979 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi16_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi16_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi16_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi17: scmi-17 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem17>; + interrupts = <GIC_SPI 980 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi17_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi17_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi17_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi18: scmi-18 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem18>; + interrupts = <GIC_SPI 981 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi18_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi18_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi18_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi19: scmi-19 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem19>; + interrupts = <GIC_SPI 982 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi19_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi19_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi19_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi20: scmi-20 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem20>; + interrupts = <GIC_SPI 983 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi20_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi20_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi20_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi21: scmi-21 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem21>; + interrupts = <GIC_SPI 984 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi21_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi21_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi21_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi22: scmi-22 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem22>; + interrupts = <GIC_SPI 985 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi22_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi22_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi22_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi23: scmi-23 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem23>; + interrupts = <GIC_SPI 986 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi23_sensor: protocol@15 { + reg = <0x15>; + #thermal-sensor-cells = <1>; + }; + }; + + scmi24: scmi-24 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem24>; + interrupts = <GIC_SPI 987 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi24_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi24_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi24_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi25: scmi-25 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem25>; + interrupts = <GIC_ESPI 0 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi25_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi25_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi25_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi26: scmi-26 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem26>; + interrupts = <GIC_ESPI 1 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi26_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi26_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi26_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi27: scmi-27 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem27>; + interrupts = <GIC_ESPI 2 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi27_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi27_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi27_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi28: scmi-28 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem28>; + interrupts = <GIC_ESPI 3 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi28_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi28_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi28_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi29: scmi-29 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem29>; + interrupts = <GIC_ESPI 4 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi29_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi29_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi29_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi30: scmi-30 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem30>; + interrupts = <GIC_ESPI 5 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi30_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi30_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi30_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi31: scmi-31 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem31>; + interrupts = <GIC_ESPI 6 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi31_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi31_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi31_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi32: scmi-32 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem32>; + interrupts = <GIC_ESPI 7 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi32_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi32_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi32_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi33: scmi-33 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem33>; + interrupts = <GIC_ESPI 8 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi33_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi33_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi33_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi34: scmi-34 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem34>; + interrupts = <GIC_ESPI 9 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi34_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi34_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi34_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi35: scmi-35 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem35>; + interrupts = <GIC_ESPI 10 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi35_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi35_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi35_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi36: scmi-36 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem36>; + interrupts = <GIC_ESPI 11 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi36_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi36_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi36_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi37: scmi-37 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem37>; + interrupts = <GIC_ESPI 12 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi37_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi37_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi37_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi38: scmi-38 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem38>; + interrupts = <GIC_ESPI 13 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi38_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi38_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi38_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi39: scmi-39 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem39>; + interrupts = <GIC_ESPI 14 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi39_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi39_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi39_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi40: scmi-40 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem40>; + interrupts = <GIC_ESPI 15 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi40_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi40_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi40_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi41: scmi-41 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem41>; + interrupts = <GIC_ESPI 16 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi41_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi41_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi41_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi42: scmi-42 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem42>; + interrupts = <GIC_ESPI 17 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi42_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi42_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi42_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi43: scmi-43 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem43>; + interrupts = <GIC_ESPI 18 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi43_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi43_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi43_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi44: scmi-44 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem44>; + interrupts = <GIC_ESPI 19 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi44_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi44_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi44_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi45: scmi-45 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem45>; + interrupts = <GIC_ESPI 20 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi45_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi45_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi45_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi46: scmi-46 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem46>; + interrupts = <GIC_ESPI 21 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi46_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi46_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi46_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi47: scmi-47 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem47>; + interrupts = <GIC_ESPI 22 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi47_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi47_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi47_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi48: scmi-48 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem48>; + interrupts = <GIC_ESPI 23 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi48_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi48_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi48_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi49: scmi-49 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem49>; + interrupts = <GIC_ESPI 24 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi49_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi49_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi49_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi50: scmi-50 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem50>; + interrupts = <GIC_ESPI 25 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi50_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi50_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi50_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi51: scmi-51 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem51>; + interrupts = <GIC_ESPI 26 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi51_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi51_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi51_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi52: scmi-52 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem52>; + interrupts = <GIC_ESPI 27 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi52_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi52_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi52_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi53: scmi-53 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem53>; + interrupts = <GIC_ESPI 28 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi53_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi53_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi53_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi54: scmi-54 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem54>; + interrupts = <GIC_ESPI 29 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi54_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi54_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi54_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi55: scmi-55 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem55>; + interrupts = <GIC_ESPI 30 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi55_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi55_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi55_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi56: scmi-56 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem56>; + interrupts = <GIC_ESPI 31 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi56_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi56_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi56_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi57: scmi-57 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem57>; + interrupts = <GIC_ESPI 32 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi57_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi57_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi57_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi58: scmi-58 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem58>; + interrupts = <GIC_ESPI 33 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi58_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi58_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi58_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi59: scmi-59 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem59>; + interrupts = <GIC_ESPI 34 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi59_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi59_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi59_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi60: scmi-60 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem60>; + interrupts = <GIC_ESPI 35 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi60_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi60_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi60_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi61: scmi-61 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem61>; + interrupts = <GIC_ESPI 36 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi61_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi61_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi61_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi62: scmi-62 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem62>; + interrupts = <GIC_ESPI 37 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi62_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi62_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi62_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; + + scmi63: scmi-63 { + compatible = "qcom,scmi-smc"; + arm,smc-id = <0xc6008012>; + shmem = <&shmem63>; + interrupts = <GIC_ESPI 38 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "a2p"; + #address-cells = <1>; + #size-cells = <0>; + arm,max-msg = <10>; + arm,max-msg-size = <256>; + arm,max-rx-timeout-ms = <3000>; + + status = "disabled"; + + scmi63_pd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + + scmi63_dvfs: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + + scmi63_rst: protocol@16 { + reg = <0x16>; + #reset-cells = <1>; + }; + }; +}; + +&i2c0 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 0>, + <&scmi9_dvfs 0>; + power-domain-names = "power", + "perf"; +}; + +&i2c1 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 1>, + <&scmi9_dvfs 1>; + power-domain-names = "power", + "perf"; +}; + +&i2c2 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 2>, + <&scmi9_dvfs 2>; + power-domain-names = "power", + "perf"; +}; + +&i2c3 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 3>, + <&scmi9_dvfs 3>; + power-domain-names = "power", + "perf"; +}; + +&i2c4 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 4>, + <&scmi9_dvfs 4>; + power-domain-names = "power", + "perf"; +}; + +&i2c5 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 5>, + <&scmi9_dvfs 5>; + power-domain-names = "power", + "perf"; +}; + +&i2c7 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 7>, + <&scmi9_dvfs 7>; + power-domain-names = "power", + "perf"; +}; + +&i2c8 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 8>, + <&scmi9_dvfs 8>; + power-domain-names = "power", + "perf"; +}; + +&i2c9 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 9>, + <&scmi9_dvfs 9>; + power-domain-names = "power", + "perf"; +}; + +&i2c10 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 10>, + <&scmi9_dvfs 10>; + power-domain-names = "power", + "perf"; +}; + +&i2c11 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 11>, + <&scmi9_dvfs 11>; + power-domain-names = "power", + "perf"; +}; + +&i2c12 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 12>, + <&scmi9_dvfs 12>; + power-domain-names = "power", + "perf"; +}; + +&i2c13 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 13>, + <&scmi9_dvfs 13>; + power-domain-names = "power", + "perf"; +}; + +&i2c14 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 14>, + <&scmi9_dvfs 14>; + power-domain-names = "power", + "perf"; +}; + +&i2c15 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 15>, + <&scmi9_dvfs 15>; + power-domain-names = "power", + "perf"; +}; + +&i2c16 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 16>, + <&scmi9_dvfs 16>; + power-domain-names = "power", + "perf"; +}; + +&i2c17 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 17>, + <&scmi9_dvfs 17>; + power-domain-names = "power", + "perf"; +}; + +&i2c18 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 18>, + <&scmi9_dvfs 18>; + power-domain-names = "power", + "perf"; +}; + +&i2c19 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 19>, + <&scmi9_dvfs 19>; + power-domain-names = "power", + "perf"; +}; + +&i2c20 { + compatible = "qcom,sa8797p-geni-i2c", + "qcom,sa8255p-geni-i2c"; + power-domains = <&scmi9_pd 20>, + <&scmi9_dvfs 20>; + power-domain-names = "power", + "perf"; +}; + +&qupv3_0 { + compatible = "qcom,sa8797p-geni-se-qup", + "qcom,sa8255p-geni-se-qup"; +}; + +&qupv3_1 { + compatible = "qcom,sa8797p-geni-se-qup", + "qcom,sa8255p-geni-se-qup"; +}; + +&qupv3_2 { + compatible = "qcom,sa8797p-geni-se-qup", + "qcom,sa8255p-geni-se-qup"; +}; + +&reserved_memory { + shmem0: scmi-shmem@d7600000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7600000 0x0 0x1000>; + no-map; + }; + + shmem1: scmi-shmem@d7601000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7601000 0x0 0x1000>; + no-map; + }; + + shmem2: scmi-shmem@d7602000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7602000 0x0 0x1000>; + no-map; + }; + + shmem3: scmi-shmem@d7603000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7603000 0x0 0x1000>; + no-map; + }; + + shmem4: scmi-shmem@d7604000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7604000 0x0 0x1000>; + no-map; + }; + + shmem5: scmi-shmem@d7605000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7605000 0x0 0x1000>; + no-map; + }; + + shmem6: scmi-shmem@d7606000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7606000 0x0 0x1000>; + no-map; + }; + + shmem7: scmi-shmem@d7607000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7607000 0x0 0x1000>; + no-map; + }; + + shmem8: scmi-shmem@d7608000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7608000 0x0 0x1000>; + no-map; + }; + + shmem9: scmi-shmem@d7609000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7609000 0x0 0x1000>; + no-map; + }; + + shmem10: scmi-shmem@d760a000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd760a000 0x0 0x1000>; + no-map; + }; + + shmem11: scmi-shmem@d760b000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd760b000 0x0 0x1000>; + no-map; + }; + + shmem12: scmi-shmem@d760c000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd760c000 0x0 0x1000>; + no-map; + }; + + shmem13: scmi-shmem@d760d000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd760d000 0x0 0x1000>; + no-map; + }; + + shmem14: scmi-shmem@d760e000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd760e000 0x0 0x1000>; + no-map; + }; + + shmem15: scmi-shmem@d760f000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd760f000 0x0 0x1000>; + no-map; + }; + + shmem16: scmi-shmem@d7610000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7610000 0x0 0x1000>; + no-map; + }; + + shmem17: scmi-shmem@d7611000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7611000 0x0 0x1000>; + no-map; + }; + + shmem18: scmi-shmem@d7612000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7612000 0x0 0x1000>; + no-map; + }; + + shmem19: scmi-shmem@d7613000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7613000 0x0 0x1000>; + no-map; + }; + + shmem20: scmi-shmem@d7614000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7614000 0x0 0x1000>; + no-map; + }; + + shmem21: scmi-shmem@d7615000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7615000 0x0 0x1000>; + no-map; + }; + + shmem22: scmi-shmem@d7616000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7616000 0x0 0x1000>; + no-map; + }; + + shmem23: scmi-shmem@d7617000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7617000 0x0 0x1000>; + no-map; + }; + + shmem24: scmi-shmem@d7618000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7618000 0x0 0x1000>; + no-map; + }; + + shmem25: scmi-shmem@d7619000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7619000 0x0 0x1000>; + no-map; + }; + + shmem26: scmi-shmem@d761a000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd761a000 0x0 0x1000>; + no-map; + }; + + shmem27: scmi-shmem@d761b000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd761b000 0x0 0x1000>; + no-map; + }; + + shmem28: scmi-shmem@d761c000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd761c000 0x0 0x1000>; + no-map; + }; + + shmem29: scmi-shmem@d761d000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd761d000 0x0 0x1000>; + no-map; + }; + + shmem30: scmi-shmem@d761e000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd761e000 0x0 0x1000>; + no-map; + }; + + shmem31: scmi-shmem@d761f000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd761f000 0x0 0x1000>; + no-map; + }; + + shmem32: scmi-shmem@d7620000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7620000 0x0 0x1000>; + no-map; + }; + + shmem33: scmi-shmem@d7621000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7621000 0x0 0x1000>; + no-map; + }; + + shmem34: scmi-shmem@d7622000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7622000 0x0 0x1000>; + no-map; + }; + + shmem35: scmi-shmem@d7623000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7623000 0x0 0x1000>; + no-map; + }; + + shmem36: scmi-shmem@d7624000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7624000 0x0 0x1000>; + no-map; + }; + + shmem37: scmi-shmem@d7625000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7625000 0x0 0x1000>; + no-map; + }; + + shmem38: scmi-shmem@d7626000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7626000 0x0 0x1000>; + no-map; + }; + + shmem39: scmi-shmem@d7627000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7627000 0x0 0x1000>; + no-map; + }; + + shmem40: scmi-shmem@d7628000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7628000 0x0 0x1000>; + no-map; + }; + + shmem41: scmi-shmem@d7629000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7629000 0x0 0x1000>; + no-map; + }; + + shmem42: scmi-shmem@d762a000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd762a000 0x0 0x1000>; + no-map; + }; + + shmem43: scmi-shmem@d762b000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd762b000 0x0 0x1000>; + no-map; + }; + + shmem44: scmi-shmem@d762c000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd762c000 0x0 0x1000>; + no-map; + }; + + shmem45: scmi-shmem@d762d000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd762d000 0x0 0x1000>; + no-map; + }; + + shmem46: scmi-shmem@d762e000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd762e000 0x0 0x1000>; + no-map; + }; + + shmem47: scmi-shmem@d762f000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd762f000 0x0 0x1000>; + no-map; + }; + + shmem48: scmi-shmem@d7630000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7630000 0x0 0x1000>; + no-map; + }; + + shmem49: scmi-shmem@d7631000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7631000 0x0 0x1000>; + no-map; + }; + + shmem50: scmi-shmem@d7632000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7632000 0x0 0x1000>; + no-map; + }; + + shmem51: scmi-shmem@d7633000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7633000 0x0 0x1000>; + no-map; + }; + + shmem52: scmi-shmem@d7634000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7634000 0x0 0x1000>; + no-map; + }; + + shmem53: scmi-shmem@d7635000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7635000 0x0 0x1000>; + no-map; + }; + + shmem54: scmi-shmem@d7636000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7636000 0x0 0x1000>; + no-map; + }; + + shmem55: scmi-shmem@d7637000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7637000 0x0 0x1000>; + no-map; + }; + + shmem56: scmi-shmem@d7638000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7638000 0x0 0x1000>; + no-map; + }; + + shmem57: scmi-shmem@d7639000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd7639000 0x0 0x1000>; + no-map; + }; + + shmem58: scmi-shmem@d763a000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd763a000 0x0 0x1000>; + no-map; + }; + + shmem59: scmi-shmem@d763b000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd763b000 0x0 0x1000>; + no-map; + }; + + shmem60: scmi-shmem@d763c000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd763c000 0x0 0x1000>; + no-map; + }; + + shmem61: scmi-shmem@d763d000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd763d000 0x0 0x1000>; + no-map; + }; + + shmem62: scmi-shmem@d763e000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd763e000 0x0 0x1000>; + no-map; + }; + + shmem63: scmi-shmem@d763f000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0xd763f000 0x0 0x1000>; + no-map; + }; +}; + +&spi0 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 0>, + <&scmi10_dvfs 0>; + power-domain-names = "power", + "perf"; +}; + +&spi1 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 1>, + <&scmi10_dvfs 1>; + power-domain-names = "power", + "perf"; +}; + +&spi2 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 2>, + <&scmi10_dvfs 2>; + power-domain-names = "power", + "perf"; +}; + +&spi3 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 3>, + <&scmi10_dvfs 3>; + power-domain-names = "power", + "perf"; +}; + +&spi4 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 4>, + <&scmi10_dvfs 4>; + power-domain-names = "power", + "perf"; +}; + +&spi5 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 5>, + <&scmi10_dvfs 5>; + power-domain-names = "power", + "perf"; +}; + +&spi7 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 7>, + <&scmi10_dvfs 7>; + power-domain-names = "power", + "perf"; +}; + +&spi8 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 8>, + <&scmi10_dvfs 8>; + power-domain-names = "power", + "perf"; +}; + +&spi11 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 11>, + <&scmi10_dvfs 11>; + power-domain-names = "power", + "perf"; +}; + +&spi12 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 12>, + <&scmi10_dvfs 12>; + power-domain-names = "power", + "perf"; +}; + +&spi13 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 13>, + <&scmi10_dvfs 13>; + power-domain-names = "power", + "perf"; +}; + +&spi14 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 14>, + <&scmi10_dvfs 14>; + power-domain-names = "power", + "perf"; +}; + +&spi15 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 15>, + <&scmi10_dvfs 15>; + power-domain-names = "power", + "perf"; +}; + +&spi16 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 16>, + <&scmi10_dvfs 16>; + power-domain-names = "power", + "perf"; +}; + +&spi17 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 17>, + <&scmi10_dvfs 17>; + power-domain-names = "power", + "perf"; +}; + +&spi18 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 18>, + <&scmi10_dvfs 18>; + power-domain-names = "power", + "perf"; +}; + +&spi19 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 19>, + <&scmi10_dvfs 19>; + power-domain-names = "power", + "perf"; +}; + +&spi20 { + compatible = "qcom,sa8797p-geni-spi", + "qcom,sa8255p-geni-spi"; + power-domains = <&scmi10_pd 20>, + <&scmi10_dvfs 20>; + power-domain-names = "power", + "perf"; +}; + +&uart0 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 0>, + <&scmi11_dvfs 0>; + power-domain-names = "power", + "perf"; +}; + +&uart1 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 1>, + <&scmi11_dvfs 1>; + power-domain-names = "power", + "perf"; +}; + +&uart2 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 2>, + <&scmi11_dvfs 2>; + power-domain-names = "power", + "perf"; +}; + +&uart3 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 3>, + <&scmi11_dvfs 3>; + power-domain-names = "power", + "perf"; +}; + +&uart4 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 4>, + <&scmi11_dvfs 4>; + power-domain-names = "power", + "perf"; +}; + +&uart5 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 5>, + <&scmi11_dvfs 5>; + power-domain-names = "power", + "perf"; +}; + +&uart7 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 7>, + <&scmi11_dvfs 7>; + power-domain-names = "power", + "perf"; +}; + +&uart8 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 8>, + <&scmi11_dvfs 8>; + power-domain-names = "power", + "perf"; +}; + +&uart9 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 9>, + <&scmi11_dvfs 9>; + power-domain-names = "power", + "perf"; +}; + +&uart10 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 10>, + <&scmi11_dvfs 10>; + power-domain-names = "power", + "perf"; +}; + +&uart11 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 11>, + <&scmi11_dvfs 11>; + power-domain-names = "power", + "perf"; +}; + +&uart12 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 12>, + <&scmi11_dvfs 12>; + power-domain-names = "power", + "perf"; +}; + +&uart13 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 13>, + <&scmi11_dvfs 13>; + power-domain-names = "power", + "perf"; +}; + +&uart14 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 14>, + <&scmi11_dvfs 14>; + power-domain-names = "power", + "perf"; +}; + +&uart15 { + compatible = "qcom,sa8797p-geni-debug-uart", + "qcom,sa8255p-geni-debug-uart"; + power-domains = <&scmi11_pd 15>, + <&scmi11_dvfs 15>; + power-domain-names = "power", + "perf"; +}; + +&uart16 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 16>, + <&scmi11_dvfs 16>; + power-domain-names = "power", + "perf"; +}; + +&uart17 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 17>, + <&scmi11_dvfs 17>; + power-domain-names = "power", + "perf"; +}; + +&uart18 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 18>, + <&scmi11_dvfs 18>; + power-domain-names = "power", + "perf"; +}; + +&uart19 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 19>, + <&scmi11_dvfs 19>; + power-domain-names = "power", + "perf"; +}; + +&uart20 { + compatible = "qcom,sa8797p-geni-uart", + "qcom,sa8255p-geni-uart"; + power-domains = <&scmi11_pd 20>, + <&scmi11_dvfs 20>; + power-domain-names = "power", + "perf"; +}; + +&ufs_mem_hc { + compatible = "qcom,sa8797p-ufshc", + "qcom,sa8255p-ufshc"; + power-domains = <&scmi3_pd 0>; +};
diff --git a/arch/arm64/boot/dts/qcom/nord-ride.dts b/arch/arm64/boot/dts/qcom/nord-ride.dts new file mode 100644 index 0000000..1af4117 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/nord-ride.dts
@@ -0,0 +1,254 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; + +#include "nord-gearvm.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. SA8797P Ride"; + compatible = "qcom,sa8797p-ride", "qcom,nord"; + + aliases { + i2c18 = &i2c18; + serial0 = &uart15; + serial1 = &uart4; + spi16 = &spi16; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + clocks { + xo_board_clk: xo-board-clk { + compatible = "fixed-clock"; + clock-frequency = <38400000>; + #clock-cells = <0>; + }; + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + clock-frequency = <32000>; + #clock-cells = <0>; + }; + }; +}; + +&i2c18 { + status = "okay"; +}; + +&scmi3 { + status = "okay"; +}; + +&scmi9 { + status = "okay"; +}; + +&scmi10 { + status = "okay"; +}; + +&scmi11 { + status = "okay"; +}; + +&scmi23 { + status = "okay"; +}; + +&spi16 { + status = "okay"; +}; + +&thermal_zones { + pmic_kobra_thermal: pmic-a-die-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&scmi23_sensor 3>; + + trips { + trip0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + pmic_kai_0_thermal: pmic-e-die-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&scmi23_sensor 4>; + + trips { + trip0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + pmic_kai_1_thermal: pmic-f-die-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&scmi23_sensor 5>; + + trips { + trip0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + pmic_kai_2_thermal: pmic-g-die-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&scmi23_sensor 6>; + + trips { + trip0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + pmic_kai_3_thermal: pmic-h-die-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&scmi23_sensor 7>; + + trips { + trip0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + pmic_kai_4_thermal: pmic-i-die-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&scmi23_sensor 8>; + + trips { + trip0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + pmic_kai_5_thermal: pmic-j-die-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&scmi23_sensor 9>; + + trips { + trip0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + pmic_kai_6_thermal: pmic-k-die-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&scmi23_sensor 10>; + + trips { + trip0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + pmic_kai_7_thermal: pmic-l-die-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&scmi23_sensor 11>; + + trips { + trip0 { + temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + }; + }; + + pmic_kai_ufs_thermal: ufs-thermal { + polling-delay-passive = <0>; + thermal-sensors = <&scmi23_sensor 0>; + + trips { + trip0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + + trip1 { + temperature = <115000>; + hysteresis = <5000>; + type = "critical"; + }; + }; + }; + + pmic_kai_sdram0_thermal: sdram0-thermal { + polling-delay-passive = <0>; + thermal-sensors = <&scmi23_sensor 1>; + + trips { + trip0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + + trip1 { + temperature = <115000>; + hysteresis = <5000>; + type = "critical"; + }; + }; + }; + + pmic_kai_sdram1_thermal: sdram1-thermal { + polling-delay-passive = <0>; + thermal-sensors = <&scmi23_sensor 2>; + + trips { + trip0 { + temperature = <105000>; + hysteresis = <5000>; + type = "passive"; + }; + + trip1 { + temperature = <115000>; + hysteresis = <5000>; + type = "critical"; + }; + }; + }; +}; + +&uart4 { + status = "okay"; +}; + +&uart15 { + status = "okay"; +}; + +&ufs_mem_hc { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/qcom/nord-rrd.dts b/arch/arm64/boot/dts/qcom/nord-rrd.dts new file mode 100644 index 0000000..3673003 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/nord-rrd.dts
@@ -0,0 +1,424 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/regulator/qcom,rpmh-regulator.h> + +#include "nord-embedded.dtsi" + +/ { + model = "Qualcomm Technologies, Inc. IQ10 RRD"; + compatible = "qcom,iq10-rrd", "qcom,nord"; + + aliases { + serial0 = &uart15; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + clocks { + xo_board: xo-board-clk { + compatible = "fixed-clock"; + clock-frequency = <38400000>; + #clock-cells = <0>; + }; + + sleep_clk: sleep-clk { + compatible = "fixed-clock"; + clock-frequency = <32000>; + #clock-cells = <0>; + }; + + bi_tcxo_div2: bi-tcxo-div2-clk { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + clocks = <&rpmhcc RPMH_CXO_CLK>; + clock-mult = <1>; + clock-div = <2>; + }; + + bi_tcxo_ao_div2: bi-tcxo-ao-div2-clk { + compatible = "fixed-factor-clock"; + #clock-cells = <0>; + clocks = <&rpmhcc RPMH_CXO_CLK_A>; + clock-mult = <1>; + clock-div = <2>; + }; + }; +}; + +&apps_rsc { + /* PMIC A - Kobra_MM (PMM8650AU) - SID 0x0, Bus E0 */ + regulators-0 { + compatible = "qcom,pmm8654au-rpmh-regulators"; + qcom,pmic-id = "A_E0"; + + vreg_l4a_1p2: ldo4 { + regulator-name = "vreg_l4a_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6a_1p2: ldo6 { + regulator-name = "vreg_l6a_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7a_1p2: ldo7 { + regulator-name = "vreg_l7a_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; + regulator-boot-on; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l8a_1p8: ldo8 { + regulator-name = "vreg_l8a_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; + regulator-boot-on; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s1a_vdd2h_l: smps1 { + regulator-name = "vreg_s1a_vdd2h_l"; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <1100000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; + regulator-boot-on; + }; + + vreg_s3a_1p8: smps3 { + regulator-name = "vreg_s3a_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; + regulator-boot-on; + }; + + vreg_s5a_mv: smps5 { + regulator-name = "vreg_s5a_mv"; + regulator-min-microvolt = <1328000>; + regulator-max-microvolt = <1370000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; + regulator-boot-on; + }; + + vreg_s6a_vddq_l: smps6 { + regulator-name = "vreg_s6a_vddq_l"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <570000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + /* PMIC E - Kai_MV - SID 0x4, Bus E0 */ + regulators-1 { + compatible = "qcom,pmau0102-rpmh-regulators"; + qcom,pmic-id = "E_E0"; + + vreg_l1e_0p9: ldo1 { + regulator-name = "vreg_l1e_0p9"; + regulator-min-microvolt = <936000>; + regulator-max-microvolt = <936000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2e_0p9: ldo2 { + regulator-name = "vreg_l2e_0p9"; + regulator-min-microvolt = <936000>; + regulator-max-microvolt = <936000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3e_1p8: ldo3 { + regulator-name = "vreg_l3e_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + /* PMIC F - Kai_MV - SID 0x5, Bus E0 */ + regulators-2 { + compatible = "qcom,pmau0102-rpmh-regulators"; + qcom,pmic-id = "F_E0"; + + vreg_l1f_vdd2l: ldo1 { + regulator-name = "vreg_l1f_vdd2l"; + regulator-min-microvolt = <904000>; + regulator-max-microvolt = <904000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; + regulator-boot-on; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3f_vdd1: ldo3 { + regulator-name = "vreg_l3f_vdd1"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; + regulator-boot-on; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s7f_lv_sub: smps7 { + regulator-name = "vreg_s7f_lv_sub"; + regulator-min-microvolt = <1036000>; + regulator-max-microvolt = <1136000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; + regulator-boot-on; + }; + + vreg_s8f_vddq_h: smps8 { + regulator-name = "vreg_s8f_vddq_h"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <570000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + /* PMIC G - Kai_MV - SID 0x6, Bus E0 */ + regulators-3 { + compatible = "qcom,pmau0102-rpmh-regulators"; + qcom,pmic-id = "G_E0"; + + vreg_l2g_0p7: ldo2 { + regulator-name = "vreg_l2g_0p7"; + regulator-min-microvolt = <752000>; + regulator-max-microvolt = <752000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s5g_vdd2h_h: smps5 { + regulator-name = "vreg_s5g_vdd2h_h"; + regulator-min-microvolt = <1080000>; + regulator-max-microvolt = <1150000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; + regulator-boot-on; + }; + }; + + /* PMIC H - Kai_MV - SID 0x7, Bus E0 */ + regulators-4 { + compatible = "qcom,pmau0102-rpmh-regulators"; + qcom,pmic-id = "H_E0"; + + vreg_l1h_0p9: ldo1 { + regulator-name = "vreg_l1h_0p9"; + regulator-min-microvolt = <904000>; + regulator-max-microvolt = <904000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2h_1p2: ldo2 { + regulator-name = "vreg_l2h_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + /* PMIC I - Kai_MV - SID 0x8, Bus E0 */ + regulators-5 { + compatible = "qcom,pmau0102-rpmh-regulators"; + qcom,pmic-id = "I_E0"; + + vreg_l1i_0p9: ldo1 { + regulator-name = "vreg_l1i_0p9"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2i_1p2: ldo2 { + regulator-name = "vreg_l2i_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3i_2p5: ldo3 { + regulator-name = "vreg_l3i_2p5"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <2504000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + /* PMIC K - Kai_MV - SID 0xA, Bus E0 */ + regulators-6 { + compatible = "qcom,pmau0102-rpmh-regulators"; + qcom,pmic-id = "K_E0"; + + vreg_l1k_vdd2l: ldo1 { + regulator-name = "vreg_l1k_vdd2l"; + regulator-min-microvolt = <904000>; + regulator-max-microvolt = <904000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; + regulator-boot-on; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2k_0p9: ldo2 { + regulator-name = "vreg_l2k_0p9"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3k_vdd1: ldo3 { + regulator-name = "vreg_l3k_vdd1"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; + regulator-boot-on; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + /* PMIC L - Kai_MV - SID 0xB, Bus E0 */ + regulators-7 { + compatible = "qcom,pmau0102-rpmh-regulators"; + qcom,pmic-id = "L_E0"; + + vreg_l3l_1p8: ldo3 { + regulator-name = "vreg_l3l_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; +}; + +&i2c7 { + clock-frequency = <400000>; + + status = "okay"; + + rtc@32 { + compatible = "epson,rx8900"; + reg = <0x32>; + }; +}; + +&qupv3_0 { + firmware-name = "qcom/nord/qupv3fw.elf"; + + status = "okay"; +}; + +&qupv3_1 { + firmware-name = "qcom/nord/qupv3fw.elf"; + + status = "okay"; +}; + +&qupv3_2 { + firmware-name = "qcom/nord/qupv3fw.elf"; + + status = "okay"; +}; + +&spi16 { + status = "okay"; +}; + +&uart4 { + status = "okay"; +}; + +&uart15 { + status = "okay"; +}; + +&ufs_mem_hc { + reset-gpios = <&tlmm 181 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l3i_2p5>; + vcc-max-microamp = <1300000>; + vccq-supply = <&vreg_l2i_1p2>; + vccq-max-microamp = <1200000>; + + status = "okay"; +}; + +&ufs_mem_phy { + vdda-phy-supply = <&vreg_l1i_0p9>; + vdda-pll-supply = <&vreg_l2h_1p2>; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/qcom/nord.dtsi b/arch/arm64/boot/dts/qcom/nord.dtsi new file mode 100644 index 0000000..fdbe290 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/nord.dtsi
@@ -0,0 +1,4650 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include <dt-bindings/interrupt-controller/arm-gic.h> + +/ { + interrupt-parent = <&intc>; + #address-cells = <2>; + #size-cells = <2>; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x0>; + enable-method = "psci"; + power-domains = <&cpu0_pd>, <&cpu_perf 0>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; + + l2_0: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; + }; + }; + + cpu1: cpu@100 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x100>; + enable-method = "psci"; + power-domains = <&cpu1_pd>, <&cpu_perf 0>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; + }; + + cpu2: cpu@200 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x200>; + enable-method = "psci"; + power-domains = <&cpu2_pd>, <&cpu_perf 0>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; + }; + + cpu3: cpu@300 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x300>; + enable-method = "psci"; + power-domains = <&cpu3_pd>, <&cpu_perf 0>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; + }; + + cpu4: cpu@400 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x400>; + enable-method = "psci"; + power-domains = <&cpu4_pd>, <&cpu_perf 0>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; + }; + + cpu5: cpu@500 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x500>; + enable-method = "psci"; + power-domains = <&cpu5_pd>, <&cpu_perf 0>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_0>; + #cooling-cells = <2>; + }; + + cpu6: cpu@10000 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x10000>; + power-domains = <&cpu6_pd>, <&cpu_perf 1>; + power-domain-names = "psci", "perf"; + enable-method = "psci"; + next-level-cache = <&l2_10000>; + #cooling-cells = <2>; + + l2_10000: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; + }; + }; + + cpu7: cpu@10100 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x10100>; + enable-method = "psci"; + power-domains = <&cpu7_pd>, <&cpu_perf 1>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_10000>; + #cooling-cells = <2>; + }; + + cpu8: cpu@10200 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x10200>; + enable-method = "psci"; + power-domains = <&cpu8_pd>, <&cpu_perf 1>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_10000>; + #cooling-cells = <2>; + }; + + cpu9: cpu@10300 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x10300>; + enable-method = "psci"; + power-domains = <&cpu9_pd>, <&cpu_perf 1>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_10000>; + #cooling-cells = <2>; + }; + + cpu10: cpu@10400 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x10400>; + enable-method = "psci"; + power-domains = <&cpu10_pd>, <&cpu_perf 1>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_10000>; + #cooling-cells = <2>; + }; + + cpu11: cpu@10500 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x10500>; + enable-method = "psci"; + power-domains = <&cpu11_pd>, <&cpu_perf 1>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_10000>; + #cooling-cells = <2>; + }; + + cpu12: cpu@20000 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x20000>; + enable-method = "psci"; + power-domains = <&cpu12_pd>, <&cpu_perf 2>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_20000>; + #cooling-cells = <2>; + + l2_20000: l2-cache { + compatible = "cache"; + cache-level = <2>; + cache-unified; + }; + }; + + cpu13: cpu@20100 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x20100>; + enable-method = "psci"; + power-domains = <&cpu13_pd>, <&cpu_perf 2>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_20000>; + #cooling-cells = <2>; + }; + + cpu14: cpu@20200 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x20200>; + enable-method = "psci"; + power-domains = <&cpu14_pd>, <&cpu_perf 2>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_20000>; + #cooling-cells = <2>; + }; + + cpu15: cpu@20300 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x20300>; + enable-method = "psci"; + power-domains = <&cpu15_pd>, <&cpu_perf 2>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_20000>; + #cooling-cells = <2>; + }; + + cpu16: cpu@20400 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x20400>; + enable-method = "psci"; + power-domains = <&cpu16_pd>, <&cpu_perf 2>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_20000>; + #cooling-cells = <2>; + }; + + cpu17: cpu@20500 { + device_type = "cpu"; + compatible = "qcom,oryon-1-5"; + reg = <0x0 0x20500>; + enable-method = "psci"; + power-domains = <&cpu17_pd>, <&cpu_perf 2>; + power-domain-names = "psci", "perf"; + next-level-cache = <&l2_20000>; + #cooling-cells = <2>; + }; + + cpu-map { + cluster0 { + core0 { + cpu = <&cpu0>; + }; + + core1 { + cpu = <&cpu1>; + }; + + core2 { + cpu = <&cpu2>; + }; + + core3 { + cpu = <&cpu3>; + }; + + core4 { + cpu = <&cpu4>; + }; + + core5 { + cpu = <&cpu5>; + }; + }; + + cluster1 { + core0 { + cpu = <&cpu6>; + }; + + core1 { + cpu = <&cpu7>; + }; + + core2 { + cpu = <&cpu8>; + }; + + core3 { + cpu = <&cpu9>; + }; + + core4 { + cpu = <&cpu10>; + }; + + core5 { + cpu = <&cpu11>; + }; + }; + + cluster2 { + core0 { + cpu = <&cpu12>; + }; + + core1 { + cpu = <&cpu13>; + }; + + core2 { + cpu = <&cpu14>; + }; + + core3 { + cpu = <&cpu15>; + }; + + core4 { + cpu = <&cpu16>; + }; + + core5 { + cpu = <&cpu17>; + }; + }; + }; + + idle-states { + entry-method = "psci"; + + core_off_c4: cluster-c4 { + compatible = "arm,idle-state"; + idle-state-name = "retention"; + entry-latency-us = <93>; + exit-latency-us = <129>; + min-residency-us = <560>; + arm,psci-suspend-param = <0x00000003>; + }; + }; + + domain-idle-states { + cluster_pwr_dn: cluster-sleep-0 { + compatible = "domain-idle-state"; + arm,psci-suspend-param = <0x01000053>; + entry-latency-us = <2150>; + exit-latency-us = <1983>; + min-residency-us = <9144>; + }; + + domain_ss3: domain-sleep-0 { + compatible = "domain-idle-state"; + arm,psci-suspend-param = <0x02000153>; + entry-latency-us = <2800>; + exit-latency-us = <4400>; + min-residency-us = <10150>; + }; + }; + }; + + firmware: firmware { + scm { + compatible = "qcom,scm-nord", + "qcom,scm"; + qcom,dload-mode = <&tcsr 0x79000>; + }; + + pdp_scmi: scmi { + compatible = "arm,scmi"; + mboxes = <&pdp0_mbox 0>, + <&pdp0_mbox 11>, + <&pdp0_mbox 1>; + mbox-names = "tx", + "tx_reply", + "rx"; + shmem = <&pdp0_a2p>, + <&pdp0_p2a>; + #address-cells = <1>; + #size-cells = <0>; + + cpu_perf: protocol@13 { + reg = <0x13>; + #power-domain-cells = <1>; + }; + }; + }; + + memory@80000000 { + device_type = "memory"; + /* Size will be updated by bootloader */ + reg = <0x0 0x80000000 0x0 0x0>; + }; + + pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + + cpu0_pd: power-domain-cpu0 { + #power-domain-cells = <0>; + power-domains = <&cluster0_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu1_pd: power-domain-cpu1 { + #power-domain-cells = <0>; + power-domains = <&cluster0_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu2_pd: power-domain-cpu2 { + #power-domain-cells = <0>; + power-domains = <&cluster0_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu3_pd: power-domain-cpu3 { + #power-domain-cells = <0>; + power-domains = <&cluster0_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu4_pd: power-domain-cpu4 { + #power-domain-cells = <0>; + power-domains = <&cluster0_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu5_pd: power-domain-cpu5 { + #power-domain-cells = <0>; + power-domains = <&cluster0_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu6_pd: power-domain-cpu6 { + #power-domain-cells = <0>; + power-domains = <&cluster1_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu7_pd: power-domain-cpu7 { + #power-domain-cells = <0>; + power-domains = <&cluster1_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu8_pd: power-domain-cpu8 { + #power-domain-cells = <0>; + power-domains = <&cluster1_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu9_pd: power-domain-cpu9 { + #power-domain-cells = <0>; + power-domains = <&cluster1_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu10_pd: power-domain-cpu10 { + #power-domain-cells = <0>; + power-domains = <&cluster1_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu11_pd: power-domain-cpu11 { + #power-domain-cells = <0>; + power-domains = <&cluster1_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu12_pd: power-domain-cpu12 { + #power-domain-cells = <0>; + power-domains = <&cluster2_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu13_pd: power-domain-cpu13 { + #power-domain-cells = <0>; + power-domains = <&cluster2_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu14_pd: power-domain-cpu14 { + #power-domain-cells = <0>; + power-domains = <&cluster2_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu15_pd: power-domain-cpu15 { + #power-domain-cells = <0>; + power-domains = <&cluster2_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu16_pd: power-domain-cpu16 { + #power-domain-cells = <0>; + power-domains = <&cluster2_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cpu17_pd: power-domain-cpu17 { + #power-domain-cells = <0>; + power-domains = <&cluster2_pd>; + domain-idle-states = <&core_off_c4>; + }; + + cluster0_pd: power-domain-cluster0 { + #power-domain-cells = <0>; + power-domains = <&system_pd>; + domain-idle-states = <&cluster_pwr_dn>; + }; + + cluster1_pd: power-domain-cluster1 { + #power-domain-cells = <0>; + power-domains = <&system_pd>; + domain-idle-states = <&cluster_pwr_dn>; + }; + + cluster2_pd: power-domain-cluster2 { + #power-domain-cells = <0>; + power-domains = <&system_pd>; + domain-idle-states = <&cluster_pwr_dn>; + }; + + system_pd: power-domain-system { + #power-domain-cells = <0>; + domain-idle-states = <&domain_ss3>; + }; + }; + + reserved_memory: reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + cpucp_scandump_mem: cpucp-scandump-region@80000000 { + reg = <0x0 0x80000000 0x0 0x800000>; + no-map; + }; + + tme_sail_mem: tme-sail-region@81ff0000 { + reg = <0x0 0x81ff0000 0x0 0x10000>; + no-map; + }; + + tz_sail_mailbox_mem: tz-sail-mailbox-region@82000000 { + reg = <0x0 0x82000000 0x0 0x8000>; + no-map; + }; + + sail_mailbox_mem: sail-mailbox-region@82008000 { + reg = <0x0 0x82008000 0x0 0x1f8000>; + no-map; + }; + + sail_ota_mem: sail-ota-region@82200000 { + reg = <0x0 0x82200000 0x0 0x5ff000>; + no-map; + }; + + sail_vdt_mem: sail-vdt-region@827ff000 { + reg = <0x0 0x827ff000 0x0 0x1000>; + no-map; + }; + + hyp_mem: hyp-region@82800000 { + reg = <0x0 0x82800000 0x0 0x2400000>; + no-map; + }; + + deepsleep_mem: deepsleep-region@84c00000 { + reg = <0x0 0x84c00000 0x0 0x800000>; + no-map; + }; + + deepsleep_backup_mem: deepsleep-backup-region@86a00000 { + reg = <0x0 0x86a00000 0x0 0x200000>; + no-map; + }; + + soccp_fe_vm_0: soccp-fe-vm-0-region@86c00000 { + reg = <0x0 0x86c00000 0x0 0xac000>; + no-map; + }; + + soccp_fe_vm_1: soccp-fe-vm-1-region@86cac000 { + reg = <0x0 0x86cac000 0x0 0x18d000>; + no-map; + }; + + soccp_fe_vm_2: soccp-fe-vm-2-region@86e39000 { + reg = <0x0 0x86e39000 0x0 0x1c7000>; + no-map; + }; + + tme_crash_dump_mem: tme-crash-dump-region@87000000 { + reg = <0x0 0x87000000 0x0 0xa0000>; + no-map; + }; + + tme_log_mem: tme-log-region@87140000 { + reg = <0x0 0x87140000 0x0 0x4000>; + no-map; + }; + + aop_cmd_db_p_mem: aop-cmd-db-p-region@87148000 { + compatible = "qcom,cmd-db"; + reg = <0x0 0x87148000 0x0 0x20000>; + no-map; + }; + + nsp_sync_buffer_mem: nsp-sync-buffer-region@871ff000 { + reg = <0x0 0x871ff000 0x0 0x1000>; + no-map; + }; + + ddr_training_checksum_data_mem: ddr-training-checksum-data-region@87200000 { + reg = <0x0 0x87200000 0x0 0x2000>; + no-map; + }; + + xbl_dtlog_mem: xbl-dtlog-region@87202000 { + reg = <0x0 0x87202000 0x0 0x60000>; + no-map; + }; + + xbl_ramdump_mem: xbl-ramdump-region@87262000 { + reg = <0x0 0x87262000 0x0 0x1c0000>; + no-map; + }; + + uefi_log: uefi-log@87442000 { + reg = <0x0 0x87442000 0x0 0x10000>; + no-map; + }; + + secdata_apss_mem: secdata-apss-region@87452000 { + reg = <0x0 0x87452000 0x0 0x1000>; + no-map; + }; + + antireplay_emulation_mem: antireplay-emulation-region@87453000 { + reg = <0x0 0x87453000 0x0 0x1000>; + no-map; + }; + + soccp_sdi_mem: soccp-sdi-region@87454000 { + reg = <0x0 0x87454000 0x0 0x40000>; + no-map; + }; + + hyp_mem_database_mem: hyp-mem-database-region@87494000 { + reg = <0x0 0x87494000 0x0 0x60000>; + no-map; + }; + + pmic_mini_dump_mem: pmic-mini-dump-region@874f4000 { + reg = <0x0 0x874f4000 0x0 0x80000>; + no-map; + }; + + qup_fw_mem: qup-fw-region@87574000 { + reg = <0x0 0x87574000 0x0 0x20000>; + no-map; + }; + + softsku_mem: softsku-region@87594000 { + reg = <0x0 0x87594000 0x0 0x9000>; + no-map; + }; + + resource_scheduler_mem: resource-scheduler-region@8759d000 { + reg = <0x0 0x8759d000 0x0 0x20000>; + no-map; + }; + + pdp_ns_mem: pdp-ns-mem-region@87600000 { + reg = <0x0 0x87600000 0x0 0x8000>, + <0x0 0x87609000 0x0 0x1f7000>; + no-map; + }; + + pdp0_p2a: scmi-shmem@87608000 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x87608000 0x0 0x80>; + no-map; + }; + + pdp0_a2p: scmi-shmem@87608180 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x87608180 0x0 0x80>; + no-map; + }; + + tz_stat_mem: tz-stat-region@87a00000 { + reg = <0x0 0x87a00000 0x0 0x100000>; + no-map; + }; + + qdss_apps_mem: qdss-apps-region@87b00000 { + reg = <0x0 0x87b00000 0x0 0x2000000>; + no-map; + }; + + global_sync_mem: global-sync-region@89f00000 { + reg = <0x0 0x89f00000 0x0 0x400000>; + no-map; + }; + + tzffi_mem: tzffi-region@8a300000 { + compatible = "shared-dma-pool"; + reg = <0x0 0x8a300000 0x0 0x1400000>; + no-map; + }; + + gunyah_md_mem: gunyah-md-region@8b700000 { + reg = <0x0 0x8b700000 0x0 0x80000>; + no-map; + }; + + flashless_qntm_tool_mem: flashless-qntm-tool-region@8b780000 { + reg = <0x0 0x8b780000 0x0 0x182000>; + no-map; + }; + + ipa_fw_mem: ipa-fw-region@8bb00000 { + reg = <0x0 0x8bb00000 0x0 0x10000>; + no-map; + }; + + ipa_gsi_mem: ipa-gsi-region@8bb10000 { + reg = <0x0 0x8bb10000 0x0 0xa000>; + no-map; + }; + + gpu_microcode_mem: gpu-microcode-region@8bb1a000 { + reg = <0x0 0x8bb1a000 0x0 0x2000>; + no-map; + }; + + gpu_microcode_2_mem: gpu-microcode-2-region@8bb1c000 { + reg = <0x0 0x8bb1c000 0x0 0x2000>; + no-map; + }; + + soccp_mem: soccp-region@8bc00000 { + reg = <0x0 0x8bc00000 0x0 0x300000>; + no-map; + }; + + cvp_mem: cvp-region@8d100000 { + reg = <0x0 0x8d100000 0x0 0x800000>; + no-map; + }; + + cdsp0_mem: cdsp0-region@8d900000 { + reg = <0x0 0x8d900000 0x0 0x2300000>; + no-map; + }; + + cdsp1_mem: cdsp1-region@8fc00000 { + reg = <0x0 0x8fc00000 0x0 0x2300000>; + no-map; + }; + + cdsp2_mem: cdsp2-region@91f00000 { + reg = <0x0 0x91f00000 0x0 0x2300000>; + no-map; + }; + + cdsp3_mem: cdsp3-region@94200000 { + reg = <0x0 0x94200000 0x0 0x2300000>; + no-map; + }; + + hpass_dsp0_mem: hpass-dsp0-region@96500000 { + reg = <0x0 0x96500000 0x0 0x2800000>; + no-map; + }; + + hpass_dsp1_mem: hpass-dsp1-region@98d00000 { + reg = <0x0 0x98d00000 0x0 0x2800000>; + no-map; + }; + + hpass_dsp2_mem: hpass-dsp2-region@9b500000 { + reg = <0x0 0x9b500000 0x0 0x2800000>; + no-map; + }; + + q6_cdsp0_dtb_mem: q6-cdsp0-dtb-region@9dd00000 { + reg = <0x0 0x9dd00000 0x0 0x80000>; + no-map; + }; + + q6_cdsp1_dtb_mem: q6-cdsp1-dtb-region@9dd80000 { + reg = <0x0 0x9dd80000 0x0 0x80000>; + no-map; + }; + + q6_cdsp2_dtb_mem: q6-cdsp2-dtb-region@9de00000 { + reg = <0x0 0x9de00000 0x0 0x80000>; + no-map; + }; + + q6_cdsp3_dtb_mem: q6-cdsp3-dtb-region@9de80000 { + reg = <0x0 0x9de80000 0x0 0x80000>; + no-map; + }; + + hpass_dsp0_dtb_mem: hpass-dsp0-dtb-region@9df00000 { + reg = <0x0 0x9df00000 0x0 0x80000>; + no-map; + }; + + hpass_dsp1_dtb_mem: hpass-dsp1-dtb-region@9df80000 { + reg = <0x0 0x9df80000 0x0 0x80000>; + no-map; + }; + + hpass_dsp2_dtb_mem: hpass-dsp2-dtb-region@9e000000 { + reg = <0x0 0x9e000000 0x0 0x100000>; + no-map; + }; + + camera_icp_1_mem: camera-icp-1-region@9e100000 { + reg = <0x0 0x9e100000 0x0 0x800000>; + no-map; + }; + + camera_icp_2_mem: camera-icp-2-region@9e900000 { + reg = <0x0 0x9e900000 0x0 0x800000>; + no-map; + }; + + camera_qup_1_mem: camera-qup-1-region@9f100000 { + reg = <0x0 0x9f100000 0x0 0x200000>; + no-map; + }; + + camera_qup_2_mem: camera-qup-2-region@9f300000 { + reg = <0x0 0x9f300000 0x0 0x200000>; + no-map; + }; + + video_mem: video-region@9f500000 { + reg = <0x0 0x9f500000 0x0 0xc00000>; + no-map; + }; + + pil_umd_reserved: mdt-load-region@a0100000 { + reg = <0x0 0xa0100000 0x0 0x100000>; + no-map; + }; + + mm_dspq: mm-dspq-region@ba200000 { + reg = <0x0 0xba200000 0x0 0x200000>; + no-map; + }; + + display_config_reserved: display-config-region@ba400000 { + reg = <0x0 0xba400000 0x0 0xa00000>; + no-map; + }; + + mm_calibration_data_mem: mm-calibration-data-region@bae00000 { + reg = <0x0 0xbae00000 0x0 0x800000>; + no-map; + }; + + audio_config_mem: audio-config-region@bb600000 { + reg = <0x0 0xbb600000 0x0 0xa00000>; + no-map; + }; + + dare_tz_mem: dare-tz-region@bc000000 { + reg = <0x0 0xbc000000 0x0 0xa300000>; + no-map; + }; + + hpass_rpc_remote_heap_mem: hpass-rpc-remote-heap-region@d4600000 { + reg = <0x0 0xd4600000 0x0 0x800000>; + no-map; + }; + + mdf_mem: mdf-region@d4e00000 { + reg = <0x0 0xd4e00000 0x0 0x2000000>; + no-map; + }; + + firmware_mem: firmware-region@d6e00000 { + reg = <0x0 0xd6e00000 0x0 0x800000>; + no-map; + }; + + firmware_shared_mem: firmware-shared-region@d7650000 { + reg = <0x0 0xd7650000 0x0 0x180000>; + no-map; + }; + + firmware_logs_mem: firmware-logs-region@d77d0000 { + reg = <0x0 0xd77d0000 0x0 0x20000>; + no-map; + }; + + sail_p_mem: sail-p-region@8c0000000 { + reg = <0x8 0xc0000000 0x0 0x8000000>; + no-map; + }; + + reserved_mem2: reserved-region@8c8000000 { + reg = <0x8 0xc8000000 0x0 0x18000000>; + no-map; + }; + + dump_mem: mem-dump-region { + alloc-ranges = <0x0 0x00000000 0x0 0xffffffff>; + size = <0x0 0x79b0000>; + }; + }; + + soc: soc@0 { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + dma-ranges = <0 0 0 0 0x10 0>; + ranges = <0 0 0 0 0x10 0>; + + qupv3_2: geniqup@8c0000 { + compatible = "qcom,geni-se-qup"; + reg = <0x0 0x008c0000 0x0 0x2000>; + #address-cells = <2>; + #size-cells = <2>; + iommus = <&apps_smmu_0 0x15a3 0x0>; + ranges; + + i2c14: i2c@880000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00880000 0x0 0x4000>; + interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi14: spi@880000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00880000 0x0 0x4000>; + interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart14: serial@880000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00880000 0x0 0x4000>; + interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c15: i2c@884000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00884000 0x0 0x4000>; + interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi15: spi@884000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00884000 0x0 0x4000>; + interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart15: serial@884000 { + compatible = "qcom,geni-debug-uart"; + reg = <0x0 0x00884000 0x0 0x4000>; + interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c16: i2c@888000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00888000 0x0 0x4000>; + interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi16: spi@888000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00888000 0x0 0x4000>; + interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart16: serial@888000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00888000 0x0 0x4000>; + interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c17: i2c@88c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x0088c000 0x0 0x4000>; + interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi17: spi@88c000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x0088c000 0x0 0x4000>; + interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart17: serial@88c000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x0088c000 0x0 0x4000>; + interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c18: i2c@890000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00890000 0x0 0x4000>; + interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi18: spi@890000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00890000 0x0 0x4000>; + interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart18: serial@890000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00890000 0x0 0x4000>; + interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c19: i2c@894000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00894000 0x0 0x4000>; + interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi19: spi@894000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00894000 0x0 0x4000>; + interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart19: serial@894000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00894000 0x0 0x4000>; + interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c20: i2c@898000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00898000 0x0 0x4000>; + interrupts = <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi20: spi@898000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00898000 0x0 0x4000>; + interrupts = <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart20: serial@898000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00898000 0x0 0x4000>; + interrupts = <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + }; + + qupv3_0: geniqup@9c0000 { + compatible = "qcom,geni-se-qup"; + reg = <0x0 0x009c0000 0x0 0x2000>; + #address-cells = <2>; + #size-cells = <2>; + iommus = <&apps_smmu_2 0x1003 0x0>; + ranges; + + i2c0: i2c@980000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00980000 0x0 0x4000>; + interrupts = <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi0: spi@980000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00980000 0x0 0x4000>; + interrupts = <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart0: serial@980000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00980000 0x0 0x4000>; + interrupts = <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c1: i2c@984000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00984000 0x0 0x4000>; + interrupts = <GIC_SPI 513 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi1: spi@984000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00984000 0x0 0x4000>; + interrupts = <GIC_SPI 513 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart1: serial@984000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00984000 0x0 0x4000>; + interrupts = <GIC_SPI 513 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c2: i2c@988000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00988000 0x0 0x4000>; + interrupts = <GIC_SPI 514 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi2: spi@988000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00988000 0x0 0x4000>; + interrupts = <GIC_SPI 514 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart2: serial@988000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00988000 0x0 0x4000>; + interrupts = <GIC_SPI 514 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c3: i2c@98c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x0098c000 0x0 0x4000>; + interrupts = <GIC_SPI 515 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi3: spi@98c000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x0098c000 0x0 0x4000>; + interrupts = <GIC_SPI 515 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart3: serial@98c000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x0098c000 0x0 0x4000>; + interrupts = <GIC_SPI 515 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c4: i2c@990000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00990000 0x0 0x4000>; + interrupts = <GIC_SPI 516 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi4: spi@990000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00990000 0x0 0x4000>; + interrupts = <GIC_SPI 516 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart4: serial@990000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00990000 0x0 0x4000>; + interrupts = <GIC_SPI 516 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c5: i2c@994000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00994000 0x0 0x4000>; + interrupts = <GIC_SPI 517 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi5: spi@994000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00994000 0x0 0x4000>; + interrupts = <GIC_SPI 517 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart5: serial@994000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00994000 0x0 0x4000>; + interrupts = <GIC_SPI 517 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + }; + + qupv3_1: geniqup@ac0000 { + compatible = "qcom,geni-se-qup"; + reg = <0x0 0x00ac0000 0x0 0x2000>; + #address-cells = <2>; + #size-cells = <2>; + iommus = <&apps_smmu_2 0x1043 0x0>; + ranges; + + i2c7: i2c@a80000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a80000 0x0 0x4000>; + interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi7: spi@a80000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a80000 0x0 0x4000>; + interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart7: serial@a80000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00a80000 0x0 0x4000>; + interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c8: i2c@a84000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a84000 0x0 0x4000>; + interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi8: spi@a84000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a84000 0x0 0x4000>; + interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart8: serial@a84000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00a84000 0x0 0x4000>; + interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c9: i2c@a88000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a88000 0x0 0x4000>; + interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart9: serial@a88000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00a88000 0x0 0x4000>; + interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c10: i2c@a8c000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a8c000 0x0 0x4000>; + interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + uart10: serial@a8c000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00a8c000 0x0 0x4000>; + interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c11: i2c@a90000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a90000 0x0 0x4000>; + interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi11: spi@a90000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a90000 0x0 0x4000>; + interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart11: serial@a90000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00a90000 0x0 0x4000>; + interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c12: i2c@a94000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a94000 0x0 0x4000>; + interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi12: spi@a94000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a94000 0x0 0x4000>; + interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart12: serial@a94000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00a94000 0x0 0x4000>; + interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + i2c13: i2c@a98000 { + compatible = "qcom,geni-i2c"; + reg = <0x0 0x00a98000 0x0 0x4000>; + interrupts = <GIC_SPI 363 IRQ_TYPE_LEVEL_HIGH>; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + }; + + spi13: spi@a98000 { + compatible = "qcom,geni-spi"; + reg = <0x0 0x00a98000 0x0 0x4000>; + interrupts = <GIC_SPI 363 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + + uart13: serial@a98000 { + compatible = "qcom,geni-uart"; + reg = <0x0 0x00a98000 0x0 0x4000>; + interrupts = <GIC_SPI 363 IRQ_TYPE_LEVEL_HIGH>; + + status = "disabled"; + }; + }; + + rng: rng@10c3000 { + compatible = "qcom,nord-trng", + "qcom,trng"; + reg = <0x0 0x010c3000 0x0 0x1000>; + }; + + ufs_mem_hc: ufshc@1d44000 { + compatible = "qcom,nord-ufshc", + "qcom,ufshc", + "jedec,ufs-2.0"; + reg = <0x0 0x01d44000 0x0 0x3000>, + <0x0 0x01d60000 0x0 0x15000>; + reg-names = "std", + "mcq"; + interrupts = <GIC_SPI 265 IRQ_TYPE_LEVEL_HIGH>; + lanes-per-direction = <2>; + iommus = <&apps_smmu_0 0x14c0 0x0>; + dma-coherent; + msi-parent = <&gic_its 0x14c0>; + + status = "disabled"; + }; + + cryptobam: dma-controller@1dc4000 { + compatible = "qcom,bam-v1.7.4", "qcom,bam-v1.7.0"; + reg = <0x0 0x01dc4000 0x0 0x28000>; + interrupts = <GIC_SPI 272 IRQ_TYPE_LEVEL_HIGH>; + #dma-cells = <1>; + iommus = <&apps_smmu_0 0x1689 0>; + qcom,ee = <0>; + qcom,num-ees = <4>; + num-channels = <20>; + qcom,controlled-remotely; + }; + + crypto: crypto@1dfa000 { + compatible = "qcom,nord-qce", "qcom,sm8150-qce", "qcom,qce"; + reg = <0x0 0x01dfa000 0x0 0x6000>; + dmas = <&cryptobam 4>, <&cryptobam 5>; + dma-names = "rx", "tx"; + iommus = <&apps_smmu_0 0x1689 0>; + + /* It stops nord-gearvm variant from booting to console */ + status = "disabled"; + }; + + tcsr_mutex: hwlock@1f40000 { + compatible = "qcom,tcsr-mutex"; + reg = <0x0 0x01f40000 0x0 0x20000>; + #hwlock-cells = <1>; + }; + + tcsr: syscon@1f60000 { + compatible = "qcom,nord-tcsr", + "syscon"; + reg = <0x0 0x01f60000 0x0 0xa0000>; + }; + + pdc: interrupt-controller@b220000 { + compatible = "qcom,nord-pdc", + "qcom,pdc"; + reg = <0x0 0x0b220000 0x0 0x10000>; + qcom,pdc-ranges = <0 745 43>, + <67 543 31>, + <98 609 32>, + <130 717 12>, + <142 251 5>, + <147 796 16>; + #interrupt-cells = <2>; + interrupt-parent = <&intc>; + interrupt-controller; + }; + + tsens0: thermal-sensor@c22c000 { + compatible = "qcom,nord-tsens", + "qcom,tsens-v2"; + reg = <0x0 0x0c22c000 0x0 0x1000>, + <0x0 0x0c222000 0x0 0x1000>; + interrupts = <GIC_SPI 771 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 484 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <16>; + #thermal-sensor-cells = <1>; + }; + + tsens1: thermal-sensor@c22d000 { + compatible = "qcom,nord-tsens", + "qcom,tsens-v2"; + reg = <0x0 0x0c22d000 0x0 0x1000>, + <0x0 0x0c223000 0x0 0x1000>; + interrupts = <GIC_SPI 772 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 485 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <16>; + #thermal-sensor-cells = <1>; + }; + + tsens2: thermal-sensor@c22e000 { + compatible = "qcom,nord-tsens", + "qcom,tsens-v2"; + reg = <0x0 0x0c22e000 0x0 0x1000>, + <0x0 0x0c224000 0x0 0x1000>; + interrupts = <GIC_SPI 773 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <16>; + #thermal-sensor-cells = <1>; + }; + + tsens3: thermal-sensor@c22f000 { + compatible = "qcom,nord-tsens", + "qcom,tsens-v2"; + reg = <0x0 0x0c22f000 0x0 0x1000>, + <0x0 0x0c225000 0x0 0x1000>; + interrupts = <GIC_SPI 774 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <16>; + #thermal-sensor-cells = <1>; + }; + + tsens4: thermal-sensor@c230000 { + compatible = "qcom,nord-tsens", + "qcom,tsens-v2"; + reg = <0x0 0x0c230000 0x0 0x1000>, + <0x0 0x0c226000 0x0 0x1000>; + interrupts = <GIC_SPI 775 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 399 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <16>; + #thermal-sensor-cells = <1>; + }; + + tsens5: thermal-sensor@c231000 { + compatible = "qcom,nord-tsens", + "qcom,tsens-v2"; + reg = <0x0 0x0c231000 0x0 0x1000>, + <0x0 0x0c227000 0x0 0x1000>; + interrupts = <GIC_SPI 776 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 400 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <16>; + #thermal-sensor-cells = <1>; + }; + + tsens6: thermal-sensor@c232000 { + compatible = "qcom,nord-tsens", + "qcom,tsens-v2"; + reg = <0x0 0x0c232000 0x0 0x1000>, + <0x0 0x0c228000 0x0 0x1000>; + interrupts = <GIC_SPI 777 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 401 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <16>; + #thermal-sensor-cells = <1>; + }; + + tsens7: thermal-sensor@c233000 { + compatible = "qcom,nord-tsens", + "qcom,tsens-v2"; + reg = <0x0 0x0c233000 0x0 0x1000>, + <0x0 0x0c229000 0x0 0x1000>; + interrupts = <GIC_SPI 778 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 402 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "uplow", + "critical"; + #qcom,sensors = <16>; + #thermal-sensor-cells = <1>; + }; + + tlmm: pinctrl@f100000 { + compatible = "qcom,nord-tlmm"; + reg = <0x0 0x0f100000 0x0 0xc0000>; + interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + gpio-ranges = <&tlmm 0 0 181>; + wakeup-parent = <&pdc>; + }; + + apps_smmu_0: iommu@15a00000 { + compatible = "qcom,nord-smmu-500", + "qcom,smmu-500", + "arm,mmu-500"; + reg = <0x0 0x15a00000 0x0 0x100000>; + #iommu-cells = <2>; + #global-interrupts = <1>; + dma-coherent; + interrupts = <GIC_SPI 886 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 32 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 33 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 34 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 35 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 36 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 37 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 38 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 39 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 40 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 41 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 42 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 43 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 44 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 45 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 46 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 47 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 48 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 49 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 50 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 51 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 52 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 53 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 54 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 55 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 56 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 57 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 58 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 59 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 60 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 61 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 62 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 63 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 64 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 65 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 66 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 67 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 68 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 69 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 70 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 71 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 72 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 73 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 74 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 75 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 76 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 77 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 78 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 79 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 80 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 81 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 82 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 83 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 84 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 85 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 86 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 87 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 88 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 89 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 90 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 91 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 92 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 93 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 94 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 95 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 96 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 97 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 98 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 99 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 100 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 101 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 102 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 103 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 104 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 105 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 106 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 107 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 108 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 109 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 110 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 111 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 112 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 113 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 114 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 115 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 116 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 117 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 118 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 119 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 120 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 121 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 122 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 123 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 124 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 125 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 126 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 127 IRQ_TYPE_LEVEL_HIGH>; + }; + + apps_smmu_1: iommu@15c00000 { + compatible = "qcom,nord-smmu-500", + "qcom,smmu-500", + "arm,mmu-500"; + reg = <0x0 0x15c00000 0x0 0x100000>; + #iommu-cells = <2>; + #global-interrupts = <1>; + dma-coherent; + interrupts = <GIC_SPI 882 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 128 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 129 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 130 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 131 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 132 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 133 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 134 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 135 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 136 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 137 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 138 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 139 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 140 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 141 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 142 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 143 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 144 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 145 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 146 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 147 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 148 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 149 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 150 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 151 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 152 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 153 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 154 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 155 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 156 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 157 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 158 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 159 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 160 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 161 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 162 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 163 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 164 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 165 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 166 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 167 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 168 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 169 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 170 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 171 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 172 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 173 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 174 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 175 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 176 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 177 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 178 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 179 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 180 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 181 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 182 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 183 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 184 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 185 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 186 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 187 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 188 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 189 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 190 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 191 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 192 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 193 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 194 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 195 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 196 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 197 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 198 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 199 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 200 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 201 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 202 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 203 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 204 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 205 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 206 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 207 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 208 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 209 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 210 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 211 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 212 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 213 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 214 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 215 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 216 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 217 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 218 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 219 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 220 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 221 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 222 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 223 IRQ_TYPE_LEVEL_HIGH>; + }; + + apps_smmu_2: iommu@15e00000 { + compatible = "qcom,nord-smmu-500", + "qcom,smmu-500", + "arm,mmu-500"; + reg = <0x0 0x15e00000 0x0 0x100000>; + #iommu-cells = <2>; + #global-interrupts = <1>; + dma-coherent; + interrupts = <GIC_SPI 877 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 224 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 225 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 226 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 227 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 228 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 229 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 230 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 231 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 232 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 233 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 234 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 235 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 236 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 237 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 238 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 239 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 240 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 241 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 242 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 243 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 244 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 245 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 246 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 247 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 248 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 249 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 250 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 251 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 252 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 253 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 254 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 255 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 256 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 257 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 258 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 259 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 260 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 261 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 262 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 263 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 264 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 265 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 266 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 267 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 268 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 269 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 270 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 271 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 272 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 273 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 274 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 275 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 276 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 277 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 278 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 279 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 280 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 281 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 282 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 283 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 284 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 285 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 286 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 287 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 288 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 289 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 290 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 291 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 292 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 293 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 294 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 295 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 296 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 297 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 298 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 299 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 300 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 301 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 302 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 303 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 304 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 305 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 306 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 307 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 308 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 309 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 310 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 311 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 312 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 313 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 314 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 315 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 316 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 317 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 318 IRQ_TYPE_LEVEL_HIGH>, + <GIC_ESPI 319 IRQ_TYPE_LEVEL_HIGH>; + }; + + intc: interrupt-controller@17000000 { + compatible = "arm,gic-v3"; + reg = <0x0 0x17000000 0x0 0x10000>, + <0x0 0x17080000 0x0 0x480000>; + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + #interrupt-cells = <3>; + interrupt-controller; + #redistributor-regions = <1>; + redistributor-stride = <0x0 0x40000>; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + gic_its: msi-controller@17040000 { + compatible = "arm,gic-v3-its"; + reg = <0x0 0x17040000 0x0 0x40000>; + msi-controller; + #msi-cells = <1>; + }; + }; + + pdp0_mbox: mailbox@17610000 { + compatible = "qcom,nord-cpucp-mbox", + "qcom,x1e80100-cpucp-mbox"; + reg = <0x0 0x17610000 0x0 0x4c08>, + <0x0 0x19980000 0x0 0x300>; + #mbox-cells = <1>; + interrupts = <GIC_SPI 56 IRQ_TYPE_LEVEL_HIGH>; + }; + + memtimer: timer@17810000 { + compatible = "arm,armv7-timer-mem"; + reg = <0x0 0x17810000 0x0 0x1000>; + ranges = <0x0 0x0 0x0 0x20000000>; + #address-cells = <1>; + #size-cells = <1>; + + frame@17811000 { + reg = <0x17811000 0x1000>, + <0x17812000 0x1000>; + interrupts = <GIC_SPI 38 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 31 IRQ_TYPE_LEVEL_HIGH>; + frame-number = <0>; + }; + + frame@17813000 { + reg = <0x17813000 0x1000>; + interrupts = <GIC_SPI 39 IRQ_TYPE_LEVEL_HIGH>; + frame-number = <1>; + + status = "disabled"; + }; + + frame@17815000 { + reg = <0x17815000 0x1000>; + interrupts = <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>; + frame-number = <2>; + + status = "disabled"; + }; + + frame@17817000 { + reg = <0x17817000 0x1000>; + interrupts = <GIC_SPI 41 IRQ_TYPE_LEVEL_HIGH>; + frame-number = <3>; + + status = "disabled"; + }; + + frame@17819000 { + reg = <0x17819000 0x1000>; + interrupts = <GIC_SPI 42 IRQ_TYPE_LEVEL_HIGH>; + frame-number = <4>; + + status = "disabled"; + }; + + frame@1781b000 { + reg = <0x1781b000 0x1000>; + interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH>; + frame-number = <5>; + + status = "disabled"; + }; + + frame@1781d000 { + reg = <0x1781d000 0x1000>; + interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>; + frame-number = <6>; + + status = "disabled"; + }; + }; + + watchdog@17826000 { + compatible = "qcom,apss-wdt-nord", + "qcom,kpss-wdt"; + reg = <0x0 0x17826000 0x0 0x1000>; + clocks = <&sleep_clk>; + interrupts = <GIC_ESPI 848 IRQ_TYPE_EDGE_RISING>; + }; + + llcc: system-cache-controller@21800000 { + compatible = "qcom,nord-llcc"; + reg = <0x0 0x21800000 0x0 0x100000>, + <0x0 0x21a00000 0x0 0x100000>, + <0x0 0x21c00000 0x0 0x100000>, + <0x0 0x21e00000 0x0 0x100000>, + <0x0 0x22800000 0x0 0x100000>, + <0x0 0x22a00000 0x0 0x100000>, + <0x0 0x22c00000 0x0 0x100000>, + <0x0 0x22e00000 0x0 0x100000>, + <0x0 0x23800000 0x0 0x100000>, + <0x0 0x23a00000 0x0 0x100000>, + <0x0 0x23c00000 0x0 0x100000>, + <0x0 0x23e00000 0x0 0x100000>, + <0x0 0x24800000 0x0 0x100000>, + <0x0 0x24a00000 0x0 0x100000>, + <0x0 0x24c00000 0x0 0x100000>, + <0x0 0x24e00000 0x0 0x100000>, + <0x0 0x20400000 0x0 0x100000>, + <0x0 0x20600000 0x0 0x100000>; + reg-names = "llcc0_base", + "llcc1_base", + "llcc2_base", + "llcc3_base", + "llcc4_base", + "llcc5_base", + "llcc6_base", + "llcc7_base", + "llcc8_base", + "llcc9_base", + "llcc10_base", + "llcc11_base", + "llcc12_base", + "llcc13_base", + "llcc14_base", + "llcc15_base", + "llcc_broadcast_base", + "llcc_broadcast_and_base"; + }; + }; + + arch_timer: timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, + <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, + <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, + <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; + }; + + thermal_zones: thermal-zones { + ddr-0-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 0>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-0-0-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 1>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-0-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 2>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-0-2-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 3>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-0-3-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 4>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-0-4-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 5>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-0-5-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 6>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpullc-0-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 7>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-1-0-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 8>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-1-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 9>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-1-2-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 10>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-1-3-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 11>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-1-4-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 12>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-1-5-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 13>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpullc-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 14>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + ddr-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens0 15>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + ddr-0-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 0>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-0-0-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 1>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-0-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 2>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-0-2-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 3>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-0-3-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 4>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-0-4-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 5>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-0-5-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 6>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpullc-0-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 7>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-1-0-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 8>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-1-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 9>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-1-2-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 10>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-1-3-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 11>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-1-4-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 12>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-1-5-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 13>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpullc-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 14>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + ddr-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens1 15>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + amux-2-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens2 0>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-2-0-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens2 1>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-2-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens2 2>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-2-2-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens2 3>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-2-3-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens2 4>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-2-4-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens2 5>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-2-5-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens2 6>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpullc-2-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens2 7>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + audhvx-0-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens2 8>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + audhmx-0-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens2 9>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + audhvx-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens2 10>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + audhmx-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens2 11>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + audhvx-2-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens2 12>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + audhmx-2-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens2 13>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + pcie-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens2 15>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + amux-3-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens3 0>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-2-0-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens3 1>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-2-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens3 2>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-2-2-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens3 3>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-2-3-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens3 4>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-2-4-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens3 5>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpu-2-5-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens3 6>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <125000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cpullc-2-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens3 7>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + audhvx-0-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens3 8>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + audhmx-0-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens3 9>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + audhvx-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens3 10>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + audhmx-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens3 11>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + audhvx-2-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens3 12>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + audhmx-2-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens3 13>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + pcie-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens3 15>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsphvx-0-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens4 0>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsphvx-0-2-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens4 1>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsp-0-0-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens4 2>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsp-0-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens4 3>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsphvx-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens4 4>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsphvx-1-2-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens4 5>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsp-1-0-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens4 6>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsp-1-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens4 7>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsphvx-2-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens4 8>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsphvx-2-2-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens4 9>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsp-2-0-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens4 10>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsp-2-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens4 11>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsphvx-3-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens4 12>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsphvx-3-2-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens4 13>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsp-3-0-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens4 14>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsp-3-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens4 15>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsphvx-0-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens5 0>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsphvx-0-3-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens5 1>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsp-0-0-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens5 2>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsp-0-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens5 3>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsphvx-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens5 4>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsphvx-1-3-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens5 5>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsp-1-0-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens5 6>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsp-1-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens5 7>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsphvx-2-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens5 8>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsphvx-2-3-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens5 9>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsp-2-0-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens5 10>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsp-2-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens5 11>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsphvx-3-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens5 12>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsphvx-3-3-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens5 13>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsp-3-0-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens5 14>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + nsp-3-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens5 15>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + amux-6-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens6 0>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpuss-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens6 1>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpuss-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens6 2>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpuss-2-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens6 3>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpu-0-0-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens6 4>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpuss-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens6 5>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpuss-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens6 6>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cv-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens6 7>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + video-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens6 8>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + camera-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens6 9>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + ddr-2-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens6 10>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + ddr-3-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens6 11>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpuss-0-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens6 12>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpuss-1-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens6 13>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpuss-2-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens6 14>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpu-0-1-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens6 15>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + amux-7-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens7 0>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpuss-0-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens7 1>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpuss-1-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens7 2>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpuss-2-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens7 3>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpu-0-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens7 4>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpuss-1-2-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens7 5>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpu-1-0-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens7 6>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + cv-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens7 7>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + video-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens7 8>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + camera-2-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens7 9>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + ddr-2-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens7 10>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + ddr-3-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens7 11>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpuss-0-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens7 12>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpuss-1-0-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens7 13>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpuss-2-0-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens7 14>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + + gpu-0-0-1-thermal { + polling-delay-passive = <0>; + polling-delay = <0>; + thermal-sensors = <&tsens7 15>; + + trips { + trip-point0 { + temperature = <105000>; + hysteresis = <10000>; + type = "passive"; + }; + + trip-point1 { + temperature = <115000>; + hysteresis = <10000>; + type = "passive"; + }; + }; + }; + }; +};
diff --git a/arch/arm64/boot/dts/qcom/pm4125.dtsi b/arch/arm64/boot/dts/qcom/pm4125.dtsi index 3dc8d66..77de9db 100644 --- a/arch/arm64/boot/dts/qcom/pm4125.dtsi +++ b/arch/arm64/boot/dts/qcom/pm4125.dtsi
@@ -8,6 +8,35 @@ #include <dt-bindings/interrupt-controller/irq.h> #include <dt-bindings/spmi/spmi.h> +/ { + thermal-zones { + pm4125-thermal { + polling-delay-passive = <100>; + thermal-sensors = <&pm4125_tz>; + + trips { + pm4125_trip0: trip0 { + temperature = <105000>; + hysteresis = <0>; + type = "passive"; + }; + + pm4125_trip1: trip1 { + temperature = <125000>; + hysteresis = <0>; + type = "hot"; + }; + + pm4125_trip2: trip2 { + temperature = <155000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + }; +}; + &spmi_bus { pmic@0 { compatible = "qcom,pm2250", "qcom,spmi-pmic"; @@ -65,6 +94,81 @@ pm4125_typec: typec@1500 { status = "disabled"; }; + pm4125_tz: temp-alarm@2400 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0x2400>; + interrupts = <0x0 0x24 0x0 IRQ_TYPE_EDGE_BOTH>; + io-channels = <&pm4125_adc ADC5_DIE_TEMP>; + io-channel-names = "thermal"; + #thermal-sensor-cells = <0>; + }; + + pm4125_adc: adc@3100 { + compatible = "qcom,spmi-adc5"; + reg = <0x3100>; + #address-cells = <1>; + #size-cells = <0>; + #io-channel-cells = <1>; + interrupts = <0x0 0x31 0x0 IRQ_TYPE_EDGE_RISING>; + + /* Channel nodes */ + channel@0 { + reg = <ADC5_REF_GND>; + label = "ref_gnd"; + qcom,pre-scaling = <1 1>; + }; + + channel@1 { + reg = <ADC5_1P25VREF>; + label = "vref_1p25"; + qcom,pre-scaling = <1 1>; + }; + + channel@6 { + reg = <ADC5_DIE_TEMP>; + label = "die_temp"; + qcom,pre-scaling = <1 1>; + }; + + channel@7 { + reg = <ADC5_USB_IN_I>; + label = "usb_in_i_uv"; + qcom,pre-scaling = <1 1>; + }; + + channel@8 { + reg = <ADC5_USB_IN_V_16>; + label = "usb_in_v_div_16"; + qcom,pre-scaling = <1 16>; + }; + + channel@9 { + reg = <ADC5_CHG_TEMP>; + label = "chg_temp"; + qcom,pre-scaling = <1 1>; + }; + + channel@4b { + reg = <ADC5_BAT_ID_100K_PU>; + label = "bat_id"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + channel@83 { + reg = <ADC5_VPH_PWR>; + label = "vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + channel@84 { + reg = <ADC5_VBAT_SNS>; + label = "vbat_sns"; + qcom,pre-scaling = <1 3>; + }; + }; + rtc@6000 { compatible = "qcom,pm8941-rtc"; reg = <0x6000>, <0x6100>;
diff --git a/arch/arm64/boot/dts/qcom/pm8005.dtsi b/arch/arm64/boot/dts/qcom/pm8005.dtsi index 0f0ab2d..ce31a85 100644 --- a/arch/arm64/boot/dts/qcom/pm8005.dtsi +++ b/arch/arm64/boot/dts/qcom/pm8005.dtsi
@@ -4,6 +4,34 @@ #include <dt-bindings/spmi/spmi.h> #include <dt-bindings/interrupt-controller/irq.h> +/ { + thermal-zones { + pm8005-thermal { + thermal-sensors = <&pm8005_tz>; + + trips { + pm8005_trip0: trip0 { + temperature = <105000>; + hysteresis = <0>; + type = "passive"; + }; + + pm8005_trip1: trip1 { + temperature = <125000>; + hysteresis = <0>; + type = "hot"; + }; + + pm8005_trip2: trip2 { + temperature = <145000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + }; +}; + &spmi_bus { pm8005_lsid0: pmic@4 { compatible = "qcom,pm8005", "qcom,spmi-pmic"; @@ -11,6 +39,13 @@ pm8005_lsid0: pmic@4 { #address-cells = <1>; #size-cells = <0>; + pm8005_tz: temp-alarm@2400 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0x2400>; + interrupts = <0x4 0x24 0x0 IRQ_TYPE_EDGE_BOTH>; + #thermal-sensor-cells = <0>; + }; + pm8005_gpios: gpio@c000 { compatible = "qcom,pm8005-gpio", "qcom,spmi-gpio"; reg = <0xc000>;
diff --git a/arch/arm64/boot/dts/qcom/pmh0104-hawi.dtsi b/arch/arm64/boot/dts/qcom/pmh0104-hawi.dtsi new file mode 100644 index 0000000..9a45c0d --- /dev/null +++ b/arch/arm64/boot/dts/qcom/pmh0104-hawi.dtsi
@@ -0,0 +1,103 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/spmi/spmi.h> + +/ { + thermal-zones { + pmh0104-c-thermal { + polling-delay-passive = <100>; + + thermal-sensors = <&pmh0104_c_e0_temp_alarm>; + + trips { + trip0 { + temperature = <95000>; + hysteresis = <0>; + type = "passive"; + }; + + trip1 { + temperature = <115000>; + hysteresis = <0>; + type = "hot"; + }; + }; + }; + + pmh0104-j-thermal { + polling-delay-passive = <100>; + + thermal-sensors = <&pmh0104_j_e1_temp_alarm>; + + trips { + trip0 { + temperature = <95000>; + hysteresis = <0>; + type = "passive"; + }; + + trip1 { + temperature = <115000>; + hysteresis = <0>; + type = "hot"; + }; + }; + }; + }; +}; + +&spmi_bus0 { + pmh0104_c_e0: pmic@2 { + compatible = "qcom,pmh0104", "qcom,spmi-pmic"; + reg = <0x2 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmh0104_c_e0_temp_alarm: temp-alarm@a00 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0xa00>; + interrupts = <0x2 0xa 0x0 IRQ_TYPE_EDGE_BOTH>; + #thermal-sensor-cells = <0>; + }; + + pmh0104_c_e0_gpios: gpio@8800 { + compatible = "qcom,pmh0104-gpio", "qcom,spmi-gpio"; + reg = <0x8800>; + gpio-controller; + gpio-ranges = <&pmh0104_c_e0_gpios 0 0 8>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; +}; + +&spmi_bus1 { + pmh0104_j_e1: pmic@9 { + compatible = "qcom,pmh0104", "qcom,spmi-pmic"; + reg = <0x9 SPMI_USID>; + #address-cells = <1>; + #size-cells = <0>; + + pmh0104_j_e1_temp_alarm: temp-alarm@a00 { + compatible = "qcom,spmi-temp-alarm"; + reg = <0xa00>; + interrupts = <0x9 0xa 0x0 IRQ_TYPE_EDGE_BOTH>; + #thermal-sensor-cells = <0>; + }; + + pmh0104_j_e1_gpios: gpio@8800 { + compatible = "qcom,pmh0104-gpio", "qcom,spmi-gpio"; + reg = <0x8800>; + gpio-controller; + gpio-ranges = <&pmh0104_j_e1_gpios 0 0 8>; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; + }; + }; +};
diff --git a/arch/arm64/boot/dts/qcom/pmi8996.dtsi b/arch/arm64/boot/dts/qcom/pmi8996.dtsi index 31b4720..711a01c 100644 --- a/arch/arm64/boot/dts/qcom/pmi8996.dtsi +++ b/arch/arm64/boot/dts/qcom/pmi8996.dtsi
@@ -3,12 +3,12 @@ * Copyright (c) 2021, Konrad Dybcio <konrad.dybcio@somainline.org> */ - /* - * PMI8996 is a slight modification of PMI8994 with - * some notable changes, like being the first PMIC - * whose the bootloader has to check to continue booting - * and a change to a LABIBB parameter. - */ +/* + * PMI8996 is a slight modification of PMI8994 with + * some notable changes, like being the first PMIC + * whose the bootloader has to check to continue booting + * and a change to a LABIBB parameter. + */ / { qcom,pmic-id = <0x20009 0x10013 0 0>;
diff --git a/arch/arm64/boot/dts/qcom/purwa-iot-evk.dts b/arch/arm64/boot/dts/qcom/purwa-iot-evk.dts index ad503be..a811d8c 100644 --- a/arch/arm64/boot/dts/qcom/purwa-iot-evk.dts +++ b/arch/arm64/boot/dts/qcom/purwa-iot-evk.dts
@@ -60,6 +60,26 @@ chosen { stdout-path = "serial0:115200n8"; }; + clocks { + clk_rtmr0_xo: clock-rtmr0-xo { + compatible = "fixed-clock"; + clock-frequency = <25000000>; + #clock-cells = <0>; + }; + + clk_rtmr1_xo: clock-rtmr1-xo { + compatible = "fixed-clock"; + clock-frequency = <25000000>; + #clock-cells = <0>; + }; + + clk_rtmr2_xo: clock-rtmr2-xo { + compatible = "fixed-clock"; + clock-frequency = <25000000>; + #clock-cells = <0>; + }; + }; + connector3 { compatible = "usb-a-connector"; label = "USB-3-Type-A"; @@ -295,7 +315,6 @@ vreg_pcie_3v3_aux: regulator-pcie-3v3-aux { pinctrl-names = "default"; }; - /* Left unused as the retimer is not used on this board. */ vreg_rtmr0_1p15: regulator-rtmr0-1p15 { compatible = "regulator-fixed"; @@ -471,32 +490,6 @@ vph_pwr: regulator-vph-pwr { regulator-boot-on; }; - /* - * TODO: These two regulators are actually part of the removable M.2 - * card and not the EVK mainboard. Need to describe this differently. - * Functionally it works correctly, because all we need to do is to - * turn on the actual 3.3V supply above. - */ - vreg_wcn_0p95: regulator-wcn-0p95 { - compatible = "regulator-fixed"; - - regulator-name = "VREG_WCN_0P95"; - regulator-min-microvolt = <950000>; - regulator-max-microvolt = <950000>; - - vin-supply = <&vreg_wcn_3p3>; - }; - - vreg_wcn_1p9: regulator-wcn-1p9 { - compatible = "regulator-fixed"; - - regulator-name = "VREG_WCN_1P9"; - regulator-min-microvolt = <1900000>; - regulator-max-microvolt = <1900000>; - - vin-supply = <&vreg_wcn_3p3>; - }; - vreg_wcn_3p3: regulator-wcn-3p3 { compatible = "regulator-fixed"; @@ -616,63 +609,74 @@ platform { sound-dai = <&q6apm>; }; }; + + dp0-dai-link { + link-name = "DP0 Playback"; + + codec { + sound-dai = <&mdss_dp0>; + }; + + cpu { + sound-dai = <&q6apmbedai DISPLAY_PORT_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + dp1-dai-link { + link-name = "DP1 Playback"; + + codec { + sound-dai = <&mdss_dp1>; + }; + + cpu { + sound-dai = <&q6apmbedai DISPLAY_PORT_RX_1>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; }; - wcn7850-pmu { - compatible = "qcom,wcn7850-pmu"; + wifi-bt-connector { + compatible = "pcie-m2-e-connector"; + vpcie3v3-supply = <&vreg_wcn_3p3>; - vdd-supply = <&vreg_wcn_0p95>; - vddio-supply = <&vreg_l15b_1p8>; - vddaon-supply = <&vreg_wcn_0p95>; - vdddig-supply = <&vreg_wcn_0p95>; - vddrfa1p2-supply = <&vreg_wcn_1p9>; - vddrfa1p8-supply = <&vreg_wcn_1p9>; + w-disable1-gpios = <&tlmm 117 GPIO_ACTIVE_LOW>; + w-disable2-gpios = <&tlmm 116 GPIO_ACTIVE_LOW>; - bt-enable-gpios = <&tlmm 116 GPIO_ACTIVE_HIGH>; - wlan-enable-gpios = <&tlmm 117 GPIO_ACTIVE_HIGH>; - - pinctrl-0 = <&wcn_bt_en>, <&wcn_wlan_en>; + pinctrl-0 = <&wcn_wlan_en>, <&wcn_bt_en>; pinctrl-names = "default"; - regulators { - vreg_pmu_rfa_cmn: ldo0 { - regulator-name = "vreg_pmu_rfa_cmn"; + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + m2_e_pcie_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&pcie4_port0_ep>; + }; }; - vreg_pmu_aon_0p59: ldo1 { - regulator-name = "vreg_pmu_aon_0p59"; - }; + port@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; - vreg_pmu_wlcx_0p8: ldo2 { - regulator-name = "vreg_pmu_wlcx_0p8"; - }; - - vreg_pmu_wlmx_0p85: ldo3 { - regulator-name = "vreg_pmu_wlmx_0p85"; - }; - - vreg_pmu_btcmx_0p85: ldo4 { - regulator-name = "vreg_pmu_btcmx_0p85"; - }; - - vreg_pmu_rfa_0p8: ldo5 { - regulator-name = "vreg_pmu_rfa_0p8"; - }; - - vreg_pmu_rfa_1p2: ldo6 { - regulator-name = "vreg_pmu_rfa_1p2"; - }; - - vreg_pmu_rfa_1p8: ldo7 { - regulator-name = "vreg_pmu_rfa_1p8"; - }; - - vreg_pmu_pcie_0p9: ldo8 { - regulator-name = "vreg_pmu_pcie_0p9"; - }; - - vreg_pmu_pcie_1p8: ldo9 { - regulator-name = "vreg_pmu_pcie_1p8"; + m2_e_uart_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&uart14_ep>; + }; }; }; }; @@ -686,7 +690,7 @@ typec-mux@8 { compatible = "parade,ps8830"; reg = <0x08>; - clocks = <&rpmhcc RPMH_RF_CLK5>; + clocks = <&clk_rtmr2_xo>; vdd-supply = <&vreg_rtmr2_1p15>; vdd33-supply = <&vreg_rtmr2_3p3>; @@ -743,7 +747,7 @@ typec-mux@8 { compatible = "parade,ps8830"; reg = <0x8>; - clocks = <&rpmhcc RPMH_RF_CLK4>; + clocks = <&clk_rtmr0_xo>; vdd-supply = <&vreg_rtmr0_1p15>; vdd33-supply = <&vreg_rtmr0_3p3>; @@ -848,7 +852,7 @@ typec-mux@8 { compatible = "parade,ps8830"; reg = <0x8>; - clocks = <&rpmhcc RPMH_RF_CLK4>; + clocks = <&clk_rtmr1_xo>; vdd-supply = <&vreg_rtmr1_1p15>; vdd33-supply = <&vreg_rtmr1_3p3>; @@ -1012,21 +1016,10 @@ &pcie3_port0 { &pcie4_port0 { reset-gpios = <&tlmm 146 GPIO_ACTIVE_LOW>; wake-gpios = <&tlmm 148 GPIO_ACTIVE_LOW>; +}; - wifi@0 { - compatible = "pci17cb,1107"; - reg = <0x10000 0x0 0x0 0x0 0x0>; - - vddaon-supply = <&vreg_pmu_aon_0p59>; - vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; - vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; - vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; - vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; - vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; - vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; - vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; - vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; - }; +&pcie4_port0_ep { + remote-endpoint = <&m2_e_pcie_ep>; }; &pcie5 { @@ -1325,6 +1318,38 @@ right_tweeter: speaker@0,1 { }; }; +&thermal_gpuss_0 { + trips { + trip-point0 { + temperature = <105000>; + }; + }; +}; + +&thermal_gpuss_1 { + trips { + trip-point0 { + temperature = <105000>; + }; + }; +}; + +&thermal_gpuss_2 { + trips { + trip-point0 { + temperature = <105000>; + }; + }; +}; + +&thermal_gpuss_3 { + trips { + trip-point0 { + temperature = <105000>; + }; + }; +}; + &tlmm { edp_reg_en: edp-reg-en-state { pins = "gpio70"; @@ -1499,19 +1524,10 @@ wcn_usb_sw_n: wcn-usb-sw-n-state { &uart14 { status = "okay"; +}; - bluetooth { - compatible = "qcom,wcn7850-bt"; - max-speed = <3200000>; - - vddaon-supply = <&vreg_pmu_aon_0p59>; - vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; - vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; - vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; - vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; - vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; - vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; - }; +&uart14_ep { + remote-endpoint = <&m2_e_uart_ep>; }; &uart21 {
diff --git a/arch/arm64/boot/dts/qcom/purwa-iot-som.dtsi b/arch/arm64/boot/dts/qcom/purwa-iot-som.dtsi index 488e984..4ef3a54 100644 --- a/arch/arm64/boot/dts/qcom/purwa-iot-som.dtsi +++ b/arch/arm64/boot/dts/qcom/purwa-iot-som.dtsi
@@ -476,6 +476,27 @@ &remoteproc_cdsp { status = "okay"; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { gpio-reserved-ranges = <34 2>; /* TPM LP & INT */
diff --git a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts index f41ad44..e9bf2fa 100644 --- a/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts +++ b/arch/arm64/boot/dts/qcom/qcm6490-fairphone-fp5.dts
@@ -196,6 +196,17 @@ vreg_usb_redrive_1v8: regulator-usb-redrive-1v8 { pinctrl-names = "default"; }; + vph_pwr: regulator-vph-pwr { + compatible = "regulator-fixed"; + + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + + regulator-always-on; + regulator-boot-on; + }; + vreg_vtof_ldo_2p8: regulator-vtof-ldo-2p8 { compatible = "regulator-fixed"; regulator-name = "VTOF_LDO_2P8"; @@ -372,6 +383,18 @@ active-config0 { &apps_rsc { regulators-0 { compatible = "qcom,pm7325-rpmh-regulators"; + + vdd-l1-l4-l12-l15-supply = <&vreg_s7b>; + vdd-l2-l7-supply = <&vreg_bob>; + vdd-l6-l9-l10-supply = <&vreg_s8b>; + vdd-l8-supply = <&vreg_s7b>; + vdd-l11-l17-l18-l19-supply = <&vreg_s1b>; + vdd-l13-supply = <&vreg_s7b>; + vdd-l14-l16-supply = <&vreg_s8b>; + vdd-s1-supply = <&vph_pwr>; + vdd-s7-supply = <&vph_pwr>; + vdd-s8-supply = <&vph_pwr>; + qcom,pmic-id = "b"; vreg_s1b: smps1 { @@ -380,6 +403,12 @@ vreg_s1b: smps1 { regulator-max-microvolt = <2040000>; }; + /* + * s2b (smps2) is ebi.lvl + * s3b-s4b-s5b (smps3-smps4-smps5) is VDD_APC1 + * s6b (smps6) is VDD_APC0 + */ + vreg_s7b: smps7 { regulator-name = "vreg_s7b"; regulator-min-microvolt = <535000>; @@ -414,6 +443,11 @@ vreg_l3b: ldo3 { regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; }; + /* + * l4b (ldo4) is lmx.lvl + * l5b (ldo5) is lcx.lvl + */ + vreg_l6b: ldo6 { regulator-name = "vreg_l6b"; regulator-min-microvolt = <1140000>; @@ -443,6 +477,8 @@ vreg_l9b: ldo9 { regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; }; + /* l10b (ldo10) is PMK7325 VDD_ACTIVE */ + vreg_l11b: ldo11 { regulator-name = "vreg_l11b"; regulator-min-microvolt = <1504000>; @@ -509,6 +545,16 @@ vreg_l19b: ldo19 { regulators-1 { compatible = "qcom,pm8350c-rpmh-regulators"; + + vdd-bob-supply = <&vph_pwr>; + vdd-l1-l12-supply = <&vreg_s1b>; + vdd-l2-l8-supply = <&vreg_s1b>; + vdd-l3-l4-l5-l7-l13-supply = <&vreg_bob>; + vdd-l6-l9-l11-supply = <&vreg_bob>; + vdd-l10-supply = <&vreg_s7b>; + vdd-s1-supply = <&vph_pwr>; + vdd-s9-supply = <&vph_pwr>; + qcom,pmic-id = "c"; vreg_s1c: smps1 { @@ -518,6 +564,12 @@ vreg_s1c: smps1 { regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; }; + /* + * s2c-s3c-s4c (smps2-smps3-smps4) is cx.lvl + * s5c-s6c (smps5-smps6) is mss.lvl + * s7c-s8c (smps7-smps8) is gfx.lvl + */ + vreg_s9c: smps9 { regulator-name = "vreg_s9c"; regulator-min-microvolt = <1010000>; @@ -525,6 +577,8 @@ vreg_s9c: smps9 { regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; }; + /* s10c (smps10) is mx.lvl */ + vreg_l1c: ldo1 { regulator-name = "vreg_l1c"; regulator-min-microvolt = <1800000>;
diff --git a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts index 58cce89..af7821e 100644 --- a/arch/arm64/boot/dts/qcom/qcm6490-idp.dts +++ b/arch/arm64/boot/dts/qcom/qcm6490-idp.dts
@@ -619,6 +619,12 @@ &gpu_zap_shader { firmware-name = "qcom/qcm6490/a660_zap.mbn"; }; +&ipa { + firmware-name = "qcom/qcm6490/ipa_fws.mbn"; + + status = "okay"; +}; + &lpass_rx_macro { status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts b/arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts index 5bb33a8..509fc49 100644 --- a/arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts +++ b/arch/arm64/boot/dts/qcom/qcm6490-particle-tachyon.dts
@@ -558,7 +558,7 @@ &pcie0_phy { &pcie0_port { reset-gpios = <&tlmm 87 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 89 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>; }; &pcie1 { @@ -579,6 +579,7 @@ &pcie1_phy { &pcie1_port0 { reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 3 GPIO_ACTIVE_LOW>; }; &pmk8350_adc_tm {
diff --git a/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi b/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi index a22b450..55bd53f 100644 --- a/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs404-evb.dtsi
@@ -101,8 +101,6 @@ pms405_s3: s3 { &pcie { status = "okay"; - perst-gpios = <&tlmm 43 GPIO_ACTIVE_LOW>; - pinctrl-names = "default"; pinctrl-0 = <&perst_state>; }; @@ -114,6 +112,10 @@ &pcie_phy { vdda-vph-supply = <&vreg_l5_1p8>; }; +&pcie_port0 { + reset-gpios = <&tlmm 43 GPIO_ACTIVE_LOW>; +}; + &remoteproc_adsp { status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/qcs404.dtsi b/arch/arm64/boot/dts/qcom/qcs404.dtsi index 736accf..7b62266 100644 --- a/arch/arm64/boot/dts/qcom/qcs404.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs404.dtsi
@@ -1517,16 +1517,15 @@ pcie: pcie@10000000 { "pwr", "ahb"; - phys = <&pcie_phy>; - phy-names = "pciephy"; - status = "disabled"; - pcie@0 { + pcie_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie_phy>; + #address-cells = <3>; #size-cells = <2>; ranges;
diff --git a/arch/arm64/boot/dts/qcom/qcs615-ride.dts b/arch/arm64/boot/dts/qcom/qcs615-ride.dts index 047b4ef..142dafb 100644 --- a/arch/arm64/boot/dts/qcom/qcs615-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs615-ride.dts
@@ -444,9 +444,6 @@ &mdss_dsi0_phy { }; &pcie { - perst-gpios = <&tlmm 101 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 100 GPIO_ACTIVE_HIGH>; - pinctrl-0 = <&pcie_default_state>; pinctrl-names = "default"; @@ -461,6 +458,8 @@ &pcie_phy { }; &pcie_port0 { + reset-gpios = <&tlmm 101 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 100 GPIO_ACTIVE_LOW>; wifi@0 { compatible = "pci17cb,1103"; reg = <0x10000 0x0 0x0 0x0 0x0>;
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts b/arch/arm64/boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts index 41d60c8..ed0b817 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-radxa-dragon-q6a.dts
@@ -541,7 +541,7 @@ &pcie0_phy { &pcie0_port { reset-gpios = <&tlmm 87 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 89 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>; }; &pcie1 { @@ -571,7 +571,7 @@ &pcie1_phy { &pcie1_port0 { reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 3 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 3 GPIO_ACTIVE_LOW>; }; &pm7325_gpios {
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso index 46bb52c..e878064 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-industrial-mezzanine.dtso
@@ -33,7 +33,7 @@ vreg_1p8: regulator-1v8 { }; &remoteproc_wpss { - status = "disabled"; + status = "disabled"; }; &spi11 { @@ -78,6 +78,8 @@ &pcie0_port { #address-cells = <3>; #size-cells = <2>; + wake-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>; + pcie@0,0 { compatible = "pci1179,0623"; reg = <0x10000 0x0 0x0 0x0 0x0>; @@ -130,20 +132,12 @@ pcie@3,0 { ranges; bus-range = <0x5 0xff>; - pcie@0,0 { + dev@0,0 { reg = <0x50000 0x0 0x0 0x0 0x0>; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - ranges; }; - pcie@0,1 { + dev@0,1 { reg = <0x50100 0x0 0x0 0x0 0x0>; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - ranges; }; }; @@ -225,20 +219,12 @@ pcie@3,0 { ranges; bus-range = <0x5 0xff>; - pcie@0,0 { + dev@0,0 { reg = <0x50000 0x0 0x0 0x0 0x0>; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - ranges; }; - pcie@0,1 { + dev@0,1 { reg = <0x50100 0x0 0x0 0x0 0x0>; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - ranges; }; }; }; @@ -286,5 +272,5 @@ pcie1_tc9563_resx_n: pcie1-tc9563-resx-state { }; &wifi { - status = "disabled"; + status = "disabled"; };
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso index b9e4a52..aceafea 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2-vision-mezzanine.dtso
@@ -51,8 +51,8 @@ camera@1a { reset-gpios = <&tlmm 78 GPIO_ACTIVE_LOW>; pinctrl-names = "default", "suspend"; - pinctrl-0 = <&cam2_default>; - pinctrl-1 = <&cam2_suspend>; + pinctrl-0 = <&cam_mclk3_default>; + pinctrl-1 = <&cam_mclk3_suspend>; clocks = <&camcc CAM_CC_MCLK3_CLK>; assigned-clocks = <&camcc CAM_CC_MCLK3_CLK>; @@ -73,14 +73,7 @@ imx577_ep: endpoint { }; &tlmm { - cam2_default: cam2-default-state { - pins = "gpio67"; - function = "cam_mclk"; - drive-strength = <2>; - bias-disable; - }; - - cam2_suspend: cam2-suspend-state { + cam_mclk3_suspend: cam-mclk3-suspend-state { pins = "gpio67"; function = "cam_mclk"; drive-strength = <2>;
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts index a13315b..9090398 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-rb3gen2.dts
@@ -954,20 +954,12 @@ pcie@3,0 { ranges; bus-range = <0x5 0xff>; - pcie@0,0 { + dev@0,0 { reg = <0x50000 0x0 0x0 0x0 0x0>; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - ranges; }; - pcie@0,1 { + dev@0,1 { reg = <0x50100 0x0 0x0 0x0 0x0>; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - ranges; }; }; }; @@ -1105,6 +1097,16 @@ &pon_resin { status = "okay"; }; +&qup_spi3_cs { + drive-strength = <8>; + bias-disable; +}; + +&qup_spi3_data_clk { + drive-strength = <8>; + bias-disable; +}; + &qup_uart7_cts { /* * Configure a bias-bus-hold on CTS to lower power @@ -1233,7 +1235,7 @@ can@0 { reg = <0>; interrupts-extended = <&tlmm 7 IRQ_TYPE_LEVEL_LOW>; clocks = <&mcp2518fd_osc>; - spi-max-frequency = <14000000>; + spi-max-frequency = <17000000>; vdd-supply = <&vreg_l11c_2p8>; microchip,xstbyen; };
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts index 31bafa2..cfcb22b 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-minipc-g1iot.dts
@@ -705,7 +705,7 @@ &pcie0_phy { &pcie0_port { reset-gpios = <&tlmm 87 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 89 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>; }; &pcie1 { @@ -736,7 +736,7 @@ &pcie1_phy { &pcie1_port0 { reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 3 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 3 GPIO_ACTIVE_LOW>; pcie@0,0 { compatible = "pci1179,0623"; @@ -790,20 +790,12 @@ pcie@3,0 { ranges; bus-range = <0x5 0xff>; - pcie@0,0 { + dev@0,0 { reg = <0x50000 0x0 0x0 0x0 0x0>; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - ranges; }; - pcie@0,1 { + dev@0,1 { reg = <0x50100 0x0 0x0 0x0 0x0>; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - ranges; }; }; };
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3-cam1-imx219.dtso b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3-cam1-imx219.dtso new file mode 100644 index 0000000..b6d7a82 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3-cam1-imx219.dtso
@@ -0,0 +1,115 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2026, Thundercomm All rights reserved. + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/leds/common.h> + +&{/} { + cam1_imx219_clk: clock-camera1-24m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + }; + + leds-camera1 { + compatible = "gpio-leds"; + + pinctrl-0 = <&cam1_privacy_led_state>; + pinctrl-names = "default"; + + cam1_privacy_led: led-camera1 { + function = LED_FUNCTION_INDICATOR; + function-enumerator = <1>; + gpios = <&tlmm 18 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; + + /* Camera module power domain controlled through connector PWR_EN. */ + vreg_cam1_pwr: regulator-camera1-pwr { + compatible = "regulator-fixed"; + + regulator-name = "vreg_camera1_pwr"; + + gpio = <&tlmm 57 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&cam1_pwr_en>; + pinctrl-names = "default"; + + vin-supply = <&vreg_vcc3v3_output>; + }; +}; + +&camss { + vdda-phy-supply = <&vreg_l10c_0p88>; + vdda-pll-supply = <&vreg_l6b_1p2>; + + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + csiphy1_ep: endpoint { + data-lanes = <0 1>; + remote-endpoint = <&cam1_imx219_ep>; + }; + }; + }; +}; + +&cci1 { + status = "okay"; +}; + +&cci1_i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + camera@10 { + compatible = "sony,imx219"; + reg = <0x10>; + + clocks = <&cam1_imx219_clk>; + + VANA-supply = <&vreg_cam1_pwr>; + VDIG-supply = <&vreg_cam1_pwr>; + VDDL-supply = <&vreg_cam1_pwr>; + + leds = <&cam1_privacy_led>; + led-names = "privacy"; + + port { + cam1_imx219_ep: endpoint { + data-lanes = <1 2>; + link-frequencies = /bits/ 64 <456000000>; + remote-endpoint = <&csiphy1_ep>; + }; + }; + }; +}; + +&tlmm { + cam1_privacy_led_state: cam1-privacy-led-state { + pins = "gpio18"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + + cam1_pwr_en: cam1-pwr-en-state { + pins = "gpio57"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; +};
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3-cam2-imx219.dtso b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3-cam2-imx219.dtso new file mode 100644 index 0000000..ff1ccf9 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3-cam2-imx219.dtso
@@ -0,0 +1,115 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2026, Thundercomm All rights reserved. + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/leds/common.h> + +&{/} { + cam2_imx219_clk: clock-camera2-24m { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + }; + + leds-camera2 { + compatible = "gpio-leds"; + + pinctrl-0 = <&cam2_privacy_led_state>; + pinctrl-names = "default"; + + cam2_privacy_led: led-camera2 { + function = LED_FUNCTION_INDICATOR; + function-enumerator = <2>; + gpios = <&tlmm 19 GPIO_ACTIVE_HIGH>; + default-state = "off"; + }; + }; + + /* Camera module power domain controlled through connector PWR_EN. */ + vreg_cam2_pwr: regulator-camera2-pwr { + compatible = "regulator-fixed"; + + regulator-name = "vreg_camera2_pwr"; + + gpio = <&tlmm 58 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&cam2_pwr_en>; + pinctrl-names = "default"; + + vin-supply = <&vreg_vcc3v3_output>; + }; +}; + +&camss { + vdda-phy-supply = <&vreg_l10c_0p88>; + vdda-pll-supply = <&vreg_l6b_1p2>; + + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@4 { + reg = <4>; + + csiphy4_ep: endpoint { + data-lanes = <0 1>; + remote-endpoint = <&cam2_imx219_ep>; + }; + }; + }; +}; + +&cci0 { + status = "okay"; +}; + +&cci0_i2c0 { + #address-cells = <1>; + #size-cells = <0>; + + camera@10 { + compatible = "sony,imx219"; + reg = <0x10>; + + clocks = <&cam2_imx219_clk>; + + VANA-supply = <&vreg_cam2_pwr>; + VDIG-supply = <&vreg_cam2_pwr>; + VDDL-supply = <&vreg_cam2_pwr>; + + leds = <&cam2_privacy_led>; + led-names = "privacy"; + + port { + cam2_imx219_ep: endpoint { + data-lanes = <1 2>; + link-frequencies = /bits/ 64 <456000000>; + remote-endpoint = <&csiphy4_ep>; + }; + }; + }; +}; + +&tlmm { + cam2_privacy_led_state: cam2-privacy-led-state { + pins = "gpio19"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + + cam2_pwr_en: cam2-pwr-en-state { + pins = "gpio58"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; +};
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts index 13e8e62..4ab7771 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-thundercomm-rubikpi3.dts
@@ -214,6 +214,22 @@ vreg_usbhub_rest_1v8: regulator-usbhub-rest-1v8 { regulator-boot-on; }; + vreg_vcc3v3_output: regulator-vcc3v3-output { + compatible = "regulator-fixed"; + + regulator-name = "vcc3v3_output"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 14 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&vcc3v3_output_en>; + pinctrl-names = "default"; + + regulator-always-on; + }; + vph_pwr: regulator-vph-pwr { compatible = "regulator-fixed"; @@ -833,7 +849,7 @@ &pcie0_phy { &pcie0_port { reset-gpios = <&tlmm 87 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 89 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>; }; &pcie1 { @@ -1251,6 +1267,13 @@ usb_eth_power: usb-eth-power-state { bias-disable; }; + vcc3v3_output_en: vcc3v3-output-en-state { + pins = "gpio14"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + wifi_reset_active: wifi-reset-active-state { pins = "gpio16"; function = "gpio";
diff --git a/arch/arm64/boot/dts/qcom/qcs6490-vicharak-axon-mini.dts b/arch/arm64/boot/dts/qcom/qcs6490-vicharak-axon-mini.dts index 4f2e010..496b758 100644 --- a/arch/arm64/boot/dts/qcom/qcs6490-vicharak-axon-mini.dts +++ b/arch/arm64/boot/dts/qcom/qcs6490-vicharak-axon-mini.dts
@@ -652,9 +652,6 @@ &ice { }; &pcie0 { - perst-gpios = <&tlmm 87 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 89 GPIO_ACTIVE_HIGH>; - pinctrl-0 = <&pcie0_clkreq_n>, <&pcie0_reset_n>, <&pcie0_wake_n>; pinctrl-names = "default"; @@ -668,10 +665,12 @@ &pcie0_phy { status = "okay"; }; -&pcie1 { - perst-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 3 GPIO_ACTIVE_HIGH>; +&pcie0_port { + reset-gpios = <&tlmm 87 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>; +}; +&pcie1 { pinctrl-0 = <&pcie1_reset_n>, <&pcie1_wake_n>, <&pcie1_clkreq_n>; pinctrl-names = "default"; @@ -685,6 +684,11 @@ &pcie1_phy { status = "okay"; }; +&pcie1_port0 { + reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 3 GPIO_ACTIVE_LOW>; +}; + &pm7250b_adc { channel@4d { reg = <ADC5_AMUX_THM1_100K_PU>;
diff --git a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts index 1ff3953..be850a2 100644 --- a/arch/arm64/boot/dts/qcom/qcs8300-ride.dts +++ b/arch/arm64/boot/dts/qcom/qcs8300-ride.dts
@@ -615,7 +615,7 @@ &pcie0 { &pcieport0 { reset-gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 0 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 0 GPIO_ACTIVE_LOW>; wifi@0 { compatible = "pci17cb,1103"; @@ -651,7 +651,7 @@ &pcie1 { &pcieport1 { reset-gpios = <&tlmm 23 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 21 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 21 GPIO_ACTIVE_LOW>; }; &pcie1_phy { @@ -702,7 +702,9 @@ &remoteproc_gpdsp { }; &serdes0 { - phy-supply = <&vreg_l5a>; + vdda-0p9-supply = <&vreg_l4a>; + vdda-1p2-supply = <&vreg_l5a>; + status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/qcs8550-aim300.dtsi b/arch/arm64/boot/dts/qcom/qcs8550-aim300.dtsi index ae301d7..4faedcc 100644 --- a/arch/arm64/boot/dts/qcom/qcs8550-aim300.dtsi +++ b/arch/arm64/boot/dts/qcom/qcs8550-aim300.dtsi
@@ -335,9 +335,6 @@ &mdss_dsi0_phy { }; &pcie0 { - perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; - pinctrl-0 = <&pcie0_default_state>; pinctrl-names = "default"; }; @@ -347,10 +344,12 @@ &pcie0_phy { vdda-pll-supply = <&vreg_l3e_1p2>; }; -&pcie1 { - perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>; +&pcie0_port0 { + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; +}; +&pcie1 { pinctrl-0 = <&pcie1_default_state>; pinctrl-names = "default"; }; @@ -361,6 +360,11 @@ &pcie1_phy { vdda-qref-supply = <&vreg_l1e_0p88>; }; +&pcie1_port0 { + reset-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 99 GPIO_ACTIVE_LOW>; +}; + &pm8550b_eusb2_repeater { vdd18-supply = <&vreg_l15b_1p8>; vdd3-supply = <&vreg_l5b_3p1>;
diff --git a/arch/arm64/boot/dts/qcom/qcs8550-ayaneo-pocket-ds.dts b/arch/arm64/boot/dts/qcom/qcs8550-ayaneo-pocket-ds.dts new file mode 100644 index 0000000..72c8166 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs8550-ayaneo-pocket-ds.dts
@@ -0,0 +1,1742 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2025, Teguh Sobirin. + * Copyright (c) 2025, ROCKNIX (https://github.com/ROCKNIX) + */ + +/dts-v1/; + +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/regulator/qcom,rpmh-regulator.h> +#include "qcs8550.dtsi" +#include "pm8550.dtsi" +#include "pm8550b.dtsi" +#define PMK8550VE_SID 5 +#include "pm8550ve.dtsi" +#include "pm8550vs.dtsi" +#include "pmk8550.dtsi" + +/delete-node/ &aop_image_mem; +/delete-node/ &aop_config_mem; +/delete-node/ &camera_mem; +/delete-node/ &ipa_fw_mem; +/delete-node/ &ipa_gsi_mem; +/delete-node/ &mpss_dsm_mem; +/delete-node/ &mpss_mem; +/delete-node/ &q6_mpss_dtb_mem; +/delete-node/ &cdsp_mem; +/delete-node/ &q6_cdsp_dtb_mem; + +/ { + model = "AYANEO Pocket DS"; + compatible = "ayaneo,pocket-ds", "qcom,qcs8550", "qcom,sm8550"; + + aliases { + serial0 = &uart7; + serial1 = &uart14; + serial2 = &uart11; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&volume_up_n>; + pinctrl-names = "default"; + + key-volume-up { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + gpios = <&pm8550_gpios 6 GPIO_ACTIVE_LOW>; + debounce-interval = <15>; + }; + }; + + pmic-glink { + compatible = "qcom,sm8550-pmic-glink", "qcom,pmic-glink"; + + #address-cells = <1>; + #size-cells = <0>; + + orientation-gpios = <&tlmm 11 GPIO_ACTIVE_HIGH>; + + connector@0 { + compatible = "usb-c-connector"; + + reg = <0>; + + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in: endpoint { + remote-endpoint = <&usb_1_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in: endpoint { + remote-endpoint = <&redriver_ss_out>; + }; + }; + + port@2 { + reg = <2>; + + pmic_glink_sbu: endpoint { + remote-endpoint = <&redriver_sbu>; + }; + }; + }; + }; + }; + + pwm_fan: pwm-fan { + compatible = "pwm-fan"; + + pinctrl-0 = <&fan_pwm_active>, <&fan_int>; + pinctrl-1 = <&fan_pwm_sleep>, <&fan_int>; + pinctrl-names = "default", "sleep"; + + fan-supply = <&vdd_fan_5v0>; + pwms = <&pm8550_pwm 3 40000>; + + interrupt-parent = <&tlmm>; + interrupts = <64 IRQ_TYPE_EDGE_FALLING>; + + #cooling-cells = <2>; + cooling-levels = <0 30 45 60 70 90 120 150>; + }; + + reserved-memory { + hyp_mem: hyp-region@80000000 { + reg = <0 0x80000000 0 0xa00000>; + no-map; + }; + + cpusys_vm_mem: cpusys-vm-region@80a00000 { + reg = <0 0x80a00000 0 0x400000>; + no-map; + }; + + hyp_tags_mem: hyp-tags-region@80e00000 { + reg = <0 0x80e00000 0 0x3d0000>; + no-map; + }; + + xbl_sc_mem: xbl-sc-region@d8100000 { + reg = <0 0xd8100000 0 0x40000>; + no-map; + }; + + hyp_tags_reserved_mem: hyp-tags-reserved-region@811d0000 { + reg = <0 0x811d0000 0 0x30000>; + no-map; + }; + + xbl_dt_log_merged_mem: xbl-dt-log-merged-region@81a00000 { + reg = <0 0x81a00000 0 0x260000>; + no-map; + }; + + aop_config_merged_mem: aop-config-merged-region@81c80000 { + reg = <0 0x81c80000 0 0x74000>; + no-map; + }; + + chipinfo_mem: chipinfo-region@81cf4000 { + reg = <0 0x81cf4000 0 0x1000>; + no-map; + }; + + global_sync_mem: global-sync-region@82600000 { + reg = <0 0x82600000 0 0x100000>; + no-map; + }; + + tz_stat_mem: tz-stat-region@82700000 { + reg = <0 0x82700000 0 0x100000>; + no-map; + }; + + cpucp_fw_mem: cpucp-fw-region@d8140000 { + reg = <0 0xd8140000 0 0x1c0000>; + no-map; + }; + + qtee_mem: qtee-region@d8300000 { + reg = <0 0xd8300000 0 0x500000>; + no-map; + }; + + hwfence_shbuf: hwfence-shbuf-region@e6440000 { + reg = <0 0xe6440000 0 0x2dd000>; + no-map; + }; + + hyp_ext_reserved_mem: hyp-ext-reserved-region@ff700000 { + reg = <0 0xff700000 0 0x100000>; + no-map; + }; + + llcc_lpi_mem: llcc-lpi-region@ff800000 { + reg = <0 0xff800000 0 0x600000>; + no-map; + }; + + hyp_ext_tags_mem: hyp-ext-tags-region@fce00000 { + reg = <0 0xfce00000 0 0x2900000>; + no-map; + }; + + splash_region: splash-region@b8000000 { + reg = <0x0 0xb8000000 0x0 0x2b00000>; + no-map; + }; + }; + + sound { + compatible = "qcom,sm8550-sndcard", "qcom,sm8450-sndcard"; + model = "SM8550-APS"; + + audio-routing = "SpkrLeft IN", "WSA_SPK1 OUT", + "SpkrRight IN", "WSA_SPK2 OUT"; + + wsa-dai-link { + link-name = "WSA Playback"; + + codec { + sound-dai = <&spk_amp_l>, + <&spk_amp_r>, + <&swr0 0>, + <&lpass_wsamacro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai WSA_CODEC_DMA_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + va-dai-link { + link-name = "VA Capture"; + + codec { + sound-dai = <&lpass_vamacro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai VA_CODEC_DMA_TX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + }; + + tca6424_vcc: tca6424-vcc-regulator { + compatible = "regulator-fixed"; + + regulator-name = "tca6424_vcc"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpios = <&tlmm 168 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + upd720201_avdd33_reg: upd720201-avdd33-regulator { + compatible = "regulator-fixed"; + + regulator-name = "upd720201_avdd33"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpios = <&tlmm 10 GPIO_ACTIVE_HIGH>; + enable-active-high; + + vin-supply = <&vph_pwr>; + + pinctrl-0 = <&upd720201_avdd33>; + pinctrl-names = "default"; + }; + + upd720201_vdd10_reg: upd720201-vdd10-regulator { + compatible = "regulator-fixed"; + + regulator-name = "upd720201_vdd10"; + regulator-min-microvolt = <1050000>; + regulator-max-microvolt = <1050000>; + + gpios = <&tlmm 13 GPIO_ACTIVE_HIGH>; + enable-active-high; + + vin-supply = <&vph_pwr>; + + pinctrl-0 = <&upd720201_vdd10>; + pinctrl-names = "default"; + }; + + upd720201_vdd33_reg: upd720201-vdd33-regulator { + compatible = "regulator-fixed"; + + regulator-name = "upd720201_vdd33"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpios = <&tlmm 18 GPIO_ACTIVE_HIGH>; + enable-active-high; + + vin-supply = <&vph_pwr>; + + pinctrl-0 = <&upd720201_vdd33>; + pinctrl-names = "default"; + }; + + vreg_panel1_iovcc: panel1-iovcc-regulator { + compatible = "regulator-fixed"; + + regulator-name = "panel1_iovcc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + gpios = <&tca6408 0 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vdd_fan_5v0: vdd-fan-5v0-regulator { + compatible = "regulator-fixed"; + + regulator-name = "vdd_fan_5v0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + + gpios = <&tlmm 31 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&fan_pwr_active>; + pinctrl-names = "default"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_ts: vdd-ts-regulator { + compatible = "regulator-fixed"; + + regulator-name = "vdd_ts_en"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpios = <&tca6408 1 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vph_pwr: vph-pwr-regulator { + compatible = "regulator-fixed"; + + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + + regulator-always-on; + regulator-boot-on; + }; + + wcn7850-pmu { + compatible = "qcom,wcn7850-pmu"; + + pinctrl-0 = <&wlan_en>, <&bt_default>, <&pmk8550_sleep_clk>; + pinctrl-names = "default"; + + wlan-enable-gpios = <&tlmm 80 GPIO_ACTIVE_HIGH>; + bt-enable-gpios = <&tlmm 81 GPIO_ACTIVE_HIGH>; + + vdd-supply = <&vreg_s5g_0p85>; + vddio-supply = <&vreg_l15b_1p8>; + vddaon-supply = <&vreg_s2g_0p85>; + vdddig-supply = <&vreg_s4e_0p95>; + vddrfa1p2-supply = <&vreg_s4g_1p25>; + vddrfa1p8-supply = <&vreg_s6g_1p86>; + + regulators { + vreg_pmu_rfa_cmn: ldo0 { + regulator-name = "vreg_pmu_rfa_cmn"; + }; + + vreg_pmu_aon_0p59: ldo1 { + regulator-name = "vreg_pmu_aon_0p59"; + }; + + vreg_pmu_wlcx_0p8: ldo2 { + regulator-name = "vreg_pmu_wlcx_0p8"; + }; + + vreg_pmu_wlmx_0p85: ldo3 { + regulator-name = "vreg_pmu_wlmx_0p85"; + }; + + vreg_pmu_btcmx_0p85: ldo4 { + regulator-name = "vreg_pmu_btcmx_0p85"; + }; + + vreg_pmu_rfa_0p8: ldo5 { + regulator-name = "vreg_pmu_rfa_0p8"; + }; + + vreg_pmu_rfa_1p2: ldo6 { + regulator-name = "vreg_pmu_rfa_1p2"; + }; + + vreg_pmu_rfa_1p8: ldo7 { + regulator-name = "vreg_pmu_rfa_1p8"; + }; + + vreg_pmu_pcie_0p9: ldo8 { + regulator-name = "vreg_pmu_pcie_0p9"; + }; + + vreg_pmu_pcie_1p8: ldo9 { + regulator-name = "vreg_pmu_pcie_1p8"; + }; + }; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pm8550-rpmh-regulators"; + qcom,pmic-id = "b"; + + vdd-bob1-supply = <&vph_pwr>; + vdd-bob2-supply = <&vph_pwr>; + vdd-l1-l4-l10-supply = <&vreg_s6g_1p86>; + vdd-l2-l13-l14-supply = <&vreg_bob1>; + vdd-l3-supply = <&vreg_s4g_1p25>; + vdd-l5-l16-supply = <&vreg_bob1>; + vdd-l6-l7-supply = <&vreg_bob1>; + vdd-l8-l9-supply = <&vreg_bob1>; + vdd-l11-supply = <&vreg_s4g_1p25>; + vdd-l12-supply = <&vreg_s6g_1p86>; + vdd-l15-supply = <&vreg_s6g_1p86>; + vdd-l17-supply = <&vreg_bob2>; + + vreg_bob1: bob1 { + regulator-name = "vreg_bob1"; + regulator-min-microvolt = <3296000>; + regulator-max-microvolt = <3960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_bob2: bob2 { + regulator-name = "vreg_bob2"; + regulator-min-microvolt = <2720000>; + regulator-max-microvolt = <3960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2b_3p0: ldo2 { + regulator-name = "vreg_l2b_3p0"; + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5b_3p1: ldo5 { + regulator-name = "vreg_l5b_3p1"; + regulator-min-microvolt = <3104000>; + regulator-max-microvolt = <3104000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6b_1p8: ldo6 { + regulator-name = "vreg_l6b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7b_1p8: ldo7 { + regulator-name = "vreg_l7b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l8b_1p8: ldo8 { + regulator-name = "vreg_l8b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l9b_2p9: ldo9 { + regulator-name = "vreg_l9b_2p9"; + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l10b_1p8: ldo10 { + regulator-name = "vreg_l10b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l11b_1p2: ldo11 { + regulator-name = "vreg_l11b_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1504000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l12b_1p8: ldo12 { + regulator-name = "vreg_l12b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l13b_3p0: ldo13 { + regulator-name = "vreg_l13b_3p0"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l14b_3p2: ldo14 { + regulator-name = "vreg_l14b_3p2"; + regulator-min-microvolt = <3200000>; + regulator-max-microvolt = <3200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l15b_1p8: ldo15 { + regulator-name = "vreg_l15b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l16b_2p8: ldo16 { + regulator-name = "vreg_l16b_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l17b_2p5: ldo17 { + regulator-name = "vreg_l17b_2p5"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <2504000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-1 { + compatible = "qcom,pm8550vs-rpmh-regulators"; + qcom,pmic-id = "c"; + + vdd-l1-supply = <&vreg_s4g_1p25>; + vdd-l2-supply = <&vreg_s4e_0p95>; + vdd-l3-supply = <&vreg_s4e_0p95>; + + vreg_l3c_0p9: ldo3 { + regulator-name = "vreg_l3c_0p9"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-2 { + compatible = "qcom,pm8550vs-rpmh-regulators"; + qcom,pmic-id = "d"; + + vdd-l1-supply = <&vreg_s4e_0p95>; + vdd-l2-supply = <&vreg_s4e_0p95>; + vdd-l3-supply = <&vreg_s4e_0p95>; + + vreg_l1d_0p88: ldo1 { + regulator-name = "vreg_l1d_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-3 { + compatible = "qcom,pm8550vs-rpmh-regulators"; + qcom,pmic-id = "e"; + + vdd-l1-supply = <&vreg_s4e_0p95>; + vdd-l2-supply = <&vreg_s4e_0p95>; + vdd-l3-supply = <&vreg_s4g_1p25>; + vdd-s4-supply = <&vph_pwr>; + vdd-s5-supply = <&vph_pwr>; + + vreg_s4e_0p95: smps4 { + regulator-name = "vreg_s4e_0p95"; + regulator-min-microvolt = <904000>; + regulator-max-microvolt = <984000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s5e_1p08: smps5 { + regulator-name = "vreg_s5e_1p08"; + regulator-min-microvolt = <1010000>; + regulator-max-microvolt = <1120000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1e_0p88: ldo1 { + regulator-name = "vreg_l1e_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2e_0p9: ldo2 { + regulator-name = "vreg_l2e_0p9"; + regulator-min-microvolt = <904000>; + regulator-max-microvolt = <970000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3e_1p2: ldo3 { + regulator-name = "vreg_l3e_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-4 { + compatible = "qcom,pm8550ve-rpmh-regulators"; + qcom,pmic-id = "f"; + + vdd-l1-supply = <&vreg_s4e_0p95>; + vdd-l2-supply = <&vreg_s4e_0p95>; + vdd-l3-supply = <&vreg_s4e_0p95>; + vdd-s4-supply = <&vph_pwr>; + + vreg_s4f_0p5: smps4 { + regulator-name = "vreg_s4f_0p5"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <700000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1f_0p9: ldo1 { + regulator-name = "vreg_l1f_0p9"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2f_0p88: ldo2 { + regulator-name = "vreg_l2f_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3f_0p88: ldo3 { + regulator-name = "vreg_l3f_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-5 { + compatible = "qcom,pm8550vs-rpmh-regulators"; + qcom,pmic-id = "g"; + + vdd-l1-supply = <&vreg_s4g_1p25>; + vdd-l2-supply = <&vreg_s4g_1p25>; + vdd-l3-supply = <&vreg_s4g_1p25>; + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + vdd-s3-supply = <&vph_pwr>; + vdd-s4-supply = <&vph_pwr>; + vdd-s5-supply = <&vph_pwr>; + vdd-s6-supply = <&vph_pwr>; + + vreg_s1g_1p25: smps1 { + regulator-name = "vreg_s1g_1p25"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1300000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s2g_0p85: smps2 { + regulator-name = "vreg_s2g_0p85"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s3g_0p8: smps3 { + regulator-name = "vreg_s3g_0p8"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1004000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s4g_1p25: smps4 { + regulator-name = "vreg_s4g_1p25"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1352000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s5g_0p85: smps5 { + regulator-name = "vreg_s5g_0p85"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1004000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s6g_1p86: smps6 { + regulator-name = "vreg_s6g_1p86"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1g_1p2: ldo1 { + regulator-name = "vreg_l1g_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3g_1p2: ldo3 { + regulator-name = "vreg_l3g_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; +}; + +&gpi_dma1 { + status = "okay"; +}; + +&gpi_dma2 { + status = "okay"; +}; + +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/sm8550/a740_zap.mbn"; +}; + +&i2c0 { + clock-frequency = <400000>; + + status = "okay"; + + tca6408: gpio@20 { + compatible = "ti,tca6408"; + reg = <0x20>; + + gpio-controller; + #gpio-cells = <2>; + + vcc-supply = <&tca6424_vcc>; + }; + + backlight: backlight@2e { + compatible = "silergy,sy7758"; + reg = <0x2e>; + + enable-gpios = <&tlmm 42 GPIO_ACTIVE_HIGH>; + }; + + sgm3804: regulator@3e { + compatible = "sgmicro,sgm3804"; + reg = <0x3e>; + + vin-supply = <&vph_pwr>; + + sgm3804_pos: pos { + regulator-name = "panel1_avdd"; + regulator-min-microvolt = <5200000>; + regulator-max-microvolt = <5200000>; + + enable-gpios = <&tlmm 152 GPIO_ACTIVE_HIGH>; + }; + + sgm3804_neg: neg { + regulator-name = "panel1_avee"; + regulator-min-microvolt = <5200000>; + regulator-max-microvolt = <5200000>; + + enable-gpios = <&tlmm 153 GPIO_ACTIVE_HIGH>; + + regulator-always-on; + }; + }; +}; + +&i2c2 { + clock-frequency = <400000>; + + status = "okay"; + + touchscreen@5d { + compatible = "goodix,gt911"; + reg = <0x5d>; + + interrupt-parent = <&tlmm>; + interrupts = <39 IRQ_TYPE_EDGE_FALLING>; + + reset-gpios = <&tlmm 38 GPIO_ACTIVE_HIGH>; + irq-gpios = <&tlmm 39 GPIO_ACTIVE_HIGH>; + + VDDIO-supply = <&vdd_ts>; + + pinctrl-0 = <&ts2_reset>, <&ts2_irq>; + pinctrl-names = "default"; + + touchscreen-size-x = <768>; + touchscreen-size-y = <1024>; + }; +}; + +&i2c4 { + clock-frequency = <100000>; + + status = "okay"; + + touchscreen: touchscreen@38 { + compatible = "focaltech,ft5426"; + reg = <0x38>; + + interrupt-parent = <&tlmm>; + interrupts = <25 IRQ_TYPE_EDGE_FALLING>; + + reset-gpios = <&tlmm 24 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l14b_3p2>; + iovcc-supply = <&vreg_l12b_1p8>; + + pinctrl-0 = <&ts_int_default &ts_rst_default>; + pinctrl-1 = <&ts_int_sleep &ts_rst_sleep>; + pinctrl-names = "default", "sleep"; + + touchscreen-size-x = <1080>; + touchscreen-size-y = <1920>; + }; +}; + +&i2c_hub_2 { + status = "okay"; + + typec-retimer@1c { + compatible = "onnn,nb7vpq904m"; + reg = <0x1c>; + + vcc-supply = <&vreg_l15b_1p8>; + + retimer-switch; + orientation-switch; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + redriver_ss_out: endpoint { + remote-endpoint = <&pmic_glink_ss_in>; + }; + }; + + port@1 { + reg = <1>; + + redriver_ss_in: endpoint { + data-lanes = <3 2 1 0>; + remote-endpoint = <&usb_dp_qmpphy_out>; + }; + }; + + port@2 { + reg = <2>; + + redriver_sbu: endpoint { + remote-endpoint = <&pmic_glink_sbu>; + }; + }; + }; + }; +}; + +&i2c_master_hub_0 { + status = "okay"; +}; + +&ipa { + /delete-property/ memory-region; +}; + +&iris { + status = "okay"; +}; + +/* DMIC 01 23 */ +&lpass_vamacro { + pinctrl-0 = <&dmic01_default>, <&dmic23_default>; + pinctrl-names = "default"; + + vdd-micb-supply = <&vreg_l10b_1p8>; + + qcom,dmic-sample-rate = <4800000>; +}; + +&mdss { + status = "okay"; +}; + +&mdss_dp0 { + status = "okay"; +}; + +&mdss_dp0_out { + data-lanes = <0 1 2 3>; +}; + +&mdss_dsi1 { + vdda-supply = <&vreg_l3e_1p2>; + + status = "okay"; + + panel@0 { + compatible = "ayaneo,pocket-ds-lower-panel"; + reg = <0>; + + vcc-supply = <&sgm3804_pos>; + iovcc-supply = <&vreg_panel1_iovcc>; + + reset-gpios = <&tca6408 2 GPIO_ACTIVE_LOW>; + backlight = <&backlight>; + rotation = <270>; + + pinctrl-0 = <&sde_dsi1_active>; + pinctrl-1 = <&sde_dsi1_suspend>; + pinctrl-names = "default", "sleep"; + + port { + panel1_in: endpoint { + remote-endpoint = <&mdss_dsi1_out>; + }; + }; + }; +}; + +&mdss_dsi1_out { + remote-endpoint = <&panel1_in>; + data-lanes = <0 1 2 3>; +}; + +&mdss_dsi1_phy { + vdds-supply = <&vreg_l1e_0p88>; + + status = "okay"; +}; + +&pcie0 { + wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; + perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + + max-link-speed = <2>; + + pinctrl-0 = <&pcie0_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie0_phy { + vdda-phy-supply = <&vreg_l1e_0p88>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&pcie0_port0 { + wifi@0 { + compatible = "pci17cb,1107"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; + vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; + }; +}; + +&pcie1 { + wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>; + perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&pcie1_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie1_phy { + vdda-phy-supply = <&vreg_l3c_0p9>; + vdda-pll-supply = <&vreg_l3e_1p2>; + vdda-qref-supply = <&vreg_l1e_0p88>; + + status = "okay"; +}; + +&pcie1_port0 { + /* Renesas μPD720201 PCIe USB3.0 HOST CONTROLLER */ + usb-controller@0 { + compatible = "pci1912,0014"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + + avdd33-supply = <&upd720201_avdd33_reg>; + vdd10-supply = <&upd720201_vdd10_reg>; + vdd33-supply = <&upd720201_vdd33_reg>; + + pinctrl-0 = <&gamepad_pwr_en>; + pinctrl-names = "default"; + }; +}; + +&pon_pwrkey { + status = "okay"; +}; + +&pon_resin { + linux,code = <KEY_VOLUMEDOWN>; + + status = "okay"; +}; + +&pm8550_gpios { + sdc2_card_det_n: sdc2-card-det-n-state { + pins = "gpio12"; + function = "normal"; + input-enable; + output-disable; + bias-pull-up; + power-source = <1>; + }; + + volume_up_n: volume-up-n-state { + pins = "gpio6"; + function = "normal"; + power-source = <1>; + bias-pull-up; + input-enable; + }; + + fan_pwm_active: fan-pwm-active-state { + pins = "gpio9"; + function = "func1"; + output-low; + bias-disable; + power-source = <0>; + qcom,drive-strength = <3>; /* PMIC_GPIO_STRENGTH_LOW */ + }; + + fan_pwm_sleep: fan-pwm-sleep-state { + pins = "gpio9"; + function = "normal"; + output-high; + bias-disable; + power-source = <0>; + qcom,drive-strength = <3>; /* PMIC_GPIO_STRENGTH_LOW */ + }; +}; + +&pm8550_pwm { + status = "okay"; + + multi-led { + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_STATUS; + label = "Power Status"; + + #address-cells = <1>; + #size-cells = <0>; + + led@1 { + reg = <1>; + color = <LED_COLOR_ID_RED>; + }; + + led@2 { + reg = <2>; + color = <LED_COLOR_ID_GREEN>; + }; + + led@3 { + reg = <3>; + color = <LED_COLOR_ID_BLUE>; + }; + }; +}; + +&pm8550b_eusb2_repeater { + vdd18-supply = <&vreg_l15b_1p8>; + vdd3-supply = <&vreg_l5b_3p1>; +}; + +&pmk8550_gpios { + pmk8550_sleep_clk: sleep-clk-state { + pins = "gpio3"; + function = "func1"; + input-disable; + output-enable; + bias-disable; + power-source = <0>; + }; +}; + +&pmk8550_rtc { + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "offset"; +}; + +&pmk8550_sdam_2 { + rtc_offset: rtc-offset@bc { + reg = <0xbc 0x4>; + }; +}; + +&qupv3_id_0 { + status = "okay"; +}; + +&qupv3_id_1 { + status = "okay"; +}; + +&remoteproc_adsp { + firmware-name = "qcom/sm8550/ayaneo/adsp.mbn", + "qcom/sm8550/ayaneo/adsp_dtb.mbn"; + + status = "okay"; +}; + +&remoteproc_cdsp { + /delete-property/ memory-region; +}; + +&remoteproc_mpss { + /delete-property/ memory-region; +}; + +&sdhc_2 { + cd-gpios = <&pm8550_gpios 12 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&sdc2_default &sdc2_card_det_n>; + pinctrl-1 = <&sdc2_sleep &sdc2_card_det_n>; + pinctrl-names = "default", "sleep"; + + vmmc-supply = <&vreg_l9b_2p9>; + vqmmc-supply = <&vreg_l8b_1p8>; + + no-sdio; + no-mmc; + + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + sd-uhs-ddr50; + + qcom,dll-config = <0x0007442c>; + + status = "okay"; +}; + +&sleep_clk { + clock-frequency = <32764>; +}; + +&swr0 { + status = "okay"; + + spk_amp_l: speaker@0,0 { + compatible = "sdw20217020400"; + reg = <0 0>; + + pinctrl-0 = <&spkr_1_sd_n_active>; + pinctrl-names = "default"; + + powerdown-gpios = <&tlmm 7 GPIO_ACTIVE_LOW>; + + vdd-1p8-supply = <&vreg_l10b_1p8>; + vdd-io-supply = <&vreg_l10b_1p8>; + + #sound-dai-cells = <0>; + sound-name-prefix = "SpkrLeft"; + qcom,port-mapping = <1 2 3 7 10 13>; + }; + + spk_amp_r: speaker@0,1 { + compatible = "sdw20217020400"; + reg = <0 1>; + + pinctrl-0 = <&spkr_2_sd_n_active>; + pinctrl-names = "default"; + + powerdown-gpios = <&tlmm 12 GPIO_ACTIVE_LOW>; + + vdd-1p8-supply = <&vreg_l10b_1p8>; + vdd-io-supply = <&vreg_l10b_1p8>; + + #sound-dai-cells = <0>; + sound-name-prefix = "SpkrRight"; + qcom,port-mapping = <4 5 6 7 11 13>; + }; +}; + +&thermal_cpu7_top { + trips { + cpu7_active: cpu7-active { + temperature = <50000>; + hysteresis = <3000>; + type = "active"; + }; + }; + + cooling-maps { + map { + trip = <&cpu7_active>; + cooling-device = <&pwm_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; +}; + +&thermal_cpuss0 { + trips { + cpuss0_active: cpuss0-active { + temperature = <50000>; + hysteresis = <3000>; + type = "active"; + }; + }; + + cooling-maps { + map { + trip = <&cpuss0_active>; + cooling-device = <&pwm_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; +}; + +&thermal_cpuss1 { + trips { + cpuss1_active: cpuss1-active { + temperature = <50000>; + hysteresis = <3000>; + type = "active"; + }; + }; + + cooling-maps { + map { + trip = <&cpuss1_active>; + cooling-device = <&pwm_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; +}; + +&thermal_cpuss2 { + trips { + cpuss2_active: cpuss2-active { + temperature = <50000>; + hysteresis = <3000>; + type = "active"; + }; + }; + + cooling-maps { + map { + trip = <&cpuss2_active>; + cooling-device = <&pwm_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; +}; + +&thermal_cpuss3 { + trips { + cpuss3_active: cpuss3-active { + temperature = <50000>; + hysteresis = <3000>; + type = "active"; + }; + }; + + cooling-maps { + map { + trip = <&cpuss3_active>; + cooling-device = <&pwm_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; +}; + +&thermal_gpuss0 { + trips { + gpuss0_active: gpuss0-active { + temperature = <55000>; + hysteresis = <3000>; + type = "active"; + }; + }; + + cooling-maps { + map { + trip = <&gpuss0_active>; + cooling-device = <&pwm_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; +}; + +&thermal_gpuss1 { + trips { + gpuss1_active: gpuss1-active { + temperature = <55000>; + hysteresis = <3000>; + type = "active"; + }; + }; + + cooling-maps { + map { + trip = <&gpuss1_active>; + cooling-device = <&pwm_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; +}; + +&thermal_gpuss2 { + trips { + gpuss2_active: gpuss2-active { + temperature = <55000>; + hysteresis = <3000>; + type = "active"; + }; + }; + + cooling-maps { + map { + trip = <&gpuss2_active>; + cooling-device = <&pwm_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; +}; + +&thermal_gpuss3 { + trips { + gpuss3_active: gpuss3-active { + temperature = <55000>; + hysteresis = <3000>; + type = "active"; + }; + }; + + cooling-maps { + map { + trip = <&gpuss3_active>; + cooling-device = <&pwm_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; +}; + +&thermal_gpuss4 { + trips { + gpuss4_active: gpuss4-active { + temperature = <55000>; + hysteresis = <3000>; + type = "active"; + }; + }; + + cooling-maps { + map { + trip = <&gpuss4_active>; + cooling-device = <&pwm_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; +}; + +&thermal_gpuss5 { + trips { + gpuss5_active: gpuss5-active { + temperature = <55000>; + hysteresis = <3000>; + type = "active"; + }; + }; + + cooling-maps { + map { + trip = <&gpuss5_active>; + cooling-device = <&pwm_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; +}; + +&thermal_gpuss6 { + trips { + gpuss6_active: gpuss6-active { + temperature = <55000>; + hysteresis = <3000>; + type = "active"; + }; + }; + + cooling-maps { + map { + trip = <&gpuss6_active>; + cooling-device = <&pwm_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; +}; + +&thermal_gpuss7 { + trips { + gpuss7_active: gpuss7-active { + temperature = <55000>; + hysteresis = <3000>; + type = "active"; + }; + }; + + cooling-maps { + map { + trip = <&gpuss7_active>; + cooling-device = <&pwm_fan THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; +}; + +&tlmm { + gpio-reserved-ranges = <32 4>; + + bt_default: bt-default-state { + bt-en-pins { + pins = "gpio81"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + sw-ctrl-pins { + pins = "gpio82"; + function = "gpio"; + bias-pull-down; + }; + }; + + fan_pwr_active: fan-pwr-active-state { + pins = "gpio31"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + fan_int: fan-int-state { + pins = "gpio64"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + upd720201_avdd33: upd720201-avdd33-state { + pins = "gpio10"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + upd720201_vdd10: upd720201-vdd10-state { + pins = "gpio13"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + upd720201_vdd33: upd720201-vdd33-state { + pins = "gpio18"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + gamepad_pwr_en: gamepad-pwr-en-active-state { + pins = "gpio52"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + output-high; + }; + + wlan_en: wlan-en-state { + pins = "gpio80"; + function = "gpio"; + drive-strength = <8>; + bias-pull-down; + }; + + spkr_1_sd_n_active: spkr-1-sd-n-active-state { + pins = "gpio7"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + spkr_2_sd_n_active: spkr-2-sd-n-active-state { + pins = "gpio12"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + ts_rst_default: ts-rst-default-state { + pins = "gpio24"; + function = "gpio"; + bias-pull-up; + drive-strength = <8>; + }; + + ts_rst_sleep: ts-rst-sleep-state { + pins = "gpio24"; + function = "gpio"; + bias-pull-down; + drive-strength = <2>; + }; + + ts_int_default: ts-int-default-state { + pins = "gpio25"; + function = "gpio"; + bias-pull-up; + drive-strength = <8>; + }; + + ts_int_sleep: ts-int-sleep-state { + pins = "gpio25"; + function = "gpio"; + bias-pull-down; + drive-strength = <2>; + }; + + ts2_irq: ts2-irq-state { + pins = "gpio39"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + + sde_dsi1_active: sde-dsi1-active-state { + pins = "gpio137"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + output-high; + }; + + sde_dsi1_suspend: sde-dsi1-suspend-state { + pins = "gpio137"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + ts2_reset: ts2-reset-state { + pins = "gpio38"; + function = "gpio"; + drive-strength = <8>; + bias-pull-down; + }; +}; + +&uart7 { + status = "okay"; +}; + +/* AYANEO Controller serial interface */ +&uart11 { + status = "okay"; +}; + +&uart14 { + status = "okay"; + + bluetooth { + compatible = "qcom,wcn7850-bt"; + + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + + max-speed = <3200000>; + }; +}; + +&ufs_mem_hc { + reset-gpios = <&tlmm 210 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l17b_2p5>; + vcc-max-microamp = <1300000>; + vccq-supply = <&vreg_l1g_1p2>; + vccq-max-microamp = <1200000>; + vdd-hba-supply = <&vreg_l3g_1p2>; + + status = "okay"; +}; + +&ufs_mem_phy { + vdda-phy-supply = <&vreg_l1d_0p88>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&usb_1 { + status = "okay"; +}; + +&usb_1_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in>; +}; + +&usb_1_hsphy { + vdd-supply = <&vreg_l1e_0p88>; + vdda12-supply = <&vreg_l3e_1p2>; + + phys = <&pm8550b_eusb2_repeater>; + + status = "okay"; +}; + +&usb_dp_qmpphy { + vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-pll-supply = <&vreg_l3f_0p88>; + + status = "okay"; +}; + +&usb_dp_qmpphy_out { + remote-endpoint = <&redriver_ss_in>; +}; + +&xo_board { + clock-frequency = <76800000>; +};
diff --git a/arch/arm64/boot/dts/qcom/qcs8550-ayntec-common.dtsi b/arch/arm64/boot/dts/qcom/qcs8550-ayntec-common.dtsi new file mode 100644 index 0000000..d567708 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs8550-ayntec-common.dtsi
@@ -0,0 +1,1819 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2025, Teguh Sobirin. + */ + +#include <dt-bindings/leds/common.h> +#include <dt-bindings/regulator/qcom,rpmh-regulator.h> +#include "qcs8550.dtsi" +#include "pm8550.dtsi" +#include "pm8550b.dtsi" +#define PMK8550VE_SID 5 +#include "pm8550ve.dtsi" +#include "pm8550vs.dtsi" +#include "pmk8550.dtsi" + +/delete-node/ &aop_image_mem; +/delete-node/ &aop_config_mem; +/delete-node/ &camera_mem; +/delete-node/ &ipa; +/delete-node/ &ipa_fw_mem; +/delete-node/ &ipa_gsi_mem; +/delete-node/ &mpss_dsm_mem; +/delete-node/ &mpss_mem; +/delete-node/ &q6_mpss_dtb_mem; +/delete-node/ &remoteproc_mpss; + +/ { + chassis-type = "handset"; + + aliases { + serial0 = &uart7; + serial1 = &uart14; + }; + + /* The tzlog label is required by ABL to apply a dtbo, but it can be on any node */ + qcom_tzlog: chosen { + stdout-path = "serial0:115200n8"; + }; + + gpio_keys: gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&volume_up_n>; + pinctrl-names = "default"; + + key-volume-up { + label = "Volume Up"; + debounce-interval = <15>; + gpios = <&pm8550_gpios 6 GPIO_ACTIVE_LOW>; + linux,code = <KEY_VOLUMEUP>; + linux,can-disable; + wakeup-source; + }; + }; + + pmic-glink { + compatible = "qcom,sm8550-pmic-glink", "qcom,pmic-glink"; + #address-cells = <1>; + #size-cells = <0>; + orientation-gpios = <&tlmm 11 GPIO_ACTIVE_HIGH>; + + connector@0 { + compatible = "usb-c-connector"; + reg = <0>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in: endpoint { + remote-endpoint = <&usb_1_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + + pmic_glink_ss_in: endpoint { + remote-endpoint = <&usb_dp_qmpphy_out>; + }; + }; + + port@2 { + reg = <2>; + + pmic_glink_sbu: endpoint { + remote-endpoint = <&usb0_sbu_mux>; + }; + }; + }; + }; + }; + + pwm_fan: pwm-fan { + compatible = "pwm-fan"; + + fan-supply = <&vdd_fan_5v0>; + pwms = <&pm8550_pwm 3 50000>; + + pinctrl-0 = <&fan_pwm_active>, <&fan_int>; + pinctrl-names = "default"; + + pulses-per-revolution = <4>; + interrupts-extended = <&tlmm 13 IRQ_TYPE_EDGE_FALLING>; + + cooling-levels = <0 40 65 75 90 100 120 150 175>; + #cooling-cells = <2>; + }; + + reserved-memory { + hyp_mem: hyp-region@80000000 { + reg = <0 0x80000000 0 0xa00000>; + no-map; + }; + + cpusys_vm_mem: cpusys-vm-region@80a00000 { + reg = <0 0x80a00000 0 0x400000>; + no-map; + }; + + hyp_tags_mem: hyp-tags-region@80e00000 { + reg = <0 0x80e00000 0 0x3d0000>; + no-map; + }; + + xbl_sc_mem: xbl-sc-region@d8100000 { + reg = <0 0xd8100000 0 0x40000>; + no-map; + }; + + hyp_tags_reserved_mem: hyp-tags-reserved-region@811d0000 { + reg = <0 0x811d0000 0 0x30000>; + no-map; + }; + + xbl_dt_log_merged_mem: xbl-dt-log-merged-region@81a00000 { + reg = <0 0x81a00000 0 0x260000>; + no-map; + }; + + aop_config_merged_mem: aop-config-merged-region@81c80000 { + reg = <0 0x81c80000 0 0x74000>; + no-map; + }; + + chipinfo_mem: chipinfo-region@81cf4000 { + reg = <0 0x81cf4000 0 0x1000>; + no-map; + }; + + global_sync_mem: global-sync-region@82600000 { + reg = <0 0x82600000 0 0x100000>; + no-map; + }; + + tz_stat_mem: tz-stat-region@82700000 { + reg = <0 0x82700000 0 0x100000>; + no-map; + }; + + cpucp_fw_mem: cpucp-fw-region@d8140000 { + reg = <0 0xd8140000 0 0x1c0000>; + no-map; + }; + + qtee_mem: qtee-region@d8300000 { + reg = <0 0xd8300000 0 0x500000>; + no-map; + }; + + hwfence_shbuf: hwfence-shbuf-region@e6440000 { + reg = <0 0xe6440000 0 0x2dd000>; + no-map; + }; + + hyp_ext_reserved_mem: hyp-ext-reserved-region@ff700000 { + reg = <0 0xff700000 0 0x100000>; + no-map; + }; + + llcc_lpi_mem: llcc_lpi_region@ff800000 { + reg = <0 0xff800000 0 0x600000>; + no-map; + }; + + hyp_ext_tags_mem: hyp-ext-tags-region@fce00000 { + reg = <0 0xfce00000 0 0x2900000>; + no-map; + }; + }; + + sound { + compatible = "qcom,sm8550-sndcard", "qcom,sm8450-sndcard"; + pinctrl-0 = <&i2s0_default_state>, <&audio_mclk0_default_state>, <&lpi_i2s3_active>; + pinctrl-names = "default"; + + model = "AYN-Odin2"; + audio-routing = "IN1_HPHL", "HPHL_OUT", + "IN2_HPHR", "HPHR_OUT", + "AMIC2", "MIC BIAS2", + "TX SWR_INPUT1", "ADC2_OUTPUT"; + + speaker-i2s-dai-link { + link-name = "Primary MI2S Playback"; + + codec { + sound-dai = <&spk_amp_l>, <&spk_amp_r>; + }; + + cpu { + sound-dai = <&q6apmbedai PRIMARY_MI2S_RX>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + wcd-playback-dai-link { + link-name = "WCD Playback"; + + codec { + sound-dai = <&wcd938x 0>, <&swr1 0>, <&lpass_rxmacro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai RX_CODEC_DMA_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + wcd-capture-dai-link { + link-name = "WCD Capture"; + + codec { + sound-dai = <&wcd938x 1>, <&swr2 0>, <&lpass_txmacro 0>; + }; + + cpu { + sound-dai = <&q6apmbedai TX_CODEC_DMA_TX_3>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + dp0-dai-link { + link-name = "DP0 Playback"; + + codec { + sound-dai = <&mdss_dp0>; + }; + + cpu { + sound-dai = <&q6apmbedai DISPLAY_PORT_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + }; + + thermal-zones { + cpu0-thermal { + polling-delay = <200>; + + trips { + cpuss0_active0: cpu-active0 { + temperature = <50000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss0_active1: cpu-active1 { + temperature = <55000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss0_active2: cpu-active2 { + temperature = <60000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss0_active3: cpu-active3 { + temperature = <65000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss0_active4: cpu-active4 { + temperature = <70000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss0_active5: cpu-active5 { + temperature = <75000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss0_active6: cpu-active6 { + temperature = <80000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss0_active7: cpu-active7 { + temperature = <85000>; + hysteresis = <4000>; + type = "active"; + }; + }; + + cooling-maps { + map0 { + cooling-device = <&pwm_fan 0 1>; + trip = <&cpuss0_active0>; + }; + + map1 { + cooling-device = <&pwm_fan 1 2>; + trip = <&cpuss0_active1>; + }; + + map2 { + cooling-device = <&pwm_fan 2 3>; + trip = <&cpuss0_active2>; + }; + + map3 { + cooling-device = <&pwm_fan 3 4>; + trip = <&cpuss0_active3>; + }; + + map4 { + cooling-device = <&pwm_fan 4 5>; + trip = <&cpuss0_active4>; + }; + + map5 { + cooling-device = <&pwm_fan 5 6>; + trip = <&cpuss0_active5>; + }; + + map6 { + cooling-device = <&pwm_fan 6 7>; + trip = <&cpuss0_active6>; + }; + + map7 { + cooling-device = <&pwm_fan 7 8>; + trip = <&cpuss0_active7>; + }; + }; + }; + + cpu3-bottom-thermal { + polling-delay = <200>; + + trips { + cpuss3_active0: cpu-active0 { + temperature = <50000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss3_active1: cpu-active1 { + temperature = <55000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss3_active2: cpu-active2 { + temperature = <60000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss3_active3: cpu-active3 { + temperature = <65000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss3_active4: cpu-active4 { + temperature = <70000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss3_active5: cpu-active5 { + temperature = <75000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss3_active6: cpu-active6 { + temperature = <80000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss3_active7: cpu-active7 { + temperature = <85000>; + hysteresis = <4000>; + type = "active"; + }; + }; + + cooling-maps { + map0 { + cooling-device = <&pwm_fan 0 1>; + trip = <&cpuss3_active0>; + }; + + map1 { + cooling-device = <&pwm_fan 1 2>; + trip = <&cpuss3_active1>; + }; + + map2 { + cooling-device = <&pwm_fan 2 3>; + trip = <&cpuss3_active2>; + }; + + map3 { + cooling-device = <&pwm_fan 3 4>; + trip = <&cpuss3_active3>; + }; + + map4 { + cooling-device = <&pwm_fan 4 5>; + trip = <&cpuss3_active4>; + }; + + map5 { + cooling-device = <&pwm_fan 5 6>; + trip = <&cpuss3_active5>; + }; + + map6 { + cooling-device = <&pwm_fan 6 7>; + trip = <&cpuss3_active6>; + }; + + map7 { + cooling-device = <&pwm_fan 7 8>; + trip = <&cpuss3_active7>; + }; + }; + }; + + cpu7-bottom-thermal { + polling-delay = <200>; + + trips { + cpuss7_active0: cpu-active0 { + temperature = <50000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss7_active1: cpu-active1 { + temperature = <55000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss7_active2: cpu-active2 { + temperature = <60000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss7_active3: cpu-active3 { + temperature = <65000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss7_active4: cpu-active4 { + temperature = <70000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss7_active5: cpu-active5 { + temperature = <75000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss7_active6: cpu-active6 { + temperature = <80000>; + hysteresis = <4000>; + type = "active"; + }; + + cpuss7_active7: cpu-active7 { + temperature = <85000>; + hysteresis = <4000>; + type = "active"; + }; + }; + + cooling-maps { + map0 { + cooling-device = <&pwm_fan 0 1>; + trip = <&cpuss7_active0>; + }; + + map1 { + cooling-device = <&pwm_fan 1 2>; + trip = <&cpuss7_active1>; + }; + + map2 { + cooling-device = <&pwm_fan 2 3>; + trip = <&cpuss7_active2>; + }; + + map3 { + cooling-device = <&pwm_fan 3 4>; + trip = <&cpuss7_active3>; + }; + + map4 { + cooling-device = <&pwm_fan 4 5>; + trip = <&cpuss7_active4>; + }; + + map5 { + cooling-device = <&pwm_fan 5 6>; + trip = <&cpuss7_active5>; + }; + + map6 { + cooling-device = <&pwm_fan 6 7>; + trip = <&cpuss7_active6>; + }; + + map7 { + cooling-device = <&pwm_fan 7 8>; + trip = <&cpuss7_active7>; + }; + }; + }; + + gpuss-0-thermal { + polling-delay = <200>; + + trips { + gpuss0_active0: gpu-active0 { + temperature = <50000>; + hysteresis = <4000>; + type = "active"; + }; + + gpuss0_active1: gpu-active1 { + temperature = <55000>; + hysteresis = <4000>; + type = "active"; + }; + + gpuss0_active2: gpu-active2 { + temperature = <60000>; + hysteresis = <4000>; + type = "active"; + }; + + gpuss0_active3: gpu-active3 { + temperature = <65000>; + hysteresis = <4000>; + type = "active"; + }; + + gpuss0_active4: gpu-active4 { + temperature = <70000>; + hysteresis = <4000>; + type = "active"; + }; + + gpuss0_active5: gpu-active5 { + temperature = <75000>; + hysteresis = <4000>; + type = "active"; + }; + + gpuss0_active6: gpu-active6 { + temperature = <80000>; + hysteresis = <4000>; + type = "active"; + }; + + gpuss0_active7: gpu-active7 { + temperature = <85000>; + hysteresis = <4000>; + type = "active"; + }; + }; + + cooling-maps { + map0 { + cooling-device = <&pwm_fan 0 1>; + trip = <&gpuss0_active0>; + }; + + map1 { + cooling-device = <&pwm_fan 1 2>; + trip = <&gpuss0_active1>; + }; + + map2 { + cooling-device = <&pwm_fan 2 3>; + trip = <&gpuss0_active2>; + }; + + map3 { + cooling-device = <&pwm_fan 3 4>; + trip = <&gpuss0_active3>; + }; + + map4 { + cooling-device = <&pwm_fan 4 5>; + trip = <&gpuss0_active4>; + }; + + map5 { + cooling-device = <&pwm_fan 5 6>; + trip = <&gpuss0_active5>; + }; + + map6 { + cooling-device = <&pwm_fan 6 7>; + trip = <&gpuss0_active6>; + }; + + map7 { + cooling-device = <&pwm_fan 7 8>; + trip = <&gpuss0_active7>; + }; + }; + }; + }; + + usb0-sbu-mux { + compatible = "pericom,pi3usb102", "gpio-sbu-mux"; + + enable-gpios = <&tlmm 140 GPIO_ACTIVE_LOW>; + select-gpios = <&tlmm 141 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&usb0_sbu_default>; + pinctrl-names = "default"; + + mode-switch; + orientation-switch; + + port { + usb0_sbu_mux: endpoint { + remote-endpoint = <&pmic_glink_sbu>; + }; + }; + }; + + vdd_fan_5v0: vdd-fan-5v0-regulator { + compatible = "regulator-fixed"; + regulator-name = "vdd_fan_5v0"; + + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + + gpio = <&tlmm 109 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-0 = <&fan_pwr_active>; + pinctrl-names = "default"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_mcu_3v3: vdd-mcu-3v3-regulator { + compatible = "regulator-fixed"; + regulator-name = "vdd_mcu_3v3"; + + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + gpio = <&tlmm 99 GPIO_ACTIVE_HIGH>; + regulator-always-on; + regulator-boot-on; + enable-active-high; + }; + + vph_pwr: regulator-vph-pwr { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + + regulator-always-on; + regulator-boot-on; + }; + + wcd938x: audio-codec { + compatible = "qcom,wcd9385-codec"; + + pinctrl-0 = <&wcd_default>; + pinctrl-names = "default"; + + qcom,micbias1-microvolt = <1800000>; + qcom,micbias2-microvolt = <1800000>; + qcom,micbias3-microvolt = <1800000>; + qcom,micbias4-microvolt = <1800000>; + qcom,mbhc-buttons-vthreshold-microvolt = <75000 150000 237000 500000 + 500000 500000 500000 500000>; + qcom,mbhc-headset-vthreshold-microvolt = <1700000>; + qcom,mbhc-headphone-vthreshold-microvolt = <50000>; + qcom,rx-device = <&wcd_rx>; + qcom,tx-device = <&wcd_tx>; + + reset-gpios = <&tlmm 108 GPIO_ACTIVE_LOW>; + + vdd-buck-supply = <&vreg_l15b_1p8>; + vdd-rxtx-supply = <&vreg_l15b_1p8>; + vdd-io-supply = <&vreg_l15b_1p8>; + vdd-mic-bias-supply = <&vreg_bob1>; + + #sound-dai-cells = <1>; + }; + + wcn7850-pmu { + compatible = "qcom,wcn7850-pmu"; + + pinctrl-0 = <&wlan_en>, <&bt_default>, <&pmk8550_sleep_clk>; + pinctrl-names = "default"; + + wlan-enable-gpios = <&tlmm 80 GPIO_ACTIVE_HIGH>; + bt-enable-gpios = <&tlmm 81 GPIO_ACTIVE_HIGH>; + + vdd-supply = <&vreg_s5g_0p8>; + vddio-supply = <&vreg_l15b_1p8>; + vddaon-supply = <&vreg_s2g_0p8>; + vdddig-supply = <&vreg_s4e_0p95>; + vddrfa1p2-supply = <&vreg_s4g_1p3>; + vddrfa1p8-supply = <&vreg_s6g_1p8>; + + regulators { + vreg_pmu_rfa_cmn: ldo0 { + regulator-name = "vreg_pmu_rfa_cmn"; + }; + + vreg_pmu_aon_0p59: ldo1 { + regulator-name = "vreg_pmu_aon_0p59"; + }; + + vreg_pmu_wlcx_0p8: ldo2 { + regulator-name = "vreg_pmu_wlcx_0p8"; + }; + + vreg_pmu_wlmx_0p85: ldo3 { + regulator-name = "vreg_pmu_wlmx_0p85"; + }; + + vreg_pmu_btcmx_0p85: ldo4 { + regulator-name = "vreg_pmu_btcmx_0p85"; + }; + + vreg_pmu_rfa_0p8: ldo5 { + regulator-name = "vreg_pmu_rfa_0p8"; + }; + + vreg_pmu_rfa_1p2: ldo6 { + regulator-name = "vreg_pmu_rfa_1p2"; + }; + + vreg_pmu_rfa_1p8: ldo7 { + regulator-name = "vreg_pmu_rfa_1p8"; + }; + + vreg_pmu_pcie_0p9: ldo8 { + regulator-name = "vreg_pmu_pcie_0p9"; + }; + + vreg_pmu_pcie_1p8: ldo9 { + regulator-name = "vreg_pmu_pcie_1p8"; + }; + }; + }; + + /* The arch_timer label is unused here, but is required by ABL to apply a dtbo */ + arch_timer: timer { }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pm8550-rpmh-regulators"; + qcom,pmic-id = "b"; + + vdd-bob1-supply = <&vph_pwr>; + vdd-bob2-supply = <&vph_pwr>; + vdd-l1-l4-l10-supply = <&vreg_s6g_1p8>; + vdd-l2-l13-l14-supply = <&vreg_bob1>; + vdd-l3-supply = <&vreg_s4g_1p3>; + vdd-l5-l16-supply = <&vreg_bob1>; + vdd-l6-l7-supply = <&vreg_bob1>; + vdd-l8-l9-supply = <&vreg_bob1>; + vdd-l11-supply = <&vreg_s4g_1p3>; + vdd-l12-supply = <&vreg_s6g_1p8>; + vdd-l15-supply = <&vreg_s6g_1p8>; + vdd-l17-supply = <&vreg_bob2>; + + vreg_bob1: bob1 { + regulator-name = "vreg_bob1"; + regulator-min-microvolt = <3296000>; + regulator-max-microvolt = <3960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_bob2: bob2 { + regulator-name = "vreg_bob2"; + regulator-min-microvolt = <2720000>; + regulator-max-microvolt = <3960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2b_3p0: ldo2 { + regulator-name = "vreg_l2b_3p0"; + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5b_3p1: ldo5 { + regulator-name = "vreg_l5b_3p1"; + regulator-min-microvolt = <3104000>; + regulator-max-microvolt = <3104000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6b_1p8: ldo6 { + regulator-name = "vreg_l6b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7b_1p8: ldo7 { + regulator-name = "vreg_l7b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l8b_1p8: ldo8 { + regulator-name = "vreg_l8b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l9b_2p9: ldo9 { + regulator-name = "vreg_l9b_2p9"; + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l11b_1p2: ldo11 { + regulator-name = "vreg_l11b_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1504000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l12b_1p8: ldo12 { + regulator-name = "vreg_l12b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l13b_3p0: ldo13 { + regulator-name = "vreg_l13b_3p0"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l14b_3p2: ldo14 { + regulator-name = "vreg_l14b_3p2"; + regulator-min-microvolt = <3200000>; + regulator-max-microvolt = <3200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l15b_1p8: ldo15 { + regulator-name = "vreg_l15b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l16b_2p8: ldo16 { + regulator-name = "vreg_l16b_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l17b_2p5: ldo17 { + regulator-name = "vreg_l17b_2p5"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <2504000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-1 { + compatible = "qcom,pm8550vs-rpmh-regulators"; + qcom,pmic-id = "c"; + + vdd-l1-supply = <&vreg_s4g_1p3>; + vdd-l2-supply = <&vreg_s4e_0p95>; + vdd-l3-supply = <&vreg_s4e_0p95>; + + vreg_l3c_0p9: ldo3 { + regulator-name = "vreg_l3c_0p9"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-2 { + compatible = "qcom,pm8550vs-rpmh-regulators"; + qcom,pmic-id = "d"; + + vdd-l1-supply = <&vreg_s4e_0p95>; + vdd-l2-supply = <&vreg_s4e_0p95>; + vdd-l3-supply = <&vreg_s4e_0p95>; + + vreg_l1d_0p88: ldo1 { + regulator-name = "vreg_l1d_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-3 { + compatible = "qcom,pm8550vs-rpmh-regulators"; + qcom,pmic-id = "e"; + + vdd-l1-supply = <&vreg_s4e_0p95>; + vdd-l2-supply = <&vreg_s4e_0p95>; + vdd-l3-supply = <&vreg_s4g_1p3>; + vdd-s4-supply = <&vph_pwr>; + vdd-s5-supply = <&vph_pwr>; + + vreg_s4e_0p95: smps4 { + regulator-name = "vreg_s4e_0p95"; + regulator-min-microvolt = <904000>; + regulator-max-microvolt = <984000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s5e_1p08: smps5 { + regulator-name = "vreg_s5e_1p08"; + regulator-min-microvolt = <1010000>; + regulator-max-microvolt = <1120000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1e_0p88: ldo1 { + regulator-name = "vreg_l1e_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2e_0p9: ldo2 { + regulator-name = "vreg_l2e_0p9"; + regulator-min-microvolt = <870000>; + regulator-max-microvolt = <970000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3e_1p2: ldo3 { + regulator-name = "vreg_l3e_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-4 { + compatible = "qcom,pm8550ve-rpmh-regulators"; + qcom,pmic-id = "f"; + + vdd-l1-supply = <&vreg_s4e_0p95>; + vdd-l2-supply = <&vreg_s4e_0p95>; + vdd-l3-supply = <&vreg_s4e_0p95>; + vdd-s4-supply = <&vph_pwr>; + + vreg_s4f_0p5: smps4 { + regulator-name = "vreg_s4f_0p5"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <700000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1f_0p9: ldo1 { + regulator-name = "vreg_l1f_0p9"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2f_0p88: ldo2 { + regulator-name = "vreg_l2f_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3f_0p88: ldo3 { + regulator-name = "vreg_l3f_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-5 { + compatible = "qcom,pm8550vs-rpmh-regulators"; + qcom,pmic-id = "g"; + + vdd-l1-supply = <&vreg_s4g_1p3>; + vdd-l2-supply = <&vreg_s4g_1p3>; + vdd-l3-supply = <&vreg_s4g_1p3>; + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + vdd-s3-supply = <&vph_pwr>; + vdd-s4-supply = <&vph_pwr>; + vdd-s5-supply = <&vph_pwr>; + vdd-s6-supply = <&vph_pwr>; + + vreg_s1g_1p2: smps1 { + regulator-name = "vreg_s1g_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1300000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s2g_0p8: smps2 { + regulator-name = "vreg_s2g_0p8"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s3g_0p7: smps3 { + regulator-name = "vreg_s3g_0p7"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1004000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s4g_1p3: smps4 { + regulator-name = "vreg_s4g_1p3"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1352000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s5g_0p8: smps5 { + regulator-name = "vreg_s5g_0p8"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1004000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s6g_1p8: smps6 { + regulator-name = "vreg_s6g_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1g_1p2: ldo1 { + regulator-name = "vreg_l1g_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3g_1p2: ldo3 { + regulator-name = "vreg_l3g_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; +}; + +&gpi_dma1 { + status = "okay"; +}; + +&gpi_dma2 { + status = "okay"; +}; + +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/sm8550/a740_zap.mbn"; +}; + +&i2c_master_hub_0 { + status = "okay"; +}; + +&i2c_hub_2 { + clock-frequency = <400000>; + + status = "okay"; + + spk_amp_l: amplifier@34 { + compatible = "awinic,aw88166"; + reg = <0x34>; + reset-gpios = <&tlmm 103 GPIO_ACTIVE_LOW>; + sound-name-prefix = "Amplifier L"; + + awinic,audio-channel = <0>; + awinic,sync-flag; + + #sound-dai-cells = <0>; + }; + + spk_amp_r: amplifier@35 { + compatible = "awinic,aw88166"; + reg = <0x35>; + reset-gpios = <&tlmm 100 GPIO_ACTIVE_LOW>; + sound-name-prefix = "Amplifier R"; + + awinic,audio-channel = <1>; + awinic,sync-flag; + + #sound-dai-cells = <0>; + }; +}; + +&iris { + status = "okay"; +}; + +&lpass_tlmm { + lpi_i2s3_active: lpi_i2s3-active-state { + sck-pins { + pins = "gpio12"; + function = "i2s3_clk"; + drive-strength = <8>; + bias-disable; + output-high; + }; + + ws-pins { + pins = "gpio13"; + function = "i2s3_ws"; + drive-strength = <8>; + bias-disable; + output-high; + }; + + data0-pins { + pins = "gpio17"; + function = "i2s3_data"; + drive-strength = <8>; + bias-disable; + output-high; + }; + + data1-pins { + pins = "gpio18"; + function = "i2s3_data"; + drive-strength = <8>; + bias-disable; + output-high; + }; + }; +}; + +&lpass_vamacro { + qcom,dmic-sample-rate = <4800000>; +}; + +&lpass_wsamacro { + status = "disabled"; +}; + +&mdss { + status = "okay"; +}; + +&mdss_dp0 { + status = "okay"; +}; + +&mdss_dsi1 { + vdda-supply = <&vreg_l3e_1p2>; + + status = "okay"; + + display_panel: panel@0 { + reg = <0>; + + port { + panel1_in: endpoint { + remote-endpoint = <&mdss_dsi1_out>; + }; + }; + }; +}; + +&mdss_dsi1_out { + remote-endpoint = <&panel1_in>; + data-lanes = <0 1 2 3>; +}; + +&mdss_dsi1_phy { + vdds-supply = <&vreg_l1e_0p88>; + + status = "okay"; +}; + +&pcie0 { + perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&pcie0_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie0_port0 { + wifi@0 { + compatible = "pci17cb,1107"; + reg = <0x10000 0x0 0x0 0x0 0x0>; + + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; + vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; + }; +}; + +&pcie0_phy { + vdda-phy-supply = <&vreg_l1e_0p88>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&pm8550_gpios { + fan_pwm_active: fan-pwm-active-state { + pins = "gpio8"; + function = "func1"; + input-disable; + output-enable; + output-low; + bias-disable; + power-source = <1>; + }; + + sdc2_card_det_n: sdc2-card-det-n-state { + pins = "gpio12"; + function = "normal"; + input-enable; + output-disable; + bias-pull-up; + power-source = <1>; + }; + + volume_up_n: volume-up-n-state { + pins = "gpio6"; + function = "normal"; + power-source = <1>; + bias-pull-up; + input-enable; + }; +}; + +&pm8550_pwm { + status = "okay"; + + pm8550_multi_led: multi-led { + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_STATUS; + + #address-cells = <1>; + #size-cells = <0>; + + led@1 { + reg = <1>; + color = <LED_COLOR_ID_RED>; + }; + + led@2 { + reg = <2>; + color = <LED_COLOR_ID_GREEN>; + }; + + led@3 { + reg = <3>; + color = <LED_COLOR_ID_BLUE>; + }; + }; +}; + +&pm8550b_eusb2_repeater { + qcom,tune-usb2-disc-thres = /bits/ 8 <0x6>; + qcom,tune-usb2-amplitude = /bits/ 8 <0xb>; + qcom,tune-usb2-preem = /bits/ 8 <0x3>; + vdd18-supply = <&vreg_l15b_1p8>; + vdd3-supply = <&vreg_l5b_3p1>; +}; + +&pmk8550_gpios { + pmk8550_sleep_clk: sleep-clk-state { + pins = "gpio3"; + function = "func1"; + input-disable; + output-enable; + bias-disable; + power-source = <0>; + }; + + pwm_backlight_default: pwm-backlight-default-state { + pins = "gpio5"; + function = "func3"; + input-disable; + output-low; + output-enable; + bias-disable; + power-source = <0>; + qcom,drive-strength = <2>; + }; +}; + +&pmk8550_rtc { + nvmem-cells = <&rtc_offset>; + nvmem-cell-names = "offset"; +}; + +&pmk8550_sdam_2 { + rtc_offset: rtc-offset@bc { + reg = <0xbc 0x4>; + }; +}; + +&pon_pwrkey { + status = "okay"; +}; + +&pon_resin { + linux,code = <KEY_VOLUMEDOWN>; + + status = "okay"; +}; + +&q6apmbedai { + #address-cells = <1>; + #size-cells = <0>; + + dai@16 { + reg = <PRIMARY_MI2S_RX>; + clocks = <&q6prmcc LPASS_CLK_ID_PRI_MI2S_IBIT + LPASS_CLK_ATTRIBUTE_COUPLE_NO>, + <&q6prmcc LPASS_CLK_ID_MCLK_1 + LPASS_CLK_ATTRIBUTE_COUPLE_NO>; + clock-names = "bclk", "mclk"; + }; +}; + +&qupv3_id_0 { + status = "okay"; +}; + +&qupv3_id_1 { + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/sm8550/ayntec/cdsp.mbn", + "qcom/sm8550/ayntec/cdsp_dtb.mbn"; + + status = "okay"; +}; + +&sdhc_2 { + cd-gpios = <&pm8550_gpios 12 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&sdc2_default &sdc2_card_det_n>; + pinctrl-1 = <&sdc2_sleep &sdc2_card_det_n>; + pinctrl-names = "default", "sleep"; + vmmc-supply = <&vreg_l9b_2p9>; + vqmmc-supply = <&vreg_l8b_1p8>; + no-sdio; + no-mmc; + + status = "okay"; +}; + +&sleep_clk { + clock-frequency = <32764>; +}; + +&swr1 { + status = "okay"; + + wcd_rx: codec@0,4 { + compatible = "sdw20217010d00"; + reg = <0 4>; + qcom,rx-port-mapping = <1 2 3 4 5>; + }; +}; + +&swr2 { + status = "okay"; + + wcd_tx: codec@0,3 { + compatible = "sdw20217010d00"; + reg = <0 3>; + qcom,tx-port-mapping = <2 2 3 4>; + }; +}; + +&tlmm { + gpio-reserved-ranges = <32 8>; + + mcu_en_active: mcu-en-active-state { + pins = "gpio12"; + function = "gpio"; + bias-pull-down; + }; + + fan_int: fan-int-state { + pins = "gpio13"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + ts_s_rst_default: ts-s-rst-default-state { + pins = "gpio14"; + function = "gpio"; + bias-pull-up; + drive-strength = <8>; + }; + + ts_s_rst_sleep: ts-s-rst-sleep-state { + pins = "gpio14"; + function = "gpio"; + bias-pull-down; + drive-strength = <2>; + }; + + ts_s_int_default: ts-s-int-default-state { + pins = "gpio15"; + function = "gpio"; + bias-pull-up; + drive-strength = <8>; + }; + + ts_s_int_sleep: ts-s-int-sleep-state { + pins = "gpio15"; + function = "gpio"; + bias-pull-down; + drive-strength = <2>; + }; + + ts_p_rst_default: ts-p-rst-default-state { + pins = "gpio24"; + function = "gpio"; + bias-pull-up; + drive-strength = <8>; + }; + + ts_p_rst_sleep: ts-p-rst-sleep-state { + pins = "gpio24"; + function = "gpio"; + bias-pull-down; + drive-strength = <2>; + }; + + ts_p_int_default: ts-p-int-default-state { + pins = "gpio25"; + function = "gpio"; + bias-pull-up; + drive-strength = <8>; + }; + + ts_p_int_sleep: ts-p-int-sleep-state { + pins = "gpio25"; + function = "gpio"; + bias-pull-down; + drive-strength = <2>; + }; + + wlan_en: wlan-en-state { + pins = "gpio80"; + function = "gpio"; + drive-strength = <8>; + bias-pull-down; + }; + + bt_default: bt-default-state { + bt-en-pins { + pins = "gpio81"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + sw-ctrl-pins { + pins = "gpio82"; + function = "gpio"; + bias-pull-down; + }; + }; + + dsi_p_te_active: dsi-p-te-active-state { + pins = "gpio86"; + function = "mdp_vsync"; + drive-strength = <2>; + bias-pull-down; + }; + + dsi_p_te_suspend: dsi-s-te-suspend-state { + pins = "gpio86"; + function = "mdp_vsync"; + drive-strength = <2>; + bias-pull-down; + }; + + dsi_s_te_active: dsi-s-te-active-state { + pins = "gpio87"; + function = "mdp_vsync"; + drive-strength = <2>; + bias-pull-down; + }; + + dsi_s_te_suspend: dsi-s-te-suspend-state { + pins = "gpio87"; + function = "mdp_vsync"; + drive-strength = <2>; + bias-pull-down; + }; + + wcd_default: wcd-reset-n-active-state { + pins = "gpio108"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + fan_pwr_active: fan-pwr-active-state { + pins = "gpio109"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + audio_mclk0_default_state: audio-mclk0-default-state { + pins = "gpio125"; + function = "audio_ext_mclk0"; + drive-strength = <8>; + bias-disable; + output-high; + }; + + i2s0_default_state: i2s0-default-state { + sck-pins { + pins = "gpio126"; + function = "i2s0_sck"; + drive-strength = <8>; + bias-disable; + output-high; + }; + + data0-pins { + pins = "gpio127"; + function = "i2s0_data0"; + drive-strength = <8>; + bias-disable; + }; + + data1-pins { + pins = "gpio128"; + function = "i2s0_data1"; + drive-strength = <8>; + bias-disable; + }; + + ws-pins { + pins = "gpio129"; + function = "i2s0_ws"; + drive-strength = <8>; + bias-disable; + output-high; + }; + }; + + dsi_p_rst_active: dsi-p-rst-active-state { + pins = "gpio133"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + + dsi_p_rst_suspend: dsi-p-rst-suspend-state { + pins = "gpio133"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + dsi_s_rst_active: dsi-s-rst-active-state { + pins = "gpio137"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + + dsi_s_rst_suspend: dsi-s-rst-suspend-state { + pins = "gpio137"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + usb0_sbu_default: usb0-sbu-state { + oe-n-pins { + pins = "gpio140"; + function = "gpio"; + bias-disable; + drive-strength = <8>; + output-high; + }; + + sel-pins { + pins = "gpio141"; + function = "gpio"; + bias-disable; + drive-strength = <8>; + }; + }; +}; + +&uart7 { + status = "okay"; +}; + +&uart14 { + status = "okay"; + + bluetooth { + compatible = "qcom,wcn7850-bt"; + + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + + max-speed = <3200000>; + }; +}; + +&ufs_mem_hc { + reset-gpios = <&tlmm 210 GPIO_ACTIVE_LOW>; + vcc-supply = <&vreg_l17b_2p5>; + vcc-max-microamp = <1300000>; + vccq-supply = <&vreg_l1g_1p2>; + vccq-max-microamp = <1200000>; + vdd-hba-supply = <&vreg_l3g_1p2>; + + status = "okay"; +}; + +&ufs_mem_phy { + vdda-phy-supply = <&vreg_l1d_0p88>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&usb_1 { + status = "okay"; +}; + +&usb_1_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in>; +}; + +&usb_1_hsphy { + phys = <&pm8550b_eusb2_repeater>; + + vdd-supply = <&vreg_l1e_0p88>; + vdda12-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&usb_dp_qmpphy { + vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-pll-supply = <&vreg_l3f_0p88>; + + status = "okay"; +}; + +&usb_dp_qmpphy_out { + remote-endpoint = <&pmic_glink_ss_in>; +}; + +&xo_board { + clock-frequency = <76800000>; +};
diff --git a/arch/arm64/boot/dts/qcom/qcs8550-ayntec-odin2mini.dts b/arch/arm64/boot/dts/qcom/qcs8550-ayntec-odin2mini.dts new file mode 100644 index 0000000..cc894bd --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs8550-ayntec-odin2mini.dts
@@ -0,0 +1,44 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2025, Teguh Sobirin. + */ + +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include "qcs8550-ayntec-common.dtsi" + +&{/} { + model = "AYN Odin 2 Mini"; + compatible = "ayntec,odin2mini", "qcom,qcs8550", "qcom,sm8550"; + + vdd_disp_2v8: vdd-disp-2v8-regulator { + compatible = "regulator-fixed"; + regulator-name = "vdd_disp_2v8"; + + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + gpio = <&tlmm 142 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +/* There is an hdmi bridge on i2c_hub_0@48, but it is not currently supported */ + +&remoteproc_adsp { + firmware-name = "qcom/sm8550/ayntec/odin2mini/adsp.mbn", + "qcom/sm8550/ayntec/odin2mini/adsp_dtb.mbn"; + + status = "okay"; +}; + +&spk_amp_l { + firmware-name = "qcom/sm8550/ayntec/odin2mini/aw883xx_acf.bin"; +}; + +&spk_amp_r { + firmware-name = "qcom/sm8550/ayntec/odin2mini/aw883xx_acf.bin"; +}; +
diff --git a/arch/arm64/boot/dts/qcom/qcs8550-ayntec-odin2portal.dts b/arch/arm64/boot/dts/qcom/qcs8550-ayntec-odin2portal.dts new file mode 100644 index 0000000..2c6e63f --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs8550-ayntec-odin2portal.dts
@@ -0,0 +1,99 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2025, Teguh Sobirin. + */ + +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include "qcs8550-ayntec-common.dtsi" + +&{/} { + model = "AYN Odin 2 Portal"; + compatible = "ayntec,odin2portal", "qcom,qcs8550", "qcom,sm8550"; + + vdd_bl_5v0: vdd-bl-5v0-regulator { + compatible = "regulator-fixed"; + regulator-name = "vdd_bl_5v0"; + + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + + gpio = <&tlmm 52 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vdd_disp_2v8: vdd-disp-2v8-regulator { + compatible = "regulator-fixed"; + regulator-name = "vdd_disp_2v8"; + + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + gpio = <&tlmm 142 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&display_panel { + compatible = "ayntec,odin2portal-panel", "chipone,icna3512"; + + pinctrl-0 = <&dsi_p_rst_active>, <&dsi_p_te_active>; + pinctrl-1 = <&dsi_p_rst_suspend>, <&dsi_p_te_suspend>; + pinctrl-names = "default", "sleep"; + + vdd-supply = <&vreg_l11b_1p2>; + vddio-supply = <&vreg_l12b_1p8>; + vci-supply = <&vreg_l13b_3p0>; + disp-supply = <&vdd_disp_2v8>; + blvdd-supply = <&vdd_bl_5v0>; + + reset-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>; + + rotation = <270>; +}; + +&i2c4 { + clock-frequency = <400000>; + + status = "okay"; + + touchscreen@38 { + compatible = "focaltech,ft5426"; + reg = <0x38>; + + interrupt-parent = <&tlmm>; + interrupts = <25 IRQ_TYPE_EDGE_FALLING>; + + reset-gpios = <&tlmm 24 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l14b_3p2>; + iovcc-supply = <&vreg_l12b_1p8>; + + pinctrl-0 = <&ts_p_rst_default &ts_p_int_default>; + pinctrl-1 = <&ts_p_rst_sleep &ts_p_int_sleep>; + pinctrl-names = "default", "sleep"; + + touchscreen-size-x = <1080>; + touchscreen-size-y = <1920>; + touchscreen-swapped-x-y; + touchscreen-inverted-y; + }; +}; + +&remoteproc_adsp { + firmware-name = "qcom/sm8550/ayntec/odin2portal/adsp.mbn", + "qcom/sm8550/ayntec/odin2portal/adsp_dtb.mbn"; + + status = "okay"; +}; + +&spk_amp_l { + firmware-name = "qcom/sm8550/ayntec/odin2portal/aw883xx_acf.bin"; +}; + +&spk_amp_r { + firmware-name = "qcom/sm8550/ayntec/odin2portal/aw883xx_acf.bin"; +}; +
diff --git a/arch/arm64/boot/dts/qcom/qcs8550-ayntec-thor.dts b/arch/arm64/boot/dts/qcom/qcs8550-ayntec-thor.dts new file mode 100644 index 0000000..7683911 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs8550-ayntec-thor.dts
@@ -0,0 +1,250 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2025, Teguh Sobirin. + */ + +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include "qcs8550-ayntec-common.dtsi" + +&{/} { + model = "AYN Thor"; + compatible = "ayntec,thor", "qcom,qcs8550", "qcom,sm8550"; + + vdd_bl_5v0: vdd-bl-5v0-regulator { + compatible = "regulator-fixed"; + regulator-name = "vdd_bl_5v0"; + + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + + gpio = <&tlmm 52 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vdd_disp_1v8: vdd-disp-1v8-regulator { + compatible = "regulator-fixed"; + regulator-name = "vdd_disp_1v8"; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + gpio = <&tlmm 70 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vdd_disp1_2v8: vdd-disp1-2v8-regulator { + compatible = "regulator-fixed"; + regulator-name = "vdd_disp1_2v8"; + + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + gpio = <&tlmm 142 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vdd_disp2_2v8: vdd-disp2-2v8-regulator { + compatible = "regulator-fixed"; + regulator-name = "vdd_disp2_2v8"; + + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + gpio = <&tlmm 143 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vdd_ts_3v0: vdd-ts-3v0-regulator { + compatible = "regulator-fixed"; + regulator-name = "vdd_ts_3v0"; + + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + + gpio = <&tlmm 144 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vdd_ts_1v8: vdd-ts-1v8-regulator { + compatible = "regulator-fixed"; + regulator-name = "vdd_ts_1v8"; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + gpio = <&tlmm 102 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&display_panel { + compatible = "ayntec,thor-panel-top", "chipone,icna3520"; + + pinctrl-0 = <&dsi_s_rst_active>, <&dsi_s_te_active>; + pinctrl-1 = <&dsi_s_rst_suspend>, <&dsi_s_te_suspend>; + pinctrl-names = "default", "sleep"; + + vdd-supply = <&vreg_l11b_1p2>; + vddio-supply = <&vreg_l12b_1p8>; + vci-supply = <&vreg_l14b_3p2>; + disp-supply = <&vdd_disp1_2v8>; + blvdd-supply = <&vdd_bl_5v0>; + + reset-gpios = <&tlmm 137 GPIO_ACTIVE_LOW>; + + rotation = <90>; +}; + +&gpio_keys { + pinctrl-0 = <&volume_up_n &key_ayn_n>; + + key-ayn { + label = "AYN Key"; + debounce-interval = <15>; + gpios = <&tlmm 41 GPIO_ACTIVE_LOW>; + linux,code = <KEY_F24>; + linux,can-disable; + }; + + switch-lid { + label = "Hall Lid Sensor"; + gpios = <&tlmm 17 GPIO_ACTIVE_LOW>; + linux,input-type = <EV_SW>; + linux,code = <SW_LID>; + linux,can-disable; + wakeup-source; + }; +}; + +&i2c4 { + clock-frequency = <400000>; + + status = "okay"; + + touchscreen@38 { + compatible = "focaltech,ft5426"; + reg = <0x38>; + + interrupt-parent = <&tlmm>; + interrupts = <25 IRQ_TYPE_EDGE_FALLING>; + + reset-gpios = <&tlmm 24 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l14b_3p2>; + iovcc-supply = <&vreg_l12b_1p8>; + + pinctrl-0 = <&ts_p_rst_default &ts_p_int_default>; + pinctrl-1 = <&ts_p_rst_sleep &ts_p_int_sleep>; + pinctrl-names = "default", "sleep"; + + touchscreen-size-x = <1080>; + touchscreen-size-y = <1920>; + touchscreen-swapped-x-y; + touchscreen-inverted-x; + }; +}; + +&i2c_hub_3 { + clock-frequency = <100000>; + + status = "okay"; + + touchscreen@38 { + compatible = "focaltech,ft5452"; + reg = <0x38>; + + interrupt-parent = <&tlmm>; + interrupts = <15 IRQ_TYPE_EDGE_FALLING>; + + reset-gpios = <&tlmm 14 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vdd_ts_3v0>; + iovcc-supply = <&vdd_ts_1v8>; + + pinctrl-0 = <&ts_s_rst_default &ts_s_int_default>; + pinctrl-1 = <&ts_s_rst_sleep &ts_s_int_sleep>; + pinctrl-names = "default", "sleep"; + + touchscreen-size-x = <1080>; + touchscreen-size-y = <1240>; + touchscreen-swapped-x-y; + touchscreen-inverted-x; + }; +}; + +&mdss_dsi0 { + vdda-supply = <&vreg_l3e_1p2>; + + status = "okay"; + + panel@0 { + reg = <0>; + compatible = "ayntec,thor-panel-bottom", "chipwealth,ch13726a"; + + pinctrl-0 = <&dsi_p_rst_active>, <&dsi_p_te_active>; + pinctrl-1 = <&dsi_p_rst_suspend>, <&dsi_p_te_suspend>; + pinctrl-names = "default", "sleep"; + + vdd1v2-supply = <&vreg_l11b_1p2>; + vddio-supply = <&vdd_disp_1v8>; + vdd-supply = <&vreg_l13b_3p0>; + avdd-supply = <&vdd_disp2_2v8>; + + reset-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>; + + rotation = <90>; + + port { + panel0_in: endpoint { + remote-endpoint = <&mdss_dsi0_out>; + }; + }; + }; +}; + +&mdss_dsi0_out { + remote-endpoint = <&panel0_in>; + data-lanes = <0 1 2 3>; +}; + +&mdss_dsi0_phy { + vdds-supply = <&vreg_l1e_0p88>; + + status = "okay"; +}; + +&mdss_dsi1_out { + qcom,te-source = "mdp_vsync_s"; +}; + +&pm8550_multi_led { + status = "disabled"; +}; + +&remoteproc_adsp { + firmware-name = "qcom/sm8550/ayntec/thor/adsp.mbn", + "qcom/sm8550/ayntec/thor/adsp_dtb.mbn"; + + status = "okay"; +}; + +&spk_amp_l { + firmware-name = "qcom/sm8550/ayntec/thor/aw883xx_acf.bin"; +}; + +&spk_amp_r { + firmware-name = "qcom/sm8550/ayntec/thor/aw883xx_acf.bin"; +}; + +&tlmm { + key_ayn_n: key-ayn-n-state { + pins = "gpio41"; + function = "gpio"; + bias-pull-up; + output-disable; + }; +};
diff --git a/arch/arm64/boot/dts/qcom/qcs8550-imdt-sbc.dts b/arch/arm64/boot/dts/qcom/qcs8550-imdt-sbc.dts new file mode 100644 index 0000000..fa87948 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs8550-imdt-sbc.dts
@@ -0,0 +1,401 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2026 IMD Technologies Ltd + */ + +/dts-v1/; + +#include "qcs8550-imdt-som.dtsi" + +/ { + model = "IMDT QCS8550 SBC"; + compatible = "imdt,qcs8550-sbc", "imdt,qcs8550-som", + "qcom,qcs8550", "qcom,sm8550"; + chassis-type = "embedded"; + + aliases { + serial0 = &uart7; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + connector { + compatible = "pcie-m2-e-connector"; + vpcie3v3-supply = <&m2e_3p3>; + vpcie1v8-supply = <&per_pwr>; + w-disable1-gpios = <&tlmm 80 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&m2e_wlan_disable>; + pinctrl-names = "default"; + + /* SDIO datapath is disabled because the SDIO lines are + * routed through unpopulated resistors. + * UART datapath is also disabled as the UART lines are + * routed through an analogue mux which currently cannot + * be described by a device tree. + */ + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + + m2e_pcie_ep: endpoint@0 { + reg = <0>; + remote-endpoint = <&pcie0_port0_ep>; + }; + }; + }; + }; + + m2e_3p3: regulator-m2e-3p3 { + compatible = "regulator-fixed"; + regulator-name = "m2e_3p3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + pinctrl-0 = <&m2_pd_en_default>; + pinctrl-names = "default"; + + gpio = <&tlmm 144 GPIO_ACTIVE_LOW>; + }; + + /* Enables 5V_PER, 3V3_PER and 1V8_PER rails. 5V_PER and 3V3_PER + * aren't used within the DTS but are used for on board logic + * level conversion and as rails for pull-ups. 1V8_PER is used + * for M2 Key E. + */ + per_pwr: regulator-per-pwr { + compatible = "regulator-fixed"; + regulator-name = "per_pwr"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + pinctrl-0 = <&pwr_per_en_default>; + pinctrl-names = "default"; + + gpio = <&tlmm 142 GPIO_ACTIVE_HIGH>; + enable-active-high; + + regulator-always-on; + regulator-boot-on; + }; + + sdhci_2_vqmmc: regulator-sdhci-2-vqmmc { + compatible = "regulator-gpio"; + + regulator-name = "sdhci_2_vqmmc"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-type = "voltage"; + + pinctrl-0 = <&sd_vset_default>; + pinctrl-names = "default"; + + gpios = <&tlmm 4 GPIO_ACTIVE_HIGH>; + enable-active-high; + + gpios-states = <0>; + states = <3300000 0>, + <1800000 1>; + + startup-delay-us = <10000>; + }; + + vph_pwr: regulator-vph-pwr { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + regulator-always-on; + regulator-boot-on; + }; + + usb_id: usb-id { + compatible = "linux,extcon-usb-gpio"; + id-gpios = <&tlmm 53 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&usb_id_default>; + pinctrl-names = "default"; + }; +}; + +&gpi_dma1 { + status = "okay"; +}; + +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/sm8550/a740_zap.mbn"; +}; + +&i2c_hub_2 { + clock-frequency = <400000>; + + status = "okay"; + + ptn3222: redriver@43 { + compatible = "nxp,ptn3222"; + reg = <0x43>; + #phy-cells = <0>; + + vdd1v8-supply = <&vreg_l15b_1p8>; + vdd3v3-supply = <&vreg_l5b_3p1>; + + pinctrl-0 = <&eusb2_repeater_reset_default>; + pinctrl-names = "default"; + + reset-gpios = <&pm8550vs_d_gpios 4 GPIO_ACTIVE_LOW>; + }; +}; + +&i2c_master_hub_0 { + status = "okay"; +}; + +&ipa { + qcom,gsi-loader = "self"; + memory-region = <&ipa_fw_mem>; + firmware-name = "qcom/sm8550/ipa_fws.mbn"; + + status = "okay"; +}; + +&iris { + status = "okay"; +}; + +&pcie0 { + wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; + perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&pcie0_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcie0_phy { + vdda-phy-supply = <&vreg_l1e_0p88>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&pcie0_port0 { + /* Required for pwrctrl driver bind */ + compatible = "pciclass,0604"; + + port { + pcie0_port0_ep: endpoint { + remote-endpoint = <&m2e_pcie_ep>; + }; + }; +}; + +&pm8550_gpios { + sd_card_detect_default: sd-card-detect-default-state { + pins = "gpio12"; + function = "normal"; + input-enable; + output-disable; + bias-disable; + power-source = <1>; /* 1.8 V */ + }; +}; + +&pm8550_rpmh_regulators { + vdd-bob1-supply = <&vph_pwr>; + vdd-bob2-supply = <&vph_pwr>; +}; + +&pm8550ve_rpmh_regulators { + vdd-s4-supply = <&vph_pwr>; +}; + +&pm8550vs_d_gpios { + eusb2_repeater_reset_default: eusb2-repeater-reset-default-state { + pins = "gpio4"; + function = "normal"; + + input-enable; + output-enable; + bias-disable; + + drive-push-pull; + power-source = <1>; /* 1.8V */ + qcom,drive-strength = <3>; + }; +}; + +&pm8550vs_e_rpmh_regulators { + vdd-s4-supply = <&vph_pwr>; + vdd-s5-supply = <&vph_pwr>; +}; + +&pm8550vs_g_rpmh_regulators { + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + vdd-s3-supply = <&vph_pwr>; + vdd-s4-supply = <&vph_pwr>; + vdd-s5-supply = <&vph_pwr>; + vdd-s6-supply = <&vph_pwr>; +}; + +&pon_pwrkey { + status = "okay"; +}; + +&pon_resin { + linux,code = <KEY_VOLUMEDOWN>; + + status = "okay"; +}; + +&qupv3_id_0 { + status = "okay"; +}; + +&qupv3_id_1 { + status = "okay"; +}; + +&remoteproc_adsp { + firmware-name = "qcom/sm8550/adsp.mbn", + "qcom/sm8550/adsp_dtb.mbn"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/sm8550/cdsp.mbn", + "qcom/sm8550/cdsp_dtb.mbn"; + + status = "okay"; +}; + +&sdc2_default { + clk-pins { + drive-strength = <16>; + }; + + cmd-pins { + /delete-property/ bias-pull-up; + bias-disable; + drive-strength = <16>; + }; + + data-pins { + /delete-property/ bias-pull-up; + bias-disable; + drive-strength = <16>; + }; +}; + +&sdhc_2 { + cd-gpios = <&pm8550_gpios 12 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&sdc2_default>, <&sd_card_detect_default>; + pinctrl-1 = <&sdc2_default>, <&sd_card_detect_default>; + pinctrl-names = "default", "sleep"; + + vqmmc-supply = <&sdhci_2_vqmmc>; + + bus-width = <4>; + no-sdio; + no-mmc; + + status = "okay"; +}; + +&tlmm { + /* Reserved I/Os for NFC */ + gpio-reserved-ranges = <32 8>; + + m2_pd_en_default: m2-pd-en-default-state { + pins = "gpio144"; + function = "gpio"; + drive-strength = <16>; + drive-open-drain; + }; + + m2e_wlan_disable: m2e-wlan-disable-default-state { + pins = "gpio80"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + pwr_per_en_default: pwr-per-en-default-state { + pins = "gpio142"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + sd_vset_default: sd-vset-default-state { + pins = "gpio4"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + usb_id_default: usb-id-default-state { + pins = "gpio53"; + function = "gpio"; + bias-pull-up; + }; +}; + +&uart7 { + status = "okay"; +}; + +&ufs_mem_hc { + reset-gpios = <&tlmm 210 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l17b_2p5>; + vcc-max-microamp = <1300000>; + vccq-supply = <&vreg_l1g_1p2>; + vccq-max-microamp = <1200000>; + vdd-hba-supply = <&vreg_l3g_1p2>; + + status = "okay"; +}; + +&ufs_mem_phy { + vdda-phy-supply = <&vreg_l1d_0p88>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + +&usb_1 { + dr_mode = "otg"; + extcon = <&usb_id>; + + status = "okay"; +}; + +&usb_1_hsphy { + vdd-supply = <&vreg_l1e_0p88>; + vdda12-supply = <&vreg_l3e_1p2>; + + phys = <&ptn3222>; + + status = "okay"; +}; + +&usb_dp_qmpphy { + vdda-phy-supply = <&vreg_l3e_1p2>; + vdda-pll-supply = <&vreg_l3f_0p88>; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/qcom/qcs8550-imdt-som.dtsi b/arch/arm64/boot/dts/qcom/qcs8550-imdt-som.dtsi new file mode 100644 index 0000000..3202632 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs8550-imdt-som.dtsi
@@ -0,0 +1,315 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2026 IMD Technologies Ltd + */ + +#include <dt-bindings/regulator/qcom,rpmh-regulator.h> +#include "qcs8550.dtsi" +#include "pm8550.dtsi" +#define PMK8550VE_SID 5 +#include "pm8550ve.dtsi" +#include "pm8550vs.dtsi" +#include "pmk8550.dtsi" + +&apps_rsc { + pm8550_rpmh_regulators: regulators-0 { + compatible = "qcom,pm8550-rpmh-regulators"; + qcom,pmic-id = "b"; + + vdd-l1-l4-l10-supply = <&vreg_s6g_1p86>; + vdd-l2-l13-l14-supply = <&vreg_bob1>; + vdd-l3-supply = <&vreg_s4g_1p25>; + vdd-l5-l16-supply = <&vreg_bob1>; + vdd-l6-l7-supply = <&vreg_bob1>; + vdd-l8-l9-supply = <&vreg_bob1>; + vdd-l11-supply = <&vreg_s4g_1p25>; + vdd-l12-supply = <&vreg_s6g_1p86>; + vdd-l15-supply = <&vreg_s6g_1p86>; + vdd-l17-supply = <&vreg_bob2>; + + /* + * PMIC outputs whose testpoints lack capacitors are + * omitted to prevent accidental use: + * L1B_1P8, L4B_1P8, L6B_1P8, L7B_1P8, L8B_1P8, + * L13B_3P0, L14B_3P2. + * Other outputs are unused. + */ + vreg_bob1: bob1 { + regulator-name = "vreg_bob1"; + regulator-min-microvolt = <3296000>; + regulator-max-microvolt = <3960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_bob2: bob2 { + regulator-name = "vreg_bob2"; + regulator-min-microvolt = <2720000>; + regulator-max-microvolt = <3960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5b_3p1: ldo5 { + regulator-name = "vreg_l5b_3p1"; + regulator-min-microvolt = <3104000>; + regulator-max-microvolt = <3104000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l15b_1p8: ldo15 { + regulator-name = "vreg_l15b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l17b_2p5: ldo17 { + regulator-name = "vreg_l17b_2p5"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <2504000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + pm8550vs_c_rpmh_regulators: regulators-1 { + compatible = "qcom,pm8550vs-rpmh-regulators"; + qcom,pmic-id = "c"; + + vdd-l1-supply = <&vreg_s4g_1p25>; + vdd-l2-supply = <&vreg_s4e_0p95>; + vdd-l3-supply = <&vreg_s4e_0p95>; + + vreg_l3c_0p9: ldo3 { + regulator-name = "vreg_l3c_0p9"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + pm8550vs_d_rpmh_regulators: regulators-2 { + compatible = "qcom,pm8550vs-rpmh-regulators"; + qcom,pmic-id = "d"; + + vdd-l1-supply = <&vreg_s4e_0p95>; + vdd-l2-supply = <&vreg_s4e_0p95>; + vdd-l3-supply = <&vreg_s4e_0p95>; + + vreg_l1d_0p88: ldo1 { + regulator-name = "vreg_l1d_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + /* ldo2 supplies SM8550 VDD_LPI_MX */ + }; + + pm8550vs_e_rpmh_regulators: regulators-3 { + compatible = "qcom,pm8550vs-rpmh-regulators"; + qcom,pmic-id = "e"; + + vdd-l1-supply = <&vreg_s4e_0p95>; + vdd-l2-supply = <&vreg_s4e_0p95>; + vdd-l3-supply = <&vreg_s4g_1p25>; + + vreg_s4e_0p95: smps4 { + regulator-name = "vreg_s4e_0p95"; + regulator-min-microvolt = <904000>; + regulator-max-microvolt = <984000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s5e_1p08: smps5 { + regulator-name = "vreg_s5e_1p08"; + regulator-min-microvolt = <1080000>; + regulator-max-microvolt = <1120000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1e_0p88: ldo1 { + regulator-name = "vreg_l1e_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <880000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2e_0p9: ldo2 { + regulator-name = "vreg_l2e_0p9"; + regulator-min-microvolt = <904000>; + regulator-max-microvolt = <970000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3e_1p2: ldo3 { + regulator-name = "vreg_l3e_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + pm8550ve_rpmh_regulators: regulators-4 { + compatible = "qcom,pm8550ve-rpmh-regulators"; + qcom,pmic-id = "f"; + + vdd-l1-supply = <&vreg_s4e_0p95>; + vdd-l2-supply = <&vreg_s4e_0p95>; + vdd-l3-supply = <&vreg_s4e_0p95>; + + vreg_s4f_0p5: smps4 { + regulator-name = "vreg_s4f_0p5"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <700000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1f_0p9: ldo1 { + regulator-name = "vreg_l1f_0p9"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2f_0p88: ldo2 { + regulator-name = "vreg_l2f_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3f_0p88: ldo3 { + regulator-name = "vreg_l3f_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + pm8550vs_g_rpmh_regulators: regulators-5 { + compatible = "qcom,pm8550vs-rpmh-regulators"; + qcom,pmic-id = "g"; + + vdd-l1-supply = <&vreg_s4g_1p25>; + vdd-l2-supply = <&vreg_s4g_1p25>; + vdd-l3-supply = <&vreg_s4g_1p25>; + + vreg_s1g_1p25: smps1 { + regulator-name = "vreg_s1g_1p25"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1300000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s2g_0p85: smps2 { + regulator-name = "vreg_s2g_0p85"; + regulator-min-microvolt = <800000>; + regulator-max-microvolt = <1000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s3g_0p8: smps3 { + regulator-name = "vreg_s3g_0p8"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <1004000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s4g_1p25: smps4 { + regulator-name = "vreg_s4g_1p25"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1352000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s5g_0p85: smps5 { + regulator-name = "vreg_s5g_0p85"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1004000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s6g_1p86: smps6 { + regulator-name = "vreg_s6g_1p86"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1g_1p2: ldo1 { + regulator-name = "vreg_l1g_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3g_1p2: ldo3 { + regulator-name = "vreg_l3g_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; +}; + +&pm8550vs_c { + status = "okay"; +}; + +&pm8550vs_d { + status = "okay"; +}; + +&pm8550vs_e { + status = "okay"; +}; + +&pm8550vs_g { + status = "okay"; +}; + +&sleep_clk { + clock-frequency = <32764>; +}; + +&xo_board { + clock-frequency = <76800000>; +};
diff --git a/arch/arm64/boot/dts/qcom/qcs8550-rb5gen2.dts b/arch/arm64/boot/dts/qcom/qcs8550-rb5gen2.dts index 9df8dcd..b7ee1573c 100644 --- a/arch/arm64/boot/dts/qcom/qcs8550-rb5gen2.dts +++ b/arch/arm64/boot/dts/qcom/qcs8550-rb5gen2.dts
@@ -1045,9 +1045,6 @@ &mdss_dp0 { &pcie0 { vddpe-3v3-supply = <&pcie_upd_3p3>; - wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&pcie0_default_state>; pinctrl-names = "default"; @@ -1074,6 +1071,9 @@ &pcie0_phy { }; &pcie0_port0 { + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; + pcie@0,0 { compatible = "pci1179,0623"; reg = <0x10000 0x0 0x0 0x0 0x0>; @@ -1126,29 +1126,18 @@ pcie@3,0 { ranges; bus-range = <0x5 0xff>; - pci@0,0 { + dev@0,0 { reg = <0x50000 0x0 0x0 0x0 0x0>; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - ranges; }; - pci@0,1 { + dev@0,1 { reg = <0x50100 0x0 0x0 0x0 0x0>; - #address-cells = <3>; - #size-cells = <2>; - device_type = "pci"; - ranges; }; }; }; }; &pcie1 { - wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&pcie1_default_state>; pinctrl-names = "default"; @@ -1176,6 +1165,9 @@ &pcie1_phy { }; &pcie1_port0 { + reset-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 99 GPIO_ACTIVE_LOW>; + pcie@0,0 { compatible = "pci1179,0623"; reg = <0x10000 0x0 0x0 0x0 0x0>;
diff --git a/arch/arm64/boot/dts/qcom/qcs8550-retroidpocket-nova.dts b/arch/arm64/boot/dts/qcom/qcs8550-retroidpocket-nova.dts new file mode 100644 index 0000000..0a05469 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs8550-retroidpocket-nova.dts
@@ -0,0 +1,116 @@ +// SPDX-License-Identifier: BSD-3-Clause + +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include "qcs8550-ayntec-common.dtsi" + +&{/} { + model = "Retroid Pocket Nova"; + compatible = "retroidpocket,nova", "qcom,qcs8550", "qcom,sm8550"; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pmk8550_pwm 0 860000>; + brightness-levels = <1023 0>; + num-interpolated-steps = <1023>; + default-brightness-level = <600>; + power-supply = <&vph_pwr>; + enable-gpios = <&pmk8550_gpios 5 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&pwm_backlight_default>; + pinctrl-names = "default"; + }; + + vdd_disp_1v8: regulator-vdd-disp-1v8 { + compatible = "regulator-fixed"; + regulator-name = "vdd_disp_1v8"; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + gpio = <&tlmm 70 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vdd_disp_2v8: regulator-vdd-disp-2v8 { + compatible = "regulator-fixed"; + regulator-name = "vdd_disp_2v8"; + + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + gpio = <&tlmm 142 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + ts_avdd_3v0: regulator-ts-avdd-3v0 { + compatible = "regulator-fixed"; + regulator-name = "ts_avdd_3v0"; + + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + + gpio = <&tlmm 144 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + ts_vddio_1v8: regulator-ts-vddio-1v8 { + compatible = "regulator-fixed"; + regulator-name = "ts_vddio_1v8"; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + gpio = <&tlmm 102 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&i2c_hub_3 { + clock-frequency = <100000>; + + status = "okay"; + + touchscreen@38 { + compatible = "focaltech,ft5426"; + reg = <0x38>; + + interrupt-parent = <&tlmm>; + interrupts = <15 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&tlmm 14 GPIO_ACTIVE_LOW>; + + vcc-supply = <&ts_avdd_3v0>; + iovcc-supply = <&ts_vddio_1v8>; + + pinctrl-0 = <&ts_p_rst_default>, <&ts_p_int_default>; + pinctrl-1 = <&ts_p_rst_sleep>, <&ts_p_int_sleep>; + pinctrl-names = "default", "sleep"; + + touchscreen-size-x = <1280>; + touchscreen-size-y = <960>; + }; +}; + +&mdss_dsi1 { + status = "disabled"; +}; + +&pmk8550_pwm { + status = "okay"; +}; + +&remoteproc_adsp { + firmware-name = "qcom/sm8550/retroidpocket/nova/adsp.mbn", + "qcom/sm8550/retroidpocket/nova/adsp_dtb.mbn"; + + status = "okay"; +}; + +&spk_amp_l { + firmware-name = "qcom/sm8550/retroidpocket/nova/aw883xx_acf.bin"; +}; + +&spk_amp_r { + firmware-name = "qcom/sm8550/retroidpocket/nova/aw883xx_acf.bin"; +};
diff --git a/arch/arm64/boot/dts/qcom/qcs8550-retroidpocket-rp6.dts b/arch/arm64/boot/dts/qcom/qcs8550-retroidpocket-rp6.dts new file mode 100644 index 0000000..a93fe74 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/qcs8550-retroidpocket-rp6.dts
@@ -0,0 +1,120 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (C) 2026-present ROCKNIX (https://github.com/ROCKNIX). + */ + +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include "qcs8550-ayntec-common.dtsi" + +&{/} { + model = "Retroid Pocket 6"; + compatible = "retroidpocket,rp6", "qcom,qcs8550", "qcom,sm8550"; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pmk8550_pwm 0 860000>; + brightness-levels = <1023 0>; + num-interpolated-steps = <1023>; + default-brightness-level = <600>; + power-supply = <&vph_pwr>; + enable-gpios = <&pmk8550_gpios 5 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&pwm_backlight_default>; + pinctrl-names = "default"; + }; + + vdd_disp_1v8: regulator-vdd-disp-1v8 { + compatible = "regulator-fixed"; + regulator-name = "vdd_disp_1v8"; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + gpio = <&tlmm 70 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + vdd_disp_2v8: regulator-vdd-disp-2v8 { + compatible = "regulator-fixed"; + regulator-name = "vdd_disp_2v8"; + + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + + gpio = <&tlmm 142 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + ts_avdd_3v0: regulator-ts-avdd-3v0 { + compatible = "regulator-fixed"; + regulator-name = "ts_avdd_3v0"; + + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3000000>; + + gpio = <&tlmm 144 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + ts_vddio_1v8: regulator-ts-vddio-1v8 { + compatible = "regulator-fixed"; + regulator-name = "ts_vddio_1v8"; + + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + gpio = <&tlmm 102 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&i2c_hub_3 { + clock-frequency = <100000>; + + status = "okay"; + + touchscreen@38 { + compatible = "focaltech,ft5426"; + reg = <0x38>; + + interrupt-parent = <&tlmm>; + interrupts = <15 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&tlmm 14 GPIO_ACTIVE_LOW>; + + vcc-supply = <&ts_avdd_3v0>; + iovcc-supply = <&ts_vddio_1v8>; + + pinctrl-0 = <&ts_p_rst_default>, <&ts_p_int_default>; + pinctrl-1 = <&ts_p_rst_sleep>, <&ts_p_int_sleep>; + pinctrl-names = "default", "sleep"; + + touchscreen-size-x = <1080>; + touchscreen-size-y = <1920>; + touchscreen-swapped-x-y; + }; +}; + +&mdss_dsi1 { + status = "disabled"; +}; + +&pmk8550_pwm { + status = "okay"; +}; + +&remoteproc_adsp { + firmware-name = "qcom/sm8550/retroidpocket/rp6/adsp.mbn", + "qcom/sm8550/retroidpocket/rp6/adsp_dtb.mbn"; + + status = "okay"; +}; + +&spk_amp_l { + firmware-name = "qcom/sm8550/retroidpocket/rp6/aw883xx_acf.bin"; +}; + +&spk_amp_r { + firmware-name = "qcom/sm8550/retroidpocket/rp6/aw883xx_acf.bin"; +};
diff --git a/arch/arm64/boot/dts/qcom/qdu1000.dtsi b/arch/arm64/boot/dts/qcom/qdu1000.dtsi index af106ae..3a25b51 100644 --- a/arch/arm64/boot/dts/qcom/qdu1000.dtsi +++ b/arch/arm64/boot/dts/qcom/qdu1000.dtsi
@@ -412,7 +412,7 @@ ecpricc: clock-controller@280000 { #reset-cells = <1>; }; - gpi_dma0: dma-controller@900000 { + gpi_dma0: dma-controller@900000 { compatible = "qcom,qdu1000-gpi-dma", "qcom,sm6350-gpi-dma"; reg = <0x0 0x900000 0x0 0x60000>; interrupts = <GIC_SPI 244 IRQ_TYPE_LEVEL_HIGH>, @@ -628,7 +628,7 @@ uart7: serial@99c000 { }; }; - gpi_dma1: dma-controller@a00000 { + gpi_dma1: dma-controller@a00000 { compatible = "qcom,qdu1000-gpi-dma", "qcom,sm6350-gpi-dma"; reg = <0x0 0xa00000 0x0 0x60000>; interrupts = <GIC_SPI 279 IRQ_TYPE_LEVEL_HIGH>, @@ -1192,7 +1192,7 @@ qup_uart7_rx: qup-uart7-rx-state { function = "qup07"; }; - qup_uart7_tx: qup-uart7-tx-state { + qup_uart7_tx: qup-uart7-tx-state { pins = "gpio134"; function = "qup07"; };
diff --git a/arch/arm64/boot/dts/qcom/sa8540p-ride.dts b/arch/arm64/boot/dts/qcom/sa8540p-ride.dts index c72faaa..e85d78e 100644 --- a/arch/arm64/boot/dts/qcom/sa8540p-ride.dts +++ b/arch/arm64/boot/dts/qcom/sa8540p-ride.dts
@@ -374,7 +374,7 @@ &pcie2a { &pcie2a_port0 { reset-gpios = <&tlmm 143 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 145 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 145 GPIO_ACTIVE_LOW>; }; &pcie2a_phy { @@ -397,7 +397,7 @@ &pcie3a { &pcie3a_port0 { reset-gpios = <&tlmm 151 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 56 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 56 GPIO_ACTIVE_LOW>; }; &pcie3a_phy {
diff --git a/arch/arm64/boot/dts/qcom/sar2130p-qar2130p.dts b/arch/arm64/boot/dts/qcom/sar2130p-qar2130p.dts index 80428c0..cc04eef 100644 --- a/arch/arm64/boot/dts/qcom/sar2130p-qar2130p.dts +++ b/arch/arm64/boot/dts/qcom/sar2130p-qar2130p.dts
@@ -357,9 +357,6 @@ &i2c10 { }; &pcie0 { - perst-gpios = <&tlmm 55 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 57 GPIO_ACTIVE_HIGH>; - pinctrl-0 = <&pcie0_default_state>; pinctrl-names = "default"; @@ -367,6 +364,9 @@ &pcie0 { }; &pcieport0 { + reset-gpios = <&tlmm 55 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 57 GPIO_ACTIVE_LOW>; + wifi@0 { compatible = "pci17cb,1107"; reg = <0x10000 0x0 0x0 0x0 0x0>;
diff --git a/arch/arm64/boot/dts/qcom/sar2130p.dtsi b/arch/arm64/boot/dts/qcom/sar2130p.dtsi index a2d93fd..cc40770 100644 --- a/arch/arm64/boot/dts/qcom/sar2130p.dtsi +++ b/arch/arm64/boot/dts/qcom/sar2130p.dtsi
@@ -15,7 +15,6 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/mailbox/qcom-ipcc.h> #include <dt-bindings/phy/phy-qcom-qmp.h> -#include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/power/qcom,rpmhpd.h> #include <dt-bindings/soc/qcom,gpr.h> #include <dt-bindings/soc/qcom,rpmh-rsc.h> @@ -475,6 +474,7 @@ gcc: clock-controller@100000 { #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; + power-domains = <&rpmhpd RPMHPD_CX>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&sleep_clk>, <&pcie0_phy>, @@ -1337,9 +1337,6 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, power-domains = <&gcc PCIE_0_GDSC>; - phys = <&pcie0_phy>; - phy-names = "pciephy"; - status = "disabled"; pcieport0: pcie@0 { @@ -1347,6 +1344,8 @@ pcieport0: pcie@0 { reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie0_phy>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -1464,16 +1463,15 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, power-domains = <&gcc PCIE_1_GDSC>; - phys = <&pcie1_phy>; - phy-names = "pciephy"; - status = "disabled"; - pcie@0 { + pcie1_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie1_phy>; + #address-cells = <3>; #size-cells = <2>; ranges;
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi index 8fee8d7..f6919e0 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-homestar.dtsi
@@ -184,7 +184,7 @@ &secondary_mi2s { }; &sound_multimedia1_codec { - sound-dai = <&max98360a>, <&max98360a_1>, <&max98360a_2>, <&max98360a_3> ; + sound-dai = <&max98360a>, <&max98360a_1>, <&max98360a_2>, <&max98360a_3>; }; &wifi {
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r4.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r4.dts index 70d5a7a..3390fd0 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r4.dts +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-limozeen-nots-r4.dts
@@ -17,7 +17,7 @@ / { */ /delete-node/&trackpad; &ap_tp_i2c { - trackpad: trackpad@2c { + trackpad: trackpad@2c { compatible = "hid-over-i2c"; reg = <0x2c>; pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.dts index b60060a..c70ad039 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.dts +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-lazor-r1.dts
@@ -19,9 +19,9 @@ / { &usb_hub_2_x { - vdd-supply = <&pp3300_l7c>; + vdd-supply = <&pp3300_l7c>; }; &usb_hub_3_x { - vdd-supply = <&pp3300_l7c>; + vdd-supply = <&pp3300_l7c>; };
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom-r1.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom-r1.dts index ba222a6..9eea257 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom-r1.dts +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-pompom-r1.dts
@@ -35,9 +35,9 @@ &pm6150_adc_tm { }; &usb_hub_2_x { - vdd-supply = <&pp3300_l7c>; + vdd-supply = <&pp3300_l7c>; }; &usb_hub_3_x { - vdd-supply = <&pp3300_l7c>; + vdd-supply = <&pp3300_l7c>; };
diff --git a/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts b/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts index d393a27..1d9f3db 100644 --- a/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts +++ b/arch/arm64/boot/dts/qcom/sc7180-trogdor-r1.dts
@@ -53,11 +53,11 @@ &trackpad { }; &usb_hub_2_x { - vdd-supply = <&pp3300_l7c>; + vdd-supply = <&pp3300_l7c>; }; &usb_hub_3_x { - vdd-supply = <&pp3300_l7c>; + vdd-supply = <&pp3300_l7c>; }; /* PINCTRL - modifications to sc7180-trogdor.dtsi */
diff --git a/arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts b/arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts index 565e5a9..aa634a0 100644 --- a/arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts +++ b/arch/arm64/boot/dts/qcom/sc8180x-lenovo-flex-5g.dts
@@ -491,8 +491,6 @@ &mdss_edp_out { }; &pcie3 { - perst-gpios = <&tlmm 178 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 180 GPIO_ACTIVE_HIGH>; pinctrl-0 = <&pcie3_default_state>; pinctrl-names = "default"; @@ -506,6 +504,11 @@ &pcie3_phy { status = "okay"; }; +&pcie3_port0 { + reset-gpios = <&tlmm 178 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 180 GPIO_ACTIVE_LOW>; +}; + &pmc8180_2_gpios { bl_pwr_en: bl-pwr-en-state { pins = "gpio1";
diff --git a/arch/arm64/boot/dts/qcom/sc8180x-primus.dts b/arch/arm64/boot/dts/qcom/sc8180x-primus.dts index c10a936..2311c5f 100644 --- a/arch/arm64/boot/dts/qcom/sc8180x-primus.dts +++ b/arch/arm64/boot/dts/qcom/sc8180x-primus.dts
@@ -592,8 +592,6 @@ &mdss_edp_out { }; &pcie1 { - perst-gpios = <&tlmm 175 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 177 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; pinctrl-0 = <&pcie2_default_state>; @@ -607,6 +605,11 @@ &pcie1_phy { status = "okay"; }; +&pcie1_port0 { + reset-gpios = <&tlmm 175 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 177 GPIO_ACTIVE_LOW>; +}; + &pmc8180_pwrkey { status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/sc8180x.dtsi b/arch/arm64/boot/dts/qcom/sc8180x.dtsi index de1b72b..a85e321 100644 --- a/arch/arm64/boot/dts/qcom/sc8180x.dtsi +++ b/arch/arm64/boot/dts/qcom/sc8180x.dtsi
@@ -1779,17 +1779,17 @@ pcie0: pcie@1c00000 { <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_0 0>; interconnect-names = "pcie-mem", "cpu-pcie"; - phys = <&pcie0_phy>; - phy-names = "pciephy"; dma-coherent; status = "disabled"; - pcie@0 { + pcie0_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie0_phy>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -1898,17 +1898,17 @@ pcie3: pcie@1c08000 { <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_3 0>; interconnect-names = "pcie-mem", "cpu-pcie"; - phys = <&pcie3_phy>; - phy-names = "pciephy"; dma-coherent; status = "disabled"; - pcie@0 { + pcie3_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie3_phy>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -2018,17 +2018,17 @@ pcie1: pcie@1c10000 { <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_1 0>; interconnect-names = "pcie-mem", "cpu-pcie"; - phys = <&pcie1_phy>; - phy-names = "pciephy"; dma-coherent; status = "disabled"; - pcie@0 { + pcie1_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie1_phy>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -2138,17 +2138,17 @@ pcie2: pcie@1c18000 { <&gem_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_PCIE_2 0>; interconnect-names = "pcie-mem", "cpu-pcie"; - phys = <&pcie2_phy>; - phy-names = "pciephy"; dma-coherent; status = "disabled"; - pcie@0 { + pcie2_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie2_phy>; + #address-cells = <3>; #size-cells = <2>; ranges;
diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts index 1eea9d7..f4af4f2 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts +++ b/arch/arm64/boot/dts/qcom/sc8280xp-crd.dts
@@ -493,14 +493,17 @@ &dispcc0 { }; &gpi_dma0 { + dma-channel-mask = <0x3>; status = "okay"; }; &gpi_dma1 { + dma-channel-mask = <0x3>; status = "okay"; }; &gpi_dma2 { + dma-channel-mask = <0x3>; status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-huawei-gaokun3.dts b/arch/arm64/boot/dts/qcom/sc8280xp-huawei-gaokun3.dts index adce030..43bd2e0 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp-huawei-gaokun3.dts +++ b/arch/arm64/boot/dts/qcom/sc8280xp-huawei-gaokun3.dts
@@ -582,14 +582,17 @@ &dispcc0 { }; &gpi_dma0 { + dma-channel-mask = <0xb>; status = "okay"; }; &gpi_dma1 { + dma-channel-mask = <0x3>; status = "okay"; }; &gpi_dma2 { + dma-channel-mask = <0xb>; status = "okay"; }; @@ -1363,11 +1366,11 @@ perst-n-pins { }; wake-n-pins { - pins = "gpio145"; - function = "gpio"; - drive-strength = <2>; - bias-pull-up; - }; + pins = "gpio145"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; }; pcie4_default: pcie4-default-state {
diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts index 218573a..52e5e23 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts +++ b/arch/arm64/boot/dts/qcom/sc8280xp-lenovo-thinkpad-x13s.dts
@@ -705,14 +705,17 @@ &dispcc0 { }; &gpi_dma0 { + dma-channel-mask = <0x3>; status = "okay"; }; &gpi_dma1 { + dma-channel-mask = <0x3>; status = "okay"; }; &gpi_dma2 { + dma-channel-mask = <0x3>; status = "okay"; }; @@ -734,6 +737,7 @@ &mdss0_dp0 { &mdss0_dp0_out { data-lanes = <0 1 2 3>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; remote-endpoint = <&usb_0_qmpphy_dp_in>; }; @@ -743,6 +747,7 @@ &mdss0_dp1 { &mdss0_dp1_out { data-lanes = <0 1 2 3>; + link-frequencies = /bits/ 64 <1620000000 2700000000 5400000000 8100000000>; remote-endpoint = <&usb_1_qmpphy_dp_in>; }; @@ -1213,6 +1218,38 @@ &sound { "VA DMIC2", "MIC BIAS3", "TX SWR_ADC1", "ADC2_OUTPUT"; + dp0-dai-link { + link-name = "DP0 Playback"; + + codec { + sound-dai = <&mdss0_dp0>; + }; + + cpu { + sound-dai = <&q6apmbedai DISPLAY_PORT_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + dp1-dai-link { + link-name = "DP1 Playback"; + + codec { + sound-dai = <&mdss0_dp1>; + }; + + cpu { + sound-dai = <&q6apmbedai DISPLAY_PORT_RX_1>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + wcd-playback-dai-link { link-name = "WCD Playback"; cpu {
diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-microsoft-arcata.dts b/arch/arm64/boot/dts/qcom/sc8280xp-microsoft-arcata.dts index 89c4ba2..cc50805 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp-microsoft-arcata.dts +++ b/arch/arm64/boot/dts/qcom/sc8280xp-microsoft-arcata.dts
@@ -564,14 +564,17 @@ &dispcc0 { }; &gpi_dma0 { + dma-channel-mask = <0x3>; status = "okay"; }; &gpi_dma1 { + dma-channel-mask = <0x3>; status = "okay"; }; &gpi_dma2 { + dma-channel-mask = <0x23>; status = "okay"; }; @@ -1114,7 +1117,7 @@ wake-n-pins { function = "gpio"; drive-strength = <2>; bias-pull-up; - }; + }; }; pcie3a_default: pcie3a-default-state {
diff --git a/arch/arm64/boot/dts/qcom/sc8280xp-microsoft-blackrock.dts b/arch/arm64/boot/dts/qcom/sc8280xp-microsoft-blackrock.dts index 4f4b5f4..58e6c6f 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp-microsoft-blackrock.dts +++ b/arch/arm64/boot/dts/qcom/sc8280xp-microsoft-blackrock.dts
@@ -561,14 +561,17 @@ &dispcc0 { }; &gpi_dma0 { + dma-channel-mask = <0x3>; status = "okay"; }; &gpi_dma1 { + dma-channel-mask = <0x3>; status = "okay"; }; &gpi_dma2 { + dma-channel-mask = <0x23>; status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi index fbcfd38..d17475c 100644 --- a/arch/arm64/boot/dts/qcom/sc8280xp.dtsi +++ b/arch/arm64/boot/dts/qcom/sc8280xp.dtsi
@@ -885,7 +885,6 @@ gpi_dma2: dma-controller@800000 { <GIC_SPI 599 IRQ_TYPE_LEVEL_HIGH>; dma-channels = <12>; - dma-channel-mask = <0xfff>; #dma-cells = <3>; iommus = <&apps_smmu 0xb6 0x0>; @@ -917,8 +916,8 @@ i2c16: i2c@880000 { interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, - <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma2 0 0 QCOM_GPI_I2C>, @@ -939,8 +938,8 @@ spi16: spi@880000 { interrupts = <GIC_SPI 373 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, - <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma2 0 0 QCOM_GPI_SPI>, @@ -961,8 +960,8 @@ i2c17: i2c@884000 { interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, - <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma2 0 1 QCOM_GPI_I2C>, @@ -983,8 +982,8 @@ spi17: spi@884000 { interrupts = <GIC_SPI 583 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, - <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma2 0 1 QCOM_GPI_SPI>, @@ -1019,8 +1018,8 @@ i2c18: i2c@888000 { interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, - <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma2 0 2 QCOM_GPI_I2C>, @@ -1041,8 +1040,8 @@ spi18: spi@888000 { interrupts = <GIC_SPI 584 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, - <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma2 0 2 QCOM_GPI_SPI>, @@ -1081,8 +1080,8 @@ i2c19: i2c@88c000 { interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, - <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma2 0 3 QCOM_GPI_I2C>, @@ -1103,8 +1102,8 @@ spi19: spi@88c000 { interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, - <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma2 0 3 QCOM_GPI_SPI>, @@ -1125,8 +1124,8 @@ i2c20: i2c@890000 { interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, - <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma2 0 4 QCOM_GPI_I2C>, @@ -1147,8 +1146,8 @@ spi20: spi@890000 { interrupts = <GIC_SPI 586 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, - <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma2 0 4 QCOM_GPI_SPI>, @@ -1191,8 +1190,8 @@ spi21: spi@894000 { interrupts = <GIC_SPI 587 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, - <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma2 0 5 QCOM_GPI_SPI>, @@ -1235,8 +1234,8 @@ spi22: spi@898000 { interrupts = <GIC_SPI 833 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, - <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma2 0 6 QCOM_GPI_SPI>, @@ -1279,8 +1278,8 @@ spi23: spi@89c000 { interrupts = <GIC_SPI 834 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_2 0 &clk_virt SLAVE_QUP_CORE_2 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, - <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_2 0>, + <&aggre1_noc MASTER_QUP_2 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma2 0 7 QCOM_GPI_SPI>, @@ -1311,7 +1310,6 @@ gpi_dma0: dma-controller@900000 { <GIC_SPI 256 IRQ_TYPE_LEVEL_HIGH>; dma-channels = <13>; - dma-channel-mask = <0x1fff>; #dma-cells = <3>; iommus = <&apps_smmu 0x576 0x0>; @@ -1718,7 +1716,6 @@ gpi_dma1: dma-controller@a00000 { <GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>; dma-channels = <12>; - dma-channel-mask = <0xfff>; #dma-cells = <3>; iommus = <&apps_smmu 0x96 0x0>; @@ -1750,8 +1747,8 @@ i2c8: i2c@a80000 { interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, - <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma1 0 0 QCOM_GPI_I2C>, @@ -1772,8 +1769,8 @@ spi8: spi@a80000 { interrupts = <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, - <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma1 0 0 QCOM_GPI_SPI>, @@ -1794,8 +1791,8 @@ i2c9: i2c@a84000 { interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, - <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma1 0 1 QCOM_GPI_I2C>, @@ -1816,8 +1813,8 @@ spi9: spi@a84000 { interrupts = <GIC_SPI 354 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, - <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma1 0 1 QCOM_GPI_SPI>, @@ -1838,8 +1835,8 @@ i2c10: i2c@a88000 { interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, - <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma1 0 2 QCOM_GPI_I2C>, @@ -1860,8 +1857,8 @@ spi10: spi@a88000 { interrupts = <GIC_SPI 355 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, - <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma1 0 2 QCOM_GPI_SPI>, @@ -1882,8 +1879,8 @@ i2c11: i2c@a8c000 { interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, - <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma1 0 3 QCOM_GPI_I2C>, @@ -1904,8 +1901,8 @@ spi11: spi@a8c000 { interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, - <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma1 0 3 QCOM_GPI_SPI>, @@ -1926,8 +1923,8 @@ i2c12: i2c@a90000 { interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, - <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma1 0 4 QCOM_GPI_I2C>, @@ -1948,8 +1945,8 @@ spi12: spi@a90000 { interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, - <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma1 0 4 QCOM_GPI_SPI>, @@ -1970,8 +1967,8 @@ i2c13: i2c@a94000 { interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, - <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma1 0 5 QCOM_GPI_I2C>, @@ -1992,8 +1989,8 @@ spi13: spi@a94000 { interrupts = <GIC_SPI 358 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, - <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma1 0 5 QCOM_GPI_SPI>, @@ -2014,8 +2011,8 @@ i2c14: i2c@a98000 { interrupts = <GIC_SPI 835 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, - <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma1 0 6 QCOM_GPI_I2C>, @@ -2036,8 +2033,8 @@ spi14: spi@a98000 { interrupts = <GIC_SPI 835 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, - <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma1 0 6 QCOM_GPI_SPI>, @@ -2058,8 +2055,8 @@ i2c15: i2c@a9c000 { interrupts = <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, - <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma1 0 7 QCOM_GPI_I2C>, @@ -2080,8 +2077,8 @@ spi15: spi@a9c000 { interrupts = <GIC_SPI 836 IRQ_TYPE_LEVEL_HIGH>; power-domains = <&rpmhpd SC8280XP_CX>; interconnects = <&clk_virt MASTER_QUP_CORE_1 0 &clk_virt SLAVE_QUP_CORE_1 0>, - <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, - <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; + <&gem_noc MASTER_APPSS_PROC 0 &config_noc SLAVE_QUP_1 0>, + <&aggre1_noc MASTER_QUP_1 0 &mc_virt SLAVE_EBI1 0>; interconnect-names = "qup-core", "qup-config", "qup-memory"; dmas = <&gpi_dma1 0 7 QCOM_GPI_SPI>, @@ -2910,18 +2907,21 @@ compute-cb@1 { compatible = "qcom,fastrpc-compute-cb"; reg = <1>; iommus = <&apps_smmu 0x0521 0x0>; + dma-coherent; }; compute-cb@2 { compatible = "qcom,fastrpc-compute-cb"; reg = <2>; iommus = <&apps_smmu 0x0522 0x0>; + dma-coherent; }; compute-cb@3 { compatible = "qcom,fastrpc-compute-cb"; reg = <3>; iommus = <&apps_smmu 0x0523 0x0>; + dma-coherent; }; }; }; @@ -2978,18 +2978,21 @@ compute-cb@3 { compatible = "qcom,fastrpc-compute-cb"; reg = <3>; iommus = <&apps_smmu 0x0c03 0x0>; + dma-coherent; }; compute-cb@4 { compatible = "qcom,fastrpc-compute-cb"; reg = <4>; iommus = <&apps_smmu 0x0c04 0x0>; + dma-coherent; }; compute-cb@5 { compatible = "qcom,fastrpc-compute-cb"; reg = <5>; iommus = <&apps_smmu 0x0c05 0x0>; + dma-coherent; }; }; @@ -6235,84 +6238,98 @@ compute-cb@1 { compatible = "qcom,fastrpc-compute-cb"; reg = <1>; iommus = <&apps_smmu 0x3181 0x0420>; + dma-coherent; }; compute-cb@2 { compatible = "qcom,fastrpc-compute-cb"; reg = <2>; iommus = <&apps_smmu 0x3182 0x0420>; + dma-coherent; }; compute-cb@3 { compatible = "qcom,fastrpc-compute-cb"; reg = <3>; iommus = <&apps_smmu 0x3183 0x0420>; + dma-coherent; }; compute-cb@4 { compatible = "qcom,fastrpc-compute-cb"; reg = <4>; iommus = <&apps_smmu 0x3184 0x0420>; + dma-coherent; }; compute-cb@5 { compatible = "qcom,fastrpc-compute-cb"; reg = <5>; iommus = <&apps_smmu 0x3185 0x0420>; + dma-coherent; }; compute-cb@6 { compatible = "qcom,fastrpc-compute-cb"; reg = <6>; iommus = <&apps_smmu 0x3186 0x0420>; + dma-coherent; }; compute-cb@7 { compatible = "qcom,fastrpc-compute-cb"; reg = <7>; iommus = <&apps_smmu 0x3187 0x0420>; + dma-coherent; }; compute-cb@8 { compatible = "qcom,fastrpc-compute-cb"; reg = <8>; iommus = <&apps_smmu 0x3188 0x0420>; + dma-coherent; }; compute-cb@9 { compatible = "qcom,fastrpc-compute-cb"; reg = <9>; iommus = <&apps_smmu 0x318b 0x0420>; + dma-coherent; }; compute-cb@10 { compatible = "qcom,fastrpc-compute-cb"; reg = <10>; iommus = <&apps_smmu 0x318b 0x0420>; + dma-coherent; }; compute-cb@11 { compatible = "qcom,fastrpc-compute-cb"; reg = <11>; iommus = <&apps_smmu 0x318c 0x0420>; + dma-coherent; }; compute-cb@12 { compatible = "qcom,fastrpc-compute-cb"; reg = <12>; iommus = <&apps_smmu 0x318d 0x0420>; + dma-coherent; }; compute-cb@13 { compatible = "qcom,fastrpc-compute-cb"; reg = <13>; iommus = <&apps_smmu 0x318e 0x0420>; + dma-coherent; }; compute-cb@14 { compatible = "qcom,fastrpc-compute-cb"; reg = <14>; iommus = <&apps_smmu 0x318f 0x0420>; + dma-coherent; }; }; }; @@ -7084,7 +7101,19 @@ sound: sound { }; thermal-zones { - cpu0-thermal { + aoss-0-thermal { + thermal-sensors = <&tsens0 0>; + + trips { + aoss-critical { + temperature = <110000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu0-0-thermal { thermal-sensors = <&tsens0 1>; trips { @@ -7096,7 +7125,7 @@ cpu-crit { }; }; - cpu1-thermal { + cpu1-0-thermal { thermal-sensors = <&tsens0 2>; trips { @@ -7108,7 +7137,7 @@ cpu-crit { }; }; - cpu2-thermal { + cpu2-0-thermal { thermal-sensors = <&tsens0 3>; trips { @@ -7120,7 +7149,7 @@ cpu-crit { }; }; - cpu3-thermal { + cpu3-0-thermal { thermal-sensors = <&tsens0 4>; trips { @@ -7132,7 +7161,7 @@ cpu-crit { }; }; - cpu4-thermal { + cpu4-0-thermal { thermal-sensors = <&tsens0 5>; trips { @@ -7144,7 +7173,7 @@ cpu-crit { }; }; - cpu5-thermal { + cpu5-0-thermal { thermal-sensors = <&tsens0 6>; trips { @@ -7156,7 +7185,7 @@ cpu-crit { }; }; - cpu6-thermal { + cpu6-0-thermal { thermal-sensors = <&tsens0 7>; trips { @@ -7168,7 +7197,7 @@ cpu-crit { }; }; - cpu7-thermal { + cpu7-0-thermal { thermal-sensors = <&tsens0 8>; trips { @@ -7180,7 +7209,7 @@ cpu-crit { }; }; - cluster0-thermal { + cpuss0-thermal { thermal-sensors = <&tsens0 9>; trips { @@ -7192,10 +7221,262 @@ cpu-crit { }; }; - gpu-thermal { + nsp0-0-thermal { + thermal-sensors = <&tsens0 10>; + + trips { + nsp0-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsp1-0-thermal { + thermal-sensors = <&tsens0 11>; + + trips { + nsp1-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + smss-0-thermal { + thermal-sensors = <&tsens0 12>; + + trips { + smss-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + camss-0-thermal { + thermal-sensors = <&tsens0 13>; + + trips { + camss-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + aoss-1-thermal { + thermal-sensors = <&tsens1 0>; + + trips { + aoss-critical { + temperature = <110000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + cpu0-1-thermal { + thermal-sensors = <&tsens1 1>; + + trips { + cpu-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu1-1-thermal { + thermal-sensors = <&tsens1 2>; + + trips { + cpu-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu2-1-thermal { + thermal-sensors = <&tsens1 3>; + + trips { + cpu-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu3-1-thermal { + thermal-sensors = <&tsens1 4>; + + trips { + cpu-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu4-1-thermal { + thermal-sensors = <&tsens1 5>; + + trips { + cpu-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu5-1-thermal { + thermal-sensors = <&tsens1 6>; + + trips { + cpu-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu6-1-thermal { + thermal-sensors = <&tsens1 7>; + + trips { + cpu-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpu7-1-thermal { + thermal-sensors = <&tsens1 8>; + + trips { + cpu-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + cpuss1-thermal { + thermal-sensors = <&tsens1 9>; + + trips { + cpu-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsp0-2-thermal { + thermal-sensors = <&tsens1 10>; + + trips { + nsp0-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsp1-2-thermal { + thermal-sensors = <&tsens1 11>; + + trips { + nsp1-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + smss-1-thermal { + thermal-sensors = <&tsens1 12>; + + trips { + smss-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + camss-1-thermal { + thermal-sensors = <&tsens1 13>; + + trips { + camss-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + pcie-0-thermal { + thermal-sensors = <&tsens1 14>; + + trips { + pcie-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + ddrss-0-thermal { + thermal-sensors = <&tsens1 15>; + + trips { + trip-point0 { + temperature = <90000>; + hysteresis = <2000>; + type = "hot"; + }; + }; + }; + + aoss-2-thermal { + thermal-sensors = <&tsens2 0>; + + trips { + aoss-critical { + temperature = <110000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-0-thermal { polling-delay-passive = <250>; - thermal-sensors = <&tsens2 2>; + thermal-sensors = <&tsens2 1>; cooling-maps { map0 { @@ -7219,8 +7500,101 @@ trip-point1 { }; }; - mem-thermal { - thermal-sensors = <&tsens1 15>; + gpuss-1-thermal { + polling-delay-passive = <250>; + + thermal-sensors = <&tsens2 2>; + + cooling-maps { + map0 { + trip = <&gpu_alert1>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + + trips { + gpu_alert1: trip-point0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + + trip-point1 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpuss-2-thermal { + polling-delay-passive = <250>; + + thermal-sensors = <&tsens2 3>; + + cooling-maps { + map0 { + trip = <&gpu_alert2>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + + trips { + gpu_alert2: trip-point0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + + trip-point1 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpuss-3-thermal { + polling-delay-passive = <250>; + + thermal-sensors = <&tsens2 4>; + + cooling-maps { + map0 { + trip = <&gpu_alert3>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + + trips { + gpu_alert3: trip-point0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + + trip-point1 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + pcie-1-thermal { + thermal-sensors = <&tsens2 5>; + + trips { + pcie-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + ddrss-1-thermal { + thermal-sensors = <&tsens2 6>; trips { trip-point0 { @@ -7230,6 +7604,174 @@ trip-point0 { }; }; }; + + audio-thermal { + thermal-sensors = <&tsens2 7>; + + trips { + audio-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + video-thermal { + thermal-sensors = <&tsens2 8>; + + trips { + video-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsp0-1-thermal { + thermal-sensors = <&tsens2 9>; + + trips { + nsp0-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + nsp1-1-thermal { + thermal-sensors = <&tsens2 10>; + + trips { + nsp1-crit { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + aoss-3-thermal { + thermal-sensors = <&tsens3 0>; + + trips { + aoss-critical { + temperature = <110000>; + hysteresis = <0>; + type = "critical"; + }; + }; + }; + + gpuss-4-thermal { + polling-delay-passive = <250>; + + thermal-sensors = <&tsens3 1>; + + cooling-maps { + map0 { + trip = <&gpu_alert4>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + + trips { + gpu_alert4: trip-point0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + + trip-point1 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpuss-5-thermal { + polling-delay-passive = <250>; + + thermal-sensors = <&tsens3 2>; + + cooling-maps { + map0 { + trip = <&gpu_alert5>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + + trips { + gpu_alert5: trip-point0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + + trip-point1 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpuss-6-thermal { + polling-delay-passive = <250>; + + thermal-sensors = <&tsens3 3>; + + cooling-maps { + map0 { + trip = <&gpu_alert6>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + + trips { + gpu_alert6: trip-point0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + + trip-point1 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; + + gpuss-7-thermal { + polling-delay-passive = <250>; + + thermal-sensors = <&tsens3 4>; + + cooling-maps { + map0 { + trip = <&gpu_alert7>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + + trips { + gpu_alert7: trip-point0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + + trip-point1 { + temperature = <110000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + }; }; timer {
diff --git a/arch/arm64/boot/dts/qcom/sdm630.dtsi b/arch/arm64/boot/dts/qcom/sdm630.dtsi index a41ba0d..3a10148 100644 --- a/arch/arm64/boot/dts/qcom/sdm630.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm630.dtsi
@@ -1195,7 +1195,7 @@ kgsl_smmu: iommu@5040000 { <&gcc GCC_BIMC_GFX_CLK>, <&gcc GCC_GPU_BIMC_GFX_CLK>; clock-names = "iface", - "mem", + "mem", "mem_iface"; #global-interrupts = <2>; #iommu-cells = <1>; @@ -1423,26 +1423,26 @@ sdhc_2: mmc@c084000 { status = "disabled"; sdhc2_opp_table: opp-table { - compatible = "operating-points-v2"; + compatible = "operating-points-v2"; - opp-50000000 { + opp-50000000 { opp-hz = /bits/ 64 <50000000>; required-opps = <&rpmpd_opp_low_svs>; opp-peak-kBps = <200000 140000>; opp-avg-kBps = <130718 133320>; - }; - opp-100000000 { + }; + opp-100000000 { opp-hz = /bits/ 64 <100000000>; required-opps = <&rpmpd_opp_svs>; opp-peak-kBps = <250000 160000>; opp-avg-kBps = <196078 150000>; - }; - opp-200000000 { + }; + opp-200000000 { opp-hz = /bits/ 64 <200000000>; required-opps = <&rpmpd_opp_nom>; opp-peak-kBps = <4096000 4096000>; opp-avg-kBps = <1338562 1338562>; - }; + }; }; };
diff --git a/arch/arm64/boot/dts/qcom/sdm670-google-common.dtsi b/arch/arm64/boot/dts/qcom/sdm670-google-common.dtsi index b485480..55f313b 100644 --- a/arch/arm64/boot/dts/qcom/sdm670-google-common.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm670-google-common.dtsi
@@ -26,7 +26,9 @@ /delete-node/ &gpu_mem; / { - aliases { }; + aliases { + serial0 = &uart12; + }; battery: battery { compatible = "simple-battery"; @@ -490,6 +492,25 @@ &gpu_zap_shader { firmware-name = "qcom/sdm670/sargo/a615_zap.mbn"; }; +&i2c3 { + clock-frequency = <400000>; + + status = "okay"; + + nfc@28 { + compatible = "nxp,pn557", "nxp,nxp-nci-i2c"; + reg = <0x28>; + + interrupts-extended = <&tlmm 44 IRQ_TYPE_EDGE_RISING>; + + enable-gpios = <&tlmm 12 GPIO_ACTIVE_HIGH>; + firmware-gpios = <&tlmm 43 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&nfc_default>; + pinctrl-names = "default"; + }; +}; + &i2c9 { clock-frequency = <100000>; status = "okay"; @@ -691,6 +712,33 @@ ts-switch-pins { output-low; }; }; + + nfc_default: nfc-default-state { + enable-pins { + pins = "gpio12"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + firmware-pins { + pins = "gpio43"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + irq-pins { + pins = "gpio44"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + }; +}; + +&uart12 { + status = "okay"; }; &usb_1_hsphy {
diff --git a/arch/arm64/boot/dts/qcom/sdm670.dtsi b/arch/arm64/boot/dts/qcom/sdm670.dtsi index 5c60ea3..711e15b 100644 --- a/arch/arm64/boot/dts/qcom/sdm670.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm670.dtsi
@@ -626,6 +626,7 @@ gcc: clock-controller@100000 { #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; + power-domains = <&rpmhpd SDM670_CX>; }; qfprom: qfprom@784000 { @@ -1060,6 +1061,21 @@ i2c12: i2c@a90000 { status = "disabled"; }; + uart12: serial@a90000 { + compatible = "qcom,geni-debug-uart"; + reg = <0 0x00a90000 0 0x4000>; + clock-names = "se"; + clocks = <&gcc GCC_QUPV3_WRAP1_S4_CLK>; + pinctrl-names = "default"; + pinctrl-0 = <&qup_uart12_default>; + interrupts = <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&rpmhpd SDM670_CX>; + interconnects = <&aggre2_noc MASTER_BLSP_2 0 &config_noc SLAVE_BLSP_2 0>, + <&gladiator_noc MASTER_AMPSS_M0 0 &config_noc SLAVE_BLSP_2 0>; + interconnect-names = "qup-core", "qup-config"; + status = "disabled"; + }; + i2c13: i2c@a94000 { compatible = "qcom,geni-i2c"; reg = <0 0x00a94000 0 0x4000>; @@ -1343,6 +1359,262 @@ qup_i2c15_default: qup-i2c15-default-state { function = "qup15"; }; + qup_uart0_default: qup-uart0-default-state { + tx-pins { + pins = "gpio2"; + function = "qup0"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio3"; + function = "qup0"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart1_default: qup-uart1-default-state { + tx-pins { + pins = "gpio19"; + function = "qup1"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio20"; + function = "qup1"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart2_default: qup-uart2-default-state { + tx-pins { + pins = "gpio29"; + function = "qup2"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio30"; + function = "qup2"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart3_default: qup-uart3-default-state { + tx-pins { + pins = "gpio43"; + function = "qup3"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio44"; + function = "qup3"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart4_default: qup-uart4-default-state { + tx-pins { + pins = "gpio91"; + function = "qup4"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio92"; + function = "qup4"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart5_default: qup-uart5-default-state { + tx-pins { + pins = "gpio87"; + function = "qup5"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio88"; + function = "qup5"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart6_default: qup-uart6-default-state { + tx-pins { + pins = "gpio47"; + function = "qup6"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio48"; + function = "qup6"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart7_default: qup-uart7-default-state { + tx-pins { + pins = "gpio95"; + function = "qup7"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio96"; + function = "qup7"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart8_default: qup-uart8-default-state { + tx-pins { + pins = "gpio67"; + function = "qup8"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio68"; + function = "qup8"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart9_default: qup-uart9-default-state { + tx-pins { + pins = "gpio4"; + function = "qup9"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio5"; + function = "qup9"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart10_default: qup-uart10-default-state { + tx-pins { + pins = "gpio53"; + function = "qup10"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio54"; + function = "qup10"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart11_default: qup-uart11-default-state { + tx-pins { + pins = "gpio33"; + function = "qup11"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio34"; + function = "qup11"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart12_default: qup-uart12-default-state { + tx-pins { + pins = "gpio51"; + function = "qup12"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio52"; + function = "qup12"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart13_default: qup-uart13-default-state { + tx-pins { + pins = "gpio107"; + function = "qup13"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio108"; + function = "qup13"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart14_default: qup-uart14-default-state { + tx-pins { + pins = "gpio31"; + function = "qup14"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio32"; + function = "qup14"; + drive-strength = <2>; + bias-disable; + }; + }; + + qup_uart15_default: qup-uart15-default-state { + tx-pins { + pins = "gpio83"; + function = "qup15"; + drive-strength = <2>; + bias-disable; + }; + + rx-pins { + pins = "gpio84"; + function = "qup15"; + drive-strength = <2>; + bias-disable; + }; + }; + sdc1_state_on: sdc1-on-state { clk-pins { pins = "sdc1_clk";
diff --git a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts index 8461381..02cb29a 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-db845c.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-db845c.dts
@@ -618,9 +618,6 @@ &mss_pil { &pcie0 { status = "okay"; - perst-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 134 GPIO_ACTIVE_HIGH>; - vddpe-3v3-supply = <&pcie0_3p3v_dual>; pinctrl-names = "default"; @@ -634,9 +631,13 @@ &pcie0_phy { vdda-pll-supply = <&vreg_l26a_1p2>; }; +&pcie0_port0 { + reset-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 134 GPIO_ACTIVE_LOW>; +}; + &pcie1 { status = "okay"; - perst-gpios = <&tlmm 102 GPIO_ACTIVE_LOW>; pinctrl-names = "default"; pinctrl-0 = <&pcie1_default_state>; @@ -649,6 +650,10 @@ &pcie1_phy { vdda-pll-supply = <&vreg_l26a_1p2>; }; +&pcie1_port0 { + reset-gpios = <&tlmm 102 GPIO_ACTIVE_LOW>; +}; + &pm8998_gpios { gpio-line-names = "NC",
diff --git a/arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi index 9e952f9..f137985 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-google-common.dtsi
@@ -392,6 +392,8 @@ &gpu_zap_shader { }; &i2c3 { + clock-frequency = <400000>; + status = "okay"; nfc@28 { @@ -403,7 +405,7 @@ nfc@28 { enable-gpios = <&tlmm 25 GPIO_ACTIVE_HIGH>; firmware-gpios = <&tlmm 79 GPIO_ACTIVE_HIGH>; - pinctrl-0 = <&nfc_int_default &nfc_enable_default>; + pinctrl-0 = <&nfc_default>; pinctrl-names = "default"; }; }; @@ -476,18 +478,28 @@ &tlmm { gpio-reserved-ranges = < 0 4>, /* SPI (Intel MNH Pixel Visual Core) */ <81 4>; /* SPI (most likely Fingerprint Cards FPC1075) */ - nfc_int_default: nfc-int-default-state { - pins = "gpio63"; - function = "gpio"; - drive-strength = <2>; - bias-pull-down; - }; + nfc_default: nfc-default-state { + enable-pins { + pins = "gpio25"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; - nfc_enable_default: nfc-enable-default-state { - pins = "gpio25", "gpio79"; - function = "gpio"; - drive-strength = <2>; - bias-pull-down; + irq-pins { + pins = "gpio63"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + + firmware-pins { + pins = "gpio79"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + }; touchscreen_reset: ts-reset-state {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi index b030a10..84f0e1f 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-lg-common.dtsi
@@ -581,33 +581,26 @@ &tlmm { sdc2_clk: sdc2-clk-state { pins = "sdc2_clk"; bias-disable; - - /* - * It seems that mmc_test reports errors if drive - * strength is not 16 on clk, cmd, and data pins. - * - * TODO: copy-pasted from mtp, try other values - * on these devices. - */ drive-strength = <16>; }; sdc2_cmd: sdc2-cmd-state { pins = "sdc2_cmd"; bias-pull-up; - drive-strength = <16>; + drive-strength = <10>; }; sdc2_data: sdc2-data-state { pins = "sdc2_data"; bias-pull-up; - drive-strength = <16>; + drive-strength = <10>; }; sd_card_det_n: sd-card-det-n-state { pins = "gpio126"; function = "gpio"; bias-pull-up; + drive-strength = <2>; }; };
diff --git a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts index c66df45..88aa0b7d 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-mtp.dts
@@ -508,8 +508,6 @@ &mss_pil { }; &pcie0 { - perst-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&pcie0_default_state>; pinctrl-names = "default"; @@ -523,9 +521,11 @@ &pcie0_phy { status = "okay"; }; -&pcie1 { - perst-gpios = <&tlmm 102 GPIO_ACTIVE_LOW>; +&pcie0_port0 { + reset-gpios = <&tlmm 35 GPIO_ACTIVE_LOW>; +}; +&pcie1 { pinctrl-names = "default"; pinctrl-0 = <&pcie1_default_state>; @@ -539,6 +539,10 @@ &pcie1_phy { vdda-pll-supply = <&vreg_l26a_1p2>; }; +&pcie1_port0 { + reset-gpios = <&tlmm 102 GPIO_ACTIVE_LOW>; +}; + &pm8998_adc { channel@4c { reg = <ADC5_XO_THERM_100K_PU>;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi index 439779f3..1df09da 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-common.dtsi
@@ -510,7 +510,6 @@ &i2c10 { bq27441_fg: bq27441-battery@55 { compatible = "ti,bq27411"; - status = "okay"; reg = <0x55>; }; }; @@ -543,7 +542,7 @@ rmi4-f01@1 { rmi4_f12: rmi4-f12@12 { reg = <0x12>; touchscreen-x-mm = <68>; - touchscreen-y-mm = <144>; + syna,clip-x-high = <1079>; syna,sensor-type = <1>; syna,rezero-wait-ms = <200>; }; @@ -1099,6 +1098,10 @@ &wcd9340 { vdd-tx-supply = <&vreg_s4a_1p8>; vdd-rx-supply = <&vreg_s4a_1p8>; vdd-io-supply = <&vreg_s4a_1p8>; + qcom,mbhc-buttons-vthreshold-microvolt = <75000 150000 237000 500000 + 500000 500000 500000 500000>; + qcom,mbhc-headset-vthreshold-microvolt = <1700000>; + qcom,mbhc-headphone-vthreshold-microvolt = <50000>; }; &wifi {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-enchilada.dts b/arch/arm64/boot/dts/qcom/sdm845-oneplus-enchilada.dts index 3b30d79..276217f 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-enchilada.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-enchilada.dts
@@ -95,6 +95,11 @@ led@5 { }; }; +&rmi4_f12 { + touchscreen-y-mm = <144>; + syna,clip-y-high = <2279>; +}; + &sound { model = "OnePlus 6"; audio-routing = "RX_BIAS", "MCLK",
diff --git a/arch/arm64/boot/dts/qcom/sdm845-oneplus-fajita.dts b/arch/arm64/boot/dts/qcom/sdm845-oneplus-fajita.dts index 0542333..e9d1a1c 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-oneplus-fajita.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-oneplus-fajita.dts
@@ -70,6 +70,7 @@ &pmi8998_charger { &rmi4_f12 { touchscreen-y-mm = <148>; + syna,clip-y-high = <2339>; }; &wcd9340 {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi index 4c63286..05e5a36 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-sony-xperia-tama.dtsi
@@ -754,6 +754,8 @@ int-pins { }; &uart6 { + pinctrl-0 = <&qup_uart6_4pin>; + status = "okay"; bluetooth {
diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi index 080f529..35babe8 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-beryllium-common.dtsi
@@ -27,6 +27,7 @@ /delete-node/ &slpi_mem; /delete-node/ &spss_mem; /delete-node/ &rmtfs_mem; +/delete-node/ &xbl_mem; / { chassis-type = "handset"; @@ -71,6 +72,11 @@ key-vol-up { /* Reserved memory changes from downstream */ reserved-memory { + xbl-mem@85d00000 { + reg = <0 0x85d00000 0 0x200000>; + no-map; + }; + tz_mem: memory@86200000 { reg = <0 0x86200000 0 0x4900000>; no-map;
diff --git a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts index d3162e44..a782023 100644 --- a/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts +++ b/arch/arm64/boot/dts/qcom/sdm845-xiaomi-polaris.dts
@@ -32,6 +32,7 @@ /delete-node/ &mba_region; /delete-node/ &slpi_mem; /delete-node/ &spss_mem; +/delete-node/ &xbl_mem; / { model = "Xiaomi Mi MIX 2S"; @@ -63,6 +64,11 @@ key-vol-up { }; reserved-memory { + xbl-mem@85d00000 { + reg = <0 0x85d00000 0 0x200000>; + no-map; + }; + adsp_mem: memory@8c500000 { reg = <0 0x8c500000 0 0x1e00000>; no-map;
diff --git a/arch/arm64/boot/dts/qcom/sdm845.dtsi b/arch/arm64/boot/dts/qcom/sdm845.dtsi index b1f6782..844b840 100644 --- a/arch/arm64/boot/dts/qcom/sdm845.dtsi +++ b/arch/arm64/boot/dts/qcom/sdm845.dtsi
@@ -2395,16 +2395,15 @@ pcie0: pcie@1c00000 { power-domains = <&gcc PCIE_0_GDSC>; - phys = <&pcie0_phy>; - phy-names = "pciephy"; - status = "disabled"; - pcie@0 { + pcie0_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie0_phy>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -2525,16 +2524,15 @@ pcie1: pcie@1c08000 { power-domains = <&gcc PCIE_1_GDSC>; - phys = <&pcie1_phy>; - phy-names = "pciephy"; - status = "disabled"; - pcie@0 { + pcie1_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie1_phy>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -4626,7 +4624,7 @@ mdss: display-subsystem@ae00000 { interconnect-names = "mdp0-mem", "mdp1-mem"; iommus = <&apps_smmu 0x880 0x8>, - <&apps_smmu 0xc80 0x8>; + <&apps_smmu 0xc80 0x8>; status = "disabled"; @@ -5031,7 +5029,7 @@ adreno_smmu: iommu@5040000 { <GIC_SPI 370 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 371 IRQ_TYPE_EDGE_RISING>; clocks = <&gcc GCC_GPU_MEMNOC_GFX_CLK>, - <&gcc GCC_GPU_CFG_AHB_CLK>; + <&gcc GCC_GPU_CFG_AHB_CLK>; clock-names = "bus", "iface"; power-domains = <&gpucc GPU_CX_GDSC>; @@ -5050,7 +5048,7 @@ gmu: gmu@506a000 { interrupt-names = "hfi", "gmu"; clocks = <&gpucc GPU_CC_CX_GMU_CLK>, - <&gpucc GPU_CC_CXO_CLK>, + <&gpucc GPU_CC_CXO_CLK>, <&gcc GCC_DDRSS_GPU_AXI_CLK>, <&gcc GCC_GPU_MEMNOC_GFX_CLK>; clock-names = "gmu", "cxo", "axi", "memnoc";
diff --git a/arch/arm64/boot/dts/qcom/sdx75.dtsi b/arch/arm64/boot/dts/qcom/sdx75.dtsi index 85cc9c6..c66f7bd 100644 --- a/arch/arm64/boot/dts/qcom/sdx75.dtsi +++ b/arch/arm64/boot/dts/qcom/sdx75.dtsi
@@ -15,7 +15,6 @@ #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/mailbox/qcom-ipcc.h> #include <dt-bindings/power/qcom,rpmhpd.h> -#include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/soc/qcom,rpmh-rsc.h> / { @@ -487,6 +486,7 @@ gcc: clock-controller@80000 { #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; + power-domains = <&rpmhpd RPMHPD_CX>; }; ipcc: mailbox@408000 { @@ -1137,7 +1137,6 @@ spmi_bus: spmi@c400000 { interrupt-names = "periph_irq"; qcom,ee = <0>; qcom,channel = <0>; - qcom,bus-id = <0>; #address-cells = <2>; #size-cells = <0>; interrupt-controller;
diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-cqs-evk-imx577-camera.dtso b/arch/arm64/boot/dts/qcom/shikra-cqm-cqs-evk-imx577-camera.dtso new file mode 100644 index 0000000..791589b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/shikra-cqm-cqs-evk-imx577-camera.dtso
@@ -0,0 +1,72 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/clock/qcom,shikra-gcc.h> +#include <dt-bindings/gpio/gpio.h> + +&camss { + vdd-csiphy-1p2-supply = <&pm4125_l5>; + vdd-csiphy-1p8-supply = <&pm4125_l13>; + + status = "okay"; +}; + +&camss_csiphy1_port { + camss_csiphy1_inep: endpoint { + data-lanes = <0 1 2 3>; + remote-endpoint = <&imx577_ep1>; + }; +}; + +&cci { + status = "okay"; +}; + +&cci_i2c1 { + #address-cells = <1>; + #size-cells = <0>; + + camera@1a { + compatible = "sony,imx577"; + reg = <0x1a>; + + reset-gpios = <&tlmm 33 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&cam_mclk1_default &cam1_reset_default>; + pinctrl-names = "default"; + + clocks = <&gcc GCC_CAMSS_MCLK1_CLK>; + assigned-clocks = <&gcc GCC_CAMSS_MCLK1_CLK>; + assigned-clock-rates = <24000000>; + + /* + * avdd and dvdd are supplied by on-board regulators on the + * IMX577 module from the connector's 3.3 V rail; they are + * not SoC-controlled. dovdd (1.8 V) powers the carrier board + * level-shifter that translates CCI I2C and reset lines + * between the SoC and the connector. + */ + dovdd-supply = <&pm4125_l15>; + + port { + imx577_ep1: endpoint { + link-frequencies = /bits/ 64 <600000000>; + data-lanes = <1 2 3 4>; + remote-endpoint = <&camss_csiphy1_inep>; + }; + }; + }; +}; + +&tlmm { + cam1_reset_default: cam1-reset-default-state { + pins = "gpio33"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; +};
diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts b/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts index b112b21..bde3b7d 100644 --- a/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts +++ b/arch/arm64/boot/dts/qcom/shikra-cqm-evk.dts
@@ -7,6 +7,7 @@ #include "shikra-cqm-som.dtsi" #include "shikra-evk.dtsi" +#include <dt-bindings/gpio/gpio.h> / { model = "Qualcomm Technologies, Inc. Shikra CQM EVK"; @@ -15,6 +16,7 @@ / { aliases { mmc0 = &sdhc_1; + mmc1 = &sdhc_2; /* SDC2 SD card slot */ serial0 = &uart0; }; @@ -23,6 +25,18 @@ chosen { }; }; +&audiocorecc { + status = "okay"; +}; + +&pm4125_hs_in { + remote-endpoint = <&usb_1_dwc3_hs>; +}; + +&pm4125_ss_in { + remote-endpoint = <&usb_qmpphy_out>; +}; + &remoteproc_cdsp { firmware-name = "qcom/shikra/cdsp.mbn"; @@ -57,3 +71,45 @@ &sdhc_1 { status = "okay"; }; + +&sdhc_2 { + vmmc-supply = <&pm4125_l21>; + vqmmc-supply = <&pm4125_l4>; + + status = "okay"; +}; + +&usb_1 { + dr_mode = "otg"; +}; + +&usb_1_dwc3_hs { + remote-endpoint = <&pm4125_hs_in>; +}; + +&usb_1_hsphy { + vdd-supply = <&pm4125_l12>; + vdda-pll-supply = <&pm4125_l13>; + vdda-phy-dpdm-supply = <&pm4125_l21>; + + status = "okay"; +}; + +&usb_qmpphy { + vdda-phy-supply = <&pm4125_l8>; + vdda-pll-supply = <&pm4125_l13>; + + status = "okay"; +}; + +&usb_qmpphy_out { + remote-endpoint = <&pm4125_ss_in>; +}; + +&usb_2_hsphy { + vdd-supply = <&pm4125_l12>; + vdda-pll-supply = <&pm4125_l13>; + vdda-phy-dpdm-supply = <&pm4125_l21>; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi b/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi index 8ac42ff..95eb725 100644 --- a/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi +++ b/arch/arm64/boot/dts/qcom/shikra-cqm-som.dtsi
@@ -4,6 +4,7 @@ */ #include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/iio/qcom,spmi-vadc.h> #include <dt-bindings/pinctrl/qcom,pmic-gpio.h> #include "shikra.dtsi" @@ -32,6 +33,68 @@ key-volume-up { }; }; + msm_therm_bridge: msm-therm-bridge { + compatible = "generic-adc-thermal"; + io-channels = <&pm4125_adc ADC5_AMUX_THM3_100K_PU>; + io-channel-names = "sensor-channel"; + #thermal-sensor-cells = <0>; + }; + + pa_therm_bridge: pa-therm-bridge { + compatible = "generic-adc-thermal"; + io-channels = <&pm4125_adc ADC5_AMUX_THM1_100K_PU>; + io-channel-names = "sensor-channel"; + #thermal-sensor-cells = <0>; + }; + + quiet_therm_bridge: quiet-therm-bridge { + compatible = "generic-adc-thermal"; + io-channels = <&pm4125_adc ADC5_AMUX_THM2_100K_PU>; + io-channel-names = "sensor-channel"; + #thermal-sensor-cells = <0>; + }; + + thermal-zones { + sys-1-thermal { + polling-delay-passive = <2000>; + thermal-sensors = <&pa_therm_bridge>; + + trips { + active-config0 { + temperature = <80000>; + hysteresis = <2000>; + type = "hot"; + }; + }; + }; + + sys-2-thermal { + polling-delay-passive = <2000>; + thermal-sensors = <&quiet_therm_bridge>; + + trips { + active-config0 { + temperature = <80000>; + hysteresis = <2000>; + type = "hot"; + }; + }; + }; + + sys-3-thermal { + polling-delay-passive = <2000>; + thermal-sensors = <&msm_therm_bridge>; + + trips { + active-config0 { + temperature = <80000>; + hysteresis = <2000>; + type = "hot"; + }; + }; + }; + }; + wcn3988-pmu { compatible = "qcom,wcn3988-pmu"; @@ -69,7 +132,64 @@ vreg_pmu_ch1: ldo4 { }; }; +&pm4125_adc { + pinctrl-0 = <&pm4125_adc_gpio5_default>, <&pm4125_adc_gpio6_default>; + pinctrl-names = "default"; + + channel@4d { + reg = <ADC5_AMUX_THM1_100K_PU>; + label = "pa_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + channel@4e { + reg = <ADC5_AMUX_THM2_100K_PU>; + label = "quiet_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + channel@4f { + reg = <ADC5_AMUX_THM3_100K_PU>; + label = "msm_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + channel@54 { + reg = <ADC5_GPIO3_100K_PU>; + label = "chgr_skin"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + channel@55 { + reg = <ADC5_GPIO4_100K_PU>; + label = "gnss_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + &pm4125_gpios { + pm4125_adc_gpio5_default: pm4125-adc-gpio5-state { + pins = "gpio5"; + function = PMIC_GPIO_FUNC_NORMAL; + bias-high-impedance; + }; + + pm4125_adc_gpio6_default: pm4125-adc-gpio6-state { + pins = "gpio6"; + function = PMIC_GPIO_FUNC_NORMAL; + bias-high-impedance; + }; + vol_up_n: vol-up-n-state { pins = "gpio9"; function = PMIC_GPIO_FUNC_NORMAL; @@ -89,6 +209,47 @@ &pm8005_regulators { status = "disabled"; }; +&pm4125_typec { + status = "okay"; + + connector { + compatible = "usb-c-connector"; + + power-role = "dual"; + data-role = "dual"; + self-powered; + + vbus-supply = <&pm4125_vbus>; + + typec-power-opmode = "default"; + pd-disable; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + pm4125_hs_in: endpoint { + }; + }; + + port@1 { + reg = <1>; + pm4125_ss_in: endpoint { + }; + }; + }; + }; +}; + +&pm4125_vbus { + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + + status = "okay"; +}; + &rpm_requests { regulators { compatible = "qcom,rpm-pm2250-regulators"; @@ -197,7 +358,6 @@ pm4125_l22: l22 { &tlmm { gpio-reserved-ranges = <6 4>, /* Fingerprint SPI */ - <14 4>, /* eSE SPI */ <30 2>, /* NFC SPI */ <138 1>, /* NFC Secure IO */ <155 11>; /* eMMC Boot */
diff --git a/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts b/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts index e62ba5a..2ded25c 100644 --- a/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts +++ b/arch/arm64/boot/dts/qcom/shikra-cqs-evk.dts
@@ -7,6 +7,7 @@ #include "shikra-cqm-som.dtsi" #include "shikra-evk.dtsi" +#include <dt-bindings/gpio/gpio.h> / { model = "Qualcomm Technologies, Inc. Shikra CQS EVK"; @@ -15,6 +16,7 @@ / { aliases { mmc0 = &sdhc_1; + mmc1 = &sdhc_2; /* SDC2 SD card slot */ serial0 = &uart0; }; @@ -23,6 +25,14 @@ chosen { }; }; +&pm4125_hs_in { + remote-endpoint = <&usb_1_dwc3_hs>; +}; + +&pm4125_ss_in { + remote-endpoint = <&usb_qmpphy_out>; +}; + &remoteproc_cdsp { firmware-name = "qcom/shikra/cdsp.mbn"; @@ -57,3 +67,45 @@ &sdhc_1 { status = "okay"; }; + +&sdhc_2 { + vmmc-supply = <&pm4125_l21>; + vqmmc-supply = <&pm4125_l4>; + + status = "okay"; +}; + +&usb_1 { + dr_mode = "otg"; +}; + +&usb_1_dwc3_hs { + remote-endpoint = <&pm4125_hs_in>; +}; + +&usb_1_hsphy { + vdd-supply = <&pm4125_l12>; + vdda-pll-supply = <&pm4125_l13>; + vdda-phy-dpdm-supply = <&pm4125_l21>; + + status = "okay"; +}; + +&usb_qmpphy { + vdda-phy-supply = <&pm4125_l8>; + vdda-pll-supply = <&pm4125_l13>; + + status = "okay"; +}; + +&usb_qmpphy_out { + remote-endpoint = <&pm4125_ss_in>; +}; + +&usb_2_hsphy { + vdd-supply = <&pm4125_l12>; + vdda-pll-supply = <&pm4125_l13>; + vdda-phy-dpdm-supply = <&pm4125_l21>; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/qcom/shikra-evk.dtsi b/arch/arm64/boot/dts/qcom/shikra-evk.dtsi index 6eb4184..7fbd6d1 100644 --- a/arch/arm64/boot/dts/qcom/shikra-evk.dtsi +++ b/arch/arm64/boot/dts/qcom/shikra-evk.dtsi
@@ -3,12 +3,53 @@ * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. */ +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/shikra/a704_zap.mbn"; +}; + &qupv3_0 { firmware-name = "qcom/shikra/qupv3fw.elf"; status = "okay"; }; +&sdhc_2 { + pinctrl-0 = <&sdc2_default &sdc2_card_det_n>; + pinctrl-1 = <&sdc2_sleep &sdc2_card_det_n>; + pinctrl-names = "default", "sleep"; + + no-sdio; + no-mmc; + + cd-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>; +}; + +&spi5 { + status = "okay"; + + tpm@0 { + compatible = "st,st33htpm-spi", "tcg,tpm_tis-spi"; + reg = <0>; + spi-max-frequency = <20000000>; + }; +}; + &uart0 { status = "okay"; }; + +&usb_1 { + dr_mode = "peripheral"; + + status = "okay"; +}; + +&usb_2 { + dr_mode = "peripheral"; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/qcom/shikra-iqs-evk-imx577-camera.dtso b/arch/arm64/boot/dts/qcom/shikra-iqs-evk-imx577-camera.dtso new file mode 100644 index 0000000..e10fb33 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/shikra-iqs-evk-imx577-camera.dtso
@@ -0,0 +1,72 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/clock/qcom,shikra-gcc.h> +#include <dt-bindings/gpio/gpio.h> + +&camss { + vdd-csiphy-1p2-supply = <&pm8150_l11>; + vdd-csiphy-1p8-supply = <&pm8150_l12>; + + status = "okay"; +}; + +&camss_csiphy1_port { + camss_csiphy1_inep: endpoint { + data-lanes = <0 1 2 3>; + remote-endpoint = <&imx577_ep1>; + }; +}; + +&cci { + status = "okay"; +}; + +&cci_i2c1 { + #address-cells = <1>; + #size-cells = <0>; + + camera@1a { + compatible = "sony,imx577"; + reg = <0x1a>; + + reset-gpios = <&tlmm 33 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&cam_mclk1_default &cam1_reset_default>; + pinctrl-names = "default"; + + clocks = <&gcc GCC_CAMSS_MCLK1_CLK>; + assigned-clocks = <&gcc GCC_CAMSS_MCLK1_CLK>; + assigned-clock-rates = <24000000>; + + /* + * avdd and dvdd are supplied by on-board regulators on the + * IMX577 module from the connector's 3.3 V rail; they are + * not SoC-controlled. dovdd (1.8 V) powers the carrier board + * level-shifter that translates CCI I2C and reset lines + * between the SoC and the connector. + */ + dovdd-supply = <&pm8150_l15>; + + port { + imx577_ep1: endpoint { + link-frequencies = /bits/ 64 <600000000>; + data-lanes = <1 2 3 4>; + remote-endpoint = <&camss_csiphy1_inep>; + }; + }; + }; +}; + +&tlmm { + cam1_reset_default: cam1-reset-default-state { + pins = "gpio33"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; +};
diff --git a/arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts b/arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts index 7278094..5df30ad 100644 --- a/arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts +++ b/arch/arm64/boot/dts/qcom/shikra-iqs-evk.dts
@@ -7,6 +7,7 @@ #include "shikra-iqs-som.dtsi" #include "shikra-evk.dtsi" +#include <dt-bindings/gpio/gpio.h> / { model = "Qualcomm Technologies, Inc. Shikra IQS EVK"; @@ -15,6 +16,7 @@ / { aliases { mmc0 = &sdhc_1; + mmc1 = &sdhc_2; /* SDC2 SD card slot */ serial0 = &uart0; }; @@ -57,3 +59,33 @@ &sdhc_1 { status = "okay"; }; + +&sdhc_2 { + vmmc-supply = <&pm8150_l10>; + vqmmc-supply = <&pm8150_l2>; + + status = "okay"; +}; + +&usb_1_hsphy { + vdd-supply = <&pm8150_l4>; + vdda-pll-supply = <&pm8150_l12>; + vdda-phy-dpdm-supply = <&pm8150_l13>; + + status = "okay"; +}; + +&usb_qmpphy { + vdda-phy-supply = <&pm8150_l6>; + vdda-pll-supply = <&pm8150_l12>; + + status = "okay"; +}; + +&usb_2_hsphy { + vdd-supply = <&pm8150_l4>; + vdda-pll-supply = <&pm8150_l12>; + vdda-phy-dpdm-supply = <&pm8150_l13>; + + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/qcom/shikra-iqs-som.dtsi b/arch/arm64/boot/dts/qcom/shikra-iqs-som.dtsi index 4ff9794..ebc3052 100644 --- a/arch/arm64/boot/dts/qcom/shikra-iqs-som.dtsi +++ b/arch/arm64/boot/dts/qcom/shikra-iqs-som.dtsi
@@ -4,6 +4,7 @@ */ #include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/iio/qcom,spmi-vadc.h> #include <dt-bindings/pinctrl/qcom,pmic-gpio.h> #include "shikra.dtsi" @@ -31,6 +32,44 @@ key-volume-up { }; }; + thermal-zones { + sys-1-thermal { + thermal-sensors = <&pm8150_adc_tm 0>; + + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + sys-2-thermal { + thermal-sensors = <&pm8150_adc_tm 1>; + + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + sys-3-thermal { + thermal-sensors = <&pm8150_adc_tm 2>; + + trips { + active-config0 { + temperature = <125000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + }; + vreg_wcn_3p3: regulator-wcn-3p3 { compatible = "regulator-fixed"; regulator-name = "wcn_3p3"; @@ -76,7 +115,81 @@ vreg_pmu_ch1: ldo4 { }; }; +&pm8150_adc { + pinctrl-0 = <&pm8150_adc_gpio2_default>, <&pm8150_adc_gpio3_default>; + pinctrl-names = "default"; + + channel@4d { + reg = <ADC5_AMUX_THM1_100K_PU>; + label = "msm_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + channel@4e { + reg = <ADC5_AMUX_THM2_100K_PU>; + label = "quiet_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + channel@52 { + reg = <ADC5_GPIO1_100K_PU>; + label = "gnss_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + channel@55 { + reg = <ADC5_GPIO4_100K_PU>; + label = "pa_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; +}; + +&pm8150_adc_tm { + status = "okay"; + + pa-therm@0 { + reg = <0>; + io-channels = <&pm8150_adc ADC5_GPIO4_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time-us = <200>; + }; + + quiet-therm@1 { + reg = <1>; + io-channels = <&pm8150_adc ADC5_AMUX_THM2_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time-us = <200>; + }; + + msm-therm@2 { + reg = <2>; + io-channels = <&pm8150_adc ADC5_AMUX_THM1_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time-us = <200>; + }; +}; + &pm8150_gpios { + pm8150_adc_gpio2_default: pm8150-adc-gpio2-state { + pins = "gpio2"; + function = PMIC_GPIO_FUNC_NORMAL; + bias-high-impedance; + }; + + pm8150_adc_gpio3_default: pm8150-adc-gpio3-state { + pins = "gpio3"; + function = PMIC_GPIO_FUNC_NORMAL; + bias-high-impedance; + }; + vol_up_n: vol-up-n-state { pins = "gpio6"; function = PMIC_GPIO_FUNC_NORMAL; @@ -218,8 +331,7 @@ pm8150_l18: l18 { }; &tlmm { - gpio-reserved-ranges = <6 4>, /* Fingerprint SPI */ - <14 4>, /* eSE SPI */ + gpio-reserved-ranges = <6 4>, /* Fingerprint SPI */ <30 2>, /* NFC SPI */ <138 1>, /* NFC Secure IO */ <155 11>; /* eMMC Boot */
diff --git a/arch/arm64/boot/dts/qcom/shikra.dtsi b/arch/arm64/boot/dts/qcom/shikra.dtsi index 92d22e3..2623e13 100644 --- a/arch/arm64/boot/dts/qcom/shikra.dtsi +++ b/arch/arm64/boot/dts/qcom/shikra.dtsi
@@ -6,6 +6,7 @@ #include <dt-bindings/clock/qcom,dispcc-qcm2290.h> #include <dt-bindings/clock/qcom,qcm2290-gpucc.h> #include <dt-bindings/clock/qcom,rpmcc.h> +#include <dt-bindings/clock/qcom,shikra-audiocorecc.h> #include <dt-bindings/clock/qcom,shikra-gcc.h> #include <dt-bindings/interconnect/qcom,icc.h> #include <dt-bindings/interconnect/qcom,osm-l3.h> @@ -13,6 +14,7 @@ #include <dt-bindings/interconnect/qcom,rpm-icc.h> #include <dt-bindings/interconnect/qcom,shikra.h> #include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/phy/phy-qcom-qmp.h> #include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/thermal/thermal.h> @@ -150,6 +152,88 @@ l3: l3-cache { }; }; + dummy-eud { + compatible = "arm,coresight-dummy-sink"; + + label = "eud"; + + in-ports { + port { + eud_in: endpoint { + remote-endpoint = <&replicator_eud_out1>; + }; + }; + }; + }; + + etm0 { + compatible = "arm,coresight-etm4x-sysreg"; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + cpu = <&cpu0>; + qcom,skip-power-up; + + out-ports { + port { + etm0_out: endpoint { + remote-endpoint = <&funnel_cpuss0_in0>; + }; + }; + }; + }; + + etm1 { + compatible = "arm,coresight-etm4x-sysreg"; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + cpu = <&cpu1>; + qcom,skip-power-up; + + out-ports { + port { + etm1_out: endpoint { + remote-endpoint = <&funnel_cpuss0_in1>; + }; + }; + }; + }; + + etm2 { + compatible = "arm,coresight-etm4x-sysreg"; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + cpu = <&cpu2>; + qcom,skip-power-up; + + out-ports { + port { + etm2_out: endpoint { + remote-endpoint = <&funnel_cpuss0_in2>; + }; + }; + }; + }; + + etm3 { + compatible = "arm,coresight-etm4x-sysreg"; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + cpu = <&cpu3>; + qcom,skip-power-up; + + out-ports { + port { + etm3_out: endpoint { + remote-endpoint = <&funnel_cpuss0_in3>; + }; + }; + }; + }; + firmware { scm { compatible = "qcom,scm-shikra", "qcom,scm"; @@ -248,6 +332,21 @@ opp-2208000000 { }; }; + modem-etm0 { + compatible = "arm,coresight-dummy-source"; + + label = "modem_etm0"; + arm,static-trace-id = <36>; + + out-ports { + port { + modem_etm0_out: endpoint { + remote-endpoint = <&funnel_in1_in4>; + }; + }; + }; + }; + pmu-a55 { compatible = "arm,cortex-a55-pmu"; interrupts = <GIC_PPI 5 IRQ_TYPE_LEVEL_HIGH &ppi_cluster0>; @@ -795,6 +894,66 @@ qup_uart9_default: qup-uart9-default-state { bias-disable; }; + cci_i2c0_default: cci-i2c0-default-state { + /* SDA, SCL */ + pins = "gpio36", "gpio37"; + function = "cci_i2c0"; + drive-strength = <2>; + bias-pull-up; + }; + + cci_i2c0_sleep: cci-i2c0-sleep-state { + /* SDA, SCL */ + pins = "gpio36", "gpio37"; + function = "cci_i2c0"; + drive-strength = <2>; + bias-pull-down; + }; + + cci_i2c1_default: cci-i2c1-default-state { + /* SDA, SCL */ + pins = "gpio41", "gpio42"; + function = "cci_i2c1"; + drive-strength = <2>; + bias-pull-up; + }; + + cci_i2c1_sleep: cci-i2c1-sleep-state { + /* SDA, SCL */ + pins = "gpio41", "gpio42"; + function = "cci_i2c1"; + drive-strength = <2>; + bias-pull-down; + }; + + cam_mclk0_default: cam-mclk0-default-state { + pins = "gpio34"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + cam_mclk1_default: cam-mclk1-default-state { + pins = "gpio35"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + cam_mclk2_default: cam-mclk2-default-state { + pins = "gpio96"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + + cam_mclk3_default: cam-mclk3-default-state { + pins = "gpio98"; + function = "cam_mclk"; + drive-strength = <2>; + bias-disable; + }; + sdc1_state_on: sdc1-on-state { clk-pins { pins = "sdc1_clk"; @@ -844,6 +1003,53 @@ rclk-pins { bias-bus-hold; }; }; + + sdc2_default: sdc2-default-state { + clk-pins { + pins = "sdc2_clk"; + drive-strength = <14>; + bias-disable; + }; + + cmd-pins { + pins = "sdc2_cmd"; + drive-strength = <14>; + bias-pull-up; + }; + + data-pins { + pins = "sdc2_data"; + drive-strength = <14>; + bias-pull-up; + }; + }; + + sdc2_sleep: sdc2-sleep-state { + clk-pins { + pins = "sdc2_clk"; + drive-strength = <2>; + bias-disable; + }; + + cmd-pins { + pins = "sdc2_cmd"; + drive-strength = <2>; + bias-pull-up; + }; + + data-pins { + pins = "sdc2_data"; + drive-strength = <2>; + bias-pull-up; + }; + }; + + sdc2_card_det_n: sd-card-det-n-state { + pins = "gpio89"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; }; pmu@c91000 { @@ -922,6 +1128,85 @@ gcc: clock-controller@1400000 { #power-domain-cells = <1>; }; + usb_1_hsphy: phy@1613000 { + compatible = "qcom,shikra-qusb2-phy"; + reg = <0x0 0x01613000 0x0 0x180>; + + clocks = <&gcc GCC_AHB2PHY_USB_CLK>, + <&rpmcc RPM_SMD_XO_CLK_SRC>; + clock-names = "cfg_ahb", "ref"; + + resets = <&gcc GCC_QUSB2PHY_PRIM_BCR>; + nvmem-cells = <&qusb2_hstx_trim_1>; + #phy-cells = <0>; + + status = "disabled"; + }; + + usb_qmpphy: phy@1615000 { + compatible = "qcom,shikra-qmp-usb3-dp-phy"; + reg = <0x0 0x01615000 0x0 0x2000>; + + clocks = <&gcc GCC_USB3_PRIM_PHY_COM_AUX_CLK>, + <&gcc GCC_USB3_PRIM_CLKREF_EN>, + <&gcc GCC_AHB2PHY_USB_CLK>, + <&gcc GCC_USB3_PRIM_PHY_PIPE_CLK>; + clock-names = "aux", + "ref", + "cfg_ahb", + "pipe"; + + resets = <&gcc GCC_USB3PHY_PHY_PRIM_SP0_BCR>, + <&gcc GCC_USB3_DP_PHY_PRIM_BCR>, + <&gcc GCC_USB3_PHY_PRIM_SP0_BCR>; + reset-names = "phy_phy", + "dp_phy", + "phy"; + + #clock-cells = <1>; + #phy-cells = <1>; + orientation-switch; + + qcom,tcsr-reg = <&tcsr_regs 0xb244 0xb248>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_qmpphy_out: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb_qmpphy_usb_ss_in: endpoint { + remote-endpoint = <&usb_1_dwc3_ss>; + }; + }; + }; + }; + + usb_2_hsphy: phy@1617000 { + compatible = "qcom,shikra-qusb2-phy"; + reg = <0x0 0x01617000 0x0 0x180>; + + clocks = <&gcc GCC_AHB2PHY_USB_CLK>, + <&rpmcc RPM_SMD_XO_CLK_SRC>; + clock-names = "cfg_ahb", "ref"; + + resets = <&gcc GCC_QUSB2PHY_SEC_BCR>; + nvmem-cells = <&qusb2_hstx_trim_2>; + #phy-cells = <0>; + + status = "disabled"; + }; + system_noc: interconnect@1880000 { compatible = "qcom,shikra-sys-noc"; reg = <0x0 0x01880000 0x0 0x6a080>; @@ -962,12 +1247,52 @@ config_noc: interconnect@1900000 { #interconnect-cells = <2>; }; + cryptobam: dma-controller@1b04000 { + compatible = "qcom,bam-v1.7.4", "qcom,bam-v1.7.0"; + reg = <0x0 0x01b04000 0x0 0x24000>; + interrupts = <GIC_SPI 247 IRQ_TYPE_LEVEL_HIGH 0>; + #dma-cells = <1>; + iommus = <&apps_smmu 0x84 0x0011>, + <&apps_smmu 0x86 0x0011>, + <&apps_smmu 0x92 0x0>, + <&apps_smmu 0x94 0x0011>, + <&apps_smmu 0x96 0x0011>, + <&apps_smmu 0x98 0x0001>, + <&apps_smmu 0x9f 0x0>; + qcom,ee = <0>; + qcom,controlled-remotely; + num-channels = <16>; + qcom,num-ees = <4>; + }; + + crypto: crypto@1b3a000 { + compatible = "qcom,shikra-qce", "qcom,sm8150-qce", "qcom,qce"; + reg = <0x0 0x01b3a000 0x0 0x6000>; + dmas = <&cryptobam 4>, <&cryptobam 5>; + dma-names = "rx", "tx"; + iommus = <&apps_smmu 0x84 0x0011>, + <&apps_smmu 0x86 0x0011>, + <&apps_smmu 0x92 0x0>, + <&apps_smmu 0x94 0x0011>, + <&apps_smmu 0x96 0x0011>, + <&apps_smmu 0x98 0x0001>, + <&apps_smmu 0x9f 0x0>; + interconnects = <&system_noc MASTER_CRYPTO_CORE0 0 + &mc_virt SLAVE_EBI_CH0 0>; + interconnect-names = "memory"; + }; + qfprom: efuse@1b44000 { compatible = "qcom,shikra-qfprom", "qcom,qfprom"; reg = <0x0 0x01b44000 0x0 0x3000>; #address-cells = <1>; #size-cells = <1>; + qusb2_hstx_trim_2: hstx-trim@25a { + reg = <0x25a 0x1>; + bits = <4 4>; + }; + qusb2_hstx_trim_1: hstx-trim@25b { reg = <0x25b 0x1>; bits = <1 4>; @@ -1013,6 +1338,11 @@ tsens0: thermal-sensor@4411000 { #thermal-sensor-cells = <1>; }; + rng: rng@4454000 { + compatible = "qcom,shikra-trng", "qcom,trng"; + reg = <0x0 0x04454000 0x0 0x1000>; + }; + rpm_msg_ram: sram@45f0000 { compatible = "qcom,rpm-msg-ram", "mmio-sram"; reg = <0x0 0x045f0000 0x0 0x7000>; @@ -1027,7 +1357,7 @@ apss_mpm: sram@1b8 { }; sram@4690000 { - compatible = "qcom,rpm-stats"; + compatible = "qcom,shikra-rpm-stats", "qcom,rpm-stats"; reg = <0x0 0x04690000 0x0 0x14000>; }; @@ -1074,6 +1404,7 @@ &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>, mmc-hs400-enhanced-strobe; resets = <&gcc GCC_SDCC1_BCR>; + qcom,ice = <&sdhc_ice>; status = "disabled"; @@ -1124,6 +1455,67 @@ gpi_dma0: dma-controller@4a00000 { iommus = <&apps_smmu 0xf6 0x0>; }; + sdhc_ice: crypto@4748000 { + compatible = "qcom,shikra-inline-crypto-engine", + "qcom,inline-crypto-engine"; + reg = <0x0 0x04748000 0x0 0x18000>; + clocks = <&gcc GCC_SDCC1_ICE_CORE_CLK>, + <&gcc GCC_SDCC1_AHB_CLK>; + clock-names = "core", + "iface"; + power-domains = <&rpmpd RPMHPD_CX>; + }; + + sdhc_2: mmc@4784000 { + compatible = "qcom,shikra-sdhci", "qcom,sdhci-msm-v5"; + reg = <0x0 0x04784000 0x0 0x1000>; + + interrupts = <GIC_SPI 350 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 353 IRQ_TYPE_LEVEL_HIGH 0>; + interrupt-names = "hc_irq", + "pwr_irq"; + + bus-width = <4>; + + clocks = <&gcc GCC_SDCC2_AHB_CLK>, + <&gcc GCC_SDCC2_APPS_CLK>, + <&rpmcc RPM_SMD_XO_CLK_SRC>; + clock-names = "iface", + "core", + "xo"; + + qcom,dll-config = <0x0007442c>; + qcom,ddr-config = <0x80040868>; + + iommus = <&apps_smmu 0x0a0 0x0>; + + interconnects = <&system_noc MASTER_SDCC_2 RPM_ALWAYS_TAG + &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>, + <&mem_noc MASTER_AMPSS_M0 RPM_ACTIVE_TAG + &config_noc SLAVE_SDCC_2 RPM_ACTIVE_TAG>; + interconnect-names = "sdhc-ddr", + "cpu-sdhc"; + + power-domains = <&rpmpd RPMPD_VDDCX>; + operating-points-v2 = <&sdhc2_opp_table>; + + status = "disabled"; + + sdhc2_opp_table: opp-table-2 { + compatible = "operating-points-v2"; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + required-opps = <&rpmpd_opp_low_svs>; + }; + + opp-202000000 { + opp-hz = /bits/ 64 <202000000>; + required-opps = <&rpmpd_opp_svs_plus>; + }; + }; + }; + qupv3_0: geniqup@4ac0000 { compatible = "qcom,geni-se-qup"; reg = <0x0 0x04ac0000 0x0 0x2000>; @@ -1828,6 +2220,143 @@ &clk_virt SLAVE_QUP_CORE_0 RPM_ALWAYS_TAG>, }; }; + camss: camss@5c11000 { + compatible = "qcom,shikra-camss", "qcom,qcm2290-camss"; + + reg = <0x0 0x05c11000 0x0 0x1000>, + <0x0 0x05c6e000 0x0 0x1000>, + <0x0 0x05c75000 0x0 0x1000>, + <0x0 0x05c52000 0x0 0x1000>, + <0x0 0x05c53000 0x0 0x1000>, + <0x0 0x05c66000 0x0 0x400>, + <0x0 0x05c68000 0x0 0x400>, + <0x0 0x05c6f000 0x0 0x4000>, + <0x0 0x05c76000 0x0 0x4000>; + reg-names = "top", + "csid0", + "csid1", + "csiphy0", + "csiphy1", + "csitpg0", + "csitpg1", + "vfe0", + "vfe1"; + + clocks = <&gcc GCC_CAMERA_AHB_CLK>, + <&gcc GCC_CAMSS_AXI_CLK>, + <&gcc GCC_CAMSS_NRT_AXI_CLK>, + <&gcc GCC_CAMSS_RT_AXI_CLK>, + <&gcc GCC_CAMSS_TFE_0_CSID_CLK>, + <&gcc GCC_CAMSS_TFE_1_CSID_CLK>, + <&gcc GCC_CAMSS_CPHY_0_CLK>, + <&gcc GCC_CAMSS_CSI0PHYTIMER_CLK>, + <&gcc GCC_CAMSS_CPHY_1_CLK>, + <&gcc GCC_CAMSS_CSI1PHYTIMER_CLK>, + <&gcc GCC_CAMSS_TOP_AHB_CLK>, + <&gcc GCC_CAMSS_TFE_0_CLK>, + <&gcc GCC_CAMSS_TFE_0_CPHY_RX_CLK>, + <&gcc GCC_CAMSS_TFE_1_CLK>, + <&gcc GCC_CAMSS_TFE_1_CPHY_RX_CLK>; + clock-names = "ahb", + "axi", + "camnoc_nrt_axi", + "camnoc_rt_axi", + "csi0", + "csi1", + "csiphy0", + "csiphy0_timer", + "csiphy1", + "csiphy1_timer", + "top_ahb", + "vfe0", + "vfe0_cphy_rx", + "vfe1", + "vfe1_cphy_rx"; + + interrupts = <GIC_SPI 210 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 212 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 72 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 73 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 309 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 310 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 211 IRQ_TYPE_EDGE_RISING 0>, + <GIC_SPI 213 IRQ_TYPE_EDGE_RISING 0>; + interrupt-names = "csid0", + "csid1", + "csiphy0", + "csiphy1", + "csitpg0", + "csitpg1", + "vfe0", + "vfe1"; + + interconnects = <&mem_noc MASTER_AMPSS_M0 RPM_ACTIVE_TAG + &config_noc SLAVE_CAMERA_CFG RPM_ACTIVE_TAG>, + <&mmrt_virt MASTER_CAMNOC_HF RPM_ALWAYS_TAG + &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>, + <&mmnrt_virt MASTER_CAMNOC_SF RPM_ALWAYS_TAG + &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>; + interconnect-names = "ahb", + "hf_mnoc", + "sf_mnoc"; + + iommus = <&apps_smmu 0x400 0x0>; + + power-domains = <&gcc GCC_CAMSS_TOP_GDSC>; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + camss_csiphy0_port: port@0 { + reg = <0>; + }; + + camss_csiphy1_port: port@1 { + reg = <1>; + }; + }; + }; + + cci: cci@5c1b000 { + compatible = "qcom,shikra-cci", "qcom,msm8996-cci"; + reg = <0x0 0x05c1b000 0x0 0x1000>; + + interrupts = <GIC_SPI 206 IRQ_TYPE_EDGE_RISING 0>; + + clocks = <&gcc GCC_CAMSS_TOP_AHB_CLK>, + <&gcc GCC_CAMSS_CCI_0_CLK>; + clock-names = "ahb", + "cci"; + + power-domains = <&gcc GCC_CAMSS_TOP_GDSC>; + + pinctrl-0 = <&cci_i2c0_default &cci_i2c1_default>; + pinctrl-1 = <&cci_i2c0_sleep &cci_i2c1_sleep>; + pinctrl-names = "default", "sleep"; + + #address-cells = <1>; + #size-cells = <0>; + + status = "disabled"; + + cci_i2c0: i2c-bus@0 { + reg = <0>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + }; + + cci_i2c1: i2c-bus@1 { + reg = <1>; + clock-frequency = <400000>; + #address-cells = <1>; + #size-cells = <0>; + }; + }; + remoteproc_mpss: remoteproc@6080000 { compatible = "qcom,shikra-mpss-pas"; reg = <0x0 0x06080000 0x0 0x100>; @@ -1948,11 +2477,153 @@ compute-cb@6 { reg = <6>; iommus = <&apps_smmu 0x0206 0x0000>; }; + }; + }; + }; - compute-cb@9 { - compatible = "qcom,fastrpc-compute-cb"; - reg = <9>; - iommus = <&apps_smmu 0x0209 0x0000>; + usb_2: usb@4c00000 { + compatible = "qcom,shikra-dwc3", "qcom,snps-dwc3"; + reg = <0x0 0x04c00000 0x0 0xfc100>; + + clocks = <&gcc GCC_CFG_NOC_USB2_PRIM_AXI_CLK>, + <&gcc GCC_USB20_MASTER_CLK>, + <&gcc GCC_SYS_NOC_USB2_PRIM_AXI_CLK>, + <&gcc GCC_USB20_SLEEP_CLK>, + <&gcc GCC_USB20_MOCK_UTMI_CLK>; + clock-names = "cfg_noc", + "core", + "iface", + "sleep", + "mock_utmi"; + + assigned-clocks = <&gcc GCC_USB20_MOCK_UTMI_CLK>, + <&gcc GCC_USB20_MASTER_CLK>; + assigned-clock-rates = <19200000>, <133333333>; + + interrupts-extended = <&intc GIC_SPI 507 IRQ_TYPE_LEVEL_HIGH 0>, + <&intc GIC_SPI 509 IRQ_TYPE_LEVEL_HIGH 0>, + <&intc GIC_SPI 508 IRQ_TYPE_LEVEL_HIGH 0>, + <&mpm 59 IRQ_TYPE_LEVEL_HIGH>, + <&mpm 58 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "dwc_usb3", + "pwr_event", + "hs_phy_irq", + "dp_hs_phy_irq", + "dm_hs_phy_irq"; + + iommus = <&apps_smmu 0x140 0x0>; + + maximum-speed = "high-speed"; + + phys = <&usb_2_hsphy>; + phy-names = "usb2-phy"; + + power-domains = <&gcc GCC_USB20_GDSC>; + + qcom,select-utmi-as-pipe-clk; + resets = <&gcc GCC_USB20_BCR>; + + interconnects = <&system_noc MASTER_USB2_0 RPM_ALWAYS_TAG + &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>, + <&mem_noc MASTER_AMPSS_M0 RPM_ACTIVE_TAG + &config_noc SLAVE_USB2 RPM_ACTIVE_TAG>; + interconnect-names = "usb-ddr", "apps-usb"; + + snps,dis_u2_susphy_quirk; + snps,dis_enblslpm_quirk; + snps,has-lpm-erratum; + snps,hird-threshold = /bits/ 8 <0x10>; + + usb-role-switch; + wakeup-source; + + status = "disabled"; + + port { + usb_2_dwc3_hs: endpoint { + }; + }; + }; + + usb_1: usb@4e00000 { + compatible = "qcom,shikra-dwc3", "qcom,snps-dwc3"; + reg = <0x0 0x04e00000 0x0 0xfc100>; + + clocks = <&gcc GCC_CFG_NOC_USB3_PRIM_AXI_CLK>, + <&gcc GCC_USB30_PRIM_MASTER_CLK>, + <&gcc GCC_SYS_NOC_USB3_PRIM_AXI_CLK>, + <&gcc GCC_USB30_PRIM_SLEEP_CLK>, + <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>; + clock-names = "cfg_noc", + "core", + "iface", + "sleep", + "mock_utmi"; + + assigned-clocks = <&gcc GCC_USB30_PRIM_MOCK_UTMI_CLK>, + <&gcc GCC_USB30_PRIM_MASTER_CLK>; + assigned-clock-rates = <19200000>, <133333333>; + + interrupts-extended = <&intc GIC_SPI 255 IRQ_TYPE_LEVEL_HIGH 0>, + <&intc GIC_SPI 302 IRQ_TYPE_LEVEL_HIGH 0>, + <&intc GIC_SPI 254 IRQ_TYPE_LEVEL_HIGH 0>, + <&mpm 91 IRQ_TYPE_LEVEL_HIGH>, + <&mpm 90 IRQ_TYPE_LEVEL_HIGH>, + <&mpm 12 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "dwc_usb3", + "pwr_event", + "hs_phy_irq", + "dp_hs_phy_irq", + "dm_hs_phy_irq", + "ss_phy_irq"; + + iommus = <&apps_smmu 0x120 0x0>; + + phys = <&usb_1_hsphy>, <&usb_qmpphy QMP_USB43DP_USB3_PHY>; + phy-names = "usb2-phy", "usb3-phy"; + + power-domains = <&gcc GCC_USB30_PRIM_GDSC>; + + resets = <&gcc GCC_USB30_PRIM_BCR>; + + interconnects = <&system_noc MASTER_USB3 RPM_ALWAYS_TAG + &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>, + <&mem_noc MASTER_AMPSS_M0 RPM_ACTIVE_TAG + &config_noc SLAVE_USB3 RPM_ACTIVE_TAG>; + interconnect-names = "usb-ddr", "apps-usb"; + + snps,dis-u1-entry-quirk; + snps,dis-u2-entry-quirk; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,dis_enblslpm_quirk; + snps,has-lpm-erratum; + snps,hird-threshold = /bits/ 8 <0x10>; + snps,usb3_lpm_capable; + snps,parkmode-disable-ss-quirk; + + usb-role-switch; + + wakeup-source; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_1_dwc3_hs: endpoint { + }; + }; + + port@1 { + reg = <1>; + + usb_1_dwc3_ss: endpoint { + remote-endpoint = <&usb_qmpphy_usb_ss_in>; }; }; }; @@ -1992,6 +2663,104 @@ glink-edge { }; }; + gpu: gpu@5900000 { + compatible = "qcom,adreno-07000400", "qcom,adreno"; + reg = <0x0 0x05900000 0x0 0x40000>, + <0x0 0x0599e000 0x0 0x1000>, + <0x0 0x05961000 0x0 0x800>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem", + "cx_dbgc"; + + interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH 0>; + + clocks = <&gpucc GPU_CC_GX_GFX3D_CLK>, + <&gpucc GPU_CC_AHB_CLK>, + <&gcc GCC_DDRSS_GPU_AXI_CLK>, + <&gcc GCC_GPU_MEMNOC_GFX_CLK>, + <&gpucc GPU_CC_CX_GMU_CLK>, + <&gpucc GPU_CC_CXO_CLK>; + clock-names = "core", + "iface", + "mem_iface", + "alt_mem_iface", + "gmu", + "xo"; + + interconnects = <&mem_noc MASTER_GRAPHICS_3D RPM_ALWAYS_TAG + &mc_virt SLAVE_EBI_CH0 RPM_ALWAYS_TAG>; + interconnect-names = "gfx-mem"; + + iommus = <&adreno_smmu 0 1>; + operating-points-v2 = <&gpu_opp_table>; + power-domains = <&rpmpd RPMPD_VDDCX>; + qcom,gmu = <&gmu_wrapper>; + + #cooling-cells = <2>; + + status = "disabled"; + + gpu_zap_shader: zap-shader { + memory-region = <&gpu_micro_code_mem>; + }; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-1142400000 { + opp-hz = /bits/ 64 <1142400000>; + required-opps = <&rpmpd_opp_turbo_plus>; + opp-peak-kBps = <8171875>; + }; + + opp-1017600000 { + opp-hz = /bits/ 64 <1017600000>; + required-opps = <&rpmpd_opp_turbo>; + opp-peak-kBps = <8171875>; + }; + + opp-921600000 { + opp-hz = /bits/ 64 <921600000>; + required-opps = <&rpmpd_opp_nom_plus>; + opp-peak-kBps = <7046875>; + }; + + opp-844800000 { + opp-hz = /bits/ 64 <844800000>; + required-opps = <&rpmpd_opp_nom>; + opp-peak-kBps = <6074218>; + }; + + opp-672000000 { + opp-hz = /bits/ 64 <672000000>; + required-opps = <&rpmpd_opp_svs_plus>; + opp-peak-kBps = <5285156>; + }; + + opp-537600000 { + opp-hz = /bits/ 64 <537600000>; + required-opps = <&rpmpd_opp_svs>; + opp-peak-kBps = <3972656>; + }; + + opp-355200000 { + opp-hz = /bits/ 64 <355200000>; + required-opps = <&rpmpd_opp_low_svs>; + opp-peak-kBps = <2136718>; + }; + }; + }; + + gmu_wrapper: gmu@596a000 { + compatible = "qcom,adreno-gmu-wrapper"; + reg = <0x0 0x0596a000 0x0 0x30000>; + reg-names = "gmu"; + power-domains = <&gpucc GPU_CX_GDSC>, + <&gpucc GPU_GX_GDSC>; + power-domain-names = "cx", + "gx"; + }; + gpucc: clock-controller@5990000 { compatible = "qcom,shikra-gpucc"; reg = <0x0 0x05990000 0x0 0x9000>; @@ -2005,6 +2774,35 @@ gpucc: clock-controller@5990000 { #power-domain-cells = <1>; }; + adreno_smmu: iommu@59a0000 { + compatible = "qcom,shikra-smmu-500", "qcom,adreno-smmu", + "qcom,smmu-500", "arm,mmu-500"; + reg = <0x0 0x059a0000 0x0 0x10000>; + #iommu-cells = <2>; + #global-interrupts = <1>; + + interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 167 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH 0>; + + clocks = <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>, + <&gcc GCC_GPU_MEMNOC_GFX_CLK>, + <&gcc GCC_GPU_SNOC_DVM_GFX_CLK>, + <&gpucc GPU_CC_AHB_CLK>; + clock-names = "hlos", + "bus", + "iface", + "ahb"; + + power-domains = <&gpucc GPU_CX_GDSC>; + }; + dispcc: clock-controller@5f00000 { compatible = "qcom,shikra-dispcc", "qcom,qcm2290-dispcc"; reg = <0x0 0x05f00000 0x0 0x20000>; @@ -2026,6 +2824,1205 @@ dispcc: clock-controller@5f00000 { #power-domain-cells = <1>; }; + ctcu@8001000 { + compatible = "qcom,shikra-ctcu", "qcom,sa8775p-ctcu"; + reg = <0x0 0x08001000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb"; + + in-ports { + port { + ctcu_in0: endpoint { + remote-endpoint = <&etr0_out>; + }; + }; + }; + }; + + stm@8002000 { + compatible = "arm,coresight-stm", "arm,primecell"; + reg = <0x0 0x08002000 0x0 0x1000>, + <0x0 0x0e280000 0x0 0x180000>; + reg-names = "stm-base", + "stm-stimulus-base"; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + out-ports { + port { + stm_out: endpoint { + remote-endpoint = <&funnel_in0_in7>; + }; + }; + }; + }; + + tpdm@8003000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x08003000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + label = "tpdm_dcc"; + qcom,cmb-element-bits = <32>; + + out-ports { + port { + tpdm_dcc_out: endpoint { + remote-endpoint = <&tpda_qdss_in0>; + }; + }; + }; + }; + + tpda@8004000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x08004000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + tpda_qdss_in0: endpoint { + remote-endpoint = <&tpdm_dcc_out>; + }; + }; + + port@1 { + reg = <1>; + + tpda_qdss_in1: endpoint { + remote-endpoint = <&tpdm_spdm_out>; + }; + }; + }; + + out-ports { + port { + tpda_qdss_out: endpoint { + remote-endpoint = <&funnel_in0_in6>; + }; + }; + }; + }; + + tpdm@800f000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x0800f000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + label = "tpdm_spdm"; + qcom,cmb-element-bits = <32>; + + out-ports { + port { + tpdm_spdm_out: endpoint { + remote-endpoint = <&tpda_qdss_in1>; + }; + }; + }; + }; + + funnel@8041000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x08041000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@5 { + reg = <5>; + + funnel_in0_in5: endpoint { + remote-endpoint = <&snoc_out>; + }; + }; + + port@6 { + reg = <6>; + + funnel_in0_in6: endpoint { + remote-endpoint = <&tpda_qdss_out>; + }; + }; + + port@7 { + reg = <7>; + + funnel_in0_in7: endpoint { + remote-endpoint = <&stm_out>; + }; + }; + }; + + out-ports { + port { + funnel_in0_out: endpoint { + remote-endpoint = <&funnel_merg_in0>; + }; + }; + }; + }; + + funnel@8042000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x08042000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + funnel_in1_in1: endpoint { + remote-endpoint = <&tpda_aodbg_out>; + }; + }; + + port@4 { + reg = <4>; + + funnel_in1_in4: endpoint { + remote-endpoint = <&modem_etm0_out>; + }; + }; + + port@6 { + reg = <6>; + + funnel_in1_in6: endpoint { + remote-endpoint = <&funnel_cpuss1_out>; + }; + }; + + port@7 { + reg = <7>; + + funnel_in1_in7: endpoint { + remote-endpoint = <&funnel_center_out>; + }; + }; + }; + + out-ports { + port { + funnel_in1_out: endpoint { + remote-endpoint = <&funnel_merg_in1>; + }; + }; + }; + }; + + funnel@8045000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x08045000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + funnel_merg_in0: endpoint { + remote-endpoint = <&funnel_in0_out>; + }; + }; + + port@1 { + reg = <1>; + + funnel_merg_in1: endpoint { + remote-endpoint = <&funnel_in1_out>; + }; + }; + }; + + out-ports { + port { + funnel_merg_out: endpoint { + remote-endpoint = <&tmc_etf_in>; + }; + }; + }; + }; + + replicator@8046000 { + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; + reg = <0x0 0x08046000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + in-ports { + port { + replicator_qdss_in: endpoint { + remote-endpoint = <&tmc_etf_out>; + }; + }; + }; + + out-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + replicator_qdss_out0: endpoint { + remote-endpoint = <&etr0_in>; + }; + }; + + port@1 { + reg = <1>; + + replicator_qdss_out1: endpoint { + remote-endpoint = <&replicator_eud_in>; + }; + }; + }; + }; + + tmc@8047000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x08047000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + in-ports { + port { + tmc_etf_in: endpoint { + remote-endpoint = <&funnel_merg_out>; + }; + }; + }; + + out-ports { + port { + tmc_etf_out: endpoint { + remote-endpoint = <&replicator_qdss_in>; + }; + }; + }; + }; + + tmc@8048000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x08048000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + iommus = <&apps_smmu 0x0160 0x0>; + arm,scatter-gather; + + in-ports { + port { + etr0_in: endpoint { + remote-endpoint = <&replicator_qdss_out0>; + }; + }; + }; + + out-ports { + port { + etr0_out: endpoint { + remote-endpoint = <&ctcu_in0>; + }; + }; + }; + }; + + replicator@804a000 { + compatible = "arm,coresight-dynamic-replicator", "arm,primecell"; + reg = <0x0 0x0804a000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + in-ports { + port { + replicator_eud_in: endpoint { + remote-endpoint = <&replicator_qdss_out1>; + }; + }; + }; + + out-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + replicator_eud_out1: endpoint { + remote-endpoint = <&eud_in>; + }; + }; + }; + }; + + tpdm@8800000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x08800000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + label = "tpdm_cdsp"; + qcom,dsb-element-bits = <32>; + qcom,dsb-msrs-num = <4>; + + out-ports { + port { + tpdm_cdsp_out: endpoint { + remote-endpoint = <&funnel_cdsp_in0>; + }; + }; + }; + }; + + funnel@8801000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x08801000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + in-ports { + port { + funnel_cdsp_in0: endpoint { + remote-endpoint = <&tpdm_cdsp_out>; + }; + }; + }; + + out-ports { + port { + funnel_cdsp_out0: endpoint { + remote-endpoint = <&tpda_center_in3>; + }; + }; + }; + }; + + cti@8807000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x08807000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_turing_q6"; + }; + + cti@8833000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x08833000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_mss_q6"; + }; + + tpdm@8840000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x08840000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + label = "tpdm_vsense"; + qcom,cmb-element-bits = <32>; + + out-ports { + port { + tpdm_vsense_out: endpoint { + remote-endpoint = <&tpda_center_in6>; + }; + }; + }; + }; + + tpdm@8844000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x08844000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + label = "tpdm_dlct_1"; + qcom,dsb-element-bits = <32>; + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + tpdm_dlct_1_out: endpoint { + remote-endpoint = <&tpda_center_in13>; + }; + }; + }; + }; + + tpda@8845000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x08845000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + tpda_center_in0: endpoint { + remote-endpoint = <&funnel_mcu_out>; + }; + }; + + port@2 { + reg = <2>; + + tpda_center_in2: endpoint { + remote-endpoint = <&tpdm_dlct_out>; + }; + }; + + port@3 { + reg = <3>; + + tpda_center_in3: endpoint { + remote-endpoint = <&funnel_cdsp_out0>; + }; + }; + + port@4 { + reg = <4>; + + tpda_center_in4: endpoint { + remote-endpoint = <&funnel_ddr_out0>; + }; + }; + + port@6 { + reg = <6>; + + tpda_center_in6: endpoint { + remote-endpoint = <&tpdm_vsense_out>; + }; + }; + + port@7 { + reg = <7>; + + tpda_center_in7: endpoint { + remote-endpoint = <&tpdm_prng_out>; + }; + }; + + port@8 { + reg = <8>; + + tpda_center_in8: endpoint { + remote-endpoint = <&tpdm_west_out>; + }; + }; + + port@9 { + reg = <9>; + + tpda_center_in9: endpoint { + remote-endpoint = <&tpdm_qm_out>; + }; + }; + + port@a { + reg = <0xa>; + + tpda_center_in10: endpoint { + remote-endpoint = <&tpdm_pimem_out>; + }; + }; + + port@d { + reg = <0xd>; + + tpda_center_in13: endpoint { + remote-endpoint = <&tpdm_dlct_1_out>; + }; + }; + }; + + out-ports { + port { + tpda_center_out: endpoint { + remote-endpoint = <&funnel_center_in0>; + }; + }; + }; + }; + + funnel@8846000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x08846000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + in-ports { + port { + funnel_center_in0: endpoint { + remote-endpoint = <&tpda_center_out>; + }; + }; + }; + + out-ports { + port { + funnel_center_out: endpoint { + remote-endpoint = <&funnel_in1_in7>; + }; + }; + }; + }; + + tpdm@884c000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x0884c000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + label = "tpdm_prng"; + qcom,cmb-element-bits = <32>; + + out-ports { + port { + tpdm_prng_out: endpoint { + remote-endpoint = <&tpda_center_in7>; + }; + }; + }; + }; + + tpdm@8850000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x08850000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + label = "tpdm_pimem"; + qcom,cmb-element-bits = <64>; + qcom,dsb-element-bits = <32>; + + out-ports { + port { + tpdm_pimem_out: endpoint { + remote-endpoint = <&tpda_center_in10>; + }; + }; + }; + }; + + tpdm@8980000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x08980000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + label = "tpdm_mcu"; + qcom,dsb-element-bits = <32>; + qcom,dsb-msrs-num = <16>; + + out-ports { + port { + tpdm_mcu_out: endpoint { + remote-endpoint = <&funnel_mcu_in0>; + }; + }; + }; + }; + + funnel@8982000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x08982000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + in-ports { + port { + funnel_mcu_in0: endpoint { + remote-endpoint = <&tpdm_mcu_out>; + }; + }; + }; + + out-ports { + port { + funnel_mcu_out: endpoint { + remote-endpoint = <&tpda_center_in0>; + }; + }; + }; + }; + + tpdm@89d0000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x089d0000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + label = "tpdm_qm"; + qcom,dsb-element-bits = <32>; + + out-ports { + port { + tpdm_qm_out: endpoint { + remote-endpoint = <&tpda_center_in9>; + }; + }; + }; + }; + + tpdm@8a01000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x08a01000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + label = "tpdm_mapss"; + qcom,cmb-element-bits = <32>; + qcom,dsb-element-bits = <32>; + qcom,dsb-msrs-num = <16>; + + out-ports { + port { + tpdm_mapss_out: endpoint { + remote-endpoint = <&tpda_aodbg_in>; + }; + }; + }; + }; + + cti@8a02000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x08a02000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_mapss"; + }; + + tpda@8a04000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x08a04000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + in-ports { + port { + tpda_aodbg_in: endpoint { + remote-endpoint = <&tpdm_mapss_out>; + }; + }; + }; + + out-ports { + port { + tpda_aodbg_out: endpoint { + remote-endpoint = <&funnel_in1_in1>; + }; + }; + }; + }; + + tpdm@8a58000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x08a58000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + label = "tpdm_west"; + qcom,dsb-element-bits = <32>; + qcom,dsb-msrs-num = <16>; + + out-ports { + port { + tpdm_west_out: endpoint { + remote-endpoint = <&tpda_center_in8>; + }; + }; + }; + }; + + cti@8b30000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x08b30000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_cortex_m3"; + }; + + tpdm@8b58000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x08b58000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + label = "tpdm_dlct"; + qcom,dsb-element-bits = <32>; + qcom,dsb-msrs-num = <16>; + + out-ports { + port { + tpdm_dlct_out: endpoint { + remote-endpoint = <&tpda_center_in2>; + }; + }; + }; + }; + + cti@8b59000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x08b59000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_dlct_0"; + }; + + cti@8b5a000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x08b5a000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_dlct_1"; + }; + + cti@8b5b000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x08b5b000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_dlct_2"; + }; + + cti@8b5c000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x08b5c000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_dlct_3"; + }; + + tpdm@8b60000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x08b60000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + label = "tpdm_ddr"; + qcom,cmb-element-bits = <32>; + qcom,cmb-msrs-num = <1>; + qcom,dsb-element-bits = <32>; + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + tpdm_ddr_out: endpoint { + remote-endpoint = <&funnel_ddr_in0>; + }; + }; + }; + }; + + cti@8b62000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x08b62000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_ddr_dl_0"; + }; + + funnel@8b65000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x08b65000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + funnel_ddr_in0: endpoint { + remote-endpoint = <&tpdm_ddr_out>; + }; + }; + }; + + out-ports { + port { + funnel_ddr_out0: endpoint { + remote-endpoint = <&tpda_center_in4>; + }; + }; + }; + }; + + cti@8b70000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x08b70000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_ddr_dl_0_1"; + }; + + cti@8b71000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x08b71000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_ddr_dl_1_1"; + }; + + cti@9020000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x09020000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_apss_pe0"; + }; + + cti@90e0000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x090e0000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_apss_cluster"; + }; + + cti@9120000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x09120000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_apss_pe1"; + }; + + cti@9220000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x09220000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_apss_pe2"; + }; + + cti@9320000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x09320000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_apss_pe3"; + }; + + funnel@9800000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x09800000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + funnel_cpuss0_in0: endpoint { + remote-endpoint = <&etm0_out>; + }; + }; + + port@1 { + reg = <1>; + + funnel_cpuss0_in1: endpoint { + remote-endpoint = <&etm1_out>; + }; + }; + + port@2 { + reg = <2>; + + funnel_cpuss0_in2: endpoint { + remote-endpoint = <&etm2_out>; + }; + }; + + port@3 { + reg = <3>; + + funnel_cpuss0_in3: endpoint { + remote-endpoint = <&etm3_out>; + }; + }; + }; + + out-ports { + port { + funnel_cpuss0_out: endpoint { + remote-endpoint = <&funnel_cpuss1_in0>; + }; + }; + }; + }; + + funnel@9810000 { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x09810000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + funnel_cpuss1_in0: endpoint { + remote-endpoint = <&funnel_cpuss0_out>; + }; + }; + + port@3 { + reg = <3>; + + funnel_cpuss1_in3: endpoint { + remote-endpoint = <&tpda_apss_out>; + }; + }; + }; + + out-ports { + port { + funnel_cpuss1_out: endpoint { + remote-endpoint = <&funnel_in1_in6>; + }; + }; + }; + }; + + cti@982b000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x0982b000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_riscv"; + }; + + tpdm@9860000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x09860000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + label = "tpdm_actpm"; + qcom,cmb-element-bits = <64>; + qcom,cmb-msrs-num = <1>; + + out-ports { + port { + tpdm_actpm_out: endpoint { + remote-endpoint = <&tpda_apss_in2>; + }; + }; + }; + }; + + tpdm@9861000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x09861000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + label = "tpdm_hwe"; + qcom,dsb-element-bits = <32>; + qcom,dsb-msrs-num = <32>; + + out-ports { + port { + tpdm_hwe_out: endpoint { + remote-endpoint = <&tpda_apss_in3>; + }; + }; + }; + }; + + tpda@9863000 { + compatible = "qcom,coresight-tpda", "arm,primecell"; + reg = <0x0 0x09863000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + tpda_apss_in0: endpoint { + remote-endpoint = <&tpdm_llm_silver_out>; + }; + }; + + port@2 { + reg = <2>; + + tpda_apss_in2: endpoint { + remote-endpoint = <&tpdm_actpm_out>; + }; + }; + + port@3 { + reg = <3>; + + tpda_apss_in3: endpoint { + remote-endpoint = <&tpdm_hwe_out>; + }; + }; + }; + + out-ports { + port { + tpda_apss_out: endpoint { + remote-endpoint = <&funnel_cpuss1_in3>; + }; + }; + }; + }; + + tpdm@98a0000 { + compatible = "qcom,coresight-tpdm", "arm,primecell"; + reg = <0x0 0x098a0000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + + label = "tpdm_llm_silver"; + qcom,cmb-element-bits = <32>; + qcom,cmb-msrs-num = <12>; + + out-ports { + port { + tpdm_llm_silver_out: endpoint { + remote-endpoint = <&tpda_apss_in0>; + }; + }; + }; + }; + + cti@98e0000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x098e0000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_apss_0"; + }; + + cti@98f0000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x098f0000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_apss_1"; + }; + + cti@9900000 { + compatible = "arm,coresight-cti", "arm,primecell"; + reg = <0x0 0x09900000 0x0 0x1000>; + + clocks = <&rpmcc RPM_SMD_QDSS_CLK>; + clock-names = "apb_pclk"; + label = "cti_apss_2"; + }; + + audiocorecc: clock-controller@a0a0000 { + compatible = "qcom,shikra-audiocorecc"; + reg = <0x0 0x0a0a0000 0x0 0x10000>; + clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>, + <&sleep_clk>, + <0>; + #clock-cells = <1>; + status = "reserved"; /* Owned by Modem firmware */ + }; + + audiocore_csr: reset-controller@a0b4000 { + compatible = "qcom,shikra-audiocore-csr"; + reg = <0x0 0x0a0b4000 0x0 0x1000>; + #reset-cells = <1>; + }; + sram@c11e000 { compatible = "qcom,shikra-imem", "mmio-sram"; reg = <0x0 0x0c11e000 0x0 0x1000>; @@ -2377,6 +4374,7 @@ cpuss0-critical { }; gpuss-thermal { + polling-delay-passive = <10>; thermal-sensors = <&tsens0 6>; trips { @@ -2386,12 +4384,25 @@ trip-point0 { type = "hot"; }; - gpuss-critical { + gpuss_alert0: gpuss-alert0 { temperature = <115000>; + hysteresis = <5000>; + type = "passive"; + }; + + gpuss-critical { + temperature = <120000>; hysteresis = <0>; type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; nsp-thermal { @@ -2521,6 +4532,21 @@ cpuss1-critical { }; }; + snoc { + compatible = "arm,coresight-dummy-source"; + + label = "snoc"; + arm,static-trace-id = <18>; + + out-ports { + port { + snoc_out: endpoint { + remote-endpoint = <&funnel_in0_in5>; + }; + }; + }; + }; + timer { compatible = "arm,armv8-timer";
diff --git a/arch/arm64/boot/dts/qcom/sm4450.dtsi b/arch/arm64/boot/dts/qcom/sm4450.dtsi index b7dc40f..11ab6ed 100644 --- a/arch/arm64/boot/dts/qcom/sm4450.dtsi +++ b/arch/arm64/boot/dts/qcom/sm4450.dtsi
@@ -11,7 +11,6 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/power/qcom,rpmhpd.h> -#include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/soc/qcom,rpmh-rsc.h> / { @@ -390,6 +389,7 @@ gcc: clock-controller@100000 { #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; + power-domains = <&rpmhpd RPMHPD_CX>; clocks = <&rpmhcc RPMH_CXO_CLK>, <&sleep_clk>, <0>,
diff --git a/arch/arm64/boot/dts/qcom/sm6115-xiaomi-lemon.dts b/arch/arm64/boot/dts/qcom/sm6115-xiaomi-lemon.dts new file mode 100644 index 0000000..881e05b --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sm6115-xiaomi-lemon.dts
@@ -0,0 +1,497 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause) +/* + * Copyright (c) 2026 Adam Skladowski <a39skl@gmail.com> + */ + +/dts-v1/; + +#include "sm6115.dtsi" +#include "pm6125.dtsi" +#include "pmi632.dtsi" +#include <dt-bindings/leds/common.h> + +/delete-node/ &pil_adsp_mem; +/delete-node/ &pil_gpu_mem; +/delete-node/ &pil_ipa_fw_mem; +/delete-node/ &pil_ipa_gsi_mem; + +/ { + model = "Xiaomi Redmi 9T"; + compatible = "xiaomi,lemon", "qcom,sm6115"; + chassis-type = "handset"; + + aliases { + mmc0 = &sdhc_2; + }; + + chosen { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + framebuffer0: framebuffer@5c000000 { + compatible = "simple-framebuffer"; + reg = <0 0x5c000000 0 (2340 * 1080 * 4)>; + width = <1080>; + height = <2340>; + stride = <(1080 * 4)>; + format = "a8r8g8b8"; + clocks = <&gcc GCC_DISP_HF_AXI_CLK>; + }; + }; + + backlight_dsi: backlight-dsi { + compatible = "led-backlight"; + leds = <&led_backlight>; + brightness-levels = <255>; + default-brightness-level = <190>; + /* Backlight controllers can differ between panel variants */ + status = "disabled"; + }; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&vol_up_n>; + pinctrl-names = "default"; + + key-volume-up { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + gpios = <&pm6125_gpios 5 GPIO_ACTIVE_LOW>; + debounce-interval = <15>; + linux,can-disable; + wakeup-source; + }; + }; + + reserved-memory { + pil_adsp_mem: memory@53400000 { + reg = <0x0 0x53400000 0x0 0x2600000>; + no-map; + }; + + pil_ipa_fw_mem: memory@55a00000 { + reg = <0x0 0x55a00000 0x0 0x10000>; + no-map; + }; + + pil_ipa_gsi_mem: memory@55a10000 { + reg = <0x0 0x55a10000 0x0 0x5000>; + no-map; + }; + + pil_gpu_mem: memory@fa400000 { + reg = <0x0 0xfa400000 0x0 0x2000>; + no-map; + }; + + ramoops: ramoops@64000000 { + compatible = "ramoops"; + no-map; + reg = <0x0 0x64000000 0x0 0x400000>; + record-size = <0x100000>; + console-size = <0x100000>; + pmsg-size = <0x200000>; + ecc-size = <16>; + }; + }; + + vph_pwr: vph-pwr-regulator { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + + regulator-always-on; + regulator-boot-on; + }; +}; + +&dispcc { + /* Prevent simplefb from dying until we wire panel driver */ + status = "disabled"; +}; + +&gpi_dma0 { + status = "okay"; +}; + +&gpu { + status = "okay"; +}; + +&i2c1 { + status = "okay"; + + lm36923_bl: led-controller@36 { + compatible = "ti,lm36923"; + reg = <0x36>; + + pinctrl-0 = <&lm3692x_bl_active>; + pinctrl-names = "default"; + + enable-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>; + ti,ovp-microvolt = <29000000>; + /* Backlight controllers can differ between panel variants */ + status = "disabled"; + + #address-cells = <1>; + #size-cells = <0>; + + led_backlight: led@0 { + reg = <0>; + function = LED_FUNCTION_BACKLIGHT; + color = <LED_COLOR_ID_WHITE>; + label = ":backlight"; + linux,default-trigger = "backlight"; + led-max-microamp = <25000>; + }; + }; +}; + +&mdss_dsi0 { + vdda-supply = <&pm6125_l18>; +}; + +&mdss_dsi0_out { + data-lanes = <0 1 2 3>; +}; + +&pil_cdsp_mem { + reg = <0x0 0x51a00000 0x0 0xa00000>; +}; + +&pm6125_gpios { + vol_up_n: vol-up-n-state { + pins = "gpio5"; + function = "normal"; + power-source = <0>; + bias-pull-up; + input-enable; + }; +}; + +&pmi632_typec { + status = "okay"; + + connector { + compatible = "usb-c-connector"; + + power-role = "dual"; + data-role = "dual"; + self-powered; + + typec-power-opmode = "default"; + pd-disable; + + vbus-supply = <&pmi632_vbus>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + pmi632_hs_in: endpoint { + remote-endpoint = <&usb_dwc3_hs>; + }; + }; + + port@1 { + reg = <1>; + pmi632_ss_in: endpoint { + remote-endpoint = <&usb_qmpphy_out>; + }; + }; + }; + }; +}; + +&pmi632_vbus { + regulator-min-microamp = <500000>; + regulator-max-microamp = <1000000>; + + status = "okay"; +}; + +&pon_pwrkey { + status = "okay"; +}; + +&pon_resin { + linux,code = <KEY_VOLUMEDOWN>; + + status = "okay"; +}; + +&qupv3_id_0 { + status = "okay"; +}; + +&remoteproc_adsp { + status = "okay"; +}; + +&remoteproc_cdsp { + status = "okay"; +}; + +&remoteproc_mpss { + status = "okay"; +}; + +&rpm_requests { + regulators-0 { + compatible = "qcom,rpm-pm6125-regulators"; + + pm6125_s6: s6 { + regulator-min-microvolt = <304000>; + regulator-max-microvolt = <1456000>; + }; + + pm6125_s7: s7 { + regulator-min-microvolt = <1280000>; + regulator-max-microvolt = <2080000>; + }; + + pm6125_s8: s8 { + regulator-min-microvolt = <1064000>; + regulator-max-microvolt = <1304000>; + }; + + pm6125_l1: l1 { + regulator-min-microvolt = <952000>; + regulator-max-microvolt = <1152000>; + }; + + pm6125_l4: l4 { + regulator-min-microvolt = <488000>; + regulator-max-microvolt = <1000000>; + }; + + pm6125_l5: l5 { + regulator-min-microvolt = <1648000>; + regulator-max-microvolt = <2960000>; + regulator-allow-set-load; + + regulator-always-on; + }; + + pm6125_l6: l6 { + regulator-min-microvolt = <576000>; + regulator-max-microvolt = <656000>; + }; + + pm6125_l7: l7 { + /* sdhci2 vdd-io-bias supply */ + regulator-min-microvolt = <1256000>; + regulator-max-microvolt = <1256000>; + + regulator-always-on; + }; + + pm6125_l8: l8 { + regulator-min-microvolt = <400000>; + regulator-max-microvolt = <728000>; + }; + + pm6125_l9: l9 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2000000>; + }; + + pm6125_l10: l10 { + regulator-min-microvolt = <1704000>; + regulator-max-microvolt = <1904000>; + }; + + pm6125_l11: l11 { + regulator-min-microvolt = <1768000>; + regulator-max-microvolt = <1952000>; + }; + + pm6125_l12: l12 { + regulator-min-microvolt = <1624000>; + regulator-max-microvolt = <1984000>; + }; + + pm6125_l13: l13 { + regulator-min-microvolt = <1504000>; + regulator-max-microvolt = <1952000>; + }; + + pm6125_l14: l14 { + regulator-min-microvolt = <1704000>; + regulator-max-microvolt = <1904000>; + }; + + pm6125_l15: l15 { + regulator-min-microvolt = <2920000>; + regulator-max-microvolt = <3232000>; + }; + + pm6125_l16: l16 { + regulator-min-microvolt = <1704000>; + regulator-max-microvolt = <1904000>; + }; + + pm6125_l17: l17 { + regulator-min-microvolt = <1152000>; + regulator-max-microvolt = <1384000>; + }; + + pm6125_l18: l18 { + regulator-min-microvolt = <1232000>; + regulator-max-microvolt = <1232000>; + }; + + pm6125_l19: l19 { + regulator-min-microvolt = <1624000>; + regulator-max-microvolt = <3304000>; + }; + + pm6125_l20: l20 { + regulator-min-microvolt = <1624000>; + regulator-max-microvolt = <3304000>; + }; + + pm6125_l21: l21 { + regulator-min-microvolt = <2400000>; + regulator-max-microvolt = <3600000>; + }; + + pm6125_l22: l22 { + regulator-min-microvolt = <2952000>; + regulator-max-microvolt = <2960000>; + regulator-allow-set-load; + + regulator-always-on; + }; + + pm6125_l23: l23 { + regulator-min-microvolt = <3200000>; + regulator-max-microvolt = <3400000>; + }; + + pm6125_l24: l24 { + regulator-min-microvolt = <2704000>; + regulator-max-microvolt = <3600000>; + }; + }; +}; + +&sdhc_2 { + cd-gpios = <&tlmm 88 GPIO_ACTIVE_HIGH>; + + pinctrl-0 = <&sdc2_state_on>, <&sdc2_cd_on>; + pinctrl-1 = <&sdc2_state_off>, <&sdc2_cd_off>; + pinctrl-names = "default", "sleep"; + + vmmc-supply = <&pm6125_l22>; + vqmmc-supply = <&pm6125_l5>; + /* No binding for vdd-io-bias on L7*/ + no-sdio; + no-mmc; + + status = "okay"; +}; + +&sleep_clk { + clock-frequency = <32764>; +}; + +&spi2 { + status = "okay"; +}; + +&tlmm { + gpio-reserved-ranges = <14 4>; /* Fingerprint SPI */ + + lm3692x_bl_active: lm3692x-active-state { + pins = "gpio99"; + function = "gpio"; + drive-strength = <0x02>; + bias-pull-up; + }; + + mdss_dsi_active: mdss-dsi-active-state { + pins = "gpio85"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + + sdc2_cd_on: sdc2-cd-on-state { + pins = "gpio88"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + sdc2_cd_off: sdc2-cd-off-state { + pins = "gpio88"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + te_active: te-active-state { + pins = "gpio81"; + function = "mdp_vsync"; + drive-strength = <2>; + bias-pull-down; + }; +}; + +&ufs_mem_hc { + vcc-max-microamp = <600000>; + vcc-supply = <&pm6125_l24>; + vccq2-max-microamp = <600000>; + vccq2-supply = <&pm6125_l11>; + vdd-hba-supply = <&pm6125_l18>; + + status = "okay"; +}; + +&ufs_mem_phy { + vdda-phy-supply = <&pm6125_l4>; + vdda-pll-supply = <&pm6125_l12>; + + status = "okay"; +}; + +&usb { + status = "okay"; +}; + +&usb_dwc3 { + maximum-speed = "high-speed"; +}; + +&usb_dwc3_hs { + remote-endpoint = <&pmi632_hs_in>; +}; + +&usb_hsphy { + vdd-supply = <&pm6125_l4>; + vdda-pll-supply = <&pm6125_l12>; + vdda-phy-dpdm-supply = <&pm6125_l15>; + + status = "okay"; +}; + +&usb_qmpphy { + vdda-phy-supply = <&pm6125_l4>; + vdda-pll-supply = <&pm6125_l12>; + + status = "okay"; +}; + +&usb_qmpphy_out { + remote-endpoint = <&pmi632_ss_in>; +}; + +&xo_board { + clock-frequency = <19200000>; +};
diff --git a/arch/arm64/boot/dts/qcom/sm6115.dtsi b/arch/arm64/boot/dts/qcom/sm6115.dtsi index 3520802..0f2af8a 100644 --- a/arch/arm64/boot/dts/qcom/sm6115.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6115.dtsi
@@ -1665,7 +1665,7 @@ usb: usb@4ef8800 { resets = <&gcc GCC_USB30_PRIM_BCR>; power-domains = <&gcc GCC_USB30_PRIM_GDSC>; - /* TODO: USB<->IPA path */ + /* TODO: USB<->IPA path */ interconnects = <&system_noc MASTER_USB3 RPM_ALWAYS_TAG &bimc SLAVE_EBI_CH0 RPM_ALWAYS_TAG>, <&bimc MASTER_AMPSS_M0 RPM_ALWAYS_TAG
diff --git a/arch/arm64/boot/dts/qcom/sm6350.dtsi b/arch/arm64/boot/dts/qcom/sm6350.dtsi index 15d38b7..e0506fa 100644 --- a/arch/arm64/boot/dts/qcom/sm6350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm6350.dtsi
@@ -794,6 +794,7 @@ gcc: clock-controller@100000 { #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; + power-domains = <&rpmhpd SM6350_CX>; clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk"; @@ -2242,6 +2243,239 @@ cci1_i2c0: i2c-bus@0 { /* SM6350 seems to have cci1_i2c1 on gpio2 & gpio3 but unused downstream */ }; + camss: isp@acb3000 { + compatible = "qcom,sm6350-camss"; + + reg = <0x0 0x0acb3000 0x0 0x1000>, + <0x0 0x0acba000 0x0 0x1000>, + <0x0 0x0acc1000 0x0 0x1000>, + <0x0 0x0acc8000 0x0 0x1000>, + <0x0 0x0ac65000 0x0 0x1000>, + <0x0 0x0ac66000 0x0 0x1000>, + <0x0 0x0ac67000 0x0 0x1000>, + <0x0 0x0ac68000 0x0 0x1000>, + <0x0 0x0acaf000 0x0 0x4000>, + <0x0 0x0acb6000 0x0 0x4000>, + <0x0 0x0acbd000 0x0 0x4000>, + <0x0 0x0acc4000 0x0 0x4000>, + <0x0 0x0ac18000 0x0 0x3000>, + <0x0 0x0ac00000 0x0 0x6000>, + <0x0 0x0ac10000 0x0 0x8000>, + <0x0 0x0ac6f000 0x0 0x8000>, + <0x0 0x0ac42000 0x0 0x4600>, + <0x0 0x01fc0000 0x0 0x40000>, + <0x0 0x0ac48000 0x0 0x1000>, + <0x0 0x0ac40000 0x0 0x1000>, + <0x0 0x0ac87000 0x0 0xa000>, + <0x0 0x0ac52000 0x0 0x4000>, + <0x0 0x0ac4e000 0x0 0x4000>, + <0x0 0x0ac6b000 0x0 0xa00>; + reg-names = "csid0", + "csid1", + "csid2", + "csid_lite", + "csiphy0", + "csiphy1", + "csiphy2", + "csiphy3", + "vfe0", + "vfe1", + "vfe2", + "vfe_lite", + "a5_csr", + "a5_qgic", + "a5_sierra", + "bps", + "camnoc", + "core_top_csr_tcsr", + "cpas_cdm", + "cpas_top", + "ipe", + "jpeg_dma", + "jpeg_enc", + "lrme"; + + clocks = <&gcc GCC_CAMERA_AXI_CLK>, + <&camcc CAMCC_SOC_AHB_CLK>, + <&camcc CAMCC_CAMNOC_AXI_CLK>, + <&camcc CAMCC_CORE_AHB_CLK>, + <&camcc CAMCC_CPAS_AHB_CLK>, + <&camcc CAMCC_CSIPHY0_CLK>, + <&camcc CAMCC_CSI0PHYTIMER_CLK>, + <&camcc CAMCC_CSIPHY1_CLK>, + <&camcc CAMCC_CSI1PHYTIMER_CLK>, + <&camcc CAMCC_CSIPHY2_CLK>, + <&camcc CAMCC_CSI2PHYTIMER_CLK>, + <&camcc CAMCC_CSIPHY3_CLK>, + <&camcc CAMCC_CSI3PHYTIMER_CLK>, + <&camcc CAMCC_IFE_0_AXI_CLK>, + <&camcc CAMCC_IFE_0_CLK>, + <&camcc CAMCC_IFE_0_CPHY_RX_CLK>, + <&camcc CAMCC_IFE_0_CSID_CLK>, + <&camcc CAMCC_IFE_1_AXI_CLK>, + <&camcc CAMCC_IFE_1_CLK>, + <&camcc CAMCC_IFE_1_CPHY_RX_CLK>, + <&camcc CAMCC_IFE_1_CSID_CLK>, + <&camcc CAMCC_IFE_2_AXI_CLK>, + <&camcc CAMCC_IFE_2_CLK>, + <&camcc CAMCC_IFE_2_CPHY_RX_CLK>, + <&camcc CAMCC_IFE_2_CSID_CLK>, + <&camcc CAMCC_IFE_LITE_CLK>, + <&camcc CAMCC_IFE_LITE_CPHY_RX_CLK>, + <&camcc CAMCC_IFE_LITE_CSID_CLK>, + <&camcc CAMCC_BPS_CLK>, + <&camcc CAMCC_BPS_AHB_CLK>, + <&camcc CAMCC_BPS_AREG_CLK>, + <&camcc CAMCC_BPS_AXI_CLK>, + <&camcc CAMCC_ICP_CLK>, + <&camcc CAMCC_IPE_0_CLK>, + <&camcc CAMCC_IPE_0_AHB_CLK>, + <&camcc CAMCC_IPE_0_AREG_CLK>, + <&camcc CAMCC_IPE_0_AXI_CLK>, + <&camcc CAMCC_JPEG_CLK>, + <&camcc CAMCC_LRME_CLK>; + clock-names = "cam_axi", + "soc_ahb", + "camnoc_axi", + "core_ahb", + "cpas_ahb", + "csiphy0", + "csiphy0_timer", + "csiphy1", + "csiphy1_timer", + "csiphy2", + "csiphy2_timer", + "csiphy3", + "csiphy3_timer", + "vfe0_axi", + "vfe0", + "vfe0_cphy_rx", + "vfe0_csid", + "vfe1_axi", + "vfe1", + "vfe1_cphy_rx", + "vfe1_csid", + "vfe2_axi", + "vfe2", + "vfe2_cphy_rx", + "vfe2_csid", + "vfe_lite", + "vfe_lite_cphy_rx", + "vfe_lite_csid", + "bps", + "bps_ahb", + "bps_areg", + "bps_axi", + "icp", + "ipe0", + "ipe0_ahb", + "ipe0_areg", + "ipe0_axi", + "jpeg", + "lrme"; + + interrupts = <GIC_SPI 464 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 466 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 717 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 473 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 477 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 478 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 479 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 461 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 465 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 467 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 718 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 472 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 463 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 459 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 469 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 475 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 474 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 476 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "csid0", + "csid1", + "csid2", + "csid_lite", + "csiphy0", + "csiphy1", + "csiphy2", + "csiphy3", + "vfe0", + "vfe1", + "vfe2", + "vfe_lite", + "a5", + "cpas", + "cpas_cdm", + "jpeg_dma", + "jpeg_enc", + "lrme"; + + interconnects = <&gem_noc MASTER_AMPSS_M0 QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_CAMERA_CFG QCOM_ICC_TAG_ACTIVE_ONLY>, + <&mmss_noc MASTER_CAMNOC_HF QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_EBI_CH0 QCOM_ICC_TAG_ALWAYS>, + <&mmss_noc MASTER_CAMNOC_SF QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_EBI_CH0 QCOM_ICC_TAG_ALWAYS>, + <&mmss_noc MASTER_CAMNOC_ICP QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_EBI_CH0 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "ahb", + "hf_mnoc", + "sf_mnoc", + "sf_icp_mnoc"; + + iommus = <&apps_smmu 0x820 0xc0>, + <&apps_smmu 0x840 0x0>, + <&apps_smmu 0x860 0xc0>, + <&apps_smmu 0x880 0x0>, + <&apps_smmu 0xc40 0x20>, + <&apps_smmu 0xc60 0x20>, + <&apps_smmu 0xc80 0x0>, + <&apps_smmu 0xca2 0x0>, + <&apps_smmu 0xcc0 0x20>, + <&apps_smmu 0xce0 0x20>, + <&apps_smmu 0xd00 0x20>, + <&apps_smmu 0xd20 0x20>, + <&apps_smmu 0xd40 0x20>, + <&apps_smmu 0xd60 0x20>; + + power-domains = <&camcc IFE_0_GDSC>, + <&camcc IFE_1_GDSC>, + <&camcc IFE_2_GDSC>, + <&camcc TITAN_TOP_GDSC>, + <&camcc BPS_GDSC>, + <&camcc IPE_0_GDSC>; + power-domain-names = "ife0", + "ife1", + "ife2", + "top", + "bps", + "ipe"; + + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + }; + + port@1 { + reg = <1>; + }; + + port@2 { + reg = <2>; + }; + + port@3 { + reg = <3>; + }; + }; + }; + camcc: clock-controller@ad00000 { compatible = "qcom,sm6350-camcc"; reg = <0x0 0x0ad00000 0x0 0x16000>;
diff --git a/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts b/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts index 5d20ad9..773304b4 100644 --- a/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts +++ b/arch/arm64/boot/dts/qcom/sm7225-fairphone-fp4.dts
@@ -992,6 +992,10 @@ xo-therm@0 { }; }; +&pmk8350_pon { + status = "disabled"; +}; + &pmk8350_rtc { status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts b/arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts index 7db9ae1..8d8fef9 100644 --- a/arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts +++ b/arch/arm64/boot/dts/qcom/sm7325-nothing-spacewar.dts
@@ -1455,5 +1455,7 @@ &venus { }; &wifi { + qcom,calibration-variant = "Nothing_Spacewar"; + status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/sm7325-xiaomi-lisa.dts b/arch/arm64/boot/dts/qcom/sm7325-xiaomi-lisa.dts new file mode 100644 index 0000000..28a19c9 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sm7325-xiaomi-lisa.dts
@@ -0,0 +1,1108 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2024, Jens Reidel <adrian@travitia.xyz> + * Copyright (c) 2026, Oleksii Onchul <oleksiionchul@gmail.com> + */ + +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/iio/qcom,spmi-adc7-pm7325.h> +#include <dt-bindings/iio/qcom,spmi-adc7-pm8350b.h> +#include <dt-bindings/iio/qcom,spmi-adc7-pmk8350.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/pinctrl/qcom,pmic-gpio.h> +#include <dt-bindings/regulator/qcom,rpmh-regulator.h> + +#include "sm7325.dtsi" +#include "pm7325.dtsi" +#include "pm8350b.dtsi" /* PM7325B */ +#include "pm8350c.dtsi" /* PM7350C */ +#include "pmk8350.dtsi" /* PMK7325 */ + +/* The following reserved memory regions have different addresses or sizes */ +/delete-node/ &adsp_mem; +/delete-node/ &adsp_rpc_remote_heap_mem; +/delete-node/ &cdsp_mem; +/delete-node/ &rmtfs_mem; + +/ { + model = "Xiaomi 11 Lite 5G NE"; + compatible = "xiaomi,lisa", "qcom,sm7325"; + chassis-type = "handset"; + + aliases { + serial0 = &uart5; + serial1 = &uart7; + }; + + chosen { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + stdout-path = "serial0:115200n8"; + + framebuffer0: framebuffer { + compatible = "simple-framebuffer"; + memory-region = <&framebuffer_mem>; + width = <1080>; + height = <2400>; + stride = <(1080 * 4)>; + format = "a8r8g8b8"; + + clocks = <&gcc GCC_DISP_HF_AXI_CLK>, + <&dispcc DISP_CC_MDSS_MDP_CLK>, + <&dispcc DISP_CC_MDSS_BYTE0_CLK>, + <&dispcc DISP_CC_MDSS_BYTE0_INTF_CLK>, + <&dispcc DISP_CC_MDSS_PCLK0_CLK>, + <&dispcc DISP_CC_MDSS_VSYNC_CLK>; + power-domains = <&dispcc DISP_CC_MDSS_CORE_GDSC>; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&volume_up_default>; + pinctrl-names = "default"; + + key-volume-up { + label = "Volume Up"; + gpios = <&pm7325_gpios 6 GPIO_ACTIVE_LOW>; + linux,code = <KEY_VOLUMEUP>; + }; + }; + + pmic-glink { + compatible = "qcom,sm7325-pmic-glink", + "qcom,qcm6490-pmic-glink", + "qcom,pmic-glink"; + + #address-cells = <1>; + #size-cells = <0>; + + orientation-gpios = <&tlmm 140 GPIO_ACTIVE_HIGH>; + + connector@0 { + compatible = "usb-c-connector"; + reg = <0>; + power-role = "dual"; + data-role = "dual"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + pmic_glink_hs_in: endpoint { + remote-endpoint = <&usb_1_dwc3_hs>; + }; + }; + + port@2 { + reg = <2>; + + pmic_glink_sbu: endpoint { + remote-endpoint = <&fsa4480_sbu_mux>; + }; + }; + }; + }; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + cdsp_secure_heap_mem: cdsp-secure-heap@81800000 { + reg = <0x0 0x81800000 0x0 0x1e00000>; + no-map; + }; + + adsp_mem: adsp@86700000 { + reg = <0x0 0x86700000 0x0 0x4000000>; + no-map; + }; + + /* Mainline video_mem is downstream cvp_mem */ + real_video_mem: video@8ad00000 { + reg = <0x0 0x8ad00000 0x0 0x500000>; + no-map; + }; + + ipa_gsi_mem: ipa-gsi@8b710000 { + reg = <0x0 0x8b710000 0x0 0xa000>; + no-map; + }; + + cdsp_mem: cdsp@9c700000 { + reg = <0x0 0x9c700000 0x0 0x1e00000>; + no-map; + }; + + adsp_rpc_remote_heap_mem: adsp-rpc-remote-heap@9e500000 { + reg = <0x0 0x9e500000 0x0 0x800000>; + no-map; + }; + + ramoops@a9000000 { + compatible = "ramoops"; + reg = <0x0 0xa9000000 0x0 0x200000>; + pmsg-size = <0x200000>; + ecc-size = <16>; + mem-type = <2>; + }; + + removed_mem: removed@c0000000 { + reg = <0x0 0xc0000000 0x0 0x5100000>; + no-map; + }; + + pil_trustedvm_mem: pil-trustedvm-region@d0800000 { + reg = <0x0 0xd0800000 0x0 0x76f7000>; + no-map; + }; + + qrtr_shmem: qrtr-shmem@d7ef7000 { + reg = <0x0 0xd7ef7000 0x0 0x9000>; + no-map; + }; + + neuron_block_0_mem: neuron-block@d7f00000 { + reg = <0x0 0xd7f00000 0x0 0x80000>; + no-map; + }; + + neuron_block_1_mem: neuron-block@d7f80000 { + reg = <0x0 0xd7f80000 0x0 0x80000>; + no-map; + }; + + framebuffer_mem: framebuffer@e1000000 { + reg = <0x0 0xe1000000 0x0 (1080 * 2400 * 4)>; + no-map; + }; + + rmtfs_mem: rmtfs@ef500000 { + compatible = "qcom,rmtfs-mem"; + reg = <0x0 0xef500000 0x0 0x280000>; + no-map; + + qcom,client-id = <1>; + qcom,vmid = <QCOM_SCM_VMID_MSS_MSA>, + <QCOM_SCM_VMID_NAV>; + }; + }; + + vph_pwr: vph-pwr-regulator { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + }; + + /* S2B is really ebi.lvl but it's there for supply map completeness sake. */ + vreg_s2b_0p7: smpa3-regulator { + compatible = "regulator-fixed"; + regulator-name = "vreg_s2b_0p7"; + + regulator-min-microvolt = <700000>; + regulator-max-microvolt = <700000>; + regulator-always-on; + vin-supply = <&vph_pwr>; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pm7325-rpmh-regulators"; + qcom,pmic-id = "b"; + + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + vdd-s7-supply = <&vph_pwr>; + vdd-s8-supply = <&vph_pwr>; + + vdd-l1-l4-l12-l15-supply = <&vreg_s7b_0p952>; + vdd-l2-l7-supply = <&vreg_bob>; + vdd-l3-supply = <&vreg_s2b_0p7>; + vdd-l5-supply = <&vreg_s2b_0p7>; + vdd-l6-l9-l10-supply = <&vreg_s8b_1p256>; + vdd-l8-supply = <&vreg_s7b_0p952>; + vdd-l11-l17-l18-l19-supply = <&vreg_s1b_1p856>; + vdd-l13-supply = <&vreg_s7b_0p952>; + vdd-l14-l16-supply = <&vreg_s8b_1p256>; + + /* + * S2, L4-L5 are ARCs: + * S2 - ebi.lvl, + * L4 - lmx.lvl, + * l5 - lcx.lvl. + * + * L10 are unused. + */ + + vdd19_pmu_rfa_i: + vreg_s1b_1p856: smps1 { + regulator-name = "vreg_s1b_1p856"; + regulator-min-microvolt = <1840000>; + regulator-max-microvolt = <2040000>; + }; + + vreg_s7b_0p952: smps7 { + regulator-name = "vreg_s7b_0p952"; + regulator-min-microvolt = <535000>; + regulator-max-microvolt = <1120000>; + }; + + vdd13_pmu_rfa_i: + vreg_s8b_1p256: smps8 { + regulator-name = "vreg_s8b_1p256"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1500000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_RET>; + }; + + vreg_l1b_0p912: ldo1 { + regulator-name = "vreg_l1b_0p912"; + regulator-min-microvolt = <825000>; + regulator-max-microvolt = <925000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vdd_a_usbhs_3p1: + vreg_l2b_3p072: ldo2 { + regulator-name = "vreg_l2b_3p072"; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <3544000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3b_0p6: ldo3 { + regulator-name = "vreg_l3b_0p6"; + regulator-min-microvolt = <312000>; + regulator-max-microvolt = <910000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vdd_a_dsi_0_1p2: + vdd_a_ufs_0_1p2: + vreg_l6b_1p2: ldo6 { + regulator-name = "vreg_l6b_1p2"; + regulator-min-microvolt = <1140000>; + regulator-max-microvolt = <1260000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7b_2p96: ldo7 { + regulator-name = "vreg_l7b_2p96"; + /* Constrained for UFS VCC, at least until UFS driver scales voltage */ + regulator-min-microvolt = <2952000>; + regulator-max-microvolt = <2952000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l8b_0p904: ldo8 { + regulator-name = "vreg_l8b_0p904"; + regulator-min-microvolt = <870000>; + regulator-max-microvolt = <970000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l9b_1p2: ldo9 { + regulator-name = "vreg_l9b_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l11b_1p776: ldo11 { + regulator-name = "vreg_l11b_1p776"; + regulator-min-microvolt = <1504000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l12b_0p8: ldo12 { + regulator-name = "vreg_l12b_0p8"; + regulator-min-microvolt = <751000>; + regulator-max-microvolt = <824000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l13b_0p8: ldo13 { + regulator-name = "vreg_l13b_0p8"; + regulator-min-microvolt = <530000>; + regulator-max-microvolt = <824000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l14b_1p2: ldo14 { + regulator-name = "vreg_l14b_1p2"; + regulator-min-microvolt = <1080000>; + regulator-max-microvolt = <1304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l15b_0p88: ldo15 { + regulator-name = "vreg_l15b_0p88"; + regulator-min-microvolt = <765000>; + regulator-max-microvolt = <1020000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l16b_1p2: ldo16 { + regulator-name = "vreg_l16b_1p2"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1300000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l17b_1p8: ldo17 { + regulator-name = "vreg_l17b_1p8"; + regulator-min-microvolt = <1700000>; + regulator-max-microvolt = <1900000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l18b_1p8: ldo18 { + regulator-name = "vreg_l18b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l19b_1p8: ldo19 { + regulator-name = "vreg_l19b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-1 { + compatible = "qcom,pm8350c-rpmh-regulators"; + qcom,pmic-id = "c"; + + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + vdd-s5-supply = <&vph_pwr>; + vdd-s7-supply = <&vph_pwr>; + vdd-s9-supply = <&vph_pwr>; + vdd-s10-supply = <&vph_pwr>; + + vdd-l1-l12-supply = <&vreg_s1b_1p856>; + vdd-l2-l8-supply = <&vreg_s1b_1p856>; + vdd-l3-l4-l5-l7-l13-supply = <&vreg_bob>; + vdd-l6-l9-l11-supply = <&vreg_bob>; + vdd-l10-supply = <&vreg_s7b_0p952>; + + vdd-bob-supply = <&vph_pwr>; + + /* + * S2, S5, S7, S10 are ARCs: + * S2 - cx.lvl, + * S5 - mss.lvl, + * S7 - gfx.lvl, + * S10 - mx.lvl. + */ + + vreg_s1c_2p2: smps1 { + regulator-name = "vreg_s1c_2p2"; + regulator-min-microvolt = <2190000>; + regulator-max-microvolt = <2210000>; + }; + + vreg_s9c_0p676: smps9 { + regulator-name = "vreg_s9c_0p676"; + regulator-min-microvolt = <1010000>; + regulator-max-microvolt = <1170000>; + }; + + vdd_a_usbhs_1p8: + vdd_qfprom: + vreg_l1c_1p8: ldo1 { + regulator-name = "vreg_l1c_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1980000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2c_1p8: ldo2 { + regulator-name = "vreg_l2c_1p8"; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <1980000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4c_1p8_3p0: ldo4 { + regulator-name = "vreg_l4c_1p8_3p0"; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <3300000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5c_1p8_3p0: ldo5 { + regulator-name = "vreg_l5c_1p8_3p0"; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <3300000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6c_2p96: ldo6 { + regulator-name = "vreg_l6c_2p96"; + regulator-min-microvolt = <1650000>; + regulator-max-microvolt = <3544000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7c_3p0: ldo7 { + regulator-name = "vreg_l7c_3p0"; + regulator-min-microvolt = <3000000>; + regulator-max-microvolt = <3544000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l8c_1p8: ldo8 { + regulator-name = "vreg_l8c_1p8"; + regulator-min-microvolt = <1620000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-always-on; + }; + + vreg_l9c_2p96: ldo9 { + regulator-name = "vreg_l9c_2p96"; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <3544000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vdd_a_dsi_0_0p9: + vdd_a_dsi_0_pll_0p9: + vdd_a_ufs_0_core: + vdd_a_usbhs_core: + vreg_l10c_0p88: ldo10 { + regulator-name = "vreg_l10c_0p88"; + regulator-min-microvolt = <720000>; + regulator-max-microvolt = <1050000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l11c_2p8: ldo11 { + regulator-name = "vreg_l11c_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <3544000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l12c_1p8: ldo12 { + regulator-name = "vreg_l12c_1p8"; + regulator-min-microvolt = <1650000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l13c_3p0: ldo13 { + regulator-name = "vreg_l13c_3p0"; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <3544000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vdd_flash: + vdd_iris_rgb: + vdd_mic_bias: + vreg_bob: bob { + regulator-name = "vreg_bob"; + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <3960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_AUTO>; + }; + }; +}; + +&gcc { + protected-clocks = <GCC_CFG_NOC_LPASS_CLK>, + <GCC_MSS_CFG_AHB_CLK>, + <GCC_MSS_OFFLINE_AXI_CLK>, + <GCC_MSS_Q6SS_BOOT_CLK_SRC>, + <GCC_MSS_Q6_MEMNOC_AXI_CLK>, + <GCC_MSS_SNOC_AXI_CLK>, + <GCC_QSPI_CNOC_PERIPH_AHB_CLK>, + <GCC_QSPI_CORE_CLK>, + <GCC_QSPI_CORE_CLK_SRC>, + <GCC_SEC_CTRL_CLK_SRC>, + <GCC_WPSS_AHB_BDG_MST_CLK>, + <GCC_WPSS_AHB_CLK>, + <GCC_WPSS_RSCP_CLK>; +}; + +&gpi_dma0 { + status = "okay"; +}; + +&gpi_dma1 { + status = "okay"; +}; + +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/sm7325/xiaomi/lisa/a660_zap.mbn"; +}; + +&i2c1 { + clock-frequency = <100000>; + + status = "okay"; + + pm8008: pmic@8 { + compatible = "qcom,pm8008"; + reg = <0x8>; + + interrupts-extended = <&tlmm 25 IRQ_TYPE_EDGE_RISING>; + reset-gpios = <&pm8350c_gpios 3 GPIO_ACTIVE_LOW>; + + vdd-l1-l2-supply = <&vreg_s8b_1p256>; + vdd-l3-l4-supply = <&vreg_bob>; + vdd-l5-supply = <&vreg_s1b_1p856>; + vdd-l6-supply = <&vreg_bob>; + vdd-l7-supply = <&vreg_bob>; + + pinctrl-names = "default"; + pinctrl-0 = <&pm8008_int_default>, <&pm8008_reset_n_default>; + + gpio-controller; + #gpio-cells = <2>; + gpio-ranges = <&pm8008 0 0 2>; + + interrupt-controller; + #interrupt-cells = <2>; + + #thermal-sensor-cells = <0>; + + regulators { + vreg_l1p: ldo1 { + regulator-name = "vreg_l1p"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1200000>; + }; + + vreg_l2p: ldo2 { + regulator-name = "vreg_l2p"; + regulator-min-microvolt = <950000>; + regulator-max-microvolt = <1200000>; + }; + + vreg_l3p: ldo3 { + regulator-name = "vreg_l3p"; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <3000000>; + }; + + vreg_l4p: ldo4 { + regulator-name = "vreg_l4p"; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2900000>; + }; + + vreg_l5p: ldo5 { + regulator-name = "vreg_l5p"; + regulator-min-microvolt = <1700000>; + regulator-max-microvolt = <1900000>; + }; + + vreg_l6p: ldo6 { + regulator-name = "vreg_l6p"; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <2900000>; + }; + + vreg_l7p: ldo7 { + regulator-name = "vreg_l7p"; + regulator-min-microvolt = <2700000>; + regulator-max-microvolt = <3000000>; + }; + }; + }; + + fsa4480: typec-mux@42 { + compatible = "fcs,fsa4480"; + reg = <0x42>; + + vcc-supply = <&vreg_bob>; + mode-switch; + orientation-switch; + + port { + fsa4480_sbu_mux: endpoint { + remote-endpoint = <&pmic_glink_sbu>; + }; + }; + }; +}; + +&i2c4 { + clock-frequency = <100000>; + + status = "okay"; + + /* awinic,aw8624_haptic @ 5a */ +}; + +&ipa { + firmware-name = "qcom/sm7325/xiaomi/lisa/ipa_fws.mbn"; + + status = "okay"; +}; + +&pm7325_gpios { + volume_up_default: volume-up-default-state { + pins = "gpio6"; + function = PMIC_GPIO_FUNC_NORMAL; + power-source = <1>; + bias-pull-up; + input-enable; + }; +}; + +&pm8350c_gpios { + pm8008_reset_n_default: pm8008-reset-n-default-state { + pins = "gpio3"; + function = PMIC_GPIO_FUNC_NORMAL; + bias-pull-down; + }; +}; + +&pm8350c_flash { + status = "okay"; + + led-0 { + function = LED_FUNCTION_FLASH; + color = <LED_COLOR_ID_WHITE>; + led-sources = <1>, <4>; + led-max-microamp = <500000>; + flash-max-microamp = <1500000>; + flash-max-timeout-us = <1280000>; + }; +}; + +&pmk8350_adc_tm { + status = "okay"; + + /* PMK8350 */ + xo-therm@0 { + reg = <0>; + io-channels = <&pmk8350_vadc PMK8350_ADC7_AMUX_THM1_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time-us = <200>; + }; + + /* PM7325 */ + quiet-therm@1 { + reg = <1>; + io-channels = <&pmk8350_vadc PM7325_ADC7_AMUX_THM1_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time-us = <200>; + }; + + cam-flash-therm@2 { + reg = <2>; + io-channels = <&pmk8350_vadc PM7325_ADC7_AMUX_THM2_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time-us = <200>; + }; + + sdm-skin-therm@3 { + reg = <3>; + io-channels = <&pmk8350_vadc PM7325_ADC7_AMUX_THM3_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time-us = <200>; + }; + + wide-rfc-therm@4 { + reg = <4>; + io-channels = <&pmk8350_vadc PM7325_ADC7_AMUX_THM4_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time-us = <200>; + }; + + 5g-pa-therm@5 { + reg = <5>; + io-channels = <&pmk8350_vadc PM7325_ADC7_AMUX_THM5_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time-us = <200>; + }; + + 4g-pa-therm@6 { + reg = <6>; + io-channels = <&pmk8350_vadc PM7325_ADC7_GPIO3_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time-us = <200>; + }; + + /* PM8350B */ + chg-skin-therm@7 { + reg = <7>; + io-channels = <&pmk8350_vadc PM8350B_ADC7_GPIO2_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time-us = <200>; + }; +}; + +&pmk8350_rtc { + status = "okay"; +}; + +&pmk8350_vadc { + /* PMK8350 */ + channel@44 { + reg = <PMK8350_ADC7_AMUX_THM1_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + label = "pmk8350_xo_therm"; + }; + + /* PM7325 */ + channel@144 { + reg = <PM7325_ADC7_AMUX_THM1_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + label = "pm7325_quiet_therm"; + }; + + channel@145 { + reg = <PM7325_ADC7_AMUX_THM2_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + label = "pm7325_cam_flash_therm"; + }; + + channel@146 { + reg = <PM7325_ADC7_AMUX_THM3_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + label = "pm7325_sdm_skin_therm"; + }; + + channel@147 { + reg = <PM7325_ADC7_AMUX_THM4_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + label = "pm7325_wide_rfc_therm"; + }; + + channel@148 { + reg = <PM7325_ADC7_AMUX_THM5_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + label = "pm7325_5g_pa_therm"; + }; + + channel@14c { + reg = <PM7325_ADC7_GPIO3_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + label = "pm7325_4g_pa_therm"; + }; + + /* PM8350B */ + channel@34b { + reg = <PM8350B_ADC7_GPIO2_100K_PU>; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + label = "pm8350b_chg_skin_therm"; + }; +}; + +&pon_pwrkey { + status = "okay"; +}; + +&pon_resin { + linux,code = <KEY_VOLUMEDOWN>; + + status = "okay"; +}; + +&qfprom { + vcc-supply = <&vdd_qfprom>; +}; + +&qup_spi13_cs { + drive-strength = <6>; + bias-disable; +}; + +&qup_spi13_data_clk { + drive-strength = <6>; + bias-disable; +}; + +&qup_uart5_rx { + drive-strength = <2>; + bias-disable; +}; + +&qup_uart5_tx { + drive-strength = <2>; + bias-disable; +}; + +&qupv3_id_0 { + status = "okay"; +}; + +&qupv3_id_1 { + status = "okay"; +}; + +&remoteproc_adsp { + firmware-name = "qcom/sm7325/xiaomi/lisa/adsp.mbn"; + + status = "okay"; +}; + +&remoteproc_cdsp { + firmware-name = "qcom/sm7325/xiaomi/lisa/cdsp.mbn"; + + status = "okay"; +}; + +&remoteproc_mpss { + firmware-name = "qcom/sm7325/xiaomi/lisa/modem.mbn"; + + status = "okay"; +}; + +&remoteproc_wpss { + firmware-name = "qcom/sm7325/xiaomi/lisa/wpss.mbn"; + + status = "okay"; +}; + +&spi13 { + status = "okay"; + + touchscreen@0 { + compatible = "goodix,gt9897"; + reg = <0>; + spi-max-frequency = <6000000>; + + interrupts-extended = <&tlmm 81 IRQ_TYPE_LEVEL_LOW>; + + reset-gpios = <&tlmm 105 GPIO_ACTIVE_LOW>; + + avdd-supply = <&vreg_l7c_3p0>; + vddio-supply = <&vreg_l2c_1p8>; + + pinctrl-0 = <&touchscreen_default>; + pinctrl-names = "default"; + + touchscreen-size-x = <1080>; + touchscreen-size-y = <2400>; + }; +}; + +&tlmm { + gpio-reserved-ranges = <32 2>, /* SMB1394 (SPMI) */ + <48 4>, /* Presumably NFC SE */ + <56 4>; /* Presumably fingerprint reader */ + + qup_uart7_sleep_cts: qup-uart7-sleep-cts-state { + pins = "gpio28"; + function = "gpio"; + /* + * Configure a bias-bus-hold on CTS to lower power + * usage when Bluetooth is turned off. Bus hold will + * maintain a low power state regardless of whether + * the Bluetooth module drives the pin in either + * direction or leaves the pin fully unpowered. + */ + bias-bus-hold; + }; + + qup_uart7_sleep_rts: qup-uart7-sleep-rts-state { + pins = "gpio29"; + function = "gpio"; + /* + * Configure pull-down on RTS. As RTS is active low + * signal, pull it low to indicate the BT SoC that it + * can wakeup the system anytime from suspend state by + * pulling RX low (by sending wakeup bytes). + */ + bias-pull-down; + }; + + qup_uart7_sleep_tx: qup-uart7-sleep-tx-state { + pins = "gpio30"; + function = "gpio"; + /* + * Configure pull-up on TX when it isn't actively driven + * to prevent BT SoC from receiving garbage during sleep. + */ + bias-pull-up; + }; + + qup_uart7_sleep_rx: qup-uart7-sleep-rx-state { + pins = "gpio31"; + function = "gpio"; + /* + * Configure a pull-up on RX. This is needed to avoid + * garbage data when the TX pin of the Bluetooth module + * is floating which may cause spurious wakeups. + */ + bias-pull-up; + }; + + bluetooth_enable_default: bluetooth-enable-default-state { + pins = "gpio85"; + function = "gpio"; + output-low; + bias-disable; + }; + + sw_ctrl_default: sw-ctrl-default-state { + pins = "gpio86"; + function = "gpio"; + bias-pull-down; + }; + + touchscreen_default: touchscreen-default-state { + pins = "gpio81", "gpio105"; + function = "gpio"; + drive-strength = <8>; + bias-pull-up; + }; + + pm8008_int_default: pm8008-int-default-state { + pins = "gpio25"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; +}; + +&uart5 { + compatible = "qcom,geni-debug-uart"; + + status = "okay"; +}; + +&uart7 { + /delete-property/interrupts; + interrupts-extended = <&intc GIC_SPI 608 IRQ_TYPE_LEVEL_HIGH>, + <&tlmm 31 IRQ_TYPE_EDGE_FALLING>; + + pinctrl-1 = <&qup_uart7_sleep_cts>, + <&qup_uart7_sleep_rts>, + <&qup_uart7_sleep_tx>, + <&qup_uart7_sleep_rx>; + pinctrl-names = "default", "sleep"; + + status = "okay"; + + bluetooth: bluetooth { + compatible = "qcom,wcn6750-bt"; + + pinctrl-0 = <&bluetooth_enable_default>, <&sw_ctrl_default>; + pinctrl-names = "default"; + + enable-gpios = <&tlmm 85 GPIO_ACTIVE_HIGH>; + swctrl-gpios = <&tlmm 86 GPIO_ACTIVE_HIGH>; + + vddio-supply = <&vreg_l19b_1p8>; + vddaon-supply = <&vreg_s7b_0p952>; + vddbtcxmx-supply = <&vreg_s7b_0p952>; + vddrfacmn-supply = <&vreg_s7b_0p952>; + vddrfa0p8-supply = <&vreg_s7b_0p952>; + vddrfa1p2-supply = <&vdd13_pmu_rfa_i>; + vddrfa1p7-supply = <&vdd19_pmu_rfa_i>; + vddrfa2p2-supply = <&vreg_s1c_2p2>; + vddasd-supply = <&vreg_l11c_2p8>; + max-speed = <3200000>; + + qcom,local-bd-address-broken; + }; +}; + +&ufs_mem_hc { + reset-gpios = <&tlmm 175 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l7b_2p96>; + vcc-max-microamp = <800000>; + /* + * Technically l9b enables an eLDO (supplied by s1b) which then powers + * VCCQ2 of the UFS. + */ + vccq-supply = <&vreg_l9b_1p2>; + vccq-max-microamp = <900000>; + + status = "okay"; +}; + +&ufs_mem_phy { + vdda-phy-supply = <&vdd_a_ufs_0_core>; + vdda-pll-supply = <&vdd_a_ufs_0_1p2>; + + status = "okay"; +}; + +&usb_1 { + qcom,select-utmi-as-pipe-clk; + + maximum-speed = "high-speed"; + phys = <&usb_1_hsphy>; + phy-names = "usb2-phy"; + + status = "okay"; +}; + +&usb_1_dwc3_hs { + remote-endpoint = <&pmic_glink_hs_in>; +}; + +&usb_1_hsphy { + vdda-pll-supply = <&vdd_a_usbhs_core>; + vdda18-supply = <&vdd_a_usbhs_1p8>; + vdda33-supply = <&vdd_a_usbhs_3p1>; + + status = "okay"; +}; + +&venus { + firmware-name = "qcom/sm7325/xiaomi/lisa/vpu20_1v.mbn"; + + status = "okay"; +}; + +&wifi { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/qcom/sm8150.dtsi b/arch/arm64/boot/dts/qcom/sm8150.dtsi index 94a3b02..293fcba 100644 --- a/arch/arm64/boot/dts/qcom/sm8150.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8150.dtsi
@@ -610,6 +610,7 @@ cpu7_opp20: opp-2841600000 { firmware { scm: scm { compatible = "qcom,scm-sm8150", "qcom,scm"; + qcom,dload-mode = <&tcsr 0x13000>; #reset-cells = <1>; }; }; @@ -913,6 +914,7 @@ gcc: clock-controller@100000 { "sleep_clk"; clocks = <&rpmhcc RPMH_CXO_CLK>, <&sleep_clk>; + power-domains = <&rpmhpd SM8150_CX>; }; gpi_dma0: dma-controller@800000 { @@ -1901,12 +1903,6 @@ pcie0: pcie@1c00000 { power-domains = <&gcc PCIE_0_GDSC>; - phys = <&pcie0_phy>; - phy-names = "pciephy"; - - perst-gpios = <&tlmm 35 GPIO_ACTIVE_HIGH>; - wake-gpios = <&tlmm 37 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&pcie0_default_state>; @@ -1917,6 +1913,10 @@ pcie@0 { reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie0_phy>; + reset-gpios = <&tlmm 35 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 37 GPIO_ACTIVE_LOW>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -2019,10 +2019,6 @@ pcie1: pcie@1c08000 { power-domains = <&gcc PCIE_1_GDSC>; - phys = <&pcie1_phy>; - phy-names = "pciephy"; - - perst-gpios = <&tlmm 102 GPIO_ACTIVE_HIGH>; enable-gpio = <&tlmm 104 GPIO_ACTIVE_HIGH>; pinctrl-names = "default"; @@ -2035,6 +2031,9 @@ pcie@0 { reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie1_phy>; + reset-gpios = <&tlmm 102 GPIO_ACTIVE_HIGH>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -2181,6 +2180,11 @@ tcsr_regs_1: syscon@1f60000 { reg = <0x0 0x01f60000 0x0 0x20000>; }; + tcsr: syscon@1fc0000 { + compatible = "qcom,sm8150-tcsr", "syscon"; + reg = <0x0 0x01fc0000 0x0 0x30000>; + }; + remoteproc_slpi: remoteproc@2400000 { compatible = "qcom,sm8150-slpi-pas"; reg = <0x0 0x02400000 0x0 0x4040>; @@ -3574,7 +3578,7 @@ sdhc_2: mmc@8804000 { iommus = <&apps_smmu 0x6a0 0x0>; qcom,dll-config = <0x0007642c>; qcom,ddr-config = <0x80040868>; - power-domains = <&rpmhpd 0>; + power-domains = <&rpmhpd SM8150_CX>; operating-points-v2 = <&sdhc2_opp_table>; status = "disabled";
diff --git a/arch/arm64/boot/dts/qcom/sm8250.dtsi b/arch/arm64/boot/dts/qcom/sm8250.dtsi index 90f8b09..f975c21 100644 --- a/arch/arm64/boot/dts/qcom/sm8250.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8250.dtsi
@@ -16,7 +16,6 @@ #include <dt-bindings/interconnect/qcom,sm8250.h> #include <dt-bindings/mailbox/qcom-ipcc.h> #include <dt-bindings/phy/phy-qcom-qmp.h> -#include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/power/qcom,rpmhpd.h> #include <dt-bindings/soc/qcom,apr.h> #include <dt-bindings/soc/qcom,rpmh-rsc.h> @@ -971,6 +970,7 @@ gcc: clock-controller@100000 { clocks = <&rpmhcc RPMH_CXO_CLK>, <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>; + power-domains = <&rpmhpd RPMHPD_CX>; }; ipcc: mailbox@408000 { @@ -2207,12 +2207,6 @@ pcie0: pcie@1c00000 { power-domains = <&gcc PCIE_0_GDSC>; - phys = <&pcie0_phy>; - phy-names = "pciephy"; - - perst-gpios = <&tlmm 79 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 81 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&pcie0_default_state>; dma-coherent; @@ -2224,6 +2218,10 @@ pcieport0: pcie@0 { reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie0_phy>; + reset-gpios = <&tlmm 79 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 81 GPIO_ACTIVE_LOW>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -2334,12 +2332,6 @@ pcie1: pcie@1c08000 { power-domains = <&gcc PCIE_1_GDSC>; - phys = <&pcie1_phy>; - phy-names = "pciephy"; - - perst-gpios = <&tlmm 82 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 84 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&pcie1_default_state>; dma-coherent; @@ -2351,6 +2343,10 @@ pcie@0 { reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie1_phy>; + reset-gpios = <&tlmm 82 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 84 GPIO_ACTIVE_LOW>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -2461,12 +2457,6 @@ pcie2: pcie@1c10000 { power-domains = <&gcc PCIE_2_GDSC>; - phys = <&pcie2_phy>; - phy-names = "pciephy"; - - perst-gpios = <&tlmm 85 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 87 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&pcie2_default_state>; dma-coherent; @@ -2478,6 +2468,10 @@ pcie@0 { reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie2_phy>; + reset-gpios = <&tlmm 85 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 87 GPIO_ACTIVE_LOW>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -3290,7 +3284,7 @@ in-ports { port@4 { reg = <4>; funnel_in1_in_funnel_apss_merg: endpoint { - remote-endpoint = <&funnel_apss_merg_out_funnel_in1>; + remote-endpoint = <&funnel_apss_merg_out_funnel_in1>; }; }; }; @@ -3306,7 +3300,7 @@ funnel@6045000 { out-ports { port { funnel_merg_out_funnel_swao: endpoint { - remote-endpoint = <&funnel_swao_in_funnel_merg>; + remote-endpoint = <&funnel_swao_in_funnel_merg>; }; }; }; @@ -3318,14 +3312,14 @@ in-ports { port@0 { reg = <0>; funnel_merg_in_funnel_in0: endpoint { - remote-endpoint = <&funnel_in0_out_funnel_merg>; + remote-endpoint = <&funnel_in0_out_funnel_merg>; }; }; port@1 { reg = <1>; funnel_merg_in_funnel_in1: endpoint { - remote-endpoint = <&funnel_in1_out_funnel_merg>; + remote-endpoint = <&funnel_in1_out_funnel_merg>; }; }; }; @@ -3493,7 +3487,7 @@ funnel@6c0b000 { out-ports { port { funnel_dl_mm_out_funnel_dl_center: endpoint { - remote-endpoint = <&funnel_dl_center_in_funnel_dl_mm>; + remote-endpoint = <&funnel_dl_center_in_funnel_dl_mm>; }; }; }; @@ -3533,7 +3527,7 @@ in-ports { port@2 { reg = <2>; funnel_dl_center_in_funnel_dl_mm: endpoint { - remote-endpoint = <&funnel_dl_mm_out_funnel_dl_center>; + remote-endpoint = <&funnel_dl_mm_out_funnel_dl_center>; }; }; }; @@ -3701,7 +3695,7 @@ funnel@7800000 { out-ports { port { funnel_apss_out_funnel_apss_merg: endpoint { - remote-endpoint = <&funnel_apss_merg_in_funnel_apss>; + remote-endpoint = <&funnel_apss_merg_in_funnel_apss>; }; }; }; @@ -3778,7 +3772,7 @@ funnel@7810000 { out-ports { port { funnel_apss_merg_out_funnel_in1: endpoint { - remote-endpoint = <&funnel_in1_in_funnel_apss_merg>; + remote-endpoint = <&funnel_in1_in_funnel_apss_merg>; }; }; }; @@ -3786,7 +3780,7 @@ funnel_apss_merg_out_funnel_in1: endpoint { in-ports { port { funnel_apss_merg_in_funnel_apss: endpoint { - remote-endpoint = <&funnel_apss_out_funnel_apss_merg>; + remote-endpoint = <&funnel_apss_out_funnel_apss_merg>; }; }; };
diff --git a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts index bb93c3e..24ad073 100644 --- a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts +++ b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
@@ -392,7 +392,7 @@ &mdss_dsi0_out { data-lanes = <0 1 2 3>; }; -&mdss_dsi0_phy { +&mdss_dsi0_phy { vdds-supply = <&vreg_l5b_0p88>; status = "okay"; }; @@ -499,9 +499,6 @@ &pcie0 { pinctrl-names = "default"; pinctrl-0 = <&pcie0_default_state>; - perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; - status = "okay"; }; @@ -512,10 +509,12 @@ &pcie0_phy { status = "okay"; }; -&pcie1 { - perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>; +&pcie0_port0 { + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; +}; +&pcie1 { pinctrl-names = "default"; pinctrl-0 = <&pcie1_default_state>; @@ -528,6 +527,11 @@ &pcie1_phy { vdda-pll-supply = <&vreg_l6b_1p2>; }; +&pcie1_port0 { + reset-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 99 GPIO_ACTIVE_LOW>; +}; + &qupv3_id_0 { status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/sm8350-sony-xperia-sagami.dtsi b/arch/arm64/boot/dts/qcom/sm8350-sony-xperia-sagami.dtsi index 4b62ee5..969c8cb 100644 --- a/arch/arm64/boot/dts/qcom/sm8350-sony-xperia-sagami.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8350-sony-xperia-sagami.dtsi
@@ -893,9 +893,20 @@ sdc2_card_det_sleep: sd-card-det-sleep-state { }; }; -/* BIG WARNING! DO NOT TOUCH UFS, YOUR DEVICE WILL DIE! */ -&ufs_mem_hc { status = "disabled"; }; -&ufs_mem_phy { status = "disabled"; }; +&ufs_mem_hc { + status = "okay"; + reset-gpios = <&tlmm 203 GPIO_ACTIVE_LOW>; + vcc-supply = <&pm8350_l7>; + vcc-max-microamp = <800000>; + vccq-supply = <&pm8350_l9>; + vcc-max-microamp = <900000>; +}; + +&ufs_mem_phy { + status = "okay"; + vdda-phy-supply = <&pm8350_l5>; + vdda-pll-supply = <&pm8350_l6>; +}; &usb_1 { status = "okay";
diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi index 32b47f5e..55b3205 100644 --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
@@ -18,7 +18,6 @@ #include <dt-bindings/interconnect/qcom,sm8350.h> #include <dt-bindings/mailbox/qcom-ipcc.h> #include <dt-bindings/phy/phy-qcom-qmp.h> -#include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/power/qcom,rpmhpd.h> #include <dt-bindings/reset/qcom,sm8350-videocc.h> #include <dt-bindings/soc/qcom,apr.h> @@ -699,6 +698,7 @@ gcc: clock-controller@100000 { <&ufs_mem_phy 2>, <&usb_1_qmpphy QMP_USB43DP_USB3_PIPE_CLK>, <0>; + power-domains = <&rpmhpd RPMHPD_CX>; }; ipcc: mailbox@408000 { @@ -1586,16 +1586,15 @@ pcie0: pcie@1c00000 { power-domains = <&gcc PCIE_0_GDSC>; - phys = <&pcie0_phy>; - phy-names = "pciephy"; - status = "disabled"; - pcie@0 { + pcie0_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie0_phy>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -1695,16 +1694,15 @@ pcie1: pcie@1c08000 { power-domains = <&gcc PCIE_1_GDSC>; - phys = <&pcie1_phy>; - phy-names = "pciephy"; - status = "disabled"; - pcie@0 { + pcie1_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie1_phy>; + #address-cells = <3>; #size-cells = <2>; ranges;
diff --git a/arch/arm64/boot/dts/qcom/sm8450.dtsi b/arch/arm64/boot/dts/qcom/sm8450.dtsi index b879348..05417cb 100644 --- a/arch/arm64/boot/dts/qcom/sm8450.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8450.dtsi
@@ -17,7 +17,6 @@ #include <dt-bindings/mailbox/qcom-ipcc.h> #include <dt-bindings/phy/phy-qcom-qmp.h> #include <dt-bindings/power/qcom,rpmhpd.h> -#include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/interconnect/qcom,icc.h> #include <dt-bindings/interconnect/qcom,sm8450.h> #include <dt-bindings/reset/qcom,sm8450-gpucc.h> @@ -942,6 +941,7 @@ gcc: clock-controller@100000 { "ufs_phy_rx_symbol_1_clk", "ufs_phy_tx_symbol_0_clk", "usb3_phy_wrapper_gcc_usb30_pipe_clk"; + power-domains = <&rpmhpd RPMHPD_CX>; }; gpi_dma2: dma-controller@800000 { @@ -2017,12 +2017,6 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, power-domains = <&gcc PCIE_0_GDSC>; - phys = <&pcie0_phy>; - phy-names = "pciephy"; - - perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&pcie0_default_state>; @@ -2063,6 +2057,10 @@ pcieport0: pcie@0 { reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie0_phy>; + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -2182,12 +2180,6 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, power-domains = <&gcc PCIE_1_GDSC>; - phys = <&pcie1_phy>; - phy-names = "pciephy"; - - perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; pinctrl-0 = <&pcie1_default_state>; @@ -2263,11 +2255,15 @@ opp-32000000-4 { }; }; - pcie@0 { + pcie1_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie1_phy>; + reset-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 99 GPIO_ACTIVE_LOW>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -3489,7 +3485,7 @@ port@1 { mdss_dp0_out: endpoint { remote-endpoint = <&usb_1_qmpphy_dp_in>; }; - }; + }; }; dp_opp_table: opp-table {
diff --git a/arch/arm64/boot/dts/qcom/sm8550-hdk.dts b/arch/arm64/boot/dts/qcom/sm8550-hdk.dts index 82fb10e..e75e3b8 100644 --- a/arch/arm64/boot/dts/qcom/sm8550-hdk.dts +++ b/arch/arm64/boot/dts/qcom/sm8550-hdk.dts
@@ -1087,16 +1087,23 @@ &mdss_dp0 { }; &pcie0 { - wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&pcie0_default_state>; pinctrl-names = "default"; status = "okay"; }; +&pcie0_phy { + vdda-phy-supply = <&vreg_l1e_0p88>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + &pcie0_port0 { + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; + wifi@0 { compatible = "pci17cb,1107"; reg = <0x10000 0x0 0x0 0x0 0x0>; @@ -1113,17 +1120,7 @@ wifi@0 { }; }; -&pcie0_phy { - vdda-phy-supply = <&vreg_l1e_0p88>; - vdda-pll-supply = <&vreg_l3e_1p2>; - - status = "okay"; -}; - &pcie1 { - wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&pcie1_default_state>; pinctrl-names = "default"; @@ -1138,6 +1135,11 @@ &pcie1_phy { status = "okay"; }; +&pcie1_port0 { + reset-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 99 GPIO_ACTIVE_LOW>; +}; + &pm8550_gpios { sdc2_card_det_n: sdc2-card-det-state { pins = "gpio12";
diff --git a/arch/arm64/boot/dts/qcom/sm8550-mtp.dts b/arch/arm64/boot/dts/qcom/sm8550-mtp.dts index 7c63457..7b191c9 100644 --- a/arch/arm64/boot/dts/qcom/sm8550-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sm8550-mtp.dts
@@ -739,9 +739,6 @@ &mdss_dp0 { }; &pcie0 { - wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; - pinctrl-names = "default"; pinctrl-0 = <&pcie0_default_state>; @@ -755,10 +752,12 @@ &pcie0_phy { status = "okay"; }; -&pcie1 { - wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; +&pcie0_port0 { + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; +}; +&pcie1 { pinctrl-names = "default"; pinctrl-0 = <&pcie1_default_state>; @@ -773,6 +772,11 @@ &pcie1_phy { status = "okay"; }; +&pcie1_port0 { + reset-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 99 GPIO_ACTIVE_LOW>; +}; + &pm8550_gpios { sdc2_card_det_n: sdc2-card-det-state { pins = "gpio12";
diff --git a/arch/arm64/boot/dts/qcom/sm8550-qrd.dts b/arch/arm64/boot/dts/qcom/sm8550-qrd.dts index 473ec4e..a3ab0bd 100644 --- a/arch/arm64/boot/dts/qcom/sm8550-qrd.dts +++ b/arch/arm64/boot/dts/qcom/sm8550-qrd.dts
@@ -987,16 +987,23 @@ &mdss_dp0 { }; &pcie0 { - wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&pcie0_default_state>; pinctrl-names = "default"; status = "okay"; }; +&pcie0_phy { + vdda-phy-supply = <&vreg_l1e_0p88>; + vdda-pll-supply = <&vreg_l3e_1p2>; + + status = "okay"; +}; + &pcie0_port0 { + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; + wifi@0 { compatible = "pci17cb,1107"; reg = <0x10000 0x0 0x0 0x0 0x0>; @@ -1013,13 +1020,6 @@ wifi@0 { }; }; -&pcie0_phy { - vdda-phy-supply = <&vreg_l1e_0p88>; - vdda-pll-supply = <&vreg_l3e_1p2>; - - status = "okay"; -}; - &pm8550_flash { status = "okay";
diff --git a/arch/arm64/boot/dts/qcom/sm8550-samsung-q5q.dts b/arch/arm64/boot/dts/qcom/sm8550-samsung-q5q.dts index 81c02ee..bf0b16d 100644 --- a/arch/arm64/boot/dts/qcom/sm8550-samsung-q5q.dts +++ b/arch/arm64/boot/dts/qcom/sm8550-samsung-q5q.dts
@@ -510,8 +510,6 @@ &i2c_master_hub_0 { }; &pcie0 { - wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; pinctrl-0 = <&pcie0_default_state>; pinctrl-names = "default"; status = "okay"; @@ -523,6 +521,11 @@ &pcie0_phy { status = "okay"; }; +&pcie0_port0 { + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; +}; + &pm8550_gpios { volume_up_n: volume-up-n-state { pins = "gpio6";
diff --git a/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts b/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts index 367f6ea..a23ebd3 100644 --- a/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts +++ b/arch/arm64/boot/dts/qcom/sm8550-sony-xperia-yodo-pdx234.dts
@@ -584,9 +584,6 @@ cirrus,gpio-ctrl2 { }; &pcie0 { - wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&pcie0_default_state>; pinctrl-names = "default"; @@ -600,6 +597,11 @@ &pcie0_phy { status = "okay"; }; +&pcie0_port0 { + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; +}; + &pm8550_flash { status = "okay";
diff --git a/arch/arm64/boot/dts/qcom/sm8550.dtsi b/arch/arm64/boot/dts/qcom/sm8550.dtsi index 0e701e7..03f6d40 100644 --- a/arch/arm64/boot/dts/qcom/sm8550.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8550.dtsi
@@ -19,7 +19,6 @@ #include <dt-bindings/interconnect/qcom,sm8550-rpmh.h> #include <dt-bindings/interconnect/qcom,osm-l3.h> #include <dt-bindings/mailbox/qcom-ipcc.h> -#include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/power/qcom,rpmhpd.h> #include <dt-bindings/soc/qcom,gpr.h> #include <dt-bindings/soc/qcom,rpmh-rsc.h> @@ -1195,6 +1194,7 @@ gcc: clock-controller@100000 { <&ufs_mem_phy 1>, <&ufs_mem_phy 2>, <&usb_dp_qmpphy QMP_USB43DP_USB3_PIPE_CLK>; + power-domains = <&rpmhpd RPMHPD_CX>; }; ipcc: mailbox@408000 { @@ -1442,6 +1442,24 @@ &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>, status = "disabled"; }; + uart11: serial@88c000 { + compatible = "qcom,geni-uart"; + reg = <0 0x0088c000 0 0x4000>; + clock-names = "se"; + clocks = <&gcc GCC_QUPV3_WRAP2_S3_CLK>; + interrupts = <GIC_SPI 585 IRQ_TYPE_LEVEL_HIGH 0>; + pinctrl-names = "default"; + pinctrl-0 = <&qup_uart11_default>; + interconnects = <&clk_virt MASTER_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS + &clk_virt SLAVE_QUP_CORE_2 QCOM_ICC_TAG_ALWAYS>, + <&gem_noc MASTER_APPSS_PROC QCOM_ICC_TAG_ACTIVE_ONLY + &config_noc SLAVE_QUP_2 QCOM_ICC_TAG_ACTIVE_ONLY>; + interconnect-names = "qup-core", "qup-config"; + operating-points-v2 = <&qup_opp_table_120mhz>; + power-domains = <&rpmhpd RPMHPD_CX>; + status = "disabled"; + }; + i2c12: i2c@890000 { compatible = "qcom,geni-i2c"; reg = <0 0x00890000 0 0x4000>; @@ -2397,9 +2415,6 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, power-domains = <&gcc PCIE_0_GDSC>; - phys = <&pcie0_phy>; - phy-names = "pciephy"; - operating-points-v2 = <&pcie0_opp_table>; status = "disabled"; @@ -2461,6 +2476,8 @@ pcie0_port0: pcie@0 { reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie0_phy>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -2583,9 +2600,6 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, power-domains = <&gcc PCIE_1_GDSC>; - phys = <&pcie1_phy>; - phy-names = "pciephy"; - operating-points-v2 = <&pcie1_opp_table>; status = "disabled"; @@ -2663,6 +2677,8 @@ pcie1_port0: pcie@0 { reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie1_phy>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -4692,7 +4708,6 @@ spmi_bus: spmi@c400000 { interrupts-extended = <&pdc 1 IRQ_TYPE_LEVEL_HIGH>; qcom,ee = <0>; qcom,channel = <0>; - qcom,bus-id = <0>; #address-cells = <2>; #size-cells = <0>; interrupt-controller; @@ -5478,6 +5493,14 @@ qup_uart7_default: qup-uart7-default-state { bias-disable; }; + qup_uart11_default: qup-uart11-default-state { + /* TX, RX */ + pins = "gpio70", "gpio71"; + function = "qup2_se3"; + drive-strength = <2>; + bias-pull-up; + }; + qup_uart14_default: qup-uart14-default-state { /* TX, RX */ pins = "gpio78", "gpio79"; @@ -6154,7 +6177,7 @@ reset-mon-config { }; }; - cpuss0-thermal { + thermal_cpuss0: cpuss0-thermal { thermal-sensors = <&tsens0 1>; trips { @@ -6172,7 +6195,7 @@ reset-mon-config { }; }; - cpuss1-thermal { + thermal_cpuss1: cpuss1-thermal { thermal-sensors = <&tsens0 2>; trips { @@ -6190,7 +6213,7 @@ reset-mon-config { }; }; - cpuss2-thermal { + thermal_cpuss2: cpuss2-thermal { thermal-sensors = <&tsens0 3>; trips { @@ -6208,7 +6231,7 @@ reset-mon-config { }; }; - cpuss3-thermal { + thermal_cpuss3: cpuss3-thermal { thermal-sensors = <&tsens0 4>; trips { @@ -6418,7 +6441,7 @@ cpu6_bottom_crit: cpu-critical { }; }; - cpu7-top-thermal { + thermal_cpu7_top: cpu7-top-thermal { thermal-sensors = <&tsens0 13>; trips { @@ -6926,7 +6949,7 @@ reset-mon-config { }; }; - gpuss-0-thermal { + thermal_gpuss0: gpuss-0-thermal { polling-delay-passive = <10>; thermal-sensors = <&tsens2 1>; @@ -6959,7 +6982,7 @@ trip-point2 { }; }; - gpuss-1-thermal { + thermal_gpuss1: gpuss-1-thermal { polling-delay-passive = <10>; thermal-sensors = <&tsens2 2>; @@ -6992,7 +7015,7 @@ trip-point2 { }; }; - gpuss-2-thermal { + thermal_gpuss2: gpuss-2-thermal { polling-delay-passive = <10>; thermal-sensors = <&tsens2 3>; @@ -7025,7 +7048,7 @@ trip-point2 { }; }; - gpuss-3-thermal { + thermal_gpuss3: gpuss-3-thermal { polling-delay-passive = <10>; thermal-sensors = <&tsens2 4>; @@ -7058,7 +7081,7 @@ trip-point2 { }; }; - gpuss-4-thermal { + thermal_gpuss4: gpuss-4-thermal { polling-delay-passive = <10>; thermal-sensors = <&tsens2 5>; @@ -7091,7 +7114,7 @@ trip-point2 { }; }; - gpuss-5-thermal { + thermal_gpuss5: gpuss-5-thermal { polling-delay-passive = <10>; thermal-sensors = <&tsens2 6>; @@ -7124,7 +7147,7 @@ trip-point2 { }; }; - gpuss-6-thermal { + thermal_gpuss6: gpuss-6-thermal { polling-delay-passive = <10>; thermal-sensors = <&tsens2 7>; @@ -7157,7 +7180,7 @@ trip-point2 { }; }; - gpuss-7-thermal { + thermal_gpuss7: gpuss-7-thermal { polling-delay-passive = <10>; thermal-sensors = <&tsens2 8>;
diff --git a/arch/arm64/boot/dts/qcom/sm8650-ayaneo-pocket-s2.dts b/arch/arm64/boot/dts/qcom/sm8650-ayaneo-pocket-s2.dts index 6ddf30e..48fbf06 100644 --- a/arch/arm64/boot/dts/qcom/sm8650-ayaneo-pocket-s2.dts +++ b/arch/arm64/boot/dts/qcom/sm8650-ayaneo-pocket-s2.dts
@@ -221,7 +221,7 @@ upd720201_vdd33_reg: upd720201-vdd33-regulator { }; sound { - compatible = "qcom,sm8650-sndcard", "qcom,sm8450-sndcard"; + compatible = "ayaneo,pocket-s2-sndcard"; model = "SM8650-APS2"; audio-routing = "SpkrLeft IN", "WSA_SPK1 OUT", "SpkrRight IN", "WSA_SPK2 OUT", @@ -325,6 +325,23 @@ platform { }; }; + sy7758_vdd33_reg: sy7758-vdd33-regulator { + compatible = "regulator-fixed"; + + regulator-name = "sy7758_vdd33"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + + gpios = <&tlmm 163 GPIO_ACTIVE_HIGH>; + enable-active-high; + + vin-supply = <&vph_pwr>; + + pinctrl-0 = <&sy7758_vdd33>; + pinctrl-names = "default"; + }; + vph_pwr: vph-pwr-regulator { compatible = "regulator-fixed"; @@ -986,6 +1003,10 @@ gpu7_active: trip-active { }; }; +&gpu { + status = "okay"; +}; + &i2c3 { clock-frequency = <100000>; @@ -1016,6 +1037,30 @@ wcd_usbss_sbu_mux: endpoint { }; }; +&i2c4 { + clock-frequency = <400000>; + + status = "okay"; + + touchscreen@5d { + compatible = "goodix,gt911"; + reg = <0x5d>; + + interrupt-parent = <&tlmm>; + interrupts = <162 IRQ_TYPE_EDGE_FALLING>; + + reset-gpios = <&tlmm 161 GPIO_ACTIVE_HIGH>; + VDDIO-supply = <&vreg_l14b_3p2>; + AVDD28-supply = <&vreg_l14b_3p2>; + + touchscreen-size-x = <1440>; + touchscreen-size-y = <2560>; + + pinctrl-names = "default"; + pinctrl-0 = <&ts_reset_default>, <&ts_irq_default>; + }; +}; + &i2c6 { clock-frequency = <100000>; @@ -1053,6 +1098,51 @@ redriver_ss_in: endpoint { }; }; +&i2c9 { + status = "okay"; + + /* Screen power */ + regulator@3e { + compatible = "sgmicro,sgm3804"; + reg = <0x3e>; + + pinctrl-0 = <&sgm3804_default>; + pinctrl-names = "default"; + + vin-supply = <&vph_pwr>; + + sgm3804_pos: pos { + regulator-name = "panel-avdd-pos"; + regulator-min-microvolt = <5200000>; + regulator-max-microvolt = <5200000>; + regulator-active-discharge = <1>; + regulator-boot-on; + enable-gpios = <&tlmm 59 GPIO_ACTIVE_HIGH>; + }; + + sgm3804_neg: neg { + regulator-name = "panel-avdd-neg"; + regulator-min-microvolt = <5200000>; + regulator-max-microvolt = <5200000>; + regulator-active-discharge = <1>; + regulator-boot-on; + enable-gpios = <&tlmm 58 GPIO_ACTIVE_HIGH>; + }; + }; + + /* Backlight */ + backlight: backlight@2e { + compatible = "silergy,sy7758"; + reg = <0x2e>; + + pinctrl-0 = <&sy7758_default>; + pinctrl-names = "default"; + + vdd-supply = <&sy7758_vdd33_reg>; + enable-gpios = <&tlmm 164 GPIO_ACTIVE_HIGH>; + }; +}; + &iris { status = "okay"; }; @@ -1073,10 +1163,94 @@ &mdss_dp0_out { status = "okay"; }; -&pcie0 { - wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; +&mdss_dsi0 { + vdda-supply = <&vreg_l3i_1p2>; + qcom,master-dsi; + qcom,dual-dsi-mode; + qcom,sync-dual-dsi; + + status = "okay"; + + panel@0 { + status = "okay"; + compatible = "ayaneo,wt0630-2k", "renesas,r63419"; + reg = <0>; + + pinctrl-0 = <&disp0_reset_n_active>; + pinctrl-1 = <&disp0_reset_n_suspend>; + pinctrl-names = "default", "sleep"; + + vddio-supply = <&vreg_l12b_1p8>; + vdd-supply = <&vreg_l11b_1p2>; + vsp-supply = <&sgm3804_pos>; + vsn-supply = <&sgm3804_neg>; + vci-supply = <&vreg_l13b_3p0>; + + backlight = <&backlight>; + + reset-gpios = <&tlmm 133 GPIO_ACTIVE_LOW>; + + rotation = <90>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + panel0_in_0: endpoint { + remote-endpoint = <&mdss_dsi0_out>; + }; + }; + + port@1{ + reg = <1>; + panel0_in_1: endpoint { + remote-endpoint = <&mdss_dsi1_out>; + }; + }; + }; + }; +}; + +&mdss_dsi0_out { + remote-endpoint = <&panel0_in_0>; + + data-lanes = <0 1 2 3>; +}; + +&mdss_dsi0_phy { + vdds-supply = <&vreg_l1i_0p88>; + + status = "okay"; +}; + +&mdss_dsi1 { + vdda-supply = <&vreg_l3i_1p2>; + + assigned-clock-parents = <&mdss_dsi0_phy DSI_BYTE_PLL_CLK>, + <&mdss_dsi0_phy DSI_PIXEL_PLL_CLK>; + + qcom,dual-dsi-mode; + qcom,sync-dual-dsi; + + status = "okay"; +}; + +&mdss_dsi1_out { + remote-endpoint = <&panel0_in_1>; + + data-lanes = <0 1 2 3>; +}; + +&mdss_dsi1_phy { + vdds-supply = <&vreg_l1i_0p88>; + + status = "okay"; +}; + +&pcie0 { pinctrl-0 = <&pcie0_default_state>; pinctrl-names = "default"; @@ -1084,6 +1258,9 @@ &pcie0 { }; &pcieport0 { + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; + wifi@0 { compatible = "pci17cb,1107"; reg = <0x10000 0x0 0x0 0x0 0x0>; @@ -1108,9 +1285,6 @@ &pcie0_phy { }; &pcie1 { - wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&pcie1_default_state>; pinctrl-names = "default"; @@ -1118,6 +1292,8 @@ &pcie1 { }; &pcie1_port0 { + reset-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 99 GPIO_ACTIVE_LOW>; /* Renesas μPD720201 PCIe USB3.0 HOST CONTROLLER */ usb-controller@0 { compatible = "pci1912,0014"; @@ -1390,6 +1566,20 @@ sw-ctrl-pins { }; }; + disp0_reset_n_active: disp0-reset-n-active-state { + pins = "gpio133"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + + disp0_reset_n_suspend: disp0-reset-n-suspend-state { + pins = "gpio133"; + function = "gpio"; + drive-strength = <2>; + bias-pull-down; + }; + fan_pwr_pins: fan-pwr-state { pins = "gpio125"; function = "gpio"; @@ -1440,6 +1630,13 @@ gamepad_pwr_en: gamepad-pwr-en-active-state { output-high; }; + sgm3804_default: sgm3804-default-state { + pins = "gpio58", "gpio59"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + spkr_23_sd_n_active: spkr-23-sd-n-active-state { pins = "gpio77"; function = "gpio"; @@ -1454,6 +1651,34 @@ spkr_01_sd_n_active: spkr-01-sd-n-active-state { bias-disable; }; + sy7758_default: sy7758-default-state { + pins = "gpio164"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + sy7758_vdd33: sy7758-vdd33-state { + pins = "gpio163"; + function = "gpio"; + drive-strength = <2>; + bias-disable; + }; + + ts_irq_default: ts-irq-active-state { + pins = "gpio162"; + function = "gpio"; + drive-strength = <8>; + bias-disable; + }; + + ts_reset_default: ts-reset-active-state { + pins = "gpio161"; + function = "gpio"; + drive-strength = <8>; + bias-pull-down; + }; + wcd_default: wcd-reset-n-active-state { pins = "gpio107"; function = "gpio"; @@ -1549,3 +1774,7 @@ &usb_dp_qmpphy_out { &xo_board { clock-frequency = <76800000>; }; + +&gpu_zap_shader { + firmware-name = "qcom/sm8650/ayaneo/ps2/gen70900_zap.mbn"; +};
diff --git a/arch/arm64/boot/dts/qcom/sm8650-hdk.dts b/arch/arm64/boot/dts/qcom/sm8650-hdk.dts index 41d0c7e..6cb0dc0 100644 --- a/arch/arm64/boot/dts/qcom/sm8650-hdk.dts +++ b/arch/arm64/boot/dts/qcom/sm8650-hdk.dts
@@ -125,7 +125,7 @@ port@2 { pmic_glink_sbu: endpoint { remote-endpoint = <&wcd_usbss_sbu_mux>; - }; + }; }; }; }; @@ -905,9 +905,9 @@ &gpi_dma1 { }; &i2c3 { - status = "okay"; + status = "okay"; - wcd_usbss: typec-mux@e { + wcd_usbss: typec-mux@e { compatible = "qcom,wcd9395-usbss", "qcom,wcd9390-usbss"; reg = <0xe>; @@ -929,7 +929,7 @@ wcd_usbss_sbu_mux: endpoint { }; }; }; - }; + }; }; &i2c6 { @@ -1027,9 +1027,6 @@ &mdss_dp0 { }; &pcie0 { - wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&pcie0_default_state>; pinctrl-names = "default"; @@ -1037,6 +1034,9 @@ &pcie0 { }; &pcieport0 { + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; + wifi@0 { compatible = "pci17cb,1107"; reg = <0x10000 0x0 0x0 0x0 0x0>; @@ -1061,9 +1061,6 @@ &pcie0_phy { }; &pcie1 { - wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&pcie1_default_state>; pinctrl-names = "default"; @@ -1078,6 +1075,11 @@ &pcie1_phy { status = "okay"; }; +&pcie1_port0 { + reset-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 99 GPIO_ACTIVE_LOW>; +}; + &pm8550_gpios { sdc2_card_det_n: sdc2-card-det-state { pins = "gpio12";
diff --git a/arch/arm64/boot/dts/qcom/sm8650-mtp.dts b/arch/arm64/boot/dts/qcom/sm8650-mtp.dts index 2604543..f3ed42f 100644 --- a/arch/arm64/boot/dts/qcom/sm8650-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sm8650-mtp.dts
@@ -642,9 +642,6 @@ &mdss_dsi0_phy { }; &pcie0 { - wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&pcie0_default_state>; pinctrl-names = "default"; @@ -658,10 +655,12 @@ &pcie0_phy { status = "okay"; }; -&pcie1 { - wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; +&pcieport0 { + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; +}; +&pcie1 { pinctrl-0 = <&pcie1_default_state>; pinctrl-names = "default"; @@ -676,6 +675,11 @@ &pcie1_phy { status = "okay"; }; +&pcie1_port0 { + reset-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 99 GPIO_ACTIVE_LOW>; +}; + &pm8550_gpios { sdc2_card_det_n: sdc2-card-det-state { pins = "gpio12";
diff --git a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts index 1fb7858..f693ea6 100644 --- a/arch/arm64/boot/dts/qcom/sm8650-qrd.dts +++ b/arch/arm64/boot/dts/qcom/sm8650-qrd.dts
@@ -86,7 +86,7 @@ port@2 { pmic_glink_sbu: endpoint { remote-endpoint = <&wcd_usbss_sbu_mux>; - }; + }; }; }; }; @@ -875,9 +875,9 @@ &gpi_dma1 { }; &i2c3 { - status = "okay"; + status = "okay"; - wcd_usbss: typec-mux@e { + wcd_usbss: typec-mux@e { compatible = "qcom,wcd9395-usbss", "qcom,wcd9390-usbss"; reg = <0xe>; @@ -907,7 +907,7 @@ wcd_usbss_headset_out: endpoint { }; }; }; - }; + }; }; &i2c6 { @@ -1021,9 +1021,6 @@ &mdss_dp0 { }; &pcie0 { - wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; - perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&pcie0_default_state>; pinctrl-names = "default"; @@ -1031,6 +1028,9 @@ &pcie0 { }; &pcieport0 { + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 96 GPIO_ACTIVE_LOW>; + wifi@0 { compatible = "pci17cb,1107"; reg = <0x10000 0x0 0x0 0x0 0x0>;
diff --git a/arch/arm64/boot/dts/qcom/sm8650-valve-deckard.dts b/arch/arm64/boot/dts/qcom/sm8650-valve-deckard.dts new file mode 100644 index 0000000..d25a09e --- /dev/null +++ b/arch/arm64/boot/dts/qcom/sm8650-valve-deckard.dts
@@ -0,0 +1,1288 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) 2026, Valve Software + */ + +/dts-v1/; + +#include <dt-bindings/leds/common.h> +#include <dt-bindings/regulator/qcom,rpmh-regulator.h> +#include <dt-bindings/phy/phy.h> +#include "sm8650.dtsi" +#include "pm8010.dtsi" +#include "pm8550.dtsi" +#include "pm8550b.dtsi" +#define PMK8550VE_SID 8 +#include "pm8550ve.dtsi" +#include "pm8550vs.dtsi" +#include "pmk8550.dtsi" + +/* Remove nodes */ +/delete-node/ &ipa; +/delete-node/ &gpu_zap_shader; +/delete-node/ &lpass_wsa2macro; +/delete-node/ &lpass_rxmacro; +/delete-node/ &lpass_txmacro; +/delete-node/ &lpass_wsamacro; +/delete-node/ &lpass_vamacro; +/delete-node/ &lpass_tlmm; +/delete-node/ &remoteproc_adsp; +/delete-node/ &remoteproc_cdsp; +/delete-node/ &remoteproc_mpss; +/delete-node/ &reserved_memory; +/delete-node/ &smp2p_adsp; +/delete-node/ &smp2p_cdsp; +/delete-node/ &smp2p_modem; +/delete-node/ &swr0; +/delete-node/ &swr1; +/delete-node/ &swr2; +/delete-node/ &swr3; + +/ { + model = "Valve Deckard"; + compatible = "valve,deckard", "qcom,sm8650"; + + aliases { + serial0 = &uart15; + serial1 = &uart14; + }; + + chosen { + stdout-path = "serial0:115200n8"; + + framebuffer { + compatible = "simple-framebuffer"; + width = <4320>; + height = <2160>; + stride = <(4320 * 4)>; + format = "a8r8g8b8"; + memory-region = <&framebuffer_mem>; + + /* Bootloader will enable the node */ + status = "disabled"; + }; + }; + + gpio-keys { + compatible = "gpio-keys"; + + pinctrl-0 = <&volume_up_n>, <&select_n>; + pinctrl-names = "default"; + + key-volume-up { + label = "Volume Up"; + linux,code = <KEY_VOLUMEUP>; + gpios = <&pm8550_gpios 6 GPIO_ACTIVE_LOW>; + debounce-interval = <15>; + linux,can-disable; + }; + + key-select { + label = "Select"; + linux,code = <KEY_SELECT>; + gpios = <&pm8550b_gpios 5 GPIO_ACTIVE_LOW>; + debounce-interval = <15>; + linux,can-disable; + }; + }; + + vph_pwr: regulator-vph-pwr { + compatible = "regulator-fixed"; + regulator-name = "vph_pwr"; + regulator-min-microvolt = <3700000>; + regulator-max-microvolt = <3700000>; + regulator-always-on; + regulator-boot-on; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + aop_mem: aop-region@81c00000 { + no-map; + reg = <0 0x81c00000 0 0x60000>; + }; + + ramoops: ramoops-region@84a00000 { + compatible = "ramoops"; + reg = <0 0x84a00000 0 0x100000>; + record-size = <0x40000>; + console-size = <0x40000>; + pmsg-size = <0x1000>; + ecc-size = <16>; + }; + + aop_cmd_db_mem: aop-cmd-db-region@81c60000 { + compatible = "qcom,cmd-db"; + reg = <0 0x81c60000 0 0x20000>; + no-map; + }; + + /* merged aop_config, tme_crash_dump, tme_log */ + aop_config_merged_mem: aop-config-merged-region@81c80000 { + reg = <0 0x81c80000 0 0x75000>; + no-map; + }; + + smem: smem-region@81d00000 { + compatible = "qcom,smem"; + reg = <0 0x81d00000 0 0x200000>; + hwlocks = <&tcsr_mutex 3>; + no-map; + }; + + cpucp_fw_mem: cpucp-fw-region@d8040000 { + reg = <0 0xd8040000 0 0x1b2000>; + no-map; + }; + + video_mem: video-region@9bb00000 { + reg = <0 0x9bb00000 0 0x800000>; + no-map; + }; + + tz_stat_mem: tz-stat-region@82700000 { + reg = <0 0x82700000 0 0x100000>; + no-map; + }; + + /* 2MB, 8 clocks to power on each 256KB block */ + lpass_lpi_tcm: lpm-region@6000000 { + compatible = "shared-dma-pool"; + reg = <0 0x06000000 0 0x00200000>; + no-map; + }; + + /* 64KB, 4 clocks to power on each 16KB block */ + lpass_audio_lpm: lpm-region@6c80000 { + compatible = "shared-dma-pool"; + reg = <0 0x06c80000 0 0x10000>; + no-map; + }; + + /* 12KB, 1 clock */ + lpass_va_lpm: lpm-region@6d40000 { + compatible = "shared-dma-pool"; + reg = <0 0x06d40000 0 0x3000>; + no-map; + }; + + lpass_lpm: lpm-region@7c10000 { + compatible = "shared-dma-pool"; + reg = <0 0x07c10000 0 0x8000>; + no-map; + }; + + framebuffer_mem: framebuffer-region@af400000 { + reg = <0 0xaf400000 0 0x03000000>; + no-map; + }; + }; + + wcn7850-pmu { + compatible = "qcom,wcn7850-pmu"; + + pinctrl-0 = <&wlan_en>, <&bt_default>; + pinctrl-names = "default"; + + wlan-enable-gpios = <&tlmm 16 GPIO_ACTIVE_HIGH>; + bt-enable-gpios = <&tlmm 17 GPIO_ACTIVE_HIGH>; + + vdd-supply = <&vreg_s4i_0p85>; + vddio-supply = <&vreg_l15b_1p8>; + vddio1p2-supply = <&vreg_l3c_1p2>; + vddaon-supply = <&vreg_s2c_0p8>; + vdddig-supply = <&vreg_s3c_0p9>; + vddrfa1p2-supply = <&vreg_s1c_1p2>; + vddrfa1p8-supply = <&vreg_s6c_1p8>; + + clocks = <&rpmhcc RPMH_RF_CLK1>; + + regulators { + vreg_pmu_rfa_cmn: ldo0 { + regulator-name = "vreg_pmu_rfa_cmn"; + }; + + vreg_pmu_aon_0p59: ldo1 { + regulator-name = "vreg_pmu_aon_0p59"; + }; + + vreg_pmu_wlcx_0p8: ldo2 { + regulator-name = "vreg_pmu_wlcx_0p8"; + }; + + vreg_pmu_wlmx_0p85: ldo3 { + regulator-name = "vreg_pmu_wlmx_0p85"; + }; + + vreg_pmu_btcmx_0p85: ldo4 { + regulator-name = "vreg_pmu_btcmx_0p85"; + }; + + vreg_pmu_rfa_0p8: ldo5 { + regulator-name = "vreg_pmu_rfa_0p8"; + }; + + vreg_pmu_rfa_1p2: ldo6 { + regulator-name = "vreg_pmu_rfa_1p2"; + }; + + vreg_pmu_rfa_1p8: ldo7 { + regulator-name = "vreg_pmu_rfa_1p8"; + }; + + vreg_pmu_pcie_0p9: ldo8 { + regulator-name = "vreg_pmu_pcie_0p9"; + }; + + vreg_pmu_pcie_1p8: ldo9 { + regulator-name = "vreg_pmu_pcie_1p8"; + }; + }; + }; +}; + +&apps_rsc { + regulators-0 { + compatible = "qcom,pm8550-rpmh-regulators"; + + vdd-bob1-supply = <&vph_pwr>; + vdd-bob2-supply = <&vph_pwr>; + vdd-l1-l4-l10-supply = <&vreg_s6c_1p8>; + vdd-l2-l13-l14-supply = <&vreg_bob1>; + vdd-l3-supply = <&vreg_s1c_1p2>; + vdd-l5-l16-supply = <&vreg_bob1>; + vdd-l8-l9-supply = <&vreg_bob1>; + vdd-l12-supply = <&vreg_s6c_1p8>; + vdd-l15-supply = <&vreg_s6c_1p8>; + vdd-l17-supply = <&vreg_bob2>; + + qcom,pmic-id = "b"; + + vreg_bob1: bob1 { + regulator-name = "vreg_bob1"; + regulator-min-microvolt = <3296000>; + regulator-max-microvolt = <3960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_bob2: bob2 { + regulator-name = "vreg_bob2"; + regulator-min-microvolt = <2720000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1b_1p8: ldo1 { + regulator-name = "vreg_l1b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2b_3p0: ldo2 { + regulator-name = "vreg_l2b_3p0"; + regulator-min-microvolt = <3008000>; + regulator-max-microvolt = <3008000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5b_3p1: ldo5 { + regulator-name = "vreg_l5b_3p1"; + regulator-min-microvolt = <3104000>; + regulator-max-microvolt = <3104000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l8b_1p8: ldo8 { + regulator-name = "vreg_l8b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l9b_2p9: ldo9 { + regulator-name = "vreg_l9b_2p9"; + regulator-min-microvolt = <2960000>; + regulator-max-microvolt = <2960000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l10b_1p8: ldo10 { + regulator-name = "vreg_l10b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l12b_1p8: ldo12 { + regulator-name = "vreg_l12b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l15b_1p8: ldo15 { + regulator-name = "vreg_l15b_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l17b_2p5: ldo17 { + regulator-name = "vreg_l17b_2p5"; + regulator-min-microvolt = <2504000>; + regulator-max-microvolt = <2504000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-1 { + compatible = "qcom,pm8550vs-rpmh-regulators"; + + vdd-l1-supply = <&vreg_s1c_1p2>; + vdd-l3-supply = <&vreg_s1c_1p2>; + vdd-s1-supply = <&vph_pwr>; + vdd-s2-supply = <&vph_pwr>; + vdd-s3-supply = <&vph_pwr>; + vdd-s4-supply = <&vph_pwr>; + vdd-s5-supply = <&vph_pwr>; + vdd-s6-supply = <&vph_pwr>; + + qcom,pmic-id = "c"; + + vreg_s1c_1p2: smps1 { + regulator-name = "vreg_s1c_1p2"; + regulator-min-microvolt = <1224000>; + regulator-max-microvolt = <1348000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s2c_0p8: smps2 { + regulator-name = "vreg_s2c_0p8"; + regulator-min-microvolt = <500000>; + regulator-max-microvolt = <1036000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s3c_0p9: smps3 { + regulator-name = "vreg_s3c_0p9"; + regulator-min-microvolt = <904000>; + regulator-max-microvolt = <1064000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s4c_1p2: smps4 { + regulator-name = "vreg_s4c_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1280000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s5c_0p7: smps5 { + regulator-name = "vreg_s5c_0p7"; + regulator-min-microvolt = <300000>; + regulator-max-microvolt = <900000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_s6c_1p8: smps6 { + regulator-name = "vreg_s6c_1p8"; + regulator-min-microvolt = <1856000>; + regulator-max-microvolt = <2000000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1c_1p2: ldo1 { + regulator-name = "vreg_l1c_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3c_1p2: ldo3 { + regulator-name = "vreg_l3c_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-2 { + compatible = "qcom,pm8550vs-rpmh-regulators"; + + vdd-l1-supply = <&vreg_s3c_0p9>; + + qcom,pmic-id = "d"; + + vreg_l1d_0p9: ldo1 { + regulator-name = "vreg_l1d_0p9"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-3 { + compatible = "qcom,pm8550vs-rpmh-regulators"; + + vdd-l3-supply = <&vreg_s3c_0p9>; + + qcom,pmic-id = "e"; + + vreg_l3e_0p9: ldo3 { + regulator-name = "vreg_l3e_0p9"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-4 { + compatible = "qcom,pm8550vs-rpmh-regulators"; + + vdd-l1-supply = <&vreg_s3c_0p9>; + vdd-l2-supply = <&vreg_s1c_1p2>; + vdd-l3-supply = <&vreg_s3c_0p9>; + + qcom,pmic-id = "g"; + + vreg_l1g_0p9: ldo1 { + regulator-name = "vreg_l1g_0p9"; + regulator-min-microvolt = <912000>; + regulator-max-microvolt = <920000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2g_1p1: ldo2 { + regulator-name = "vreg_l2g_1p1"; + regulator-min-microvolt = <1104000>; + regulator-max-microvolt = <1104000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3g_0p91: ldo3 { + regulator-name = "vreg_l3g_0p91"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-5 { + compatible = "qcom,pm8550ve-rpmh-regulators"; + + vdd-l1-supply = <&vreg_s3c_0p9>; + vdd-l2-supply = <&vreg_s3c_0p9>; + vdd-l3-supply = <&vreg_s1c_1p2>; + vdd-s4-supply = <&vph_pwr>; + + qcom,pmic-id = "i"; + + vreg_s4i_0p85: smps4 { + regulator-name = "vreg_s4i_0p85"; + regulator-min-microvolt = <852000>; + regulator-max-microvolt = <1004000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l1i_0p88: ldo1 { + regulator-name = "vreg_l1i_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2i_0p88: ldo2 { + regulator-name = "vreg_l2i_0p88"; + regulator-min-microvolt = <880000>; + regulator-max-microvolt = <912000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3i_1p2: ldo3 { + regulator-name = "vreg_l3i_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + }; + + regulators-6 { + compatible = "qcom,pm8010-rpmh-regulators"; + + vdd-l1-l2-supply = <&vreg_s1c_1p2>; + vdd-l3-l4-supply = <&vreg_bob2>; + vdd-l5-supply = <&vreg_s6c_1p8>; + vdd-l6-supply = <&vreg_bob2>; + vdd-l7-supply = <&vreg_bob1>; + + qcom,pmic-id = "m"; + + vreg_l1m_1p1: ldo1 { + regulator-name = "vreg_l1m_1p1"; + regulator-min-microvolt = <1104000>; + regulator-max-microvolt = <1104000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2m_1p2: ldo2 { + regulator-name = "vreg_l2m_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3m_2p8: ldo3 { + regulator-name = "vreg_l3m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4m_2p8: ldo4 { + regulator-name = "vreg_l4m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5m_1p8: ldo5 { + regulator-name = "vreg_l5m_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6m_2p8: ldo6 { + regulator-name = "vreg_l6m_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l7m_3p3: ldo7 { + regulator-name = "vreg_l7m_3p3"; + regulator-min-microvolt = <3304000>; + regulator-max-microvolt = <3304000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + + regulator-always-on; + }; + }; + + regulators-7 { + compatible = "qcom,pm8010-rpmh-regulators"; + + vdd-l1-l2-supply = <&vreg_s1c_1p2>; + vdd-l3-l4-supply = <&vreg_bob2>; + vdd-l5-supply = <&vreg_s6c_1p8>; + vdd-l6-supply = <&vreg_bob2>; + + qcom,pmic-id = "n"; + + vreg_l1n_1p1: ldo1 { + regulator-name = "vreg_l1n_1p1"; + regulator-min-microvolt = <1104000>; + regulator-max-microvolt = <1104000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l2n_1p2: ldo2 { + regulator-name = "vreg_l2n_1p2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + regulator-allow-set-load; + regulator-allowed-modes = <RPMH_REGULATOR_MODE_LPM + RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l3n_2p8: ldo3 { + regulator-name = "vreg_l3n_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l4n_2p8: ldo4 { + regulator-name = "vreg_l4n_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l5n_1p8: ldo5 { + regulator-name = "vreg_l5n_1p8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + + vreg_l6n_2p8: ldo6 { + regulator-name = "vreg_l6n_2p8"; + regulator-min-microvolt = <2800000>; + regulator-max-microvolt = <2800000>; + regulator-initial-mode = <RPMH_REGULATOR_MODE_HPM>; + }; + }; +}; + +&dispcc { + status = "disabled"; +}; + +&gpi_dma1 { + status = "okay"; +}; + +&gpi_dma2 { + status = "okay"; +}; + +&gpu { + status = "okay"; +}; + +&i2c_hub_8 { + clock-frequency = <100000>; + + status = "okay"; + + right_spkr_i2s: speaker@38 { + compatible = "maxim,max98390"; + reg = <0x38>; + + reset-gpios = <&tlmm 73 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&r_spkr_irq_default>; + pinctrl-names = "default"; + + #sound-dai-cells = <0>; + sound-name-prefix = "Speaker Right"; + + maxim,temperature_calib = <1024>; + maxim,r0_calib = <100232>; + }; + + left_spkr_i2s: speaker@3d { + compatible = "maxim,max98390"; + reg = <0x3d>; + + reset-gpios = <&tlmm 161 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&l_spkr_irq_default>; + pinctrl-names = "default"; + + #sound-dai-cells = <0>; + sound-name-prefix = "Speaker Left"; + + maxim,temperature_calib = <1024>; + maxim,r0_calib = <100232>; + }; + + light-sensor@60 { + compatible = "vishay,vcnl4040"; + reg = <0x60>; + + vdd-supply = <&vreg_l2b_3p0>; + vio-supply = <&vreg_l1b_1p8>; + + proximity-near-level = <220>; + }; +}; + +&i2c_master_hub_0 { + firmware-name = "qcom/sm8650/qupv3fw.elf"; + + status = "okay"; +}; + +&i2c2 { + clock-frequency = <100000>; + + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c32"; + reg = <0x50>; + + label = "strap_eeprom"; + vcc-supply = <&vreg_l15b_1p8>; + }; + + eeprom@51 { + compatible = "atmel,24c04"; + reg = <0x51>; + + label = "strap_v2_eeprom"; + vcc-supply = <&vreg_l15b_1p8>; + }; +}; + +&i2c4 { + clock-frequency = <100000>; + + status = "okay"; + + magnetometer@6c { + compatible = "allegromicro,als31300-500"; + reg = <0x6c>; + + vcc-supply = <&vreg_l2b_3p0>; + }; +}; + +&i2c5 { + clock-frequency = <100000>; + + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c64"; + reg = <0x50>; + label = "core_v2_eeprom"; + vcc-supply = <&vreg_l15b_1p8>; + pagesize = <32>; + size = <8192>; + address-width = <16>; + wp-gpios = <&tlmm 78 GPIO_ACTIVE_HIGH>; + }; +}; + +&pcie0 { + wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>; + perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>; + + pinctrl-0 = <&pcie0_default_state>; + pinctrl-names = "default"; + + status = "okay"; +}; + +&pcieport0 { + wifi@0 { + compatible = "pci17cb,1107"; + reg = <0x10000 0 0 0 0>; + + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + vddpcie0p9-supply = <&vreg_pmu_pcie_0p9>; + vddpcie1p8-supply = <&vreg_pmu_pcie_1p8>; + }; +}; + +&pcie0_phy { + vdda-phy-supply = <&vreg_l1i_0p88>; + vdda-pll-supply = <&vreg_l3i_1p2>; + + status = "okay"; +}; + +&pm8550_gpios { + sdc2_card_det_n: sdc2-card-det-state { + pins = "gpio12"; + function = "normal"; + bias-pull-up; + input-enable; + output-disable; + power-source = <1>; /* 1.8 V */ + }; + + volume_up_n: volume-up-n-state { + pins = "gpio6"; + function = "normal"; + bias-pull-up; + input-enable; + power-source = <1>; + }; +}; + +&pm8550_pwm { + status = "okay"; + + multi-led { + color = <LED_COLOR_ID_RGB>; + function = LED_FUNCTION_STATUS; + default-state = "keep"; + + #address-cells = <1>; + #size-cells = <0>; + + led@1 { + reg = <1>; + color = <LED_COLOR_ID_RED>; + }; + + led@2 { + reg = <2>; + color = <LED_COLOR_ID_GREEN>; + }; + + led@3 { + reg = <3>; + color = <LED_COLOR_ID_BLUE>; + }; + }; +}; + +&pm8550_temp_alarm { + io-channels = <&pmk8550_vadc ADC5_GEN3_DIE_TEMP(1)>; + io-channel-names = "thermal"; +}; + +&pm8550b_gpios { + detect_n: detect-n-state { + pins = "gpio6"; + function = "normal"; + power-source = <1>; + bias-pull-up; + input-enable; + }; + + select_n: select-n-state { + pins = "gpio5"; + function = "normal"; + power-source = <1>; + bias-pull-up; + input-enable; + }; +}; + +&pm8550b_eusb2_repeater { + vdd18-supply = <&vreg_l15b_1p8>; + vdd3-supply = <&vreg_l5b_3p1>; +}; + +&pm8550b_temp_alarm { + io-channels = <&pmk8550_vadc ADC5_GEN3_DIE_TEMP(7)>; + io-channel-names = "thermal"; +}; + +&pm8550vs_c { + status = "okay"; +}; + +&pm8550vs_c_temp_alarm { + io-channels = <&pmk8550_vadc ADC5_GEN3_DIE_TEMP(2)>; + io-channel-names = "thermal"; +}; + +&pm8550vs_d { + status = "okay"; +}; + +&pm8550vs_d_temp_alarm { + io-channels = <&pmk8550_vadc ADC5_GEN3_DIE_TEMP(3)>; + io-channel-names = "thermal"; +}; + +&pm8550vs_e { + status = "okay"; +}; + +&pm8550vs_e_temp_alarm { + io-channels = <&pmk8550_vadc ADC5_GEN3_DIE_TEMP(4)>; + io-channel-names = "thermal"; +}; + +&pm8550vs_g { + status = "okay"; +}; + +&pm8550vs_g_temp_alarm { + io-channels = <&pmk8550_vadc ADC5_GEN3_DIE_TEMP(6)>; + io-channel-names = "thermal"; +}; + +&pm8550ve_temp_alarm { + io-channels = <&pmk8550_vadc ADC5_GEN3_DIE_TEMP(PMK8550VE_SID)>; + io-channel-names = "thermal"; +}; + +&pmk8550_rtc { + allow-set-time; + + status = "okay"; +}; + +&pmk8550_vadc { + /* PMK8550 Channel nodes */ + channel@44 { + reg = <ADC5_GEN3_AMUX1_THM_100K_PU(0)>; + label = "pmk8550_xo_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + qcom,pre-scaling = <1 1>; + }; + + channel@49 { + reg = <ADC5_GEN3_AMUX6_THM_100K_PU(0)>; + label = "display_left_therm"; + qcom,ratiometric; + qcom,hw-settle-time = <15>; + }; + + /* PM8550 Channel nodes */ + channel@100 { + reg = <ADC5_GEN3_REF_GND(1)>; + label = "pm8550_offset_ref"; + qcom,pre-scaling = <1 1>; + }; + + channel@101 { + reg = <ADC5_GEN3_1P25VREF(1)>; + label = "pm8550_vref_1p25"; + qcom,pre-scaling = <1 1>; + }; + + channel@103 { + reg = <ADC5_GEN3_DIE_TEMP(1)>; + label = "pm8550_die_temp"; + qcom,pre-scaling = <1 1>; + }; + + channel@144 { + reg = <ADC5_GEN3_AMUX1_THM_100K_PU(1)>; + label = "pcba_at_fan_exhaust"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + channel@145 { + reg = <ADC5_GEN3_AMUX2_THM_100K_PU(1)>; + label = "pcba_at_40pin_connector"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + channel@146 { + reg = <ADC5_GEN3_AMUX3_THM_100K_PU(1)>; + label = "pcba_at_wifi"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + channel@147 { + reg = <ADC5_GEN3_AMUX4_THM_100K_PU(1)>; + label = "pcba_at_flash"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + channel@148 { + reg = <ADC5_GEN3_AMUX5_THM_100K_PU(1)>; + label = "pcba_at_nrf"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + channel@18e { + reg = <ADC5_GEN3_VPH_PWR(1)>; + label = "pm8550_vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + /* PM8550VS_C Channel nodes */ + channel@203 { + reg = <ADC5_GEN3_DIE_TEMP(2)>; + label = "pm8550vs_c_die_temp"; + qcom,pre-scaling = <1 1>; + }; + + /* PM8550VS_D Channel nodes */ + channel@303 { + reg = <ADC5_GEN3_DIE_TEMP(3)>; + label = "pm8550vs_d_die_temp"; + qcom,pre-scaling = <1 1>; + }; + + /* PM8550VS_E Channel nodes */ + channel@403 { + reg = <ADC5_GEN3_DIE_TEMP(4)>; + label = "pm8550vs_e_die_temp"; + qcom,pre-scaling = <1 1>; + }; + + /* PM8550VE Channel nodes */ + channel@503 { + reg = <ADC5_GEN3_DIE_TEMP(PMK8550VE_SID)>; + label = "pm8550ve_die_temp"; + qcom,pre-scaling = <1 1>; + }; + + /* PM8550VS_G Channel nodes */ + channel@603 { + reg = <ADC5_GEN3_DIE_TEMP(6)>; + label = "pm8550vs_g_die_temp"; + qcom,pre-scaling = <1 1>; + }; + + /* PM8550B Channel nodes */ + channel@700 { + reg = <ADC5_GEN3_REF_GND(7)>; + label = "pm8550b_offset_ref"; + qcom,pre-scaling = <1 1>; + }; + + channel@701 { + reg = <ADC5_GEN3_1P25VREF(7)>; + label = "pm8550b_vref_1p25"; + qcom,pre-scaling = <1 1>; + }; + + channel@703 { + reg = <ADC5_GEN3_DIE_TEMP(7)>; + label = "pm8550b_die_temp"; + qcom,pre-scaling = <1 1>; + }; + + channel@711 { + reg = <ADC5_GEN3_USB_SNS_V_16(7)>; + label = "pm8550b_usb_sns_v_div_16"; + qcom,pre-scaling = <1 16>; + }; + + channel@712 { + reg = <ADC5_GEN3_VIN_DIV16_MUX(7)>; + label = "pm8550b_wls_vin_div_16"; + qcom,pre-scaling = <1 16>; + }; + + channel@744 { + reg = <ADC5_GEN3_AMUX1_THM_100K_PU(7)>; + label = "battery_temp"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + channel@747 { + reg = <ADC5_GEN3_AMUX4_THM_100K_PU(7)>; + label = "pcba_at_heat_sink_fins"; + qcom,ratiometric; + qcom,hw-settle-time = <200>; + }; + + channel@78e { + reg = <ADC5_GEN3_VPH_PWR(7)>; + label = "pm8550b_vph_pwr"; + qcom,pre-scaling = <1 3>; + }; + + channel@78f { + reg = <ADC5_GEN3_VBAT_SNS_QBG(7)>; + label = "pm8550b_vbat_sns_qbg"; + qcom,pre-scaling = <1 6>; + }; +}; + +&pon_pwrkey { + status = "okay"; +}; + +&pon_resin { + linux,code = <KEY_VOLUMEDOWN>; + + status = "okay"; +}; + +&qupv3_id_0 { + firmware-name = "qcom/sm8650/qupv3fw.elf"; + + status = "okay"; +}; + +&qupv3_id_1 { + firmware-name = "qcom/sm8650/qupv3fw.elf"; + + status = "okay"; +}; + +&sdhc_2 { + cd-gpios = <&pm8550_gpios 12 GPIO_ACTIVE_LOW>; + + vmmc-supply = <&vreg_l9b_2p9>; + vqmmc-supply = <&vreg_l8b_1p8>; + bus-width = <4>; + no-sdio; + no-mmc; + + pinctrl-0 = <&sdc2_default>, <&sdc2_card_det_n>; + pinctrl-1 = <&sdc2_sleep>, <&sdc2_card_det_n>; + pinctrl-names = "default", "sleep"; + + status = "okay"; +}; + +&sleep_clk { + clock-frequency = <32764>; +}; + +&tlmm { + bt_default: bt-default-state { + bt-en-pins { + pins = "gpio17"; + function = "gpio"; + drive-strength = <16>; + bias-disable; + }; + + sw-ctrl-pins { + pins = "gpio18"; + function = "gpio"; + bias-pull-down; + }; + }; + + i2c4_default: i2c4-default-state { + pins = "gpio48", "gpio49"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + i2c5_default: i2c5-default-state { + pins = "gpio52", "gpio53"; + function = "gpio"; + drive-strength = <2>; + bias-pull-up; + }; + + l_spkr_irq_default: l-spkr-irq-state-state { + pins = "gpio77"; + function = "gpio"; + bias-pull-up; + }; + + r_spkr_irq_default: r-spkr-irq-default-state { + pins = "gpio186"; + function = "gpio"; + bias-pull-up; + }; + + wlan_en: wlan-en-state { + pins = "gpio16"; + function = "gpio"; + drive-strength = <8>; + bias-pull-down; + }; +}; + +&uart14 { + status = "okay"; + + bluetooth { + compatible = "qcom,wcn7850-bt"; + + vddrfacmn-supply = <&vreg_pmu_rfa_cmn>; + vddaon-supply = <&vreg_pmu_aon_0p59>; + vddwlcx-supply = <&vreg_pmu_wlcx_0p8>; + vddwlmx-supply = <&vreg_pmu_wlmx_0p85>; + vddrfa0p8-supply = <&vreg_pmu_rfa_0p8>; + vddrfa1p2-supply = <&vreg_pmu_rfa_1p2>; + vddrfa1p8-supply = <&vreg_pmu_rfa_1p8>; + + max-speed = <3200000>; + }; +}; + +&uart15 { + status = "okay"; +}; + +&ufs_mem_hc { + reset-gpios = <&tlmm 210 GPIO_ACTIVE_LOW>; + + vcc-supply = <&vreg_l17b_2p5>; + vcc-max-microamp = <1300000>; + vccq-supply = <&vreg_l1c_1p2>; + vccq-max-microamp = <1200000>; + + status = "okay"; +}; + +&ufs_mem_phy { + vdda-phy-supply = <&vreg_l1d_0p9>; + vdda-pll-supply = <&vreg_l3i_1p2>; + + status = "okay"; +}; + +&usb_1 { + dr_mode = "peripheral"; + + /* USB 2.0 only */ + qcom,select-utmi-as-pipe-clk; + maximum-speed = "high-speed"; + + /* Remove USB3 phy */ + phys = <&usb_1_hsphy>; + phy-names = "usb2-phy"; + + status = "okay"; +}; + +&usb_1_hsphy { + vdd-supply = <&vreg_l1i_0p88>; + vdda12-supply = <&vreg_l3i_1p2>; + + phys = <&pm8550b_eusb2_repeater>; + + status = "okay"; +}; + +&xo_board { + clock-frequency = <76800000>; +};
diff --git a/arch/arm64/boot/dts/qcom/sm8650.dtsi b/arch/arm64/boot/dts/qcom/sm8650.dtsi index b679fd8..86fbb0f 100644 --- a/arch/arm64/boot/dts/qcom/sm8650.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8650.dtsi
@@ -21,7 +21,6 @@ #include <dt-bindings/mailbox/qcom-ipcc.h> #include <dt-bindings/phy/phy-qcom-qmp.h> #include <dt-bindings/power/qcom,rpmhpd.h> -#include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/reset/qcom,sm8650-gpucc.h> #include <dt-bindings/soc/qcom,gpr.h> #include <dt-bindings/soc/qcom,rpmh-rsc.h> @@ -1907,7 +1906,7 @@ llcc_lpi_mem: llcc-lpi@ff800000 { }; }; - smp2p-adsp { + smp2p_adsp: smp2p-adsp { compatible = "qcom,smp2p"; interrupts-extended = <&ipcc IPCC_CLIENT_LPASS @@ -1933,7 +1932,7 @@ smp2p_adsp_in: slave-kernel { }; }; - smp2p-cdsp { + smp2p_cdsp: smp2p-cdsp { compatible = "qcom,smp2p"; interrupts-extended = <&ipcc IPCC_CLIENT_CDSP @@ -1959,7 +1958,7 @@ smp2p_cdsp_in: slave-kernel { }; }; - smp2p-modem { + smp2p_modem: smp2p-modem { compatible = "qcom,smp2p"; interrupts-extended = <&ipcc IPCC_CLIENT_MPSS @@ -2019,6 +2018,8 @@ gcc: clock-controller@100000 { <&ufs_mem_phy 2>, <&usb_dp_qmpphy QMP_USB43DP_USB3_PIPE_CLK>; + power-domains = <&rpmhpd RPMHPD_CX>; + #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; @@ -3700,9 +3701,6 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, num-lanes = <2>; bus-range = <0 0xff>; - phys = <&pcie0_phy>; - phy-names = "pciephy"; - #address-cells = <3>; #size-cells = <2>; ranges = <0x01000000 0 0x00000000 0 0x60200000 0 0x100000>, @@ -3769,6 +3767,8 @@ pcieport0: pcie@0 { reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie0_phy>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -3893,9 +3893,6 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, num-lanes = <2>; bus-range = <0 0xff>; - phys = <&pcie1_phy>; - phy-names = "pciephy"; - dma-coherent; #address-cells = <3>; @@ -3978,6 +3975,8 @@ pcie1_port0: pcie@0 { reg = <0x0 0x0 0x0 0x0 0x0>; bus-range = <0x01 0xff>; + phys = <&pcie1_phy>; + #address-cells = <3>; #size-cells = <2>; ranges; @@ -6154,7 +6153,6 @@ spmi_bus: spmi@c400000 { qcom,ee = <0>; qcom,channel = <0>; - qcom,bus-id = <0>; interrupt-controller; #interrupt-cells = <4>;
diff --git a/arch/arm64/boot/dts/qcom/sm8750-mtp.dts b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts index 9b5fbc0..64bc1ce 100644 --- a/arch/arm64/boot/dts/qcom/sm8750-mtp.dts +++ b/arch/arm64/boot/dts/qcom/sm8750-mtp.dts
@@ -935,6 +935,14 @@ vreg_l7n_3p3: ldo7 { }; }; +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/sm8750/gen80000_zap.mbn"; +}; + &i2c3 { status = "okay"; @@ -1119,7 +1127,7 @@ &pcie0_phy { }; &pcieport0 { - wake-gpios = <&tlmm 104 GPIO_ACTIVE_HIGH>; + wake-gpios = <&tlmm 104 GPIO_ACTIVE_LOW>; reset-gpios = <&tlmm 102 GPIO_ACTIVE_LOW>; wifi@0 {
diff --git a/arch/arm64/boot/dts/qcom/sm8750-qrd.dts b/arch/arm64/boot/dts/qcom/sm8750-qrd.dts index b56317c..75927e1 100644 --- a/arch/arm64/boot/dts/qcom/sm8750-qrd.dts +++ b/arch/arm64/boot/dts/qcom/sm8750-qrd.dts
@@ -858,6 +858,14 @@ vreg_l7n_3p3: ldo7 { }; }; +&gpu { + status = "okay"; +}; + +&gpu_zap_shader { + firmware-name = "qcom/sm8750/gen80000_zap.mbn"; +}; + &iris { status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/sm8750.dtsi b/arch/arm64/boot/dts/qcom/sm8750.dtsi index dd738d1..cf947ac 100644 --- a/arch/arm64/boot/dts/qcom/sm8750.dtsi +++ b/arch/arm64/boot/dts/qcom/sm8750.dtsi
@@ -5,10 +5,12 @@ #include <dt-bindings/clock/qcom,dsi-phy-28nm.h> #include <dt-bindings/clock/qcom,rpmh.h> +#include <dt-bindings/clock/qcom,kaanapali-gxclkctl.h> #include <dt-bindings/clock/qcom,sm8750-cambistmclkcc.h> #include <dt-bindings/clock/qcom,sm8750-camcc.h> #include <dt-bindings/clock/qcom,sm8750-dispcc.h> #include <dt-bindings/clock/qcom,sm8750-gcc.h> +#include <dt-bindings/clock/qcom,sm8750-gpucc.h> #include <dt-bindings/clock/qcom,sm8750-tcsr.h> #include <dt-bindings/clock/qcom,sm8750-videocc.h> #include <dt-bindings/dma/qcom-gpi.h> @@ -20,7 +22,6 @@ #include <dt-bindings/mailbox/qcom-ipcc.h> #include <dt-bindings/phy/phy-qcom-qmp.h> #include <dt-bindings/power/qcom,rpmhpd.h> -#include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/soc/qcom,gpr.h> #include <dt-bindings/soc/qcom,rpmh-rsc.h> #include <dt-bindings/sound/qcom,q6dsp-lpass-ports.h> @@ -462,7 +463,7 @@ gpu_micro_code_mem: gpu-micro-code@9b09a000 { no-map; }; - spss_region_mem: spss@9b0a0000 { + spss_region_mem: spss@9b0a0000 { reg = <0x0 0x9b0a0000 0x0 0x1e0000>; no-map; }; @@ -676,6 +677,8 @@ gcc: clock-controller@100000 { <0>, <&usb_dp_qmpphy QMP_USB43DP_USB3_PIPE_CLK>; + power-domains = <&rpmhpd RPMHPD_CX>; + #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; @@ -2180,6 +2183,291 @@ tcsr_mutex: hwlock@1f40000 { #hwlock-cells = <1>; }; + gpu: gpu@3d00000 { + compatible = "qcom,adreno-44050001", "qcom,adreno"; + reg = <0x0 0x03d00000 0x0 0x6d000>, + <0x0 0x03d9e000 0x0 0x2000>; + reg-names = "kgsl_3d0_reg_memory", + "cx_mem"; + + interrupts = <GIC_SPI 300 IRQ_TYPE_LEVEL_HIGH>; + + iommus = <&adreno_smmu 0 0x0>, + <&adreno_smmu 1 0x0>; + + operating-points-v2 = <&gpu_opp_table>; + + qcom,gmu = <&gmu>; + #cooling-cells = <2>; + + nvmem-cells = <&gpu_speed_bin>; + nvmem-cell-names = "speed_bin"; + + interconnects = <&gem_noc MASTER_GFX3D QCOM_ICC_TAG_ALWAYS + &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>; + interconnect-names = "gfx-mem"; + + status = "disabled"; + + gpu_zap_shader: zap-shader { + memory-region = <&gpu_micro_code_mem>; + }; + + gpu_opp_table: opp-table { + compatible = "operating-points-v2-adreno", + "operating-points-v2"; + + opp-160000000 { + opp-hz = /bits/ 64 <160000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D3>; + opp-peak-kBps = <2136718>; + opp-supported-hw = <0x1f>; + }; + + opp-222000000 { + opp-hz = /bits/ 64 <222000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D2>; + opp-peak-kBps = <2136718>; + opp-supported-hw = <0x1f>; + }; + + opp-342000000 { + opp-hz = /bits/ 64 <342000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D1>; + opp-peak-kBps = <5285156>; + opp-supported-hw = <0x1f>; + }; + + opp-389000000 { + opp-hz = /bits/ 64 <389000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_D0>; + opp-peak-kBps = <6074218>; + qcom,opp-acd-level = <0xc8285ffd>; + opp-supported-hw = <0x1f>; + }; + + opp-443000000 { + opp-hz = /bits/ 64 <443000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>; + opp-peak-kBps = <6074218>; + qcom,opp-acd-level = <0xc02e5ffd>; + opp-supported-hw = <0x1f>; + }; + + opp-525000000 { + opp-hz = /bits/ 64 <525000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS_L1>; + opp-peak-kBps = <6074218>; + qcom,opp-acd-level = <0xc02e5ffd>; + opp-supported-hw = <0x1f>; + }; + + opp-607000000 { + opp-hz = /bits/ 64 <607000000>; + opp-level = <RPMH_REGULATOR_LEVEL_SVS>; + opp-peak-kBps = <8171875>; + qcom,opp-acd-level = <0xa82e5ffd>; + opp-supported-hw = <0x1f>; + }; + + opp-660000000 { + opp-hz = /bits/ 64 <660000000>; + opp-level = <RPMH_REGULATOR_LEVEL_SVS_L0>; + opp-peak-kBps = <8171875>; + qcom,opp-acd-level = <0x882c5ffd>; + opp-supported-hw = <0x1f>; + }; + + opp-734000000 { + opp-hz = /bits/ 64 <734000000>; + opp-level = <RPMH_REGULATOR_LEVEL_SVS_L1>; + opp-peak-kBps = <12449218>; + qcom,opp-acd-level = <0xa82a5ffd>; + opp-supported-hw = <0x1f>; + }; + + opp-832000000 { + opp-hz = /bits/ 64 <832000000>; + opp-level = <RPMH_REGULATOR_LEVEL_SVS_L2>; + opp-peak-kBps = <16500000>; + qcom,opp-acd-level = <0x882a5ffd>; + opp-supported-hw = <0x1f>; + }; + + opp-900000000-0 { + opp-hz = /bits/ 64 <900000000>; + opp-level = <RPMH_REGULATOR_LEVEL_NOM>; + opp-peak-kBps = <16500000>; + qcom,opp-acd-level = <0x882a5ffd>; + opp-supported-hw = <0x0f>; + }; + + /* Only applicable for SKUs which has 900Mhz as Fmax */ + opp-900000000-1 { + opp-hz = /bits/ 64 <900000000>; + opp-level = <RPMH_REGULATOR_LEVEL_NOM>; + opp-peak-kBps = <18597656>; + qcom,opp-acd-level = <0x882a5ffd>; + opp-supported-hw = <0x10>; + }; + + opp-967000000 { + opp-hz = /bits/ 64 <967000000>; + opp-level = <RPMH_REGULATOR_LEVEL_NOM_L1>; + opp-peak-kBps = <18597656>; + qcom,opp-acd-level = <0x882a5ffd>; + opp-supported-hw = <0x0f>; + }; + + opp-1050000000 { + opp-hz = /bits/ 64 <1050000000>; + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L1>; + opp-peak-kBps = <18597656>; + qcom,opp-acd-level = <0xa8295ffd>; + opp-supported-hw = <0x0f>; + }; + + opp-1100000000 { + opp-hz = /bits/ 64 <1100000000>; + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L3>; + opp-peak-kBps = <18597656>; + qcom,opp-acd-level = <0x88295ffd>; + opp-supported-hw = <0x05>; + }; + + opp-1150000000 { + opp-hz = /bits/ 64 <1150000000>; + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L3>; + opp-peak-kBps = <18597656>; + qcom,opp-acd-level = <0x88295ffd>; + opp-supported-hw = <0x02>; + }; + + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-level = <RPMH_REGULATOR_LEVEL_TURBO_L4>; + opp-peak-kBps = <18597656>; + qcom,opp-acd-level = <0x88295ffd>; + opp-supported-hw = <0x01>; + }; + }; + }; + + gxclkctl: clock-controller@3d64000 { + compatible = "qcom,sm8750-gxclkctl"; + reg = <0x0 0x03d64000 0x0 0x6000>; + + power-domains = <&rpmhpd RPMHPD_GFX>, + <&rpmhpd RPMHPD_GMXC>, + <&gpucc GPU_CC_CX_GDSC>; + + #power-domain-cells = <1>; + }; + + gmu: gmu@3d6c000 { + compatible = "qcom,adreno-gmu-830.1", "qcom,adreno-gmu"; + + reg = <0x0 0x03d6c000 0x0 0x32000>; + reg-names = "gmu"; + + interrupts = <GIC_SPI 304 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 305 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "hfi", "gmu"; + + clocks = <&gpucc GPU_CC_AHB_CLK>, + <&gpucc GPU_CC_CX_GMU_CLK>, + <&gpucc GPU_CC_CXO_CLK>, + <&gcc GCC_DDRSS_GPU_AXI_CLK>, + <&gcc GCC_GPU_GEMNOC_GFX_CLK>, + <&gpucc GPU_CC_HUB_CX_INT_CLK>; + clock-names = "ahb", + "gmu", + "cxo", + "axi", + "memnoc", + "hub"; + + power-domains = <&gpucc GPU_CC_CX_GDSC>, + <&gxclkctl GX_CLKCTL_GX_GDSC>; + power-domain-names = "cx", + "gx"; + + iommus = <&adreno_smmu 5 0x0>; + + qcom,qmp = <&aoss_qmp>; + + operating-points-v2 = <&gmu_opp_table>; + + gmu_opp_table: opp-table { + compatible = "operating-points-v2"; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-level = <RPMH_REGULATOR_LEVEL_LOW_SVS>; + }; + + opp-650000000 { + opp-hz = /bits/ 64 <650000000>; + opp-level = <RPMH_REGULATOR_LEVEL_SVS>; + }; + }; + }; + + gpucc: clock-controller@3d90000 { + compatible = "qcom,sm8750-gpucc"; + reg = <0x0 0x03d90000 0x0 0x9800>; + + clocks = <&bi_tcxo_div2>, + <&gcc GCC_GPU_GPLL0_CLK_SRC>, + <&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>; + + power-domains = <&rpmhpd RPMHPD_MX>, + <&rpmhpd RPMHPD_CX>; + required-opps = <&rpmhpd_opp_low_svs>, + <&rpmhpd_opp_low_svs>; + #clock-cells = <1>; + #reset-cells = <1>; + #power-domain-cells = <1>; + }; + + adreno_smmu: iommu@3da0000 { + compatible = "qcom,sm8750-smmu-500", "qcom,adreno-smmu", + "qcom,smmu-500", "arm,mmu-500"; + reg = <0x0 0x03da0000 0x0 0x40000>; + #iommu-cells = <2>; + #global-interrupts = <1>; + interrupts = <GIC_SPI 674 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 678 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 679 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 680 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 681 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 682 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 683 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 684 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 685 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 686 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 687 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 688 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 422 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 476 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 574 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 575 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 576 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 577 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 660 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 662 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 665 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 666 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 667 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 669 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 670 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 700 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&gpucc GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK>; + clock-names = "hlos"; + power-domains = <&gpucc GPU_CC_CX_GDSC>; + dma-coherent; + }; + remoteproc_mpss: remoteproc@4080000 { compatible = "qcom,sm8750-mpss-pas"; reg = <0x0 0x04080000 0x0 0x10000>; @@ -3609,7 +3897,6 @@ spmi_bus: spmi@c400000 { qcom,ee = <0>; qcom,channel = <0>; - qcom,bus-id = <0>; interrupt-controller; #interrupt-cells = <4>; @@ -5951,6 +6238,18 @@ cpu_scp_lpri1: scp-sram-section@200 { }; }; + qfprom: efuse@221c8000 { + compatible = "qcom,sm8750-qfprom", "qcom,qfprom"; + reg = <0x0 0x221c8000 0x0 0x1000>; + #address-cells = <1>; + #size-cells = <1>; + + gpu_speed_bin: gpu-speed-bin@138 { + reg = <0x138 0x2>; + bits = <0 9>; + }; + }; + /* cluster0 */ pmu@240b3400 { compatible = "qcom,sm8750-cpu-bwmon", "qcom,sdm845-bwmon"; @@ -6647,10 +6946,10 @@ gpuss0-thermal { thermal-sensors = <&tsens2 1>; trips { - trip-point0 { - temperature = <120000>; + gpuss0_alert0: gpuss0-alert0 { + temperature = <105000>; hysteresis = <5000>; - type = "hot"; + type = "passive"; }; gpuss0-critical { @@ -6659,16 +6958,23 @@ gpuss0-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss0_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss1-thermal { thermal-sensors = <&tsens2 2>; trips { - trip-point0 { - temperature = <120000>; + gpuss1_alert0: gpuss1-alert0 { + temperature = <105000>; hysteresis = <5000>; - type = "hot"; + type = "passive"; }; gpuss1-critical { @@ -6677,16 +6983,23 @@ gpuss1-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss1_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss2-thermal { thermal-sensors = <&tsens2 3>; trips { - trip-point0 { - temperature = <120000>; + gpuss2_alert0: gpuss2-alert0 { + temperature = <105000>; hysteresis = <5000>; - type = "hot"; + type = "passive"; }; gpuss2-critical { @@ -6695,16 +7008,23 @@ gpuss2-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss2_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss3-thermal { thermal-sensors = <&tsens2 4>; trips { - trip-point0 { - temperature = <120000>; + gpuss3_alert0: gpuss3-alert0 { + temperature = <105000>; hysteresis = <5000>; - type = "hot"; + type = "passive"; }; gpuss3-critical { @@ -6713,16 +7033,23 @@ gpuss3-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss3_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss4-thermal { thermal-sensors = <&tsens2 5>; trips { - trip-point0 { - temperature = <120000>; + gpuss4_alert0: gpuss4-alert0 { + temperature = <105000>; hysteresis = <5000>; - type = "hot"; + type = "passive"; }; gpuss4-critical { @@ -6731,16 +7058,23 @@ gpuss4-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss4_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss5-thermal { thermal-sensors = <&tsens2 6>; trips { - trip-point0 { - temperature = <120000>; + gpuss5_alert0: gpuss5-alert0 { + temperature = <105000>; hysteresis = <5000>; - type = "hot"; + type = "passive"; }; gpuss5-critical { @@ -6749,16 +7083,23 @@ gpuss5-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss5_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss6-thermal { thermal-sensors = <&tsens2 7>; trips { - trip-point0 { - temperature = <120000>; + gpuss6_alert0: gpuss6-alert0 { + temperature = <105000>; hysteresis = <5000>; - type = "hot"; + type = "passive"; }; gpuss6-critical { @@ -6767,16 +7108,23 @@ gpuss6-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss6_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; gpuss7-thermal { thermal-sensors = <&tsens2 8>; trips { - trip-point0 { - temperature = <120000>; + gpuss7_alert0: gpuss7-alert0 { + temperature = <105000>; hysteresis = <5000>; - type = "hot"; + type = "passive"; }; gpuss7-critical { @@ -6785,6 +7133,13 @@ gpuss7-critical { type = "critical"; }; }; + + cooling-maps { + map0 { + trip = <&gpuss7_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; }; modem0-thermal {
diff --git a/arch/arm64/boot/dts/qcom/talos-evk-rpi-display-2-5in.dtso b/arch/arm64/boot/dts/qcom/talos-evk-rpi-display-2-5in.dtso new file mode 100644 index 0000000..e49da09 --- /dev/null +++ b/arch/arm64/boot/dts/qcom/talos-evk-rpi-display-2-5in.dtso
@@ -0,0 +1,88 @@ +// SPDX-License-Identifier: BSD-3-Clause +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> + +&{/} { + display_bl: backlight { + compatible = "pwm-backlight"; + pwms = <&mcu 0 255 0>; + }; + + reg_display: regulator-display { + compatible = "regulator-fixed"; + regulator-name = "rpi-display"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + reg_dsi_touch: regulator-dsi-touch { + compatible = "regulator-fixed"; + gpio = <&mcu 1 GPIO_ACTIVE_HIGH>; + regulator-name = "rpi-touch"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <50000>; + enable-active-high; + }; +}; + +&hdmi_bridge { + status = "disabled"; +}; + +&i2c1 { + clock-frequency = <400000>; + + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + + mcu: gpio@45 { + compatible = "raspberrypi,touchscreen-panel-regulator-v2"; + reg = <0x45>; + gpio-controller; + #gpio-cells = <2>; + #pwm-cells = <3>; + }; + + touchscreen@5d { + compatible = "goodix,gt911"; + reg = <0x5d>; + AVDD28-supply = <®_dsi_touch>; + touchscreen-size-x = <720>; + touchscreen-size-y = <1280>; + }; +}; + +&mdss_dsi0 { + #address-cells = <1>; + #size-cells = <0>; + + status = "okay"; + + panel: panel@0 { + compatible = "raspberrypi,dsi-5inch", "ilitek,ili9881c"; + reg = <0>; + + backlight = <&display_bl>; + power-supply = <®_display>; + reset-gpios = <&mcu 0 GPIO_ACTIVE_LOW>; + + port { + panel_in: endpoint { + remote-endpoint = <&mdss_dsi0_out>; + }; + }; + }; +}; + +&mdss_dsi0_out { + remote-endpoint = <&panel_in>; + data-lanes = <0 1>; +};
diff --git a/arch/arm64/boot/dts/qcom/talos-evk-som.dtsi b/arch/arm64/boot/dts/qcom/talos-evk-som.dtsi index a31bed7..b76df9d 100644 --- a/arch/arm64/boot/dts/qcom/talos-evk-som.dtsi +++ b/arch/arm64/boot/dts/qcom/talos-evk-som.dtsi
@@ -366,9 +366,6 @@ &mdss_dsi0_phy { }; &pcie { - perst-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>; - wake-gpios = <&tlmm 100 GPIO_ACTIVE_HIGH>; - pinctrl-0 = <&pcie_default_state>; pinctrl-names = "default"; @@ -383,6 +380,8 @@ &pcie_phy { }; &pcie_port0 { + reset-gpios = <&tlmm 89 GPIO_ACTIVE_LOW>; + wake-gpios = <&tlmm 100 GPIO_ACTIVE_LOW>; wifi@0 { compatible = "pci17cb,1103"; reg = <0x10000 0x0 0x0 0x0 0x0>; @@ -411,10 +410,14 @@ usb2_en: usb2-en-state { }; &qupv3_id_0 { + firmware-name = "qcom/qcs615/qupv3fw.elf"; + status = "okay"; }; &qupv3_id_1 { + firmware-name = "qcom/qcs615/qupv3fw.elf"; + status = "okay"; };
diff --git a/arch/arm64/boot/dts/qcom/talos-evk.dts b/arch/arm64/boot/dts/qcom/talos-evk.dts index b7f514f..2ec3710 100644 --- a/arch/arm64/boot/dts/qcom/talos-evk.dts +++ b/arch/arm64/boot/dts/qcom/talos-evk.dts
@@ -36,7 +36,7 @@ hdmi_connector: hdmi-out { port { hdmi_con_out: endpoint { - remote-endpoint = <&adv7535_out>; + remote-endpoint = <&adv7535_out>; }; }; };
diff --git a/arch/arm64/boot/dts/qcom/talos.dtsi b/arch/arm64/boot/dts/qcom/talos.dtsi index eedfdce..8ed6f27 100644 --- a/arch/arm64/boot/dts/qcom/talos.dtsi +++ b/arch/arm64/boot/dts/qcom/talos.dtsi
@@ -17,7 +17,6 @@ #include <dt-bindings/interconnect/qcom,qcs615-rpmh.h> #include <dt-bindings/interrupt-controller/arm-gic.h> #include <dt-bindings/phy/phy-qcom-qmp.h> -#include <dt-bindings/power/qcom-rpmpd.h> #include <dt-bindings/power/qcom,rpmhpd.h> #include <dt-bindings/soc/qcom,gpr.h> #include <dt-bindings/soc/qcom,rpmh-rsc.h> @@ -706,6 +705,8 @@ gcc: clock-controller@100000 { "bi_tcxo_ao", "sleep_clk"; + power-domains = <&rpmhpd RPMHPD_CX>; + #clock-cells = <1>; #reset-cells = <1>; #power-domain-cells = <1>; @@ -795,7 +796,7 @@ opp-384000000 { }; }; - gpi_dma0: dma-controller@800000 { + gpi_dma0: dma-controller@800000 { compatible = "qcom,qcs615-gpi-dma", "qcom,sdm845-gpi-dma"; reg = <0x0 0x800000 0x0 0x60000>; #dma-cells = <3>; @@ -1367,9 +1368,6 @@ &mc_virt SLAVE_EBI1 QCOM_ICC_TAG_ALWAYS>, power-domains = <&gcc PCIE_0_GDSC>; - phys = <&pcie_phy>; - phy-names = "pciephy"; - max-link-speed = <2>; operating-points-v2 = <&pcie_opp_table>; @@ -1397,10 +1395,13 @@ opp-5000000 { pcie_port0: pcie@0 { device_type = "pci"; reg = <0x0 0x0 0x0 0x0 0x0>; + bus-range = <0x01 0xff>; + + phys = <&pcie_phy>; + #address-cells = <3>; #size-cells = <2>; ranges; - bus-range = <0x01 0xff>; }; };
diff --git a/arch/arm64/boot/dts/qcom/x1-asus-vivobook-s15.dtsi b/arch/arm64/boot/dts/qcom/x1-asus-vivobook-s15.dtsi index 0dc7c1b..7ef682e 100644 --- a/arch/arm64/boot/dts/qcom/x1-asus-vivobook-s15.dtsi +++ b/arch/arm64/boot/dts/qcom/x1-asus-vivobook-s15.dtsi
@@ -1036,9 +1036,31 @@ &smb2360_1_eusb2_repeater { vdd3-supply = <&vreg_l14b_3p0>; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { gpio-reserved-ranges = <34 2>, /* Unused */ <44 4>, /* SPI (TPM) */ + <65 1>, /* EC reset */ <238 1>; /* UFS Reset */ edp_reg_en: edp-reg-en-state {
diff --git a/arch/arm64/boot/dts/qcom/x1-asus-zenbook-a14.dtsi b/arch/arm64/boot/dts/qcom/x1-asus-zenbook-a14.dtsi index 59cbbfb..ceda30b 100644 --- a/arch/arm64/boot/dts/qcom/x1-asus-zenbook-a14.dtsi +++ b/arch/arm64/boot/dts/qcom/x1-asus-zenbook-a14.dtsi
@@ -1272,8 +1272,30 @@ wcd_tx: codec@0,3 { }; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p9>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p9>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { gpio-reserved-ranges = <44 4>, /* SPI11, TZ Protected */ + <65 1>, /* EC reset */ <90 1>; /* Unknown, TZ Protected */ cam_indicator_en: cam-indicator-en-state {
diff --git a/arch/arm64/boot/dts/qcom/x1-crd.dtsi b/arch/arm64/boot/dts/qcom/x1-crd.dtsi index 60db83b..fcd7cef 100644 --- a/arch/arm64/boot/dts/qcom/x1-crd.dtsi +++ b/arch/arm64/boot/dts/qcom/x1-crd.dtsi
@@ -1528,9 +1528,31 @@ right_tweeter: speaker@0,1 { }; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { gpio-reserved-ranges = <34 2>, /* Unused */ <44 4>, /* SPI (TPM) */ + <65 1>, /* EC reset */ <238 1>; /* UFS Reset */ ec_int_n_default: ec-int-n-state {
diff --git a/arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi b/arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi index 4cda708..f00feb3 100644 --- a/arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi +++ b/arch/arm64/boot/dts/qcom/x1-dell-thena.dtsi
@@ -1039,7 +1039,7 @@ &mdss_dp3 { status = "okay"; aux-bus { - panel { + panel: panel { compatible = "edp-panel"; enable-gpios = <&tlmm 74 GPIO_ACTIVE_HIGH>; power-supply = <&vreg_edp_3p3>; @@ -1301,8 +1301,30 @@ right_tweeter: speaker@0,1 { }; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { gpio-reserved-ranges = <44 4>, /* SPI11 (TPM) */ + <65 1>, /* EC reset */ <76 4>, /* SPI19 (TZ Protected) */ <80 2>, /* I2C20 (Battery SMBus) */ <238 1>; /* UFS Reset */
diff --git a/arch/arm64/boot/dts/qcom/x1-hp-omnibook-x14.dtsi b/arch/arm64/boot/dts/qcom/x1-hp-omnibook-x14.dtsi index dba8cee..443901a 100644 --- a/arch/arm64/boot/dts/qcom/x1-hp-omnibook-x14.dtsi +++ b/arch/arm64/boot/dts/qcom/x1-hp-omnibook-x14.dtsi
@@ -1284,9 +1284,31 @@ wcd_tx: codec@0,3 { }; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { gpio-reserved-ranges = <34 2>, /* Unused */ <44 4>, /* SPI (TPM) */ + <65 1>, /* EC reset */ <72 2>, /* Secure EC I2C connection (?) */ <238 1>; /* UFS Reset */
diff --git a/arch/arm64/boot/dts/qcom/x1-microsoft-denali.dtsi b/arch/arm64/boot/dts/qcom/x1-microsoft-denali.dtsi index e3a53b8..a71c297 100644 --- a/arch/arm64/boot/dts/qcom/x1-microsoft-denali.dtsi +++ b/arch/arm64/boot/dts/qcom/x1-microsoft-denali.dtsi
@@ -20,9 +20,27 @@ aliases { gpio-keys { compatible = "gpio-keys"; - pinctrl-0 = <&hall_int_n_default>; + pinctrl-0 = <&vol_down_n>, <&vol_up_n>, <&hall_int_n_default>; pinctrl-names = "default"; + key-vol-down { + debounce-interval = <15>; + gpios = <&pm8550_gpios 8 GPIO_ACTIVE_LOW>; + label = "Volume Down"; + linux,can-disable; + linux,code = <KEY_VOLUMEDOWN>; + wakeup-source; + }; + + key-vol-up { + debounce-interval = <15>; + gpios = <&pm8550_gpios 6 GPIO_ACTIVE_LOW>; + label = "Volume Up"; + linux,can-disable; + linux,code = <KEY_VOLUMEUP>; + wakeup-source; + }; + switch-lid { gpios = <&tlmm 2 GPIO_ACTIVE_LOW>; linux,input-type = <EV_SW>; @@ -314,6 +332,38 @@ sound { "VA DMIC0", "vdd-micb", "VA DMIC1", "vdd-micb"; + displayport-0-dai-link { + link-name = "DisplayPort0 Playback"; + + codec { + sound-dai = <&mdss_dp0>; + }; + + cpu { + sound-dai = <&q6apmbedai DISPLAY_PORT_RX_0>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + + displayport-1-dai-link { + link-name = "DisplayPort1 Playback"; + + codec { + sound-dai = <&mdss_dp1>; + }; + + cpu { + sound-dai = <&q6apmbedai DISPLAY_PORT_RX_1>; + }; + + platform { + sound-dai = <&q6apm>; + }; + }; + wsa-dai-link { link-name = "WSA Playback"; @@ -984,6 +1034,22 @@ &pcie6a_port0 { }; &pm8550_gpios { + vol_up_n: vol-up-n-state { + pins = "gpio6"; + function = "normal"; + bias-pull-up; + input-enable; + power-source = <1>; /* 1.8V */ + }; + + vol_down_n: vol-down-n-state { + pins = "gpio8"; + function = "normal"; + bias-pull-up; + input-enable; + power-source = <1>; /* 1.8V */ + }; + rtmr0_default: rtmr0-reset-n-active-state { pins = "gpio10"; function = "normal"; @@ -1107,6 +1173,27 @@ right_spkr: speaker@0,1 { }; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { gpio-reserved-ranges = <44 4>, /* SPI (TPM) */ <238 1>; /* UFS Reset */
diff --git a/arch/arm64/boot/dts/qcom/x1e001de-devkit.dts b/arch/arm64/boot/dts/qcom/x1e001de-devkit.dts index be1a8ac..e105db4 100644 --- a/arch/arm64/boot/dts/qcom/x1e001de-devkit.dts +++ b/arch/arm64/boot/dts/qcom/x1e001de-devkit.dts
@@ -1193,8 +1193,30 @@ wcd_tx: codec@0,3 { }; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { - gpio-reserved-ranges = <44 4>; /* SPI (TPM) */ + gpio-reserved-ranges = <44 4>, /* SPI (TPM) */ + <65 1>; /* EC reset */ eusb3_reset_n: eusb3-reset-n-state { pins = "gpio6";
diff --git a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi index 0bee2a3..93c7e3a 100644 --- a/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi +++ b/arch/arm64/boot/dts/qcom/x1e78100-lenovo-thinkpad-t14s.dtsi
@@ -1382,9 +1382,31 @@ wcd_tx: codec@0,3 { }; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { gpio-reserved-ranges = <34 2>, /* Unused */ <44 4>, /* SPI (TPM) */ + <65 1>, /* EC reset */ <72 2>, /* Secure EC I2C connection (?) */ <238 1>; /* UFS Reset */
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts index 429deff..29150fe 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-crd.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-crd.dts
@@ -11,6 +11,95 @@ / { model = "Qualcomm Technologies, Inc. X1E80100 CRD"; compatible = "qcom,x1e80100-crd", "qcom,x1e80100"; + + thermal-zones { + soc-thermal { + thermal-sensors = <&pmk8550_vadc ADC5_GEN3_AMUX1_GPIO_100K_PU(1)>; + }; + + keyboard-thermal { + critical-action = "shutdown"; + polling-delay-passive = <1000>; + + thermal-sensors = <&pmk8550_vadc ADC5_GEN3_AMUX2_GPIO_100K_PU(1)>; + + trips { + keyboard_alert0: trip-point0 { + temperature = <53000>; + hysteresis = <1000>; + type = "passive"; + }; + + keyboard-critical { + temperature = <73000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&keyboard_alert0>; + cooling-device = <&cpu0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu1 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu2 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu3 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu5 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu7 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu8 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu9 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu10 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>, + <&cpu11 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + backcover-thermal { + critical-action = "shutdown"; + polling-delay-passive = <400>; + + thermal-sensors = <&pmk8550_vadc ADC5_GEN3_AMUX1_THM_100K_PU(1)>; + + trips { + backcover_alert0: trip-point0 { + temperature = <64000>; + hysteresis = <1000>; + type = "passive"; + }; + + backcover-critical { + temperature = <73000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&backcover_alert0>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + smb-thermal { + thermal-sensors = <&pmk8550_vadc ADC5_GEN3_AMUX2_THM_100K_PU(1)>; + }; + + sdx-thermal { + thermal-sensors = <&pmk8550_vadc ADC5_GEN3_AMUX3_THM_100K_PU(1)>; + }; + + east-thermal { + thermal-sensors = <&pmk8550_vadc ADC5_GEN3_AMUX4_THM_100K_PU(1)>; + }; + + west-thermal { + thermal-sensors = <&pmk8550_vadc ADC5_GEN3_AMUX5_THM_100K_PU(1)>; + }; + }; }; &gpu_zap_shader { @@ -20,3 +109,33 @@ &gpu_zap_shader { &iris { status = "okay"; }; + +&pmk8550_vadc { + channel@144 { + qcom,adc-tm; + }; + + channel@145 { + qcom,adc-tm; + }; + + channel@146 { + qcom,adc-tm; + }; + + channel@147 { + qcom,adc-tm; + }; + + channel@148 { + qcom,adc-tm; + }; + + channel@14a { + qcom,adc-tm; + }; + + channel@14b { + qcom,adc-tm; + }; +};
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-dell-inspiron-14-plus-7441.dts b/arch/arm64/boot/dts/qcom/x1e80100-dell-inspiron-14-plus-7441.dts index 75e10d9..edbba51 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-dell-inspiron-14-plus-7441.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-dell-inspiron-14-plus-7441.dts
@@ -10,6 +10,18 @@ / { model = "Dell Inspiron 14 Plus 7441"; compatible = "dell,inspiron-14-plus-7441", "qcom,x1e80100"; + + backlight: backlight { + compatible = "pwm-backlight"; + pwms = <&pmk8550_pwm 0 5000000>; + + brightness-levels = <0 2048 4096 8192 16384 65535>; + num-interpolated-steps = <20>; + default-brightness-level = <80>; + + pinctrl-0 = <&edp_bl_pwm>; + pinctrl-names = "default"; + }; }; &sound { @@ -25,9 +37,9 @@ &gpu_zap_shader { }; &i2c8 { - touchscreen@10 { + touchscreen@9 { compatible = "hid-over-i2c"; - reg = <0x10>; + reg = <0x9>; hid-descr-addr = <0x1>; interrupts-extended = <&tlmm 51 IRQ_TYPE_LEVEL_LOW>; @@ -42,6 +54,21 @@ &iris { status = "okay"; }; +&panel { + backlight = <&backlight>; +}; + +&pmk8550_gpios { + edp_bl_pwm: edp-bl-pwm-state { + pins = "gpio5"; + function = "func3"; + }; +}; + +&pmk8550_pwm { + status = "okay"; +}; + &remoteproc_adsp { firmware-name = "qcom/x1e80100/dell/inspiron-14-plus-7441/qcadsp8380.mbn", "qcom/x1e80100/dell/inspiron-14-plus-7441/adsp_dtbs.elf";
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-dell-xps13-9345.dts b/arch/arm64/boot/dts/qcom/x1e80100-dell-xps13-9345.dts index 2be5a37..f48e6bc 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-dell-xps13-9345.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-dell-xps13-9345.dts
@@ -1069,9 +1069,31 @@ &smb2360_1_eusb2_repeater { vdd3-supply = <&vreg_l14b_3p0>; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p9>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p9>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { gpio-reserved-ranges = <44 4>, /* SPI11 (TPM) */ <76 4>, /* SPI19 (TZ Protected) */ + <65 1>, /* EC reset */ <238 1>; /* UFS Reset */ cam_indicator_en: cam-indicator-en-state {
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-honor-magicbook-art-14.dts b/arch/arm64/boot/dts/qcom/x1e80100-honor-magicbook-art-14.dts index b70c1e0..e5b285b 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-honor-magicbook-art-14.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-honor-magicbook-art-14.dts
@@ -1066,9 +1066,31 @@ right_tweeter: speaker@0,1 { }; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { gpio-reserved-ranges = <34 2>, /* Unused */ - <44 4>; /* SPI (TPM) */ + <44 4>, /* SPI (TPM) */ + <65 1>; /* EC reset */ tpad_default: tpad-default-state { pins = "gpio3";
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts b/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts index 9eb2dfd..a807744 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-lenovo-yoga-slim7x.dts
@@ -951,6 +951,22 @@ retimer_ss0_con_sbu_out: endpoint { }; }; +&i2c5 { + clock-frequency = <400000>; + + status = "okay"; + + embedded-controller@76 { + compatible = "lenovo,yoga-slim7x-ec", "qcom,hamoa-crd-ec"; + reg = <0x76>; + + interrupts-extended = <&tlmm 66 IRQ_TYPE_EDGE_FALLING>; + + pinctrl-0 = <&ec_int_n_default>; + pinctrl-names = "default"; + }; +}; + &i2c7 { clock-frequency = <400000>; @@ -1347,11 +1363,39 @@ right_tweeter: speaker@0,1 { }; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { gpio-reserved-ranges = <34 2>, /* Unused */ <44 4>, /* SPI (TPM) */ + <65 1>, /* EC reset */ <238 1>; /* UFS Reset */ + ec_int_n_default: ec-int-n-state { + pins = "gpio66"; + function = "gpio"; + bias-disable; + }; + edp_reg_en: edp-reg-en-state { pins = "gpio70"; function = "gpio";
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-medion-sprchrgd-14-s1.dts b/arch/arm64/boot/dts/qcom/x1e80100-medion-sprchrgd-14-s1.dts index e4a0b86..9b59991 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-medion-sprchrgd-14-s1.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-medion-sprchrgd-14-s1.dts
@@ -971,8 +971,6 @@ &mdss { }; &mdss_dp0 { - sound-name-prefix = "DisplayPort0"; - status = "okay"; }; @@ -981,8 +979,6 @@ &mdss_dp0_out { }; &mdss_dp2 { - sound-name-prefix = "DisplayPort2"; - status = "okay"; }; @@ -1248,9 +1244,31 @@ right_tweeter: speaker@0,1 { }; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p9>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p9>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { gpio-reserved-ranges = <28 4>, /* Unused */ <44 4>, /* SPI (TPM) */ + <65 1>, /* EC reset */ <238 1>; /* UFS Reset */ edp_reg_en: edp-reg-en-state {
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi b/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi index 13d0f09..9f45ad9 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi +++ b/arch/arm64/boot/dts/qcom/x1e80100-microsoft-romulus.dtsi
@@ -1322,6 +1322,27 @@ wcd_tx: codec@0,3 { }; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d>; + vdda-qreftx0-0p9-supply = <&vreg_l3j>; + vdda-qreftx0-1p2-supply = <&vreg_l2j>; + vdda-qreftx1-0p9-supply = <&vreg_l3j>; + vdda-qreftx1-1p2-supply = <&vreg_l3e>; + vdda-refgen0-0p9-supply = <&vreg_l3i>; + vdda-refgen0-1p2-supply = <&vreg_l3e>; + vdda-refgen2-0p9-supply = <&vreg_l3j>; + vdda-refgen2-1p2-supply = <&vreg_l2j>; +}; + &tlmm { gpio-reserved-ranges = <44 4>, /* SPI (TPM) */ <238 1>; /* UFS Reset */
diff --git a/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts b/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts index 78380fe..65f0d3b 100644 --- a/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts +++ b/arch/arm64/boot/dts/qcom/x1e80100-qcp.dts
@@ -1177,9 +1177,31 @@ wcd_tx: codec@0,3 { }; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { gpio-reserved-ranges = <33 3>, /* Unused */ <44 4>, /* SPI (TPM) */ + <65 1>, /* EC reset */ <238 1>; /* UFS Reset */ edp_reg_en: edp-reg-en-state {
diff --git a/arch/arm64/boot/dts/qcom/x1p42100-lenovo-thinkbook-16.dts b/arch/arm64/boot/dts/qcom/x1p42100-lenovo-thinkbook-16.dts index c2f21fc..9518888 100644 --- a/arch/arm64/boot/dts/qcom/x1p42100-lenovo-thinkbook-16.dts +++ b/arch/arm64/boot/dts/qcom/x1p42100-lenovo-thinkbook-16.dts
@@ -1325,8 +1325,30 @@ wcd_tx: codec@0,3 { }; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { gpio-reserved-ranges = <34 2>, /* Unused */ + <65 1>, /* EC reset */ <72 2>; /* Secure EC I2C connection (?) */ edp_hpd_default: edp-hpd-default-state {
diff --git a/arch/arm64/boot/dts/qcom/x1p42100-microsoft-sp12in.dts b/arch/arm64/boot/dts/qcom/x1p42100-microsoft-sp12in.dts index 0314b22..edcb6b9 100644 --- a/arch/arm64/boot/dts/qcom/x1p42100-microsoft-sp12in.dts +++ b/arch/arm64/boot/dts/qcom/x1p42100-microsoft-sp12in.dts
@@ -968,6 +968,27 @@ right_spkr: speaker@0,1 { }; }; +&tcsr { + vdda-qrefrpt0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrpt1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrpt3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrpt4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qrefrx0-0p9-supply = <&vreg_l3c_0p8>; + vdda-qrefrx1-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx2-0p9-supply = <&vreg_l3i_0p8>; + vdda-qrefrx3-0p9-supply = <&vreg_l3j_0p8>; + vdda-qrefrx4-0p9-supply = <&vreg_l1d_0p8>; + vdda-qreftx0-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx0-1p2-supply = <&vreg_l2j_1p2>; + vdda-qreftx1-0p9-supply = <&vreg_l3j_0p8>; + vdda-qreftx1-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen0-0p9-supply = <&vreg_l3i_0p8>; + vdda-refgen0-1p2-supply = <&vreg_l3e_1p2>; + vdda-refgen2-0p9-supply = <&vreg_l3j_0p8>; + vdda-refgen2-1p2-supply = <&vreg_l2j_1p2>; +}; + &tlmm { gpio-reserved-ranges = <34 2>, /* Unused */ <44 4>; /* SPI (TPM) */
diff --git a/arch/arm64/boot/dts/renesas/Makefile b/arch/arm64/boot/dts/renesas/Makefile index 8bf155b..c6f3718 100644 --- a/arch/arm64/boot/dts/renesas/Makefile +++ b/arch/arm64/boot/dts/renesas/Makefile
@@ -8,6 +8,9 @@ dtb-$(CONFIG_ARCH_R8A774A1) += r8a774a1-hihope-rzg2m-rev2-ex.dtb dtb-$(CONFIG_ARCH_R8A774A1) += r8a774a1-hihope-rzg2m-rev2-ex-idk-1110wr.dtb +dtb-$(CONFIG_ARCH_R8A774A3) += r8a774a3-hihope-rzg2m.dtb +dtb-$(CONFIG_ARCH_R8A774A3) += r8a774a3-hihope-rzg2m-ex.dtb + dtb-$(CONFIG_ARCH_R8A774B1) += r8a774b1-beacon-rzg2n-kit.dtb dtb-$(CONFIG_ARCH_R8A774B1) += r8a774b1-hihope-rzg2n.dtb dtb-$(CONFIG_ARCH_R8A774B1) += r8a774b1-hihope-rzg2n-ex.dtb @@ -124,6 +127,9 @@ dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-rpi-display-2-7in.dtbo r8a779g3-sparrow-hawk-rpi-display-2-7in-dtbs := r8a779g3-sparrow-hawk.dtb r8a779g3-sparrow-hawk-rpi-display-2-7in.dtbo dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-rpi-display-2-7in.dtb +dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-ws-2ch-canfd.dtbo +r8a779g3-sparrow-hawk-ws-2ch-canfd-dtbs := r8a779g3-sparrow-hawk.dtb r8a779g3-sparrow-hawk-ws-2ch-canfd.dtbo +dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-ws-2ch-canfd.dtb dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-ws-display-13in.dtbo r8a779g3-sparrow-hawk-ws-display-13in-dtbs := r8a779g3-sparrow-hawk.dtb r8a779g3-sparrow-hawk-ws-display-13in.dtbo dtb-$(CONFIG_ARCH_R8A779G0) += r8a779g3-sparrow-hawk-ws-display-13in.dtb @@ -164,18 +170,89 @@ dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043u11-smarc-du-adv7513.dtb r9a07g043u11-smarc-pmod-dtbs := r9a07g043u11-smarc.dtb r9a07g043-smarc-pmod.dtbo dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043u11-smarc-pmod.dtb +dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043u12-hummingboard-ripple.dtb +dtb-$(CONFIG_ARCH_R9A07G043) += rzg2l-sr-som-emmc.dtbo +r9a07g043u12-hummingboard-ripple-emmc-dtbs := r9a07g043u12-hummingboard-ripple.dtb rzg2l-sr-som-emmc.dtbo +dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043u12-hummingboard-ripple-emmc.dtb +dtb-$(CONFIG_ARCH_R9A07G043) += rzg2l-hummingboard-iiot-microsd.dtbo +dtb-$(CONFIG_ARCH_R9A07G043) += rzg2ul-hummingboard-pulse-leds.dtbo +r9a07g043u12-hummingboard-ripple-leds-dtbs := r9a07g043u12-hummingboard-ripple.dtb rzg2ul-hummingboard-pulse-leds.dtbo +dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043u12-hummingboard-ripple-leds.dtb +r9a07g043u12-hummingboard-ripple-microsd-dtbs := r9a07g043u12-hummingboard-ripple.dtb rzg2l-hummingboard-iiot-microsd.dtbo +dtb-$(CONFIG_ARCH_R9A07G043) += r9a07g043u12-hummingboard-ripple-microsd.dtb +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-hummingboard-iiot.dtb +r9a07g044c2-hummingboard-iiot-emmc-dtbs := r9a07g044c2-hummingboard-iiot.dtb rzg2l-sr-som-emmc.dtbo +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-hummingboard-iiot-emmc.dtb +r9a07g044c2-hummingboard-iiot-microsd-dtbs := r9a07g044c2-hummingboard-iiot.dtb rzg2l-hummingboard-iiot-microsd.dtbo +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-hummingboard-iiot-microsd.dtb +r9a07g044c2-hummingboard-iiot-panel-dsi-WJ70N3TYJHMNG0-dtbs := r9a07g044c2-hummingboard-iiot.dtb rzg2l-hummingboard-iiot-panel-dsi-WJ70N3TYJHMNG0.dtbo +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-hummingboard-iiot-panel-dsi-WJ70N3TYJHMNG0.dtb +r9a07g044c2-hummingboard-iiot-rs485-a-dtbs := r9a07g044c2-hummingboard-iiot.dtb rzg2l-hummingboard-iiot-rs485-a.dtbo +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-hummingboard-iiot-rs485-a.dtb +r9a07g044c2-hummingboard-iiot-rs485-b-dtbs := r9a07g044c2-hummingboard-iiot.dtb rzg2l-hummingboard-iiot-rs485-b.dtbo +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-hummingboard-iiot-rs485-b.dtb +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-hummingboard-ripple.dtb +r9a07g044c2-hummingboard-ripple-emmc-dtbs := r9a07g044c2-hummingboard-ripple.dtb rzg2l-sr-som-emmc.dtbo +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-hummingboard-ripple-emmc.dtb +dtb-$(CONFIG_ARCH_R9A07G044) += rzg2lc-hummingboard-pulse-leds.dtbo +r9a07g044c2-hummingboard-ripple-leds-dtbs := r9a07g044c2-hummingboard-ripple.dtb rzg2lc-hummingboard-pulse-leds.dtbo +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-hummingboard-ripple-leds.dtb +r9a07g044c2-hummingboard-ripple-microsd-dtbs := r9a07g044c2-hummingboard-ripple.dtb rzg2l-hummingboard-iiot-microsd.dtbo +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-hummingboard-ripple-microsd.dtb dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-smarc.dtb dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-smarc-cru-csi-ov5645.dtbo r9a07g044c2-smarc-cru-csi-ov5645-dtbs := r9a07g044c2-smarc.dtb r9a07g044c2-smarc-cru-csi-ov5645.dtbo dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044c2-smarc-cru-csi-ov5645.dtb +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-hummingboard-iiot.dtb +dtb-$(CONFIG_ARCH_R9A07G044) += rzg2l-sr-som-emmc.dtbo +r9a07g044l2-hummingboard-iiot-emmc-dtbs := r9a07g044l2-hummingboard-iiot.dtb rzg2l-sr-som-emmc.dtbo +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-hummingboard-iiot-emmc.dtb +dtb-$(CONFIG_ARCH_R9A07G044) += rzg2l-hummingboard-iiot-microsd.dtbo +r9a07g044l2-hummingboard-iiot-microsd-dtbs := r9a07g044l2-hummingboard-iiot.dtb rzg2l-hummingboard-iiot-microsd.dtbo +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-hummingboard-iiot-microsd.dtb +dtb-$(CONFIG_ARCH_R9A07G044) += rzg2l-hummingboard-iiot-panel-dsi-WJ70N3TYJHMNG0.dtbo +r9a07g044l2-hummingboard-iiot-panel-dsi-WJ70N3TYJHMNG0-dtbs := r9a07g044l2-hummingboard-iiot.dtb rzg2l-hummingboard-iiot-panel-dsi-WJ70N3TYJHMNG0.dtbo +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-hummingboard-iiot-panel-dsi-WJ70N3TYJHMNG0.dtb +dtb-$(CONFIG_ARCH_R9A07G044) += rzg2l-hummingboard-iiot-rs485-a.dtbo +r9a07g044l2-hummingboard-iiot-rs485-a-dtbs := r9a07g044l2-hummingboard-iiot.dtb rzg2l-hummingboard-iiot-rs485-a.dtbo +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-hummingboard-iiot-rs485-a.dtb +dtb-$(CONFIG_ARCH_R9A07G044) += rzg2l-hummingboard-iiot-rs485-b.dtbo +r9a07g044l2-hummingboard-iiot-rs485-b-dtbs := r9a07g044l2-hummingboard-iiot.dtb rzg2l-hummingboard-iiot-rs485-b.dtbo +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-hummingboard-iiot-rs485-b.dtb +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-hummingboard-ripple.dtb +r9a07g044l2-hummingboard-ripple-emmc-dtbs := r9a07g044l2-hummingboard-ripple.dtb rzg2l-sr-som-emmc.dtbo +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-hummingboard-ripple-emmc.dtb +r9a07g044l2-hummingboard-ripple-microsd-dtbs := r9a07g044l2-hummingboard-ripple.dtb rzg2l-hummingboard-iiot-microsd.dtbo +dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-hummingboard-ripple-microsd.dtb dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-remi-pi.dtb dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc.dtb dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc-cru-csi-ov5645.dtbo r9a07g044l2-smarc-cru-csi-ov5645-dtbs := r9a07g044l2-smarc.dtb r9a07g044l2-smarc-cru-csi-ov5645.dtbo dtb-$(CONFIG_ARCH_R9A07G044) += r9a07g044l2-smarc-cru-csi-ov5645.dtb +dtb-$(CONFIG_ARCH_R9A07G054) += r9a07g054l2-hummingboard-iiot.dtb +dtb-$(CONFIG_ARCH_R9A07G054) += rzg2l-sr-som-emmc.dtbo +r9a07g054l2-hummingboard-iiot-emmc-dtbs := r9a07g054l2-hummingboard-iiot.dtb rzg2l-sr-som-emmc.dtbo +dtb-$(CONFIG_ARCH_R9A07G054) += r9a07g054l2-hummingboard-iiot-emmc.dtb +dtb-$(CONFIG_ARCH_R9A07G054) += rzg2l-hummingboard-iiot-microsd.dtbo +r9a07g054l2-hummingboard-iiot-microsd-dtbs := r9a07g054l2-hummingboard-iiot.dtb rzg2l-hummingboard-iiot-microsd.dtbo +dtb-$(CONFIG_ARCH_R9A07G054) += r9a07g054l2-hummingboard-iiot-microsd.dtb +dtb-$(CONFIG_ARCH_R9A07G054) += rzg2l-hummingboard-iiot-panel-dsi-WJ70N3TYJHMNG0.dtbo +r9a07g054l2-hummingboard-iiot-panel-dsi-WJ70N3TYJHMNG0-dtbs := r9a07g054l2-hummingboard-iiot.dtb rzg2l-hummingboard-iiot-panel-dsi-WJ70N3TYJHMNG0.dtbo +dtb-$(CONFIG_ARCH_R9A07G054) += r9a07g054l2-hummingboard-iiot-panel-dsi-WJ70N3TYJHMNG0.dtb +dtb-$(CONFIG_ARCH_R9A07G054) += rzg2l-hummingboard-iiot-rs485-a.dtbo +r9a07g054l2-hummingboard-iiot-rs485-a-dtbs := r9a07g054l2-hummingboard-iiot.dtb rzg2l-hummingboard-iiot-rs485-a.dtbo +dtb-$(CONFIG_ARCH_R9A07G054) += r9a07g054l2-hummingboard-iiot-rs485-a.dtb +dtb-$(CONFIG_ARCH_R9A07G054) += rzg2l-hummingboard-iiot-rs485-b.dtbo +r9a07g054l2-hummingboard-iiot-rs485-b-dtbs := r9a07g054l2-hummingboard-iiot.dtb rzg2l-hummingboard-iiot-rs485-b.dtbo +dtb-$(CONFIG_ARCH_R9A07G054) += r9a07g054l2-hummingboard-iiot-rs485-b.dtb +dtb-$(CONFIG_ARCH_R9A07G054) += r9a07g054l2-hummingboard-ripple.dtb +r9a07g054l2-hummingboard-ripple-emmc-dtbs := r9a07g054l2-hummingboard-ripple.dtb rzg2l-sr-som-emmc.dtbo +dtb-$(CONFIG_ARCH_R9A07G054) += r9a07g054l2-hummingboard-ripple-emmc.dtb +r9a07g054l2-hummingboard-ripple-microsd-dtbs := r9a07g054l2-hummingboard-ripple.dtb rzg2l-hummingboard-iiot-microsd.dtbo +dtb-$(CONFIG_ARCH_R9A07G054) += r9a07g054l2-hummingboard-ripple-microsd.dtb dtb-$(CONFIG_ARCH_R9A07G054) += r9a07g054l2-smarc.dtb dtb-$(CONFIG_ARCH_R9A07G054) += r9a07g054l2-smarc-cru-csi-ov5645.dtbo r9a07g054l2-smarc-cru-csi-ov5645-dtbs := r9a07g054l2-smarc.dtb r9a07g054l2-smarc-cru-csi-ov5645.dtbo @@ -216,8 +293,14 @@ dtb-$(CONFIG_ARCH_R9A09G057) += r9a09g057h48-kakip-pixpaper.dtb dtb-$(CONFIG_ARCH_R9A09G077) += r9a09g077m44-rzt2h-evk.dtb +dtb-$(CONFIG_ARCH_R9A09G077) += r9a09g077m44-evk-cn15-lcdc.dtbo +r9a09g077m44-rzt2h-evk-cn15-lcdc-dtbs := r9a09g077m44-rzt2h-evk.dtb r9a09g077m44-evk-cn15-lcdc.dtbo +dtb-$(CONFIG_ARCH_R9A09G077) += r9a09g077m44-rzt2h-evk-cn15-lcdc.dtb dtb-$(CONFIG_ARCH_R9A09G087) += r9a09g087m44-rzn2h-evk.dtb +dtb-$(CONFIG_ARCH_R9A09G087) += r9a09g087m44-evk-cn20-lcdc.dtbo +r9a09g087m44-rzn2h-evk-cn20-lcdc-dtbs := r9a09g087m44-rzn2h-evk.dtb r9a09g087m44-evk-cn20-lcdc.dtbo +dtb-$(CONFIG_ARCH_R9A09G087) += r9a09g087m44-rzn2h-evk-cn20-lcdc.dtb dtb-$(CONFIG_ARCH_RCAR_GEN3) += draak-ebisu-panel-aa104xd12.dtbo dtb-$(CONFIG_ARCH_RCAR_GEN3) += salvator-panel-aa104xd12.dtbo
diff --git a/arch/arm64/boot/dts/renesas/aistarvision-mipi-adapter-2.1.dtsi b/arch/arm64/boot/dts/renesas/aistarvision-mipi-adapter-2.1.dtsi index 529388f6..c5db051 100644 --- a/arch/arm64/boot/dts/renesas/aistarvision-mipi-adapter-2.1.dtsi +++ b/arch/arm64/boot/dts/renesas/aistarvision-mipi-adapter-2.1.dtsi
@@ -54,7 +54,7 @@ imx219_vddl_1v2: 1p2v { regulator-always-on; }; - osc25250_clk: osc25250_clk { + osc25250_clk: clock-24000000 { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <24000000>;
diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi index 62ab0a3..9632538 100644 --- a/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi +++ b/arch/arm64/boot/dts/renesas/beacon-renesom-baseboard.dtsi
@@ -142,7 +142,7 @@ reg_cam1: regulator-cam1 { startup-delay-us = <100000>; }; - sound_card { + sound-card { compatible = "audio-graph-card"; label = "rcar-sound"; dais = <&rsnd_port0>, <&rsnd_port1>; @@ -505,7 +505,7 @@ sdhi0_pins: sd0 { power-source = <3300>; }; - sdhi0_pins_uhs: sd0_uhs { + sdhi0_pins_uhs: sd0-uhs { groups = "sdhi0_data4", "sdhi0_ctrl"; function = "sdhi0"; power-source = <1800>; @@ -516,7 +516,7 @@ sound_pins: sound { function = "ssi"; }; - sound_clk_pins: sound_clk { + sound_clk_pins: sound-clk { groups = "audio_clk_a_a", "audio_clk_b_a"; function = "audio_clk"; };
diff --git a/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi b/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi index f8442b6..8825131 100644 --- a/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi +++ b/arch/arm64/boot/dts/renesas/beacon-renesom-som.dtsi
@@ -13,7 +13,7 @@ memory@48000000 { reg = <0x0 0x48000000 0x0 0x78000000>; }; - osc_32k: osc_32k { + osc_32k: clock-32768 { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <32768>; @@ -38,7 +38,7 @@ reg_3p3v: regulator-3p3v { regulator-always-on; }; - wlan_pwrseq: wlan_pwrseq { + wlan_pwrseq: wlan-pwrseq { compatible = "mmc-pwrseq-simple"; reset-gpios = <&pca9654 1 GPIO_ACTIVE_LOW>; clocks = <&osc_32k>; @@ -63,6 +63,8 @@ phy0: ethernet-phy@0 { reg = <0>; interrupts-extended = <&gpio2 11 IRQ_TYPE_LEVEL_LOW>; reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>; + reset-assert-us = <10000>; + reset-deassert-us = <300>; }; }; @@ -209,12 +211,12 @@ mux { function = "avb"; }; - pins_mdio { + pins-mdio { groups = "avb_mdio"; drive-strength = <24>; }; - pins_mii_tx { + pins-mii-tx { pins = "PIN_AVB_TX_CTL", "PIN_AVB_TXC", "PIN_AVB_TD0", "PIN_AVB_TD1", "PIN_AVB_TD2", "PIN_AVB_TD3"; drive-strength = <12>; @@ -251,7 +253,7 @@ scif5_pins: scif5 { function = "scif5"; }; - scif_clk_pins: scif_clk { + scif_clk_pins: scif-clk { groups = "scif_clk_a"; function = "scif_clk"; };
diff --git a/arch/arm64/boot/dts/renesas/cat875.dtsi b/arch/arm64/boot/dts/renesas/cat875.dtsi index 5815e9d..196cf2e 100644 --- a/arch/arm64/boot/dts/renesas/cat875.dtsi +++ b/arch/arm64/boot/dts/renesas/cat875.dtsi
@@ -26,6 +26,8 @@ phy0: ethernet-phy@0 { reg = <0>; interrupts-extended = <&gpio2 21 IRQ_TYPE_LEVEL_LOW>; reset-gpios = <&gpio1 20 GPIO_ACTIVE_LOW>; + reset-assert-us = <15000>; + reset-deassert-us = <35000>; }; };
diff --git a/arch/arm64/boot/dts/renesas/condor-common.dtsi b/arch/arm64/boot/dts/renesas/condor-common.dtsi index 9d55509..953c5bb 100644 --- a/arch/arm64/boot/dts/renesas/condor-common.dtsi +++ b/arch/arm64/boot/dts/renesas/condor-common.dtsi
@@ -472,7 +472,7 @@ scif0_pins: scif0 { function = "scif0"; }; - scif_clk_pins: scif_clk { + scif_clk_pins: scif-clk { groups = "scif_clk_b"; function = "scif_clk"; };
diff --git a/arch/arm64/boot/dts/renesas/draak.dtsi b/arch/arm64/boot/dts/renesas/draak.dtsi index f2f25fe..3304629 100644 --- a/arch/arm64/boot/dts/renesas/draak.dtsi +++ b/arch/arm64/boot/dts/renesas/draak.dtsi
@@ -561,7 +561,7 @@ sdhi2_pins: sd2 { power-source = <1800>; }; - sdhi2_pins_uhs: sd2_uhs { + sdhi2_pins_uhs: sd2-uhs { groups = "mmc_data8", "mmc_ctrl"; function = "mmc"; power-source = <1800>;
diff --git a/arch/arm64/boot/dts/renesas/ebisu.dtsi b/arch/arm64/boot/dts/renesas/ebisu.dtsi index 4b3775a..842e1a5 100644 --- a/arch/arm64/boot/dts/renesas/ebisu.dtsi +++ b/arch/arm64/boot/dts/renesas/ebisu.dtsi
@@ -674,7 +674,7 @@ sdhi0_pins: sd0 { power-source = <3300>; }; - sdhi0_pins_uhs: sd0_uhs { + sdhi0_pins_uhs: sd0-uhs { groups = "sdhi0_data4", "sdhi0_ctrl"; function = "sdhi0"; power-source = <1800>; @@ -686,7 +686,7 @@ sdhi1_pins: sd1 { power-source = <3300>; }; - sdhi1_pins_uhs: sd1_uhs { + sdhi1_pins_uhs: sd1-uhs { groups = "sdhi1_data4", "sdhi1_ctrl"; function = "sdhi1"; power-source = <1800>; @@ -698,7 +698,7 @@ sdhi3_pins: sd3 { power-source = <1800>; }; - sound_clk_pins: sound_clk { + sound_clk_pins: sound-clk { groups = "audio_clk_a", "audio_clk_b_a", "audio_clk_c_a", "audio_clkout_a", "audio_clkout1_a"; function = "audio_clk";
diff --git a/arch/arm64/boot/dts/renesas/gray-hawk-single.dtsi b/arch/arm64/boot/dts/renesas/gray-hawk-single.dtsi index 2744937..da61333 100644 --- a/arch/arm64/boot/dts/renesas/gray-hawk-single.dtsi +++ b/arch/arm64/boot/dts/renesas/gray-hawk-single.dtsi
@@ -595,12 +595,12 @@ mux { function = "avb0"; }; - pins_mdio { + pins-mdio { groups = "avb0_mdio"; drive-strength = <21>; }; - pins_mii { + pins-mii { groups = "avb0_rgmii"; drive-strength = <21>; }; @@ -696,7 +696,7 @@ i2c3_pins: i2c3 { function = "i2c3"; }; - irq0_pins: irq0_pins { + irq0_pins: irq0 { groups = "intc_ex_irq0_a"; function = "intc_ex"; }; @@ -727,7 +727,7 @@ scif_clk2_pins: scif-clk2 { function = "scif_clk2"; }; - sound_clk_pins: sound_clk { + sound_clk_pins: sound-clk { groups = "audio_clkin", "audio_clkout"; function = "audio_clk"; };
diff --git a/arch/arm64/boot/dts/renesas/hihope-common.dtsi b/arch/arm64/boot/dts/renesas/hihope-common.dtsi index 4e78139..1999f97 100644 --- a/arch/arm64/boot/dts/renesas/hihope-common.dtsi +++ b/arch/arm64/boot/dts/renesas/hihope-common.dtsi
@@ -229,7 +229,7 @@ scif2_pins: scif2 { function = "scif2"; }; - scif_clk_pins: scif_clk { + scif_clk_pins: scif-clk { groups = "scif_clk_a"; function = "scif_clk"; }; @@ -240,7 +240,7 @@ sdhi0_pins: sd0 { power-source = <3300>; }; - sdhi0_pins_uhs: sd0_uhs { + sdhi0_pins_uhs: sd0-uhs { groups = "sdhi0_data4", "sdhi0_ctrl"; function = "sdhi0"; power-source = <1800>;
diff --git a/arch/arm64/boot/dts/renesas/hihope-rev2.dtsi b/arch/arm64/boot/dts/renesas/hihope-rev2.dtsi index 25c55b32..99ade27 100644 --- a/arch/arm64/boot/dts/renesas/hihope-rev2.dtsi +++ b/arch/arm64/boot/dts/renesas/hihope-rev2.dtsi
@@ -13,14 +13,14 @@ / { leds { compatible = "gpio-leds"; - bt_active_led { + bt-active-led { label = "blue:bt"; gpios = <&gpio7 0 GPIO_ACTIVE_HIGH>; linux,default-trigger = "hci0-power"; default-state = "off"; }; - wlan_active_led { + wlan-active-led { label = "yellow:wlan"; gpios = <&gpio7 1 GPIO_ACTIVE_HIGH>; linux,default-trigger = "phy0tx"; @@ -28,7 +28,7 @@ wlan_active_led { }; }; - wlan_en_reg: regulator-wlan_en { + wlan_en_reg: regulator-wlan-en { compatible = "regulator-fixed"; regulator-name = "wlan-en-regulator"; regulator-min-microvolt = <1800000>; @@ -57,7 +57,7 @@ gpio_expander: gpio@20 { }; &pfc { - sound_clk_pins: sound_clk { + sound_clk_pins: sound-clk { groups = "audio_clk_a_a"; function = "audio_clk"; };
diff --git a/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi b/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi index acce3c0..a26a985 100644 --- a/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi +++ b/arch/arm64/boot/dts/renesas/hihope-rev4.dtsi
@@ -20,7 +20,7 @@ audio_clkout: audio-clkout { clock-frequency = <12288000>; }; - wlan_en_reg: regulator-wlan_en { + wlan_en_reg: regulator-wlan-en { compatible = "regulator-fixed"; regulator-name = "wlan-en-regulator"; regulator-min-microvolt = <1800000>; @@ -68,7 +68,7 @@ i2c2_pins: i2c2 { function = "i2c2"; }; - sound_clk_pins: sound_clk { + sound_clk_pins: sound-clk { groups = "audio_clk_a_a", "audio_clk_b_a", "audio_clkout_a"; function = "audio_clk"; };
diff --git a/arch/arm64/boot/dts/renesas/hihope-rzg2-ex.dtsi b/arch/arm64/boot/dts/renesas/hihope-rzg2-ex.dtsi index 83b6c04..0878526 100644 --- a/arch/arm64/boot/dts/renesas/hihope-rzg2-ex.dtsi +++ b/arch/arm64/boot/dts/renesas/hihope-rzg2-ex.dtsi
@@ -28,6 +28,8 @@ phy0: ethernet-phy@0 { reg = <0>; interrupts-extended = <&gpio2 11 IRQ_TYPE_LEVEL_LOW>; reset-gpios = <&gpio2 10 GPIO_ACTIVE_LOW>; + reset-assert-us = <15000>; + reset-deassert-us = <35000>; }; }; @@ -57,12 +59,12 @@ mux { function = "avb"; }; - pins_mdio { + pins-mdio { groups = "avb_mdio"; drive-strength = <24>; }; - pins_mii_tx { + pins-mii-tx { pins = "PIN_AVB_TX_CTL", "PIN_AVB_TXC", "PIN_AVB_TD0", "PIN_AVB_TD1", "PIN_AVB_TD2", "PIN_AVB_TD3"; drive-strength = <12>;
diff --git a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi index e66d86d..5d50050 100644 --- a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi
@@ -21,19 +21,19 @@ / { * clocks by default. * Boards that provide audio clocks should override them. */ - audio_clk_a: audio_clk_a { + audio_clk_a: audio-clk-a { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_b: audio_clk_b { + audio_clk_b: audio-clk-b { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_c: audio_clk_c { + audio_clk_c: audio-clk-c { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; @@ -228,13 +228,13 @@ extalr_clk: extalr { }; /* External PCIe clock - can be overridden by the board */ - pcie_bus_clk: pcie_bus { + pcie_bus_clk: pcie-bus { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - pmu_a53 { + pmu-a53 { compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, @@ -243,7 +243,7 @@ pmu_a53 { interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, <&a53_3>; }; - pmu_a57 { + pmu-a57 { compatible = "arm,cortex-a57-pmu"; interrupts= <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; @@ -2877,7 +2877,7 @@ usb3s0_clk: usb3s0 { clock-frequency = <0>; }; - usb_extal_clk: usb_extal { + usb_extal_clk: usb-extal { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>;
diff --git a/arch/arm64/boot/dts/renesas/r8a774a3-hihope-rzg2m-ex.dts b/arch/arm64/boot/dts/renesas/r8a774a3-hihope-rzg2m-ex.dts new file mode 100644 index 0000000..d346a40 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a774a3-hihope-rzg2m-ex.dts
@@ -0,0 +1,14 @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/* + * Device Tree Source for the HiHope RZ/G2M v3.0 SoC sub board + * + * Copyright (C) 2026 Renesas Electronics Corp. + */ + +#include "r8a774a3-hihope-rzg2m.dts" + +/ { + model = "HopeRun HiHope RZ/G2M v3.0 with sub board"; + compatible = "hoperun,hihope-rzg2-ex", "hoperun,hihope-rzg2m", + "renesas,r8a774a3"; +};
diff --git a/arch/arm64/boot/dts/renesas/r8a774a3-hihope-rzg2m.dts b/arch/arm64/boot/dts/renesas/r8a774a3-hihope-rzg2m.dts new file mode 100644 index 0000000..4a4a09b --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a774a3-hihope-rzg2m.dts
@@ -0,0 +1,49 @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/* + * Device Tree Source for the HiHope RZ/G2M v3.0 SoC main board + * + * Copyright (C) 2026 Renesas Electronics Corp. + */ + +/dts-v1/; +#include "r8a774a3.dtsi" + +/ { + model = "HopeRun HiHope RZ/G2M v3.0 main board based on r8a774a3"; + compatible = "hoperun,hihope-rzg2m", "renesas,r8a774a3"; + + memory@48000000 { + device_type = "memory"; + /* First 128MiB is reserved for secure area */ + reg = <0x0 0x48000000 0x0 0x78000000>; + }; + + memory@600000000 { + device_type = "memory"; + reg = <0x6 0x00000000 0x0 0x80000000>; + }; + + aliases { + serial0 = &scif2; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&extal_clk { + clock-frequency = <16666666>; +}; + +&extalr_clk { + clock-frequency = <32768>; +}; + +&scif2 { + status = "okay"; +}; + +&scif_clk { + clock-frequency = <14745600>; +};
diff --git a/arch/arm64/boot/dts/renesas/r8a774a3.dtsi b/arch/arm64/boot/dts/renesas/r8a774a3.dtsi new file mode 100644 index 0000000..4a3af85 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a774a3.dtsi
@@ -0,0 +1,302 @@ +// SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +/* + * Device Tree Source for the r8a774a3 SoC + * + * Copyright (C) 2026 Renesas Electronics Corp. + */ + +#include <dt-bindings/clock/renesas,r8a774a3-cpg-mssr.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include <dt-bindings/interrupt-controller/arm-gic.h> +#include <dt-bindings/power/renesas,r8a774a3-sysc.h> + +/ { + compatible = "renesas,r8a774a3"; + #address-cells = <2>; + #size-cells = <2>; + interrupt-parent = <&gic>; + + cluster0_opp: opp-table-0 { + compatible = "operating-points-v2"; + opp-shared; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <820000>; + clock-latency-ns = <300000>; + }; + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <820000>; + clock-latency-ns = <300000>; + }; + opp-1500000000 { + opp-hz = /bits/ 64 <1500000000>; + opp-microvolt = <820000>; + clock-latency-ns = <300000>; + opp-suspend; + }; + }; + + cluster1_opp: opp-table-1 { + compatible = "operating-points-v2"; + opp-shared; + + opp-800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <820000>; + clock-latency-ns = <300000>; + }; + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <820000>; + clock-latency-ns = <300000>; + }; + opp-1200000000 { + opp-hz = /bits/ 64 <1200000000>; + opp-microvolt = <820000>; + clock-latency-ns = <300000>; + }; + }; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&a57_0>; + }; + core1 { + cpu = <&a57_1>; + }; + }; + + cluster1 { + core0 { + cpu = <&a53_0>; + }; + core1 { + cpu = <&a53_1>; + }; + core2 { + cpu = <&a53_2>; + }; + core3 { + cpu = <&a53_3>; + }; + }; + }; + + a57_0: cpu@0 { + compatible = "arm,cortex-a57"; + reg = <0x0>; + device_type = "cpu"; + power-domains = <&sysc R8A774A3_PD_CA57_CPU0>; + next-level-cache = <&L2_CA57>; + enable-method = "psci"; + dynamic-power-coefficient = <854>; + clocks = <&cpg CPG_CORE R8A774A3_CLK_Z>; + operating-points-v2 = <&cluster0_opp>; + capacity-dmips-mhz = <1024>; + }; + + a57_1: cpu@1 { + compatible = "arm,cortex-a57"; + reg = <0x1>; + device_type = "cpu"; + power-domains = <&sysc R8A774A3_PD_CA57_CPU1>; + next-level-cache = <&L2_CA57>; + enable-method = "psci"; + clocks = <&cpg CPG_CORE R8A774A3_CLK_Z>; + operating-points-v2 = <&cluster0_opp>; + capacity-dmips-mhz = <1024>; + }; + + a53_0: cpu@100 { + compatible = "arm,cortex-a53"; + reg = <0x100>; + device_type = "cpu"; + power-domains = <&sysc R8A774A3_PD_CA53_CPU0>; + next-level-cache = <&L2_CA53>; + enable-method = "psci"; + dynamic-power-coefficient = <277>; + clocks = <&cpg CPG_CORE R8A774A3_CLK_Z2>; + operating-points-v2 = <&cluster1_opp>; + capacity-dmips-mhz = <560>; + }; + + a53_1: cpu@101 { + compatible = "arm,cortex-a53"; + reg = <0x101>; + device_type = "cpu"; + power-domains = <&sysc R8A774A3_PD_CA53_CPU1>; + next-level-cache = <&L2_CA53>; + enable-method = "psci"; + clocks = <&cpg CPG_CORE R8A774A3_CLK_Z2>; + operating-points-v2 = <&cluster1_opp>; + capacity-dmips-mhz = <560>; + }; + + a53_2: cpu@102 { + compatible = "arm,cortex-a53"; + reg = <0x102>; + device_type = "cpu"; + power-domains = <&sysc R8A774A3_PD_CA53_CPU2>; + next-level-cache = <&L2_CA53>; + enable-method = "psci"; + clocks = <&cpg CPG_CORE R8A774A3_CLK_Z2>; + operating-points-v2 = <&cluster1_opp>; + capacity-dmips-mhz = <560>; + }; + + a53_3: cpu@103 { + compatible = "arm,cortex-a53"; + reg = <0x103>; + device_type = "cpu"; + power-domains = <&sysc R8A774A3_PD_CA53_CPU3>; + next-level-cache = <&L2_CA53>; + enable-method = "psci"; + clocks = <&cpg CPG_CORE R8A774A3_CLK_Z2>; + operating-points-v2 = <&cluster1_opp>; + capacity-dmips-mhz = <560>; + }; + + L2_CA57: cache-controller-0 { + compatible = "cache"; + power-domains = <&sysc R8A774A3_PD_CA57_SCU>; + cache-unified; + cache-level = <2>; + }; + + L2_CA53: cache-controller-1 { + compatible = "cache"; + power-domains = <&sysc R8A774A3_PD_CA53_SCU>; + cache-unified; + cache-level = <2>; + }; + }; + + extal_clk: extal { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board */ + clock-frequency = <0>; + bootph-all; + }; + + extalr_clk: extalr { + compatible = "fixed-clock"; + #clock-cells = <0>; + /* This value must be overridden by the board */ + clock-frequency = <0>; + bootph-all; + }; + + pmu-a53 { + compatible = "arm,cortex-a53-pmu"; + interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, <&a53_3>; + }; + + pmu-a57 { + compatible = "arm,cortex-a57-pmu"; + interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; + interrupt-affinity = <&a57_0>, <&a57_1>; + }; + + psci { + compatible = "arm,psci-1.0", "arm,psci-0.2"; + method = "smc"; + }; + + /* External SCIF clock - to be overridden by boards that provide it */ + scif_clk: scif { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <0>; + }; + + soc: soc { + compatible = "simple-bus"; + bootph-all; + + #address-cells = <2>; + #size-cells = <2>; + ranges; + + cpg: clock-controller@e6150000 { + compatible = "renesas,r8a774a3-cpg-mssr"; + reg = <0 0xe6150000 0 0x1000>; + clocks = <&extal_clk>, <&extalr_clk>; + clock-names = "extal", "extalr"; + #clock-cells = <2>; + #power-domain-cells = <0>; + #reset-cells = <1>; + bootph-all; + }; + + rst: reset-controller@e6160000 { + compatible = "renesas,r8a774a3-rst"; + reg = <0 0xe6160000 0 0x200>; + bootph-all; + }; + + sysc: system-controller@e6180000 { + compatible = "renesas,r8a774a3-sysc"; + reg = <0 0xe6180000 0 0x400>; + #power-domain-cells = <1>; + }; + + scif2: serial@e6e88000 { + compatible = "renesas,scif-r8a774a3", + "renesas,rcar-gen3-scif", "renesas,scif"; + reg = <0 0xe6e88000 0 0x40>; + interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 310>, + <&cpg CPG_CORE R8A774A3_CLK_S3D1>, + <&scif_clk>; + clock-names = "fck", "brg_int", "scif_clk"; + power-domains = <&sysc R8A774A3_PD_ALWAYS_ON>; + resets = <&cpg 310>; + status = "disabled"; + }; + + gic: interrupt-controller@f1010000 { + compatible = "arm,gic-400"; + #interrupt-cells = <3>; + #address-cells = <0>; + interrupt-controller; + reg = <0x0 0xf1010000 0 0x1000>, + <0x0 0xf1020000 0 0x20000>, + <0x0 0xf1040000 0 0x20000>, + <0x0 0xf1060000 0 0x20000>; + interrupts = <GIC_PPI 9 + (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_HIGH)>; + clocks = <&cpg CPG_MOD 408>; + clock-names = "clk"; + power-domains = <&sysc R8A774A3_PD_ALWAYS_ON>; + resets = <&cpg 408>; + }; + + prr: chipid@fff00044 { + compatible = "renesas,prr"; + reg = <0 0xfff00044 0 4>; + bootph-all; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>, + <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(6) | IRQ_TYPE_LEVEL_LOW)>; + interrupt-names = "sec-phys", "phys", "virt", "hyp-phys"; + }; +};
diff --git a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi index 62c6703..e0d593c 100644 --- a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi
@@ -21,19 +21,19 @@ / { * clocks by default. * Boards that provide audio clocks should override them. */ - audio_clk_a: audio_clk_a { + audio_clk_a: audio-clk-a { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_b: audio_clk_b { + audio_clk_b: audio-clk-b { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_c: audio_clk_c { + audio_clk_c: audio-clk-c { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; @@ -121,13 +121,13 @@ extalr_clk: extalr { }; /* External PCIe clock - can be overridden by the board */ - pcie_bus_clk: pcie_bus { + pcie_bus_clk: pcie-bus { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - pmu_a57 { + pmu-a57 { compatible = "arm,cortex-a57-pmu"; interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; @@ -2748,7 +2748,7 @@ usb3s0_clk: usb3s0 { clock-frequency = <0>; }; - usb_extal_clk: usb_extal { + usb_extal_clk: usb-extal { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>;
diff --git a/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts b/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts index 57a281f..4be3f82 100644 --- a/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts +++ b/arch/arm64/boot/dts/renesas/r8a774c0-cat874.dts
@@ -322,7 +322,7 @@ sdhi0_pins: sd0 { power-source = <3300>; }; - sdhi0_pins_uhs: sd0_uhs { + sdhi0_pins_uhs: sd0-uhs { groups = "sdhi0_data4", "sdhi0_ctrl"; function = "sdhi0"; power-source = <1800>; @@ -334,7 +334,7 @@ sdhi3_pins: sd3 { power-source = <1800>; }; - sound_clk_pins: sound_clk { + sound_clk_pins: sound-clk { groups = "audio_clkout1_a"; function = "audio_clk"; };
diff --git a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi index 3858f43..37313f5 100644 --- a/arch/arm64/boot/dts/renesas/r8a774c0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774c0.dtsi
@@ -20,19 +20,19 @@ / { * clocks by default. * Boards that provide audio clocks should override them. */ - audio_clk_a: audio_clk_a { + audio_clk_a: audio-clk-a { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_b: audio_clk_b { + audio_clk_b: audio-clk-b { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_c: audio_clk_c { + audio_clk_c: audio-clk-c { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; @@ -112,13 +112,13 @@ extal_clk: extal { }; /* External PCIe clock - can be overridden by the board */ - pcie_bus_clk: pcie_bus { + pcie_bus_clk: pcie-bus { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - pmu_a53 { + pmu-a53 { compatible = "arm,cortex-a53-pmu"; interrupts= <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>; @@ -2014,7 +2014,7 @@ usb3s0_clk: usb3s0 { clock-frequency = <0>; }; - usb_extal_clk: usb_extal { + usb_extal_clk: usb-extal { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>;
diff --git a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi index 0ae9bb7..335b94d 100644 --- a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi
@@ -21,19 +21,19 @@ / { * clocks by default. * Boards that provide audio clocks should override them. */ - audio_clk_a: audio_clk_a { + audio_clk_a: audio-clk-a { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_b: audio_clk_b { + audio_clk_b: audio-clk-b { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_c: audio_clk_c { + audio_clk_c: audio-clk-c { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; @@ -290,13 +290,13 @@ extalr_clk: extalr { }; /* External PCIe clock - can be overridden by the board */ - pcie_bus_clk: pcie_bus { + pcie_bus_clk: pcie-bus { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - pmu_a53 { + pmu-a53 { compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, @@ -305,7 +305,7 @@ pmu_a53 { interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, <&a53_3>; }; - pmu_a57 { + pmu-a57 { compatible = "arm,cortex-a57-pmu"; interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>, @@ -3011,7 +3011,7 @@ usb3s0_clk: usb3s0 { clock-frequency = <0>; }; - usb_extal_clk: usb_extal { + usb_extal_clk: usb-extal { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77951.dtsi b/arch/arm64/boot/dts/renesas/r8a77951.dtsi index 59a0f2e..a08b160 100644 --- a/arch/arm64/boot/dts/renesas/r8a77951.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77951.dtsi
@@ -25,19 +25,19 @@ / { * clocks by default. * Boards that provide audio clocks should override them. */ - audio_clk_a: audio_clk_a { + audio_clk_a: audio-clk-a { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_b: audio_clk_b { + audio_clk_b: audio-clk-b { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_c: audio_clk_c { + audio_clk_c: audio-clk-c { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; @@ -305,13 +305,13 @@ extalr_clk: extalr { }; /* External PCIe clock - can be overridden by the board */ - pcie_bus_clk: pcie_bus { + pcie_bus_clk: pcie-bus { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - pmu_a53 { + pmu-a53 { compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, @@ -323,7 +323,7 @@ pmu_a53 { <&a53_3>; }; - pmu_a57 { + pmu-a57 { compatible = "arm,cortex-a57-pmu"; interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>, @@ -3520,7 +3520,7 @@ usb3s0_clk: usb3s0 { clock-frequency = <0>; }; - usb_extal_clk: usb_extal { + usb_extal_clk: usb-extal { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77960.dtsi b/arch/arm64/boot/dts/renesas/r8a77960.dtsi index 4f9989b..cdbb7f9 100644 --- a/arch/arm64/boot/dts/renesas/r8a77960.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77960.dtsi
@@ -20,19 +20,19 @@ / { * clocks by default. * Boards that provide audio clocks should override them. */ - audio_clk_a: audio_clk_a { + audio_clk_a: audio-clk-a { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_b: audio_clk_b { + audio_clk_b: audio-clk-b { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_c: audio_clk_c { + audio_clk_c: audio-clk-c { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; @@ -277,13 +277,13 @@ extalr_clk: extalr { }; /* External PCIe clock - can be overridden by the board */ - pcie_bus_clk: pcie_bus { + pcie_bus_clk: pcie-bus { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - pmu_a53 { + pmu-a53 { compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, @@ -292,7 +292,7 @@ pmu_a53 { interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, <&a53_3>; }; - pmu_a57 { + pmu-a57 { compatible = "arm,cortex-a57-pmu"; interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; @@ -3135,7 +3135,7 @@ usb3s0_clk: usb3s0 { clock-frequency = <0>; }; - usb_extal_clk: usb_extal { + usb_extal_clk: usb-extal { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi b/arch/arm64/boot/dts/renesas/r8a77961.dtsi index ad4491b..38f34c5c 100644 --- a/arch/arm64/boot/dts/renesas/r8a77961.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77961.dtsi
@@ -20,19 +20,19 @@ / { * clocks by default. * Boards that provide audio clocks should override them. */ - audio_clk_a: audio_clk_a { + audio_clk_a: audio-clk-a { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_b: audio_clk_b { + audio_clk_b: audio-clk-b { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_c: audio_clk_c { + audio_clk_c: audio-clk-c { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; @@ -277,13 +277,13 @@ extalr_clk: extalr { }; /* External PCIe clock - can be overridden by the board */ - pcie_bus_clk: pcie_bus { + pcie_bus_clk: pcie-bus { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - pmu_a53 { + pmu-a53 { compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>, @@ -292,7 +292,7 @@ pmu_a53 { interrupt-affinity = <&a53_0>, <&a53_1>, <&a53_2>, <&a53_3>; }; - pmu_a57 { + pmu-a57 { compatible = "arm,cortex-a57-pmu"; interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; @@ -2956,7 +2956,7 @@ usb3s0_clk: usb3s0 { clock-frequency = <0>; }; - usb_extal_clk: usb_extal { + usb_extal_clk: usb-extal { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi index 70708f5..52376c6 100644 --- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi
@@ -25,19 +25,19 @@ / { * clocks by default. * Boards that provide audio clocks should override them. */ - audio_clk_a: audio_clk_a { + audio_clk_a: audio-clk-a { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_b: audio_clk_b { + audio_clk_b: audio-clk-b { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_c: audio_clk_c { + audio_clk_c: audio-clk-c { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; @@ -156,13 +156,13 @@ extalr_clk: extalr { }; /* External PCIe clock - can be overridden by the board */ - pcie_bus_clk: pcie_bus { + pcie_bus_clk: pcie-bus { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - pmu_a57 { + pmu-a57 { compatible = "arm,cortex-a57-pmu"; interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>; @@ -2964,7 +2964,7 @@ usb3s0_clk: usb3s0 { clock-frequency = <0>; }; - usb_extal_clk: usb_extal { + usb_extal_clk: usb-extal { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso b/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso index ecb3525..a9ad009 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso +++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle-function-expansion.dtso
@@ -112,7 +112,7 @@ video-receiver@70 { reg = <0x70 0x71 0x72 0x73 0x74 0x75 0x60 0x61 0x62 0x63 0x64 0x65>; reg-names = "main", "dpll", "cp", "hdmi", "edid", "repeater", - "infoframe", "cbus", "cec", "sdp", "txa", "txb" ; + "infoframe", "cbus", "cec", "sdp", "txa", "txb"; interrupts-extended = <&gpio3 3 IRQ_TYPE_LEVEL_LOW>, <&gpio3 4 IRQ_TYPE_LEVEL_LOW>; interrupt-names = "intrq1", "intrq2";
diff --git a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts index a2ad79d..be0ee054 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts +++ b/arch/arm64/boot/dts/renesas/r8a77970-eagle.dts
@@ -335,7 +335,7 @@ scif0_pins: scif0 { function = "scif0"; }; - scif_clk_pins: scif_clk { + scif_clk_pins: scif-clk { groups = "scif_clk_b"; function = "scif_clk"; };
diff --git a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts index 10c9a2e..f184fa9 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts +++ b/arch/arm64/boot/dts/renesas/r8a77970-v3msk.dts
@@ -215,7 +215,7 @@ i2c0_pins: i2c0 { function = "i2c0"; }; - mmc_pins: mmc_3_3v { + mmc_pins: mmc-3-3v { groups = "mmc_data8", "mmc_ctrl"; function = "mmc"; power-source = <3300>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77970.dtsi b/arch/arm64/boot/dts/renesas/r8a77970.dtsi index f7f1f28..3eb519b 100644 --- a/arch/arm64/boot/dts/renesas/r8a77970.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77970.dtsi
@@ -72,7 +72,7 @@ extalr_clk: extalr { bootph-all; }; - pmu_a53 { + pmu-a53 { compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts index 52462e6..32b5ea7 100644 --- a/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts +++ b/arch/arm64/boot/dts/renesas/r8a77980-v3hsk.dts
@@ -207,7 +207,7 @@ scif0_pins: scif0 { function = "scif0"; }; - scif_clk_pins: scif_clk { + scif_clk_pins: scif-clk { groups = "scif_clk_b"; function = "scif_clk"; };
diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi index 514dafe..1df6d3d 100644 --- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi
@@ -93,13 +93,13 @@ extalr_clk: extalr { }; /* External PCIe clock - can be overridden by the board */ - pcie_bus_clk: pcie_bus { + pcie_bus_clk: pcie-bus { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - pmu_a53 { + pmu-a53 { compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/renesas/r8a77990.dtsi b/arch/arm64/boot/dts/renesas/r8a77990.dtsi index fadb5f4..0e9b837 100644 --- a/arch/arm64/boot/dts/renesas/r8a77990.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77990.dtsi
@@ -20,19 +20,19 @@ / { * clocks by default. * Boards that provide audio clocks should override them. */ - audio_clk_a: audio_clk_a { + audio_clk_a: audio-clk-a { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_b: audio_clk_b { + audio_clk_b: audio-clk-b { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_c: audio_clk_c { + audio_clk_c: audio-clk-c { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; @@ -127,13 +127,13 @@ extal_clk: extal { }; /* External PCIe clock - can be overridden by the board */ - pcie_bus_clk: pcie_bus { + pcie_bus_clk: pcie-bus { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - pmu_a53 { + pmu-a53 { compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
diff --git a/arch/arm64/boot/dts/renesas/r8a77995.dtsi b/arch/arm64/boot/dts/renesas/r8a77995.dtsi index 522a49d..a20fff9 100644 --- a/arch/arm64/boot/dts/renesas/r8a77995.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a77995.dtsi
@@ -21,13 +21,13 @@ / { * clocks by default. * Boards that provide audio clocks should override them. */ - audio_clk_a: audio_clk_a { + audio_clk_a: audio-clk-a { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; }; - audio_clk_b: audio_clk_b { + audio_clk_b: audio-clk-b { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; @@ -69,7 +69,7 @@ extal_clk: extal { bootph-all; }; - pmu_a53 { + pmu-a53 { compatible = "arm,cortex-a53-pmu"; interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>; };
diff --git a/arch/arm64/boot/dts/renesas/r8a779a0-falcon-cpu.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0-falcon-cpu.dtsi index 0916fd5..2675f48 100644 --- a/arch/arm64/boot/dts/renesas/r8a779a0-falcon-cpu.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779a0-falcon-cpu.dtsi
@@ -306,7 +306,7 @@ scif0_pins: scif0 { function = "scif0"; }; - scif_clk_pins: scif_clk { + scif_clk_pins: scif-clk { groups = "scif_clk"; function = "scif_clk"; };
diff --git a/arch/arm64/boot/dts/renesas/r8a779a0-falcon.dts b/arch/arm64/boot/dts/renesas/r8a779a0-falcon.dts index ea5dcee..5708e39 100644 --- a/arch/arm64/boot/dts/renesas/r8a779a0-falcon.dts +++ b/arch/arm64/boot/dts/renesas/r8a779a0-falcon.dts
@@ -73,12 +73,12 @@ mux { function = "avb0"; }; - pins_mdio { + pins-mdio { groups = "avb0_mdio"; drive-strength = <21>; }; - pins_mii { + pins-mii { groups = "avb0_rgmii"; drive-strength = <21>; };
diff --git a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi index 0483a5d..38f35c8 100644 --- a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi
@@ -59,7 +59,7 @@ extalr_clk: extalr { bootph-all; }; - pmu_a76 { + pmu-a76 { compatible = "arm,cortex-a76-pmu"; interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; };
diff --git a/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi index 1781bb7..0cfbff5 100644 --- a/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779f0-spider-cpu.dtsi
@@ -206,7 +206,7 @@ scif0_pins: scif0 { function = "scif0"; }; - scif_clk_pins: scif_clk { + scif_clk_pins: scif-clk { groups = "scif_clk"; function = "scif_clk"; };
diff --git a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi index a5118c2..17a6327 100644 --- a/arch/arm64/boot/dts/renesas/r8a779f0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779f0.dtsi
@@ -279,7 +279,7 @@ pcie1_clkref: pcie1-clkref { clock-frequency = <0>; }; - pmu_a55 { + pmu-a55 { compatible = "arm,cortex-a55-pmu"; interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; }; @@ -790,9 +790,11 @@ pciec0: pcie@e65d0000 { clocks = <&cpg CPG_MOD 624>, <&pcie0_clkref>; clock-names = "core", "ref"; power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>; - resets = <&cpg 624>; - reset-names = "pwr"; + resets = <&cpg 624>, <&cpg 1121>; + reset-names = "pwr", "core"; max-link-speed = <4>; + msi-parent = <&its 0>; + msi-map = <0x0 &its 0x0 0x10000>; num-lanes = <2>; #address-cells = <3>; #size-cells = <2>; @@ -803,10 +805,10 @@ pciec0: pcie@e65d0000 { dma-ranges = <0x42000000 0 0x00000000 0 0x00000000 1 0x00000000>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &gic GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 2 &gic GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 3 &gic GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 4 &gic GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 416 IRQ_TYPE_LEVEL_HIGH>; snps,enable-cdm-check; status = "disabled"; }; @@ -827,9 +829,11 @@ pciec1: pcie@e65d8000 { clocks = <&cpg CPG_MOD 625>, <&pcie1_clkref>; clock-names = "core", "ref"; power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>; - resets = <&cpg 625>; - reset-names = "pwr"; + resets = <&cpg 625>, <&cpg 1122>; + reset-names = "pwr", "core"; max-link-speed = <4>; + msi-parent = <&its 0>; + msi-map = <0x0 &its 0x0 0x10000>; num-lanes = <2>; #address-cells = <3>; #size-cells = <2>; @@ -840,10 +844,10 @@ pciec1: pcie@e65d8000 { dma-ranges = <0x42000000 0 0x00000000 0 0x00000000 1 0x00000000>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &gic GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 2 &gic GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 3 &gic GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 4 &gic GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 423 IRQ_TYPE_LEVEL_HIGH>; snps,enable-cdm-check; status = "disabled"; }; @@ -863,8 +867,8 @@ pciec0_ep: pcie-ep@e65d0000 { clocks = <&cpg CPG_MOD 624>, <&pcie0_clkref>; clock-names = "core", "ref"; power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>; - resets = <&cpg 624>; - reset-names = "pwr"; + resets = <&cpg 624>, <&cpg 1121>; + reset-names = "pwr", "core"; max-link-speed = <4>; num-lanes = <2>; max-functions = /bits/ 8 <2>; @@ -886,8 +890,8 @@ pciec1_ep: pcie-ep@e65d8000 { clocks = <&cpg CPG_MOD 625>, <&pcie1_clkref>; clock-names = "core", "ref"; power-domains = <&sysc R8A779F0_PD_ALWAYS_ON>; - resets = <&cpg 625>; - reset-names = "pwr"; + resets = <&cpg 625>, <&cpg 1122>; + reset-names = "pwr", "core"; max-link-speed = <4>; num-lanes = <2>; max-functions = /bits/ 8 <2>; @@ -1291,11 +1295,23 @@ ipmmu_mm: iommu@eefc0000 { gic: interrupt-controller@f1000000 { compatible = "arm,gic-v3"; #interrupt-cells = <3>; - #address-cells = <0>; + #address-cells = <2>; + #size-cells = <2>; interrupt-controller; reg = <0x0 0xf1000000 0 0x20000>, <0x0 0xf1060000 0 0x110000>; interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + dma-noncoherent; + + ranges = <0x0 0x0 0x0 0xf1000000 0x0 0x200000>; + + its: msi-controller@40000 { + compatible = "arm,gic-v3-its"; + reg = <0x0 0x40000 0x0 0x20000>; + dma-noncoherent; + msi-controller; + #msi-cells = <1>; + }; }; wwdt0: watchdog@ffc90000 {
diff --git a/arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts b/arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts index 67b18f2..a0fd7f3 100644 --- a/arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts +++ b/arch/arm64/boot/dts/renesas/r8a779f4-s4sk.dts
@@ -151,7 +151,7 @@ i2c5_pins: i2c5 { function = "i2c5"; }; - scif_clk_pins: scif_clk { + scif_clk_pins: scif-clk { groups = "scif_clk"; function = "scif_clk"; };
diff --git a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk.dts b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk.dts index 784d4e8..89d60b83 100644 --- a/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk.dts +++ b/arch/arm64/boot/dts/renesas/r8a779g0-white-hawk.dts
@@ -12,4 +12,98 @@ / { model = "Renesas White Hawk CPU and Breakout boards based on r8a779g0"; compatible = "renesas,white-hawk-breakout", "renesas,white-hawk-cpu", "renesas,r8a779g0"; + + sn65dsi86_refclk2: clk-x16 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <38400000>; + }; + + mini-dp-con2 { + compatible = "dp-connector"; + label = "CN15"; + type = "mini"; + + port { + mini_dp_con_in2: endpoint { + remote-endpoint = <&sn65dsi86_out2>; + }; + }; + }; +}; + +&dsc { + status = "okay"; +}; + +&dsi1 { + status = "okay"; + + ports { + port@1 { + dsi1_out: endpoint { + remote-endpoint = <&sn65dsi86_in2>; + data-lanes = <1 2 3 4>; + }; + }; + }; +}; + +&i2c4 { + pinctrl-0 = <&i2c4_pins>; + pinctrl-names = "default"; + + status = "okay"; + clock-frequency = <400000>; + + bridge@2c { + pinctrl-0 = <&irq1_pins>; + pinctrl-names = "default"; + + compatible = "ti,sn65dsi86"; + reg = <0x2c>; + + clocks = <&sn65dsi86_refclk2>; + clock-names = "refclk"; + + interrupts-extended = <&intc_ex 1 IRQ_TYPE_LEVEL_HIGH>; + + enable-gpios = <&gpio1 27 GPIO_ACTIVE_HIGH>; + + vccio-supply = <®_1p8v>; + vpll-supply = <®_1p8v>; + vcca-supply = <®_1p2v>; + vcc-supply = <®_1p2v>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + sn65dsi86_in2: endpoint { + remote-endpoint = <&dsi1_out>; + }; + }; + + port@1 { + reg = <1>; + sn65dsi86_out2: endpoint { + remote-endpoint = <&mini_dp_con_in2>; + }; + }; + }; + }; +}; + +&pfc { + i2c4_pins: i2c4 { + groups = "i2c4"; + function = "i2c4"; + }; + + irq1_pins: irq1 { + groups = "intc_ex_irq1_a"; + function = "intc_ex"; + }; };
diff --git a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi index 8a29144..5284923 100644 --- a/arch/arm64/boot/dts/renesas/r8a779g0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779g0.dtsi
@@ -16,7 +16,7 @@ / { interrupt-parent = <&gic>; /* External Audio clock - to be overridden by boards that provide it */ - audio_clkin: audio_clkin { + audio_clkin: audio-clkin { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; @@ -192,7 +192,7 @@ pcie1_clkref: pcie1-clkref { clock-frequency = <0>; }; - pmu_a76 { + pmu-a76 { compatible = "arm,cortex-a76-pmu"; interrupts = <GIC_PPI 7 IRQ_TYPE_LEVEL_LOW>; }; @@ -806,9 +806,11 @@ pciec0: pcie@e65d0000 { clocks = <&cpg CPG_MOD 624>, <&pcie0_clkref>; clock-names = "core", "ref"; power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>; - resets = <&cpg 624>; - reset-names = "pwr"; + resets = <&cpg 624>, <&cpg 1121>; + reset-names = "pwr", "core"; max-link-speed = <4>; + msi-parent = <&its 0>; + msi-map = <0x0 &its 0x0 0x10000>; num-lanes = <2>; #address-cells = <3>; #size-cells = <2>; @@ -819,10 +821,10 @@ pciec0: pcie@e65d0000 { dma-ranges = <0x42000000 0 0x00000000 0 0x00000000 1 0x00000000>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &gic GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 2 &gic GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 3 &gic GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 4 &gic GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>; snps,enable-cdm-check; status = "disabled"; @@ -853,9 +855,11 @@ pciec1: pcie@e65d8000 { clocks = <&cpg CPG_MOD 625>, <&pcie1_clkref>; clock-names = "core", "ref"; power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>; - resets = <&cpg 625>; - reset-names = "pwr"; + resets = <&cpg 625>, <&cpg 1122>; + reset-names = "pwr", "core"; max-link-speed = <4>; + msi-parent = <&its 0>; + msi-map = <0x0 &its 0x0 0x10000>; num-lanes = <2>; #address-cells = <3>; #size-cells = <2>; @@ -866,10 +870,10 @@ pciec1: pcie@e65d8000 { dma-ranges = <0x42000000 0 0x00000000 0 0x00000000 1 0x00000000>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &gic GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 2 &gic GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 3 &gic GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 4 &gic GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>; snps,enable-cdm-check; status = "disabled"; @@ -899,8 +903,8 @@ pciec0_ep: pcie-ep@e65d0000 { clocks = <&cpg CPG_MOD 624>, <&pcie0_clkref>; clock-names = "core", "ref"; power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>; - resets = <&cpg 624>; - reset-names = "pwr"; + resets = <&cpg 624>, <&cpg 1121>; + reset-names = "pwr", "core"; max-link-speed = <4>; num-lanes = <2>; max-functions = /bits/ 8 <2>; @@ -922,8 +926,8 @@ pciec1_ep: pcie-ep@e65d8000 { clocks = <&cpg CPG_MOD 625>, <&pcie1_clkref>; clock-names = "core", "ref"; power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>; - resets = <&cpg 625>; - reset-names = "pwr"; + resets = <&cpg 625>, <&cpg 1122>; + reset-names = "pwr", "core"; max-link-speed = <4>; num-lanes = <2>; max-functions = /bits/ 8 <2>; @@ -2148,11 +2152,23 @@ ipmmu_mm: iommu@eefc0000 { gic: interrupt-controller@f1000000 { compatible = "arm,gic-v3"; #interrupt-cells = <3>; - #address-cells = <0>; + #address-cells = <2>; + #size-cells = <2>; interrupt-controller; reg = <0x0 0xf1000000 0 0x20000>, <0x0 0xf1060000 0 0x110000>; interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + dma-noncoherent; + + ranges = <0x0 0x0 0x0 0xf1000000 0x0 0x200000>; + + its: msi-controller@40000 { + compatible = "arm,gic-v3-its"; + reg = <0x0 0x40000 0x0 0x20000>; + dma-noncoherent; + msi-controller; + #msi-cells = <1>; + }; }; csi40: csi2@fe500000 { @@ -2315,6 +2331,35 @@ du_out_dsi0: endpoint { port@1 { reg = <1>; du_out_dsi1: endpoint { + remote-endpoint = <&dsc_in_dsi1>; + }; + }; + }; + }; + + dsc: bridge@feb8d000 { + compatible = "renesas,r8a779g0-dsc"; + reg = <0 0xfeb8d000 0 0x400>; + interrupts = <GIC_SPI 559 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 2819>; + power-domains = <&sysc R8A779G0_PD_ALWAYS_ON>; + resets = <&cpg 2819>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dsc_in_dsi1: endpoint { + remote-endpoint = <&du_out_dsi1>; + }; + }; + + port@1 { + reg = <1>; + dsc_out_dsi1: endpoint { remote-endpoint = <&dsi1_in>; }; }; @@ -2551,7 +2596,7 @@ ports { port@0 { reg = <0>; dsi1_in: endpoint { - remote-endpoint = <&du_out_dsi1>; + remote-endpoint = <&dsc_out_dsi1>; }; };
diff --git a/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-fan-argon40.dtso b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-fan-argon40.dtso index c730ef3..6f103101 100644 --- a/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-fan-argon40.dtso +++ b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-fan-argon40.dtso
@@ -41,7 +41,6 @@ &i2c3 { #address-cells = <1>; #size-cells = <0>; clock-frequency = <400000>; - status = "okay"; pwmhat: pwm@1a { compatible = "argon40,fan-hat";
diff --git a/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-ws-2ch-canfd.dtso b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-ws-2ch-canfd.dtso new file mode 100644 index 0000000..94405a3 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk-ws-2ch-canfd.dtso
@@ -0,0 +1,135 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Overlay for the Waveshare 2-Channel Isolated CAN FD HAT + * on connector CN7 on R-Car V4H ES3.0 Sparrow Hawk board + * + * Copyright (C) 2026 Marek Vasut <marek.vasut+renesas@mailbox.org> + * + * Example usage: + * - Connect HAT signals to Sparrow Hawk board CAN BUS connector CONN2: + * HAT CAN_0 H -- CONN2 pin 6 + * HAT CAN_0 L -- CONN2 pin 2 + * HAT CAN_1 H -- CONN2 pin 5 + * HAT CAN_1 L -- CONN2 pin 1 + * + * - Determine which interface is which: + * $ ip -d link show + * 2: can0: <NOARP,ECHO> ... + * ... + * clock 40000000 ... e6660000.can <------ Native Renesas CANFD + * 3: can1: <NOARP,ECHO> ... + * ... + * 4: can2: <NOARP,ECHO> ... + * ... + * clock 40000000 ... spi1.0 <------------ SPI CANFD on this HAT + * 5: can3: <NOARP,ECHO> ... + * ... + * + * - Bring connected interfaces up: + * # CAN_0 link + * $ ip link set can0 up type can bitrate 125000 dbitrate 250000 fd on + * $ ip link set can3 up type can bitrate 125000 dbitrate 250000 fd on + * + * # CAN_1 link + * $ ip link set can1 up type can bitrate 125000 dbitrate 250000 fd on + * $ ip link set can2 up type can bitrate 125000 dbitrate 250000 fd on + * + * - Perform CAN test, run each of the pair commands in separate terminals: + * # CAN_0 link + * $ canfdtest -v can0 + * $ canfdtest -g -v can3 + * + * # CAN_1 link + * $ canfdtest -v can1 + * $ canfdtest -g -v can2 + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/* + * PWM1 uses PWM1_B pin configuration for pin GP2_13. This conflicts + * with SPI_1 CE_1 signal which is also on pin GP2_13. Disable PWM1 + * in case this hat is in use. + * + * In case of a dynamic overlay, pwm1 must be disabled before SPI_1 + * is probed. Otherwise the latter will fail with -EBUSY due to the + * conflicting pin being still in use. Hence place pwm1 node here. + */ +&pwm1 { + status = "disabled"; +}; + +&{/} { + /* Fixed clock dedicated to SPI CAN on 2-CH CAN FD HAT */ + clk_can0: clk-ws-2ch-canfd0 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <40000000>; + }; + + clk_can1: clk-ws-2ch-canfd1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <40000000>; + }; + + /* + * SPI_1 is operated as GPIO SPI, because MSIOF5 can not be + * muxed on the pins allocated for SPI_1 on this CANFD HAT. + */ + spi-ws-2ch-canfd { /* SPI_1 */ + compatible = "spi-gpio"; + #address-cells = <1>; + #size-cells = <0>; + sck-gpios = <&gpio0 10 0>; /* CN7 pin 40 */ + miso-gpios = <&gpio0 9 0>; /* CN7 pin 35 */ + mosi-gpios = <&gpio0 12 0>; /* CN7 pin 38 */ + cs-gpios = <&gpio2 13 GPIO_ACTIVE_LOW>; /* CN7 pin 12 */ + num-chipselects = <1>; + + can@0 { + compatible = "microchip,mcp2518fd"; + reg = <0>; + clocks = <&clk_can1>; + /* CN7 pin 18 */ + interrupts-extended = <&gpio1 25 IRQ_TYPE_LEVEL_LOW>; + spi-max-frequency = <20000000>; + }; + }; +}; + +&msiof0 { /* SPI_0 */ + #address-cells = <1>; + #size-cells = <0>; + pinctrl-0 = <&msiof0_pins>; + pinctrl-names = "default"; + status = "okay"; + + /* + * Native MSIOF chipselect does not work with MCP2518FD + * because MCP251xFD driver needs to keep the chipselect + * line asserted between transfers. This requirement is + * fulfilled only by using GPIO chipselect. + */ + cs-gpios = <&gpio1 8 GPIO_ACTIVE_LOW>; + + can@0 { + compatible = "microchip,mcp2518fd"; + reg = <0>; + clocks = <&clk_can0>; + /* CN7 pin 22 */ + interrupts-extended = <&gpio1 26 IRQ_TYPE_LEVEL_LOW>; + spi-max-frequency = <20000000>; + }; +}; + +&pfc { + msiof0_pins: msiof0 { /* SPI_0 */ + groups = "msiof0_clk", "msiof0_txd", "msiof0_rxd"; + function = "msiof0"; + }; +};
diff --git a/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts index af68029..3d6df10 100644 --- a/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts +++ b/arch/arm64/boot/dts/renesas/r8a779g3-sparrow-hawk.dts
@@ -289,6 +289,11 @@ channel4 { }; /* Page 27 / DSI to Display */ +&dsc { + status = "okay"; +}; + +/* Page 27 / DSI to Display */ &dsi1 { status = "okay"; @@ -498,6 +503,7 @@ &i2c3 { #size-cells = <0>; pinctrl-0 = <&i2c3_pins>; pinctrl-names = "default"; + status = "okay"; }; /* Page 31 / IO_CN */ @@ -506,6 +512,7 @@ &i2c4 { #size-cells = <0>; pinctrl-0 = <&i2c4_pins>; pinctrl-names = "default"; + status = "okay"; }; /* Page 18 / POWER_CORE and Page 19 / POWER_PMIC */ @@ -698,6 +705,12 @@ irq4_pins: irq4 { function = "intc_ex"; }; + /* Page 30 / Audio_Codec */ + msiof1_pins: msiof1 { + groups = "msiof1_clk", "msiof1_sync", "msiof1_txd", "msiof1_rxd"; + function = "msiof1"; + }; + /* Page 31 / FAN */ pwm0_pins: pwm0 { groups = "pwm0"; @@ -750,12 +763,6 @@ sd_uhs_pins: sd-uhs { }; /* Page 30 / Audio_Codec */ - msiof1_pins: sound { - groups = "msiof1_clk", "msiof1_sync", "msiof1_txd", "msiof1_rxd"; - function = "msiof1"; - }; - - /* Page 30 / Audio_Codec */ sound_clk_pins: sound-clk { groups = "audio_clkin", "audio_clkout"; function = "audio_clk";
diff --git a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi index 74bc4c4..5f9223a 100644 --- a/arch/arm64/boot/dts/renesas/r8a779h0.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a779h0.dtsi
@@ -16,7 +16,7 @@ / { interrupt-parent = <&gic>; /* External Audio clock - to be overridden by boards that provide it */ - audio_clkin: audio_clkin { + audio_clkin: audio-clkin { compatible = "fixed-clock"; #clock-cells = <0>; clock-frequency = <0>; @@ -688,9 +688,11 @@ pciec0: pcie@e65d0000 { clocks = <&cpg CPG_MOD 624>, <&pcie0_clkref>; clock-names = "core", "ref"; power-domains = <&sysc R8A779H0_PD_A2PCIPHY>; - resets = <&cpg 624>; - reset-names = "pwr"; + resets = <&cpg 624>, <&cpg 1121>; + reset-names = "pwr", "core"; max-link-speed = <4>; + msi-parent = <&its 0>; + msi-map = <0x0 &its 0x0 0x10000>; num-lanes = <2>; #address-cells = <3>; #size-cells = <2>; @@ -701,10 +703,10 @@ pciec0: pcie@e65d0000 { dma-ranges = <0x42000000 0 0x00000000 0 0x00000000 1 0x00000000>; #interrupt-cells = <1>; interrupt-map-mask = <0 0 0 7>; - interrupt-map = <0 0 0 1 &gic GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 2 &gic GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 3 &gic GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>, - <0 0 0 4 &gic GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>; snps,enable-cdm-check; status = "disabled"; }; @@ -724,8 +726,8 @@ pciec0_ep: pcie-ep@e65d0000 { clocks = <&cpg CPG_MOD 624>, <&pcie0_clkref>; clock-names = "core", "ref"; power-domains = <&sysc R8A779H0_PD_A2PCIPHY>; - resets = <&cpg 624>; - reset-names = "pwr"; + resets = <&cpg 624>, <&cpg 1121>; + reset-names = "pwr", "core"; max-link-speed = <4>; num-lanes = <2>; max-functions = /bits/ 8 <2>; @@ -1852,11 +1854,23 @@ ipmmu_mm: iommu@eefc0000 { gic: interrupt-controller@f1000000 { compatible = "arm,gic-v3"; #interrupt-cells = <3>; - #address-cells = <0>; + #address-cells = <2>; + #size-cells = <2>; interrupt-controller; reg = <0x0 0xf1000000 0 0x20000>, <0x0 0xf1060000 0 0x110000>; interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + dma-noncoherent; + + ranges = <0x0 0x0 0x0 0xf1000000 0x0 0x200000>; + + its: msi-controller@40000 { + compatible = "arm,gic-v3-its"; + reg = <0x0 0x40000 0x0 0x20000>; + dma-noncoherent; + msi-controller; + #msi-cells = <1>; + }; }; csi40: csi2@fe500000 {
diff --git a/arch/arm64/boot/dts/renesas/r8a779md-geist.dts b/arch/arm64/boot/dts/renesas/r8a779md-geist.dts index 0e47243..252d9e9 100644 --- a/arch/arm64/boot/dts/renesas/r8a779md-geist.dts +++ b/arch/arm64/boot/dts/renesas/r8a779md-geist.dts
@@ -367,7 +367,7 @@ video-receiver@70 { reg = <0x70 0x71 0x72 0x73 0x74 0x75 0x60 0x61 0x62 0x63 0x64 0x65>; reg-names = "main", "dpll", "cp", "hdmi", "edid", "repeater", - "infoframe", "cbus", "cec", "sdp", "txa", "txb" ; + "infoframe", "cbus", "cec", "sdp", "txa", "txb"; interrupts-extended = <&gpio6 30 IRQ_TYPE_LEVEL_LOW>, <&gpio6 31 IRQ_TYPE_LEVEL_LOW>; @@ -460,12 +460,12 @@ mux { function = "avb"; }; - pins_mdio { + pins-mdio { groups = "avb_mdio"; drive-strength = <24>; }; - pins_mii_tx { + pins-mii-tx { pins = "PIN_AVB_TX_CTL", "PIN_AVB_TXC", "PIN_AVB_TD0", "PIN_AVB_TD1", "PIN_AVB_TD2", "PIN_AVB_TD3"; drive-strength = <12>; @@ -507,7 +507,7 @@ scif2_pins: scif2 { function = "scif2"; }; - scif_clk_pins: scif_clk { + scif_clk_pins: scif-clk { groups = "scif_clk_a"; function = "scif_clk"; }; @@ -518,7 +518,7 @@ sdhi0_pins: sd0 { power-source = <3300>; }; - sdhi0_pins_uhs: sd0_uhs { + sdhi0_pins_uhs: sd0-uhs { groups = "sdhi0_data4", "sdhi0_ctrl"; function = "sdhi0"; power-source = <1800>; @@ -535,7 +535,7 @@ sound_pins: sound { function = "ssi"; }; - sound_clk_pins: sound_clk { + sound_clk_pins: sound-clk { groups = "audio_clk_a_a", "audio_clk_b_a", "audio_clk_c_a", "audio_clkout_a", "audio_clkout3_a"; function = "audio_clk";
diff --git a/arch/arm64/boot/dts/renesas/r8a78000-ironhide.dts b/arch/arm64/boot/dts/renesas/r8a78000-ironhide.dts index 0ab3038..b2d6b06 100644 --- a/arch/arm64/boot/dts/renesas/r8a78000-ironhide.dts +++ b/arch/arm64/boot/dts/renesas/r8a78000-ironhide.dts
@@ -134,18 +134,18 @@ ecc@18cccc0000 { no-map; }; - ecc@1a66660000 { - reg = <0x1a 0x66660000 0x0 0x999a0000>; + ecc@1acccc0000 { + reg = <0x1a 0xcccc0000 0x0 0x33340000>; no-map; }; - ecc@1c66660000 { - reg = <0x1c 0x66660000 0x0 0x999a0000>; + ecc@1ccccc0000 { + reg = <0x1c 0xcccc0000 0x0 0x33340000>; no-map; }; - ecc@1e66660000 { - reg = <0x1e 0x66660000 0x0 0x999a0000>; + ecc@1ecccc0000 { + reg = <0x1e 0xcccc0000 0x0 0x33340000>; no-map; }; };
diff --git a/arch/arm64/boot/dts/renesas/r8a78000.dtsi b/arch/arm64/boot/dts/renesas/r8a78000.dtsi index fb71974..28555fa 100644 --- a/arch/arm64/boot/dts/renesas/r8a78000.dtsi +++ b/arch/arm64/boot/dts/renesas/r8a78000.dtsi
@@ -5,6 +5,8 @@ * Copyright (C) 2025 Renesas Electronics Corp. */ +#include <dt-bindings/clock/renesas,r8a78000-cpg.h> +#include <dt-bindings/power/renesas,r8a78000-mdlc.h> #include <dt-bindings/interrupt-controller/arm-gic.h> / { @@ -668,23 +670,6 @@ L3_CA720_7: cache-controller-37 { }; }; - /* - * In the early phase, there is no clock control support, - * so assume that the clocks are enabled by default. - * Therefore, dummy clocks are used. - */ - dummy_clk_sgasyncd16: dummy-clk-sgasyncd16 { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <66666000>; - }; - - dummy_clk_sgasyncd4: dummy-clk-sgasyncd4 { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <266660000>; - }; - extal_clk: extal-clk { compatible = "fixed-clock"; #clock-cells = <0>; @@ -877,13 +862,129 @@ gic: interrupt-controller@39000000 { interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; }; + i2c1: i2c@c06c0000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc06c0000 0 0x40>; + interrupts = <GIC_SPI 956 IRQ_TYPE_LEVEL_HIGH>; + i2c-scl-internal-delay-ns = <110>; + clocks = <&cpg R8A78000_CPG_SGASYNCD8_PERW_BUS>; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x44>; + resets = <&mdlc_perw 0x44>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c2: i2c@c06c8000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc06c8000 0 0x40>; + interrupts = <GIC_SPI 957 IRQ_TYPE_LEVEL_HIGH>; + i2c-scl-internal-delay-ns = <110>; + clocks = <&cpg R8A78000_CPG_SGASYNCD8_PERW_BUS>; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x45>; + resets = <&mdlc_perw 0x45>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c3: i2c@c06d0000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc06d0000 0 0x40>; + interrupts = <GIC_SPI 958 IRQ_TYPE_LEVEL_HIGH>; + i2c-scl-internal-delay-ns = <110>; + clocks = <&cpg R8A78000_CPG_SGASYNCD8_PERW_BUS>; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x46>; + resets = <&mdlc_perw 0x46>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c4: i2c@c06d8000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc06d8000 0 0x40>; + interrupts = <GIC_SPI 959 IRQ_TYPE_LEVEL_HIGH>; + i2c-scl-internal-delay-ns = <110>; + clocks = <&cpg R8A78000_CPG_SGASYNCD8_PERW_BUS>; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x47>; + resets = <&mdlc_perw 0x47>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c5: i2c@c06e0000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc06e0000 0 0x40>; + interrupts = <GIC_ESPI 0 IRQ_TYPE_LEVEL_HIGH>; + i2c-scl-internal-delay-ns = <110>; + clocks = <&cpg R8A78000_CPG_SGASYNCD8_PERW_BUS>; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x48>; + resets = <&mdlc_perw 0x48>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c6: i2c@c06e8000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc06e8000 0 0x40>; + interrupts = <GIC_ESPI 1 IRQ_TYPE_LEVEL_HIGH>; + i2c-scl-internal-delay-ns = <110>; + clocks = <&cpg R8A78000_CPG_SGASYNCD8_PERW_BUS>; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x49>; + resets = <&mdlc_perw 0x49>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c7: i2c@c06f0000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc06f0000 0 0x40>; + interrupts = <GIC_ESPI 2 IRQ_TYPE_LEVEL_HIGH>; + i2c-scl-internal-delay-ns = <110>; + clocks = <&cpg R8A78000_CPG_SGASYNCD8_PERW_BUS>; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x4a>; + resets = <&mdlc_perw 0x4a>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + i2c8: i2c@c06f8000 { + compatible = "renesas,i2c-r8a78000", + "renesas,rcar-gen5-i2c"; + reg = <0 0xc06f8000 0 0x40>; + interrupts = <GIC_ESPI 3 IRQ_TYPE_LEVEL_HIGH>; + i2c-scl-internal-delay-ns = <110>; + clocks = <&cpg R8A78000_CPG_SGASYNCD8_PERW_BUS>; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x4b>; + resets = <&mdlc_perw 0x4b>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + scif0: serial@c0700000 { compatible = "renesas,scif-r8a78000", "renesas,rcar-gen5-scif", "renesas,scif"; reg = <0 0xc0700000 0 0x40>; interrupts = <GIC_ESPI 10 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd4>, <&scif_clk>; + clocks = <&cpg R8A78000_CPG_SGASYNCD16_PERW_BUS>, + <&cpg R8A78000_CPG_SGASYNCD4_PERW_BUS>, + <&scif_clk>; clock-names = "fck", "brg_int", "scif_clk"; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x40>; + resets = <&mdlc_perw 0x40>; status = "disabled"; }; @@ -892,8 +993,12 @@ scif1: serial@c0704000 { "renesas,rcar-gen5-scif", "renesas,scif"; reg = <0 0xc0704000 0 0x40>; interrupts = <GIC_ESPI 11 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd4>, <&scif_clk>; + clocks = <&cpg R8A78000_CPG_SGASYNCD16_PERW_BUS>, + <&cpg R8A78000_CPG_SGASYNCD4_PERW_BUS>, + <&scif_clk>; clock-names = "fck", "brg_int", "scif_clk"; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x41>; + resets = <&mdlc_perw 0x41>; status = "disabled"; }; @@ -902,8 +1007,12 @@ scif3: serial@c0708000 { "renesas,rcar-gen5-scif", "renesas,scif"; reg = <0 0xc0708000 0 0x40>; interrupts = <GIC_ESPI 12 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd4>, <&scif_clk>; + clocks = <&cpg R8A78000_CPG_SGASYNCD16_PERW_BUS>, + <&cpg R8A78000_CPG_SGASYNCD4_PERW_BUS>, + <&scif_clk>; clock-names = "fck", "brg_int", "scif_clk"; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x42>; + resets = <&mdlc_perw 0x42>; status = "disabled"; }; @@ -912,8 +1021,12 @@ scif4: serial@c070c000 { "renesas,rcar-gen5-scif", "renesas,scif"; reg = <0 0xc070c000 0 0x40>; interrupts = <GIC_ESPI 13 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&dummy_clk_sgasyncd16>, <&dummy_clk_sgasyncd4>, <&scif_clk>; + clocks = <&cpg R8A78000_CPG_SGASYNCD16_PERW_BUS>, + <&cpg R8A78000_CPG_SGASYNCD4_PERW_BUS>, + <&scif_clk>; clock-names = "fck", "brg_int", "scif_clk"; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x43>; + resets = <&mdlc_perw 0x43>; status = "disabled"; }; @@ -922,8 +1035,12 @@ hscif0: serial@c0710000 { "renesas,rcar-gen5-hscif", "renesas,hscif"; reg = <0 0xc0710000 0 0x60>; interrupts = <GIC_ESPI 14 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&dummy_clk_sgasyncd4>, <&dummy_clk_sgasyncd4>, <&scif_clk>; + clocks = <&cpg R8A78000_CPG_SGASYNCD4_PERW_BUS>, + <&cpg R8A78000_CPG_SGASYNCD4_PERW_BUS>, + <&scif_clk>; clock-names = "fck", "brg_int", "scif_clk"; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x54>; + resets = <&mdlc_perw 0x54>; status = "disabled"; }; @@ -932,8 +1049,12 @@ hscif1: serial@c0714000 { "renesas,rcar-gen5-hscif", "renesas,hscif"; reg = <0 0xc0714000 0 0x60>; interrupts = <GIC_ESPI 15 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&dummy_clk_sgasyncd4>, <&dummy_clk_sgasyncd4>, <&scif_clk>; + clocks = <&cpg R8A78000_CPG_SGASYNCD4_PERW_BUS>, + <&cpg R8A78000_CPG_SGASYNCD4_PERW_BUS>, + <&scif_clk>; clock-names = "fck", "brg_int", "scif_clk"; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x55>; + resets = <&mdlc_perw 0x55>; status = "disabled"; }; @@ -942,8 +1063,12 @@ hscif2: serial@c0718000 { "renesas,rcar-gen5-hscif", "renesas,hscif"; reg = <0 0xc0718000 0 0x60>; interrupts = <GIC_ESPI 16 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&dummy_clk_sgasyncd4>, <&dummy_clk_sgasyncd4>, <&scif_clk>; + clocks = <&cpg R8A78000_CPG_SGASYNCD4_PERW_BUS>, + <&cpg R8A78000_CPG_SGASYNCD4_PERW_BUS>, + <&scif_clk>; clock-names = "fck", "brg_int", "scif_clk"; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x56>; + resets = <&mdlc_perw 0x56>; status = "disabled"; }; @@ -952,8 +1077,12 @@ hscif3: serial@c071c000 { "renesas,rcar-gen5-hscif", "renesas,hscif"; reg = <0 0xc071c000 0 0x60>; interrupts = <GIC_ESPI 17 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&dummy_clk_sgasyncd4>, <&dummy_clk_sgasyncd4>, <&scif_clk>; + clocks = <&cpg R8A78000_CPG_SGASYNCD4_PERW_BUS>, + <&cpg R8A78000_CPG_SGASYNCD4_PERW_BUS>, + <&scif_clk>; clock-names = "fck", "brg_int", "scif_clk"; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x57>; + resets = <&mdlc_perw 0x57>; status = "disabled"; }; @@ -965,6 +1094,343 @@ stcm_transport: sram@c1060000 { ranges = <0 0x0 0xc1060000 0x1c00>; /* actual transport nodes must be set per board file */ }; + + cpg: clock-controller@c1320000 { + compatible = "renesas,r8a78000-cpg"; + reg = <0 0xc1320000 0 0x10000>; + clocks = <&extal_clk>, <&extalr_clk>; + clock-names = "extal", "extalr"; + #clock-cells = <1>; + bootph-all; + }; + + mdlc_aon: system-controller@c1338000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xc1338000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_cmnn: system-controller@ca410000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xca410000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_cmns: system-controller@ca510000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xca510000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_ddr0: system-controller@e8000000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xe8000000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_ddr1: system-controller@e8080000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xe8080000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_ddr2: system-controller@e8100000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xe8100000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_ddr3: system-controller@e8180000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xe8180000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_ddr4: system-controller@e8200000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xe8200000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_ddr5: system-controller@e8280000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xe8280000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_ddr6: system-controller@e8300000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xe8300000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_ddr7: system-controller@e8380000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xe8380000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_dsp: system-controller@cbe90000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xcbe90000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_gpc: system-controller@cb510000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xcb510000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_hscn: system-controller@c9c90000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xc9c90000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_hscs: system-controller@de200000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xde200000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_imn: system-controller@c1990000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xc1990000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_ims: system-controller@c1d90000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xc1d90000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_mm: system-controller@e9980000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xe9980000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_npu0: system-controller@d2c30000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xd2c30000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_npu1: system-controller@d6c30000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xd6c30000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_pere: system-controller@c08f0000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xc08f0000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_perw: system-controller@c05d0000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xc05d0000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_rt: system-controller@19440000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0x19440000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_scp: system-controller@c1330000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xc1330000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_top: system-controller@c6480000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xc6480000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_vio: system-controller@c5000000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xc5000000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_vipn: system-controller@c3060000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xc3060000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + mdlc_vips: system-controller@c3460000 { + compatible = "renesas,r8a78000-mdlc"; + reg = <0 0xc3460000 0 0x1000>; + #power-domain-cells = <2>; + #reset-cells = <1>; + bootph-all; + }; + + msiof0: spi@c1700000 { + compatible = "renesas,msiof-r8a78000", + "renesas,rcar-gen5-msiof"; + reg = <0 0xc1700000 0 0x100>; + interrupts = <GIC_ESPI 744 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg R8A78000_CPG_MSO_SCP_MAIN>; + power-domains = <&mdlc_scp R8A78000_MDLC_PD_SCP 0x50>; + resets = <&mdlc_scp 0x50>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + msiof1: spi@c1710000 { + compatible = "renesas,msiof-r8a78000", + "renesas,rcar-gen5-msiof"; + reg = <0 0xc1710000 0 0x100>; + interrupts = <GIC_ESPI 745 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg R8A78000_CPG_MSO_SCP_MAIN>; + power-domains = <&mdlc_scp R8A78000_MDLC_PD_SCP 0x51>; + resets = <&mdlc_scp 0x51>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + msiof2: spi@c1720000 { + compatible = "renesas,msiof-r8a78000", + "renesas,rcar-gen5-msiof"; + reg = <0 0xc1720000 0 0x100>; + interrupts = <GIC_ESPI 746 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg R8A78000_CPG_MSO_SCP_MAIN>; + power-domains = <&mdlc_scp R8A78000_MDLC_PD_SCP 0x52>; + resets = <&mdlc_scp 0x52>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + msiof3: spi@c1730000 { + compatible = "renesas,msiof-r8a78000", + "renesas,rcar-gen5-msiof"; + reg = <0 0xc1730000 0 0x100>; + interrupts = <GIC_ESPI 747 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg R8A78000_CPG_MSO_SCP_MAIN>; + power-domains = <&mdlc_scp R8A78000_MDLC_PD_SCP 0x53>; + resets = <&mdlc_scp 0x53>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + msiof4: spi@c0600000 { + compatible = "renesas,msiof-r8a78000", + "renesas,rcar-gen5-msiof"; + reg = <0 0xc0600000 0 0x100>; + interrupts = <GIC_ESPI 18 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg R8A78000_CPG_MSOCK_PERW_BUS>; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x4f>; + resets = <&mdlc_perw 0x4f>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + msiof5: spi@c0608000 { + compatible = "renesas,msiof-r8a78000", + "renesas,rcar-gen5-msiof"; + reg = <0 0xc0608000 0 0x100>; + interrupts = <GIC_ESPI 19 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg R8A78000_CPG_MSOCK_PERW_BUS>; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x50>; + resets = <&mdlc_perw 0x50>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + msiof6: spi@c0610000 { + compatible = "renesas,msiof-r8a78000", + "renesas,rcar-gen5-msiof"; + reg = <0 0xc0610000 0 0x100>; + interrupts = <GIC_ESPI 20 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg R8A78000_CPG_MSOCK_PERW_BUS>; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x51>; + resets = <&mdlc_perw 0x51>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; + + msiof7: spi@c0618000 { + compatible = "renesas,msiof-r8a78000", + "renesas,rcar-gen5-msiof"; + reg = <0 0xc0618000 0 0x100>; + interrupts = <GIC_ESPI 21 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg R8A78000_CPG_MSOCK_PERW_BUS>; + power-domains = <&mdlc_perw R8A78000_MDLC_PD_APL 0x52>; + resets = <&mdlc_perw 0x52>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + }; }; timer {
diff --git a/arch/arm64/boot/dts/renesas/r9a07g043u12-hummingboard-ripple.dts b/arch/arm64/boot/dts/renesas/r9a07g043u12-hummingboard-ripple.dts new file mode 100644 index 0000000..8ffa51d --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r9a07g043u12-hummingboard-ripple.dts
@@ -0,0 +1,89 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Description for SolidRun RZ/G2UL Type-2 HummingBoard Ripple. + * + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +/dts-v1/; + +#include "r9a07g043u.dtsi" +#include "rzg2ul-sr-som.dtsi" +#include "rzg2l-hummingboard-pulse-common.dtsi" + +/ { + compatible = "solidrun,rzg2ul-hummingboard-ripple", "solidrun,rzg2ul-sr-som", + "renesas,r9a07g043u12", "renesas,r9a07g043"; + model = "SolidRun RZ/G2UL HummingBoard Ripple"; + + leds: leds { + compatible = "gpio-leds"; + + led-0 { + color = <LED_COLOR_ID_GREEN>; + default-state = "on"; + gpios = <&pinctrl RZG2L_GPIO(12, 1) GPIO_ACTIVE_LOW>; + label = "D30"; + }; + }; + + vbus1: regulator-vbus-1 { + compatible = "regulator-fixed"; + regulator-name = "vbus1"; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + gpios = <&pinctrl RZG2L_GPIO(5, 2) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&hub_2_0 { + reset-gpios = <&pinctrl RZG2L_GPIO(13, 3) GPIO_ACTIVE_LOW>; +}; + +&pinctrl { + hdmi_pd_hog: hdmi-pd-hog { + /* + * RZ/G2UL does not have DSI output to feed DSI-to-HDMI + * bridge. Keep its shutdown signal asserted. + */ + gpio-hog; + gpios = <RZG2L_GPIO(14, 2) GPIO_ACTIVE_LOW>; + line-name = "hdmi-pd"; + output-high; + }; + + mpcie_rst_hog: mpcie-reset-hog { + gpio-hog; + gpios = <RZG2L_GPIO(0, 3) GPIO_ACTIVE_LOW>; + line-name = "mpcie-reset"; + output-low; + }; + + mikro_uart_pins: pinctrl-mikro-uart-grp { + pinmux = <RZG2L_PORT_PINMUX(14, 1, 1)>, /* SCIF1_RXD */ + <RZG2L_PORT_PINMUX(14, 0, 1)>; /* SCIF1_TXD */ + }; + + usb0_vbus_pins: usb0-vbus { + pinmux = <RZG2L_PORT_PINMUX(5, 0, 1)>; /* USB0_VBUSEN */ + }; +}; + +&usb2_phy1 { + vbus-supply = <&vbus1>; +}; + +&vmmc { + gpios = <&pinctrl RZG2L_GPIO(0, 1) GPIO_ACTIVE_LOW>; +}; + +&vmpcie { + /* + * G2UL SoM v1.2 moved this IO from J7-28 (CON4-12) + * to J7-18 (this regulator). + * There are no known users of CON4-12 and thus no need + * to differentiate here between SoM v1.1 and v1.2. + */ + gpios = <&pinctrl RZG2L_GPIO(13, 4) GPIO_ACTIVE_HIGH>; +};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g044c2-hummingboard-iiot.dts b/arch/arm64/boot/dts/renesas/r9a07g044c2-hummingboard-iiot.dts new file mode 100644 index 0000000..9cc21ae --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r9a07g044c2-hummingboard-iiot.dts
@@ -0,0 +1,20 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +/dts-v1/; + +#include "r9a07g044c2.dtsi" +#include "rzg2lc-sr-som.dtsi" +#include "rzg2l-hummingboard-iiot-common.dtsi" + +/ { + compatible = "solidrun,rzg2lc-hummingboard-iiot", "solidrun,rzg2lc-sr-som", + "renesas,r9a07g044c2", "renesas,r9a07g044"; + model = "SolidRun RZ/G2LC HummingBoard IIoT"; +}; + +&vmmc { + gpios = <&pinctrl RZG2L_GPIO(18, 1) GPIO_ACTIVE_HIGH>; +};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g044c2-hummingboard-ripple.dts b/arch/arm64/boot/dts/renesas/r9a07g044c2-hummingboard-ripple.dts new file mode 100644 index 0000000..ef8e2f6 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r9a07g044c2-hummingboard-ripple.dts
@@ -0,0 +1,93 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +/dts-v1/; + +#include "r9a07g044c2.dtsi" +#include "rzg2lc-sr-som.dtsi" +#include "rzg2l-hummingboard-pulse-common.dtsi" +#include "rzg2l-hummingboard-pulse-micro-hdmi.dtsi" + +/ { + compatible = "solidrun,rzg2lc-hummingboard-ripple", "solidrun,rzg2lc-sr-som", + "renesas,r9a07g044c2", "renesas,r9a07g044"; + model = "SolidRun RZ/G2LC HummingBoard Ripple"; + + leds: leds { + compatible = "gpio-leds"; + + led-0 { + color = <LED_COLOR_ID_GREEN>; + default-state = "on"; + gpios = <&pinctrl RZG2L_GPIO(0, 1) GPIO_ACTIVE_LOW>; + label = "D30"; + }; + }; + + vbus1: regulator-vbus-1 { + compatible = "regulator-fixed"; + regulator-name = "vbus1"; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + gpios = <&pinctrl RZG2L_GPIO(5, 0) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; +}; + +&gpt { + /* mikrobus header pwm pin is pwm channel 6 */ + pinctrl-0 = <&mikro_pwm_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&hdmi { + interrupts-extended = <&pinctrl RZG2L_GPIO(42, 2) IRQ_TYPE_EDGE_FALLING>; + pd-gpios = <&pinctrl RZG2L_GPIO(40, 2) GPIO_ACTIVE_LOW>; +}; + +&hub_2_0 { + reset-gpios = <&pinctrl RZG2L_GPIO(39, 1) GPIO_ACTIVE_LOW>; +}; + +&pinctrl { + mpcie_rst_hog: mpcie-reset-hog { + gpios = <RZG2L_GPIO(19, 1) GPIO_ACTIVE_LOW>; + gpio-hog; + line-name = "mpcie-reset"; + output-low; + }; + + mikro_pwm_pins: pinctrl-mikro-pwm-grp { + pinmux = <RZG2L_PORT_PINMUX(41, 0, 4)>; /* GTIOC3A */ + }; + + mikro_uart_pins: pinctrl-mikro-uart-grp { + pinmux = <RZG2L_PORT_PINMUX(40, 1, 1)>, /* SCIF1_RXD */ + <RZG2L_PORT_PINMUX(40, 0, 1)>; /* SCIF1_TXD */ + }; + + usb0_vbus_pins: usb0-vbus { + pinmux = <RZG2L_PORT_PINMUX(4, 0, 1)>; /* USB0_VBUSEN */ + }; +}; + +&usb2_phy1 { + vbus-supply = <&vbus1>; +}; + +&vmmc { + gpios = <&pinctrl RZG2L_GPIO(18, 1) GPIO_ACTIVE_LOW>; +}; + +&vmpcie { + /* + * G2LC SoM v1.2 moved this IO from J7-28 (CON4-12) + * to J7-18 (this regulator). + * There are no known users of CON4-12 and thus no need + * to differentiate here between SoM v1.1 and v1.2. + */ + gpios = <&pinctrl RZG2L_GPIO(39, 2) GPIO_ACTIVE_HIGH>; +};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g044l2-hummingboard-iiot.dts b/arch/arm64/boot/dts/renesas/r9a07g044l2-hummingboard-iiot.dts new file mode 100644 index 0000000..eba4f42 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r9a07g044l2-hummingboard-iiot.dts
@@ -0,0 +1,16 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +/dts-v1/; + +#include "r9a07g044l2.dtsi" +#include "rzg2l-sr-som.dtsi" +#include "rzg2l-hummingboard-iiot.dtsi" + +/ { + compatible = "solidrun,rzg2l-hummingboard-iiot", "solidrun,rzg2l-sr-som", + "renesas,r9a07g044l2", "renesas,r9a07g044"; + model = "SolidRun RZ/G2L HummingBoard IIoT"; +};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g044l2-hummingboard-ripple.dts b/arch/arm64/boot/dts/renesas/r9a07g044l2-hummingboard-ripple.dts new file mode 100644 index 0000000..95a36f8 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r9a07g044l2-hummingboard-ripple.dts
@@ -0,0 +1,18 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +/dts-v1/; + +#include "r9a07g044l2.dtsi" +#include "rzg2l-sr-som.dtsi" +#include "rzg2l-hummingboard-pulse-common.dtsi" +#include "rzg2l-hummingboard-pulse-micro-hdmi.dtsi" +#include "rzg2l-hummingboard-ripple.dtsi" + +/ { + compatible = "solidrun,rzg2l-hummingboard-ripple", "solidrun,rzg2l-sr-som", + "renesas,r9a07g044l2", "renesas,r9a07g044"; + model = "SolidRun RZ/G2L HummingBoard Ripple"; +};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g044l2-remi-pi.dts b/arch/arm64/boot/dts/renesas/r9a07g044l2-remi-pi.dts index 3267e7b..dea386f 100644 --- a/arch/arm64/boot/dts/renesas/r9a07g044l2-remi-pi.dts +++ b/arch/arm64/boot/dts/renesas/r9a07g044l2-remi-pi.dts
@@ -156,7 +156,7 @@ &i2c0 { hdmi-bridge@48 { compatible = "lontium,lt8912b"; - reg = <0x48> ; + reg = <0x48>; reset-gpios = <&pinctrl RZG2L_GPIO(42, 2) GPIO_ACTIVE_LOW>; ports {
diff --git a/arch/arm64/boot/dts/renesas/r9a07g054l2-hummingboard-iiot.dts b/arch/arm64/boot/dts/renesas/r9a07g054l2-hummingboard-iiot.dts new file mode 100644 index 0000000..d77a6ff --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r9a07g054l2-hummingboard-iiot.dts
@@ -0,0 +1,16 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +/dts-v1/; + +#include "r9a07g054l2.dtsi" +#include "rzg2l-sr-som.dtsi" +#include "rzg2l-hummingboard-iiot.dtsi" + +/ { + compatible = "solidrun,rzv2l-hummingboard-iiot", "solidrun,rzv2l-sr-som", + "renesas,r9a07g054l2", "renesas,r9a07g054"; + model = "SolidRun RZ/V2L HummingBoard IIoT"; +};
diff --git a/arch/arm64/boot/dts/renesas/r9a07g054l2-hummingboard-ripple.dts b/arch/arm64/boot/dts/renesas/r9a07g054l2-hummingboard-ripple.dts new file mode 100644 index 0000000..0c73871 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r9a07g054l2-hummingboard-ripple.dts
@@ -0,0 +1,18 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +/dts-v1/; + +#include "r9a07g054l2.dtsi" +#include "rzg2l-sr-som.dtsi" +#include "rzg2l-hummingboard-pulse-common.dtsi" +#include "rzg2l-hummingboard-pulse-micro-hdmi.dtsi" +#include "rzg2l-hummingboard-ripple.dtsi" + +/ { + compatible = "solidrun,rzv2l-hummingboard-ripple", "solidrun,rzv2l-sr-som", + "renesas,r9a07g054l2", "renesas,r9a07g054"; + model = "SolidRun RZ/V2L HummingBoard Ripple"; +};
diff --git a/arch/arm64/boot/dts/renesas/r9a08g045.dtsi b/arch/arm64/boot/dts/renesas/r9a08g045.dtsi index 3a69bb2..b98ad37 100644 --- a/arch/arm64/boot/dts/renesas/r9a08g045.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a08g045.dtsi
@@ -645,7 +645,7 @@ dmac: dma-controller@11820000 { dma-channels = <16>; }; - sdhi0: mmc@11c00000 { + sdhi0: mmc@11c00000 { compatible = "renesas,sdhi-r9a08g045", "renesas,rzg2l-sdhi"; reg = <0x0 0x11c00000 0 0x10000>; interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>, @@ -655,6 +655,7 @@ sdhi0: mmc@11c00000 { <&cpg CPG_MOD R9A08G045_SDHI0_IMCLK2>, <&cpg CPG_MOD R9A08G045_SDHI0_ACLK>; clock-names = "core", "clkh", "cd", "aclk"; + max-frequency = <125000000>; resets = <&cpg R9A08G045_SDHI0_IXRST>; power-domains = <&cpg>; status = "disabled"; @@ -670,6 +671,7 @@ sdhi1: mmc@11c10000 { <&cpg CPG_MOD R9A08G045_SDHI1_IMCLK2>, <&cpg CPG_MOD R9A08G045_SDHI1_ACLK>; clock-names = "core", "clkh", "cd", "aclk"; + max-frequency = <125000000>; resets = <&cpg R9A08G045_SDHI1_IXRST>; power-domains = <&cpg>; status = "disabled"; @@ -685,6 +687,7 @@ sdhi2: mmc@11c20000 { <&cpg CPG_MOD R9A08G045_SDHI2_IMCLK2>, <&cpg CPG_MOD R9A08G045_SDHI2_ACLK>; clock-names = "core", "clkh", "cd", "aclk"; + max-frequency = <50000000>; resets = <&cpg R9A08G045_SDHI2_IXRST>; power-domains = <&cpg>; status = "disabled";
diff --git a/arch/arm64/boot/dts/renesas/r9a08g046.dtsi b/arch/arm64/boot/dts/renesas/r9a08g046.dtsi index c63a857..f33d5d7 100644 --- a/arch/arm64/boot/dts/renesas/r9a08g046.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a08g046.dtsi
@@ -64,6 +64,110 @@ opp-1200000000 { }; }; + gpu_opp_table: opp-table-1 { + compatible = "operating-points-v2"; + + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <1000000>; + }; + + opp-533330000 { + opp-hz = /bits/ 64 <533330000>; + opp-microvolt = <1000000>; + }; + + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <1000000>; + }; + + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <1000000>; + }; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-microvolt = <1000000>; + }; + + opp-266667000 { + opp-hz = /bits/ 64 <266667000>; + opp-microvolt = <1000000>; + }; + + opp-250000000 { + opp-hz = /bits/ 64 <250000000>; + opp-microvolt = <1000000>; + }; + + opp-200000000 { + opp-hz = /bits/ 64 <200000000>; + opp-microvolt = <1000000>; + }; + + opp-150000000 { + opp-hz = /bits/ 64 <150000000>; + opp-microvolt = <1000000>; + }; + + opp-133333000 { + opp-hz = /bits/ 64 <133333000>; + opp-microvolt = <1000000>; + }; + + opp-125000000 { + opp-hz = /bits/ 64 <125000000>; + opp-microvolt = <1000000>; + }; + + opp-100000000 { + opp-hz = /bits/ 64 <100000000>; + opp-microvolt = <1000000>; + }; + + opp-75000000 { + opp-hz = /bits/ 64 <75000000>; + opp-microvolt = <1000000>; + }; + + opp-66667000 { + opp-hz = /bits/ 64 <66667000>; + opp-microvolt = <1000000>; + }; + + opp-62500000 { + opp-hz = /bits/ 64 <62500000>; + opp-microvolt = <1000000>; + }; + + opp-50000000 { + opp-hz = /bits/ 64 <50000000>; + opp-microvolt = <1000000>; + }; + + opp-18750000 { + opp-hz = /bits/ 64 <18750000>; + opp-microvolt = <1000000>; + }; + + opp-16667000 { + opp-hz = /bits/ 64 <16667000>; + opp-microvolt = <1000000>; + }; + + opp-15625000 { + opp-hz = /bits/ 64 <15625000>; + opp-microvolt = <1000000>; + }; + + opp-12500000 { + opp-hz = /bits/ 64 <12500000>; + opp-microvolt = <1000000>; + }; + }; + cpus { #address-cells = <1>; #size-cells = <0>; @@ -592,6 +696,167 @@ ssi3: ssi@100e4c00 { status = "disabled"; }; + dsi: dsi@10850000 { + compatible = "renesas,r9a08g046-mipi-dsi"; + reg = <0 0x10850000 0 0x20000>; + interrupts = <GIC_SPI 170 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 172 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 173 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 174 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 175 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 176 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "seq0", "seq1", "vin1", "rcv", + "ferr", "ppi", "debug"; + clocks = <&cpg CPG_CORE R9A08G046_MIPI_DSI_PLLCLK>, + <&cpg CPG_MOD R9A08G046_MIPI_DSI_SYSCLK>, + <&cpg CPG_MOD R9A08G046_MIPI_DSI_ACLK>, + <&cpg CPG_MOD R9A08G046_MIPI_DSI_PCLK>, + <&cpg CPG_MOD R9A08G046_MIPI_DSI_VCLK>, + <&cpg CPG_MOD R9A08G046_MIPI_DSI_LPCLK>; + clock-names = "pllclk", "sysclk", "aclk", "pclk", "vclk", "lpclk"; + power-domains = <&cpg>; + resets = <&cpg R9A08G046_MIPI_DSI_CMN_RSTB>, + <&cpg R9A08G046_MIPI_DSI_ARESET_N>, + <&cpg R9A08G046_MIPI_DSI_PRESET_N>; + reset-names = "rst", "arst", "prst"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dsi_in: endpoint { + remote-endpoint = <&du_out_dsi>; + }; + }; + + port@1 { + reg = <1>; + }; + }; + }; + + vspd: vsp@10870000 { + compatible = "renesas,r9a08g046-vsp2", + "renesas,r9a07g044-vsp2"; + reg = <0 0x10870000 0 0x10000>; + interrupts = <GIC_SPI 177 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD R9A08G046_LCDC_CLK_A>, + <&cpg CPG_MOD R9A08G046_LCDC_CLK_P>, + <&cpg CPG_MOD R9A08G046_LCDC_CLK_D>; + clock-names = "aclk", "pclk", "vclk"; + power-domains = <&cpg>; + resets = <&cpg R9A08G046_LCDC_RESET_N>; + renesas,fcp = <&fcpvd>; + }; + + fcpvd: fcp@10880000 { + compatible = "renesas,r9a08g046-fcpvd", "renesas,fcpv"; + reg = <0 0x10880000 0 0x10000>; + clocks = <&cpg CPG_MOD R9A08G046_LCDC_CLK_A>, + <&cpg CPG_MOD R9A08G046_LCDC_CLK_P>, + <&cpg CPG_MOD R9A08G046_LCDC_CLK_D>; + clock-names = "aclk", "pclk", "vclk"; + power-domains = <&cpg>; + resets = <&cpg R9A08G046_LCDC_RESET_N>; + }; + + du: display@10890000 { + compatible = "renesas,r9a08g046-du"; + reg = <0 0x10890000 0 0x10000>; + interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD R9A08G046_LCDC_CLK_A>, + <&cpg CPG_MOD R9A08G046_LCDC_CLK_P>, + <&cpg CPG_MOD R9A08G046_LCDC_CLK_D>; + clock-names = "aclk", "pclk", "vclk"; + power-domains = <&cpg>; + resets = <&cpg R9A08G046_LCDC_RESET_N>; + renesas,vsps = <&vspd 0>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + du_out_dsi: endpoint { + remote-endpoint = <&dsi_in>; + }; + }; + + port@1 { + reg = <1>; + }; + + port@2 { + reg = <2>; + du_out_lvds: endpoint { + remote-endpoint = <&lvds_in>; + }; + }; + }; + }; + + lvds: lvds@108a0000 { + compatible = "renesas,r9a08g046-lvds"; + reg = <0 0x108a0000 0 0x10000>; + clocks = <&cpg CPG_MOD R9A08G046_MIPI_DSI_PCLK>, + <&cpg CPG_MOD R9A08G046_LVDS_PLLCLK>, + <&cpg CPG_MOD R9A08G046_LVDS_CLK_DOT0>; + clock-names = "pclk", "phyclk", "dotclk"; + power-domains = <&cpg>; + resets = <&cpg R9A08G046_LVDS_RESET_N>, + <&cpg R9A08G046_MIPI_DSI_PRESET_N>, + <&cpg R9A08G046_MIPI_DSI_CMN_RSTB>, + <&cpg R9A08G046_MIPI_DSI_ARESET_N>; + reset-names = "lvdrst", "prst", "rst", "arst"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + lvds_in: endpoint { + remote-endpoint = <&du_out_lvds>; + }; + }; + + port@1 { + reg = <1>; + lvds_out: endpoint { + }; + }; + }; + }; + + gpu: gpu@108b0000 { + compatible = "renesas,r9a08g046-mali", + "arm,mali-bifrost"; + reg = <0x0 0x108b0000 0x0 0x10000>; + interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 179 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "job", "mmu", "gpu", "event"; + clocks = <&cpg CPG_MOD R9A08G046_GE3D_CLK>, + <&cpg CPG_MOD R9A08G046_GE3D_AXI_CLK>, + <&cpg CPG_MOD R9A08G046_GE3D_ACE_CLK>; + clock-names = "gpu", "bus", "bus_ace"; + power-domains = <&cpg>; + resets = <&cpg R9A08G046_GE3D_RESETN>, + <&cpg R9A08G046_GE3D_AXI_RESETN>, + <&cpg R9A08G046_GE3D_ACE_RESETN>; + reset-names = "rst", "axi_rst", "ace_rst"; + operating-points-v2 = <&gpu_opp_table>; + status = "disabled"; + }; + cpg: clock-controller@11010000 { compatible = "renesas,r9a08g046-cpg"; reg = <0 0x11010000 0 0x10000>; @@ -1001,21 +1266,87 @@ queue3 { }; }; + ohci0: usb@11e10000 { + reg = <0 0x11e10000 0 0x100>; + /* placeholder */ + }; + + ohci1: usb@11e90000 { + reg = <0 0x11e90000 0 0x100>; + /* placeholder */ + }; + + ehci0: usb@11e10100 { + reg = <0 0x11e10100 0 0x100>; + /* placeholder */ + }; + + ehci1: usb@11e90100 { + reg = <0 0x11e90100 0 0x100>; + /* placeholder */ + }; + + hsusb0: usb@11e30000 { + reg = <0 0x11e30000 0 0x10000>; + /* placeholder */ + }; + pcie: pcie@11e40000 { + compatible = "renesas,r9a08g046-pcie"; reg = <0 0x11e40000 0 0x10000>; ranges = <0x02000000 0 0x30000000 0 0x30000000 0 0x08000000>; + /* Map all possible DRAM ranges (4 GB). */ + dma-ranges = <0x42000000 0 0x40000000 0 0x40000000 1 0x00000000>; + bus-range = <0x0 0xff>; + interrupts = <GIC_SPI 483 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 484 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 485 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 486 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 487 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 488 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 489 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 490 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 491 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 492 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 493 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 494 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 495 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 496 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 497 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 498 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "serr", "serr_cor", "serr_nonfatal", + "serr_fatal", "axi_err", "inta", + "intb", "intc", "intd", "msi", + "link_bandwidth", "pm_pme", "dma", + "pcie_evt", "msg", "all"; + #interrupt-cells = <1>; + interrupt-controller; + interrupt-map-mask = <0 0 0 7>; + interrupt-map = <0 0 0 1 &pcie 0 0 0 0>, /* INTA */ + <0 0 0 2 &pcie 0 0 0 1>, /* INTB */ + <0 0 0 3 &pcie 0 0 0 2>, /* INTC */ + <0 0 0 4 &pcie 0 0 0 3>; /* INTD */ + clocks = <&cpg CPG_MOD R9A08G046_PCI_ACLK>, + <&cpg CPG_MOD R9A08G046_PCI_CLKL1PM>, + <&cpg CPG_MOD R9A08G046_PCI_CLK_PMU>; + clock-names = "aclk", "pm", "pmu"; + resets = <&cpg R9A08G046_PCI_ARESETN>; + reset-names = "aresetn"; + power-domains = <&cpg>; device_type = "pci"; #address-cells = <3>; #size-cells = <2>; - /* placeholder */ + renesas,sysc = <&sysc>; + status = "disabled"; pcie_port0: pcie@0,0 { reg = <0x0 0x0 0x0 0x0 0x0>; ranges; device_type = "pci"; + vendor-id = <0x1912>; + device-id = <0x0033>; #address-cells = <3>; #size-cells = <2>; - /* placeholder */ }; };
diff --git a/arch/arm64/boot/dts/renesas/r9a08g046l48-smarc.dts b/arch/arm64/boot/dts/renesas/r9a08g046l48-smarc.dts index 5289efd..68d7b57 100644 --- a/arch/arm64/boot/dts/renesas/r9a08g046l48-smarc.dts +++ b/arch/arm64/boot/dts/renesas/r9a08g046l48-smarc.dts
@@ -71,6 +71,18 @@ codec_dai: codec { #endif }; +&ehci0 { + status = "disabled"; +}; + +&ehci1 { + status = "disabled"; +}; + +&hsusb0 { + status = "disabled"; +}; + &i2c2 { pinctrl-0 = <&i2c2_pins>; pinctrl-names = "default"; @@ -122,6 +134,19 @@ &keys { #endif }; +&ohci0 { + status = "disabled"; +}; + +&ohci1 { + status = "disabled"; +}; + +&pcie { + pinctrl-0 = <&pcie_pins>; + pinctrl-names = "default"; +}; + &pinctrl { audio_clk_pins: audio-clock { pinmux = <RZG3L_PORT_PINMUX(H, 4, 6)>, /* AUDIO_CLK_B */ @@ -138,6 +163,17 @@ i2c3_pins: i2c3 { <RZG3L_PORT_PINMUX(2, 1, 4)>; /* RIIC3_SDA */ }; + pcie-clkreq-n-hog { + gpio-hog; + gpios = <RZG3L_GPIO(G, 6) GPIO_ACTIVE_HIGH>; + output-low; + line-name = "PCIE_A_CKREQ"; + }; + + pcie_pins: pcie { + pinmux = <RZG3L_PORT_PINMUX(G, 7, 1)>; /* PCIE_RST_OUT# */ + }; + rsci1_pins: rsci1 { pinmux = <RZG3L_PORT_PINMUX(D, 4, 5)>, /* RSCI1_RXD_MISO_SCL */ <RZG3L_PORT_PINMUX(D, 5, 5)>, /* RSCI1_TXD_MOSI_SDA */
diff --git a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi index 42462c1..fbe1e1c 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g011.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a09g011.dtsi
@@ -85,7 +85,7 @@ sdhi0: mmc@85000000 { status = "disabled"; }; - sdhi1: mmc@85010000 { + sdhi1: mmc@85010000 { compatible = "renesas,sdhi-r9a09g011", "renesas,rzg2l-sdhi"; reg = <0x0 0x85010000 0 0x2000>; @@ -101,7 +101,7 @@ sdhi1: mmc@85010000 { status = "disabled"; }; - emmc: mmc@85020000 { + emmc: mmc@85020000 { compatible = "renesas,sdhi-r9a09g011", "renesas,rzg2l-sdhi"; reg = <0x0 0x85020000 0 0x2000>;
diff --git a/arch/arm64/boot/dts/renesas/r9a09g047.dtsi b/arch/arm64/boot/dts/renesas/r9a09g047.dtsi index 060405d..737bf1c 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g047.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a09g047.dtsi
@@ -1743,6 +1743,130 @@ gic: interrupt-controller@14900000 { interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_LOW>; }; + ohci0: usb@15800000 { + compatible = "generic-ohci"; + reg = <0 0x15800000 0 0x100>; + interrupts = <GIC_SPI 742 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 0xb3>, <&cpg CPG_MOD 0xb6>; + resets = <&usb20phyrst>, <&cpg 0xac>; + phys = <&usb2_phy0 1>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; + + ohci1: usb@15810000 { + compatible = "generic-ohci"; + reg = <0 0x15810000 0 0x100>; + interrupts = <GIC_SPI 747 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 0xb4>, <&cpg CPG_MOD 0xb7>; + resets = <&usb21phyrst>, <&cpg 0xad>; + phys = <&usb2_phy1 1>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; + + ehci0: usb@15800100 { + compatible = "generic-ehci"; + reg = <0 0x15800100 0 0x100>; + interrupts = <GIC_SPI 743 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 0xb3>, <&cpg CPG_MOD 0xb6>; + resets = <&usb20phyrst>, <&cpg 0xac>; + phys = <&usb2_phy0 2>; + phy-names = "usb"; + companion = <&ohci0>; + power-domains = <&cpg>; + status = "disabled"; + }; + + ehci1: usb@15810100 { + compatible = "generic-ehci"; + reg = <0 0x15810100 0 0x100>; + interrupts = <GIC_SPI 748 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 0xb4>, <&cpg CPG_MOD 0xb7>; + resets = <&usb21phyrst>, <&cpg 0xad>; + phys = <&usb2_phy1 2>; + phy-names = "usb"; + companion = <&ohci1>; + power-domains = <&cpg>; + status = "disabled"; + }; + + usb2_phy0: usb-phy@15800200 { + compatible = "renesas,usb2-phy-r9a09g047", + "renesas,usb2-phy-r9a09g057"; + reg = <0 0x15800200 0 0x700>; + interrupts = <GIC_SPI 745 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 0xb3>, + <&cpg CPG_CORE R9A09G047_USB2_0_CLK_CORE0>; + clock-names = "fck", "usb_x1"; + resets = <&usb20phyrst>, <&cpg 0xac>; + #phy-cells = <1>; + power-domains = <&cpg>; + mux-states = <&usb20phyrst 1>; + status = "disabled"; + + usb2_phy0_vbus_otg: vbus-regulator { + regulator-name = "USB2PHY0-VBUS-OTG"; + }; + }; + + usb2_phy1: usb-phy@15810200 { + compatible = "renesas,usb2-phy-r9a09g047", + "renesas,usb2-phy-r9a09g057"; + reg = <0 0x15810200 0 0x700>; + interrupts = <GIC_SPI 750 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 0xb4>, + <&cpg CPG_CORE R9A09G047_USB2_0_CLK_CORE1>; + clock-names = "fck", "usb_x1"; + resets = <&usb21phyrst>, <&cpg 0xad>; + #phy-cells = <1>; + power-domains = <&cpg>; + mux-states = <&usb21phyrst 0>; + status = "disabled"; + }; + + hsusb0: usb@15820000 { + compatible = "renesas,usbhs-r9a09g047", + "renesas,rzg2l-usbhs"; + reg = <0 0x15820000 0 0x10000>; + interrupts = <GIC_SPI 751 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 752 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 753 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 754 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_MOD 0xb3>, <&cpg CPG_MOD 0xb5>; + resets = <&usb20phyrst>, <&cpg 0xae>; + phys = <&usb2_phy0 3>; + phy-names = "usb"; + power-domains = <&cpg>; + status = "disabled"; + }; + + usb20phyrst: reset-controller@15830000 { + compatible = "renesas,r9a09g047-usb2phy-reset", + "renesas,r9a09g057-usb2phy-reset"; + reg = <0 0x15830000 0 0x10000>; + clocks = <&cpg CPG_MOD 0xb6>; + resets = <&cpg 0xaf>; + power-domains = <&cpg>; + #reset-cells = <0>; + #mux-state-cells = <1>; + status = "disabled"; + }; + + usb21phyrst: reset-controller@15840000 { + compatible = "renesas,r9a09g047-usb2phy-reset", + "renesas,r9a09g057-usb2phy-reset"; + reg = <0 0x15840000 0 0x10000>; + clocks = <&cpg CPG_MOD 0xb7>; + resets = <&cpg 0xaf>; + power-domains = <&cpg>; + #reset-cells = <0>; + #mux-state-cells = <1>; + status = "disabled"; + }; + xhci: usb@15850000 { compatible = "renesas,r9a09g047-xhci"; reg = <0 0x15850000 0 0x10000>; @@ -1773,7 +1897,7 @@ usb3_phy: usb-phy@15870000 { status = "disabled"; }; - sdhi0: mmc@15c00000 { + sdhi0: mmc@15c00000 { compatible = "renesas,sdhi-r9a09g047", "renesas,sdhi-r9a09g057"; reg = <0x0 0x15c00000 0 0x10000>; interrupts = <GIC_SPI 735 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/renesas/r9a09g047e57-smarc.dts b/arch/arm64/boot/dts/renesas/r9a09g047e57-smarc.dts index 4eed095..095acb8 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g047e57-smarc.dts +++ b/arch/arm64/boot/dts/renesas/r9a09g047e57-smarc.dts
@@ -112,7 +112,7 @@ &canfd { channel1 { status = "okay"; #if (!SW_LCD_EN) && (SW_GPIO9_CAN1_STB) - phys = <&can_transceiver1>; + phys = <&can_transceiver 1>; #endif }; #endif @@ -121,22 +121,25 @@ channel1 { channel4 { status = "okay"; #if (SW_GPIO8_CAN0_STB) - phys = <&can_transceiver0>; + phys = <&can_transceiver 0>; #endif }; #endif }; -#if (!SW_LCD_EN) && (SW_GPIO8_CAN0_STB) -&can_transceiver0 { - standby-gpios = <&pinctrl RZG3E_GPIO(5, 4) GPIO_ACTIVE_HIGH>; - status = "okay"; -}; +#if (!SW_LCD_EN) && (SW_GPIO8_CAN0_STB || SW_GPIO9_CAN1_STB) +&can_transceiver { + standby-gpios = +#if (SW_GPIO8_CAN0_STB) + <&pinctrl RZG3E_GPIO(5, 4) GPIO_ACTIVE_HIGH>, +#else + <0>, #endif - -#if (!SW_LCD_EN) && (SW_GPIO9_CAN1_STB) -&can_transceiver1 { - standby-gpios = <&pinctrl RZG3E_GPIO(5, 5) GPIO_ACTIVE_HIGH>; +#if (SW_GPIO9_CAN1_STB) + <&pinctrl RZG3E_GPIO(5, 5) GPIO_ACTIVE_HIGH>; +#else + <0>; +#endif status = "okay"; }; #endif @@ -147,6 +150,8 @@ &i2c0 { }; &i2c1 { + clock-frequency = <1000000>; + da7212: codec@1a { compatible = "dlg,da7212"; #sound-dai-cells = <0>; @@ -296,6 +301,17 @@ sd1-data { }; }; + usb20_pins: usb20 { + ovc { + pinmux = <RZG3E_PORT_PINMUX(0, 0, 12)>; /* USB20_OVRCURN */ + bias-pull-up; + }; + + vbus { + pinmux = <RZG3E_PORT_PINMUX(0, 1, 12)>; /* USB20_VBUSEN */ + }; + }; + usb3_pins: usb3 { pinmux = <RZG3E_PORT_PINMUX(4, 1, 12)>, /* USB30_VBUSEN */ <RZG3E_PORT_PINMUX(4, 0, 12)>; /* USB30_OVRCURN */ @@ -392,6 +408,26 @@ &ssi4 { shared-pin; }; +&usb20phyrst { + status = "okay"; +}; + +&usb21phyrst { + status = "okay"; +}; + +&usb2_phy0 { + pinctrl-0 = <&usb20_pins>; + pinctrl-names = "default"; + + vbus-supply = <&usb2_phy0_vbus_otg>; + status = "okay"; +}; + +&usb2_phy1 { + status = "okay"; +}; + &usb3_phy { status = "okay"; };
diff --git a/arch/arm64/boot/dts/renesas/r9a09g056.dtsi b/arch/arm64/boot/dts/renesas/r9a09g056.dtsi index 77c2221..175e24c 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g056.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a09g056.dtsi
@@ -1447,7 +1447,7 @@ usb3_phy: usb-phy@15870000 { status = "disabled"; }; - sdhi0: mmc@15c00000 { + sdhi0: mmc@15c00000 { compatible = "renesas,sdhi-r9a09g056", "renesas,sdhi-r9a09g057"; reg = <0x0 0x15c00000 0 0x10000>; interrupts = <GIC_SPI 735 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/renesas/r9a09g057.dtsi b/arch/arm64/boot/dts/renesas/r9a09g057.dtsi index 188ce9f..bbaab75 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g057.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a09g057.dtsi
@@ -1577,7 +1577,7 @@ usb3_phy1: usb-phy@15880000 { status = "disabled"; }; - sdhi0: mmc@15c00000 { + sdhi0: mmc@15c00000 { compatible = "renesas,sdhi-r9a09g057"; reg = <0x0 0x15c00000 0 0x10000>; interrupts = <GIC_SPI 735 IRQ_TYPE_LEVEL_HIGH>,
diff --git a/arch/arm64/boot/dts/renesas/r9a09g057h44-rzv2h-evk.dts b/arch/arm64/boot/dts/renesas/r9a09g057h44-rzv2h-evk.dts index 637fc92..0926ab8 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g057h44-rzv2h-evk.dts +++ b/arch/arm64/boot/dts/renesas/r9a09g057h44-rzv2h-evk.dts
@@ -461,20 +461,20 @@ sd1-pwr-en-hog { }; sdhi1_pins: sd1 { - sd1_dat_cmd { + sd1-dat-cmd { pins = "SD1DAT0", "SD1DAT1", "SD1DAT2", "SD1DAT3", "SD1CMD"; input-enable; renesas,output-impedance = <3>; slew-rate = <0>; }; - sd1_clk { + sd1-clk { pins = "SD1CLK"; renesas,output-impedance = <3>; slew-rate = <0>; }; - sd1_cd { + sd1-cd { pinmux = <RZV2H_PORT_PINMUX(9, 4, 14)>; /* SD1_CD */ }; };
diff --git a/arch/arm64/boot/dts/renesas/r9a09g077.dtsi b/arch/arm64/boot/dts/renesas/r9a09g077.dtsi index bac3939..674e35e4 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g077.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a09g077.dtsi
@@ -1075,8 +1075,8 @@ xspi1: spi@801c1000 { cpg: clock-controller@80280000 { compatible = "renesas,r9a09g077-cpg-mssr"; - reg = <0 0x80280000 0 0x10000>, - <0 0x81280000 0 0x10000>; + reg = <0 0x80280000 0 0x20000>, + <0 0x81280000 0 0x20000>; clocks = <&extal_clk>; clock-names = "extal"; #clock-cells = <2>; @@ -1173,6 +1173,19 @@ pinctrl: pinctrl@802c0000 { power-domains = <&cpg>; }; + rtc0: rtc@81009000 { + compatible = "renesas,r9a09g077-rtc"; + reg = <0 0x81009000 0 0x1000>; + interrupts = <GIC_SPI 495 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 497 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 496 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "alarm", "timer", "pps"; + clocks = <&cpg CPG_MOD 605>, <&cpg CPG_CORE R9A09G077_PCLKRTC>; + clock-names = "hclk", "xtal"; + power-domains = <&cpg>; + status = "disabled"; + }; + gic: interrupt-controller@83000000 { compatible = "arm,gic-v3"; reg = <0x0 0x83000000 0 0x40000>, @@ -1258,14 +1271,14 @@ adc0: adc@90014000 { <GIC_SPI 699 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 700 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 701 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 702 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 851 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 852 IRQ_TYPE_EDGE_RISING>; + <GIC_SPI 702 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "adi", "gbadi", "gcadi", - "cmpai", "cmpbi", "wcmpm", "wcmpum"; + "cmpai", "cmpbi"; clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKL>, <&cpg CPG_MOD 206>; clock-names = "adclk", "pclk"; + dmas = <&dmac0 0x26ba>, <&dmac1 0x26ba>, <&dmac2 0x26ba>; + dma-names = "rx", "rx", "rx"; power-domains = <&cpg>; #address-cells = <1>; #size-cells = <0>; @@ -1280,14 +1293,14 @@ adc1: adc@90014400 { <GIC_SPI 704 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 705 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 706 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 707 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 853 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 854 IRQ_TYPE_EDGE_RISING>; + <GIC_SPI 707 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "adi", "gbadi", "gcadi", - "cmpai", "cmpbi", "wcmpm", "wcmpum"; + "cmpai", "cmpbi"; clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKL>, <&cpg CPG_MOD 207>; clock-names = "adclk", "pclk"; + dmas = <&dmac0 0x26bf>, <&dmac1 0x26bf>, <&dmac2 0x26bf>; + dma-names = "rx", "rx", "rx"; power-domains = <&cpg>; #address-cells = <1>; #size-cells = <0>; @@ -1302,14 +1315,14 @@ adc2: adc@80008000 { <GIC_SPI 709 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 710 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 711 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 712 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 855 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 856 IRQ_TYPE_EDGE_RISING>; + <GIC_SPI 712 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "adi", "gbadi", "gcadi", - "cmpai", "cmpbi", "wcmpm", "wcmpum"; + "cmpai", "cmpbi"; clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKL>, <&cpg CPG_MOD 225>; clock-names = "adclk", "pclk"; + dmas = <&dmac0 0x26c4>, <&dmac1 0x26c4>, <&dmac2 0x26c4>; + dma-names = "rx", "rx", "rx"; power-domains = <&cpg>; #address-cells = <1>; #size-cells = <0>; @@ -1364,7 +1377,7 @@ hsusb: usb@92041000 { status = "disabled"; }; - sdhi0: mmc@92080000 { + sdhi0: mmc@92080000 { compatible = "renesas,sdhi-r9a09g077", "renesas,sdhi-r9a09g057"; reg = <0x0 0x92080000 0 0x10000>; @@ -1403,6 +1416,52 @@ sdhi1_vqmmc: vqmmc-regulator { status = "disabled"; }; }; + + du: display@920c0000 { + compatible = "renesas,r9a09g077-du"; + reg = <0 0x920c0000 0 0x10000>; + interrupts = <GIC_SPI 781 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKAH>, + <&cpg CPG_MOD 1204>, + <&cpg CPG_CORE R9A09G077_LCDC_CLKD>; + clock-names = "aclk", "pclk", "vclk"; + power-domains = <&cpg>; + renesas,vsps = <&vspd 0>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + du_out_rgb: endpoint { + }; + }; + }; + }; + + fcpvd: fcp@920d0000 { + compatible = "renesas,r9a09g077-fcpvd", "renesas,fcpv"; + reg = <0 0x920d0000 0 0x10000>; + clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKAH>, + <&cpg CPG_MOD 1204>, + <&cpg CPG_CORE R9A09G077_LCDC_CLKD>; + clock-names = "aclk", "pclk", "vclk"; + power-domains = <&cpg>; + }; + + vspd: vsp@920e0000 { + compatible = "renesas,r9a09g077-vsp2", "renesas,r9a07g044-vsp2"; + reg = <0 0x920e0000 0 0x8000>; + interrupts = <GIC_SPI 780 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_CORE R9A09G077_CLK_PCLKAH>, + <&cpg CPG_MOD 1204>, + <&cpg CPG_CORE R9A09G077_LCDC_CLKD>; + clock-names = "aclk", "pclk", "vclk"; + power-domains = <&cpg>; + renesas,fcp = <&fcpvd>; + }; }; stmmac_axi_setup: stmmac-axi-config {
diff --git a/arch/arm64/boot/dts/renesas/r9a09g077m44-evk-cn15-lcdc.dtso b/arch/arm64/boot/dts/renesas/r9a09g077m44-evk-cn15-lcdc.dtso new file mode 100644 index 0000000..aaddfc1 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r9a09g077m44-evk-cn15-lcdc.dtso
@@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DT overlay for the RZ/T2H EVK with ADV7513 transmitter + * connected to DU enabled. + * + * Copyright (C) 2026 Renesas Electronics Corp. + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/interrupt-controller/irq.h> + +#define RZT2H_IRQ8 24 + +/* + * RZ/T2H LCDC configuration: + * ---------------------------------------------------------- + * Function Pin SW Setting + * ---------------------------------------------------------- + * LCDC_DATG0 P11_0, SW6[3]: OFF, SW6[4]: ON, SW6[5]: OFF + * LCDC_DATB1 P18_0, SW8[3]: OFF, SW8[4]: ON + * LCDC_DATB2 P18_1, SW8[1]: OFF, SW8[2]: ON + * IRQ8 P22_6, SW2[1]: ON, SW2[2]: OFF + */ + +&{/leds/led-4} { + /* P18_0 is used for DU function LCDC_DATB1. */ + status = "disabled"; +}; + +&{/leds/led-5} { + /* P18_1 is used for DU function LCDC_DATB2. */ + status = "disabled"; +}; + +/* + * Disable SDHI0 as SW2 settings for eMMC/SD card conflict with DU pin + * settings. + */ +&sdhi0 { + status = "disabled"; +}; + +#include "rzt2h-n2h-evk-du-adv7513.dtsi" + +&adv7513 { + interrupts-extended = <&icu RZT2H_IRQ8 IRQ_TYPE_LEVEL_LOW>; +}; + +&adv7513_irq_pins { + pinmux = <RZT2H_PORT_PINMUX(22, 6, 0x0)>; /* IRQ8 */ +};
diff --git a/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts b/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts index 572be8a..d21367c 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts +++ b/arch/arm64/boot/dts/renesas/r9a09g077m44-rzt2h-evk.dts
@@ -69,7 +69,7 @@ keys { compatible = "gpio-keys"; #if (!SD1_MICRO_SD) - /* SW2-3: OFF */ + /* SW2[3]: OFF */ key-1 { interrupts-extended = <&pinctrl RZT2H_GPIO(8, 6) IRQ_TYPE_EDGE_FALLING>; linux,code = <KEY_1>; @@ -100,7 +100,7 @@ leds { compatible = "gpio-leds"; led-0 { - /* SW8-9: ON, SW8-10: OFF */ + /* SW8[9]: ON, SW8[10]: OFF */ gpios = <&pinctrl RZT2H_GPIO(23, 1) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_GREEN>; function = LED_FUNCTION_DEBUG; @@ -108,7 +108,7 @@ led-0 { }; led-1 { - /* SW5-1: OFF, SW5-2: ON */ + /* SW5[1]: OFF, SW5[2]: ON */ gpios = <&pinctrl RZT2H_GPIO(32, 2) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_GREEN>; function = LED_FUNCTION_DEBUG; @@ -124,7 +124,7 @@ led-2 { #if (!SD1_MICRO_SD) led-3 { - /* SW2-3: OFF */ + /* SW2[3]: OFF */ gpios = <&pinctrl RZT2H_GPIO(8, 5) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_RED>; function = LED_FUNCTION_DEBUG; @@ -133,7 +133,7 @@ led-3 { #endif led-4 { - /* SW8-3: ON, SW8-4: OFF */ + /* SW8[3]: ON, SW8[4]: OFF */ gpios = <&pinctrl RZT2H_GPIO(18, 0) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_GREEN>; function = LED_FUNCTION_DEBUG; @@ -141,7 +141,7 @@ led-4 { }; led-5 { - /* SW8-1: ON, SW8-2: OFF */ + /* SW8[1]: ON, SW8[2]: OFF */ gpios = <&pinctrl RZT2H_GPIO(18, 1) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_RED>; function = LED_FUNCTION_DEBUG; @@ -149,7 +149,7 @@ led-5 { }; led-6 { - /* SW5-9: OFF, SW5-10: ON */ + /* SW5[9]: OFF, SW5[10]: ON */ gpios = <&pinctrl RZT2H_GPIO(22, 7) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_GREEN>; function = LED_FUNCTION_DEBUG; @@ -157,7 +157,7 @@ led-6 { }; led-7 { - /* SW5-7: OFF, SW5-8: ON */ + /* SW5[7]: OFF, SW5[8]: ON */ gpios = <&pinctrl RZT2H_GPIO(23, 0) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_GREEN>; function = LED_FUNCTION_DEBUG; @@ -165,7 +165,7 @@ led-7 { }; led-8 { - /* SW7-5: OFF, SW7-6: ON */ + /* SW7[5]: OFF, SW7[6]: ON */ gpios = <&pinctrl RZT2H_GPIO(23, 5) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_GREEN>; function = LED_FUNCTION_DEBUG;
diff --git a/arch/arm64/boot/dts/renesas/r9a09g087.dtsi b/arch/arm64/boot/dts/renesas/r9a09g087.dtsi index 03b976d..68c8dae 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g087.dtsi +++ b/arch/arm64/boot/dts/renesas/r9a09g087.dtsi
@@ -1078,8 +1078,8 @@ xspi1: spi@801c1000 { cpg: clock-controller@80280000 { compatible = "renesas,r9a09g087-cpg-mssr"; - reg = <0 0x80280000 0 0x10000>, - <0 0x81280000 0 0x10000>; + reg = <0 0x80280000 0 0x20000>, + <0 0x81280000 0 0x20000>; clocks = <&extal_clk>; clock-names = "extal"; #clock-cells = <2>; @@ -1176,6 +1176,19 @@ pinctrl: pinctrl@802c0000 { power-domains = <&cpg>; }; + rtc0: rtc@81009000 { + compatible = "renesas,r9a09g087-rtc", "renesas,r9a09g077-rtc"; + reg = <0 0x81009000 0 0x1000>; + interrupts = <GIC_SPI 495 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 497 IRQ_TYPE_EDGE_RISING>, + <GIC_SPI 496 IRQ_TYPE_EDGE_RISING>; + interrupt-names = "alarm", "timer", "pps"; + clocks = <&cpg CPG_MOD 605>, <&cpg CPG_CORE R9A09G087_PCLKRTC>; + clock-names = "hclk", "xtal"; + power-domains = <&cpg>; + status = "disabled"; + }; + gic: interrupt-controller@83000000 { compatible = "arm,gic-v3"; reg = <0x0 0x83000000 0 0x40000>, @@ -1261,14 +1274,14 @@ adc0: adc@90014000 { <GIC_SPI 699 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 700 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 701 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 702 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 851 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 852 IRQ_TYPE_EDGE_RISING>; + <GIC_SPI 702 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "adi", "gbadi", "gcadi", - "cmpai", "cmpbi", "wcmpm", "wcmpum"; + "cmpai", "cmpbi"; clocks = <&cpg CPG_CORE R9A09G087_CLK_PCLKL>, <&cpg CPG_MOD 206>; clock-names = "adclk", "pclk"; + dmas = <&dmac0 0x26ba>, <&dmac1 0x26ba>, <&dmac2 0x26ba>; + dma-names = "rx", "rx", "rx"; power-domains = <&cpg>; #address-cells = <1>; #size-cells = <0>; @@ -1283,14 +1296,14 @@ adc1: adc@90014400 { <GIC_SPI 704 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 705 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 706 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 707 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 853 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 854 IRQ_TYPE_EDGE_RISING>; + <GIC_SPI 707 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "adi", "gbadi", "gcadi", - "cmpai", "cmpbi", "wcmpm", "wcmpum"; + "cmpai", "cmpbi"; clocks = <&cpg CPG_CORE R9A09G087_CLK_PCLKL>, <&cpg CPG_MOD 207>; clock-names = "adclk", "pclk"; + dmas = <&dmac0 0x26bf>, <&dmac1 0x26bf>, <&dmac2 0x26bf>; + dma-names = "rx", "rx", "rx"; power-domains = <&cpg>; #address-cells = <1>; #size-cells = <0>; @@ -1305,14 +1318,14 @@ adc2: adc@80008000 { <GIC_SPI 709 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 710 IRQ_TYPE_EDGE_RISING>, <GIC_SPI 711 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 712 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 855 IRQ_TYPE_EDGE_RISING>, - <GIC_SPI 856 IRQ_TYPE_EDGE_RISING>; + <GIC_SPI 712 IRQ_TYPE_LEVEL_HIGH>; interrupt-names = "adi", "gbadi", "gcadi", - "cmpai", "cmpbi", "wcmpm", "wcmpum"; + "cmpai", "cmpbi"; clocks = <&cpg CPG_CORE R9A09G087_CLK_PCLKL>, <&cpg CPG_MOD 225>; clock-names = "adclk", "pclk"; + dmas = <&dmac0 0x26c4>, <&dmac1 0x26c4>, <&dmac2 0x26c4>; + dma-names = "rx", "rx", "rx"; power-domains = <&cpg>; #address-cells = <1>; #size-cells = <0>; @@ -1367,7 +1380,7 @@ hsusb: usb@92041000 { status = "disabled"; }; - sdhi0: mmc@92080000 { + sdhi0: mmc@92080000 { compatible = "renesas,sdhi-r9a09g087", "renesas,sdhi-r9a09g057"; reg = <0x0 0x92080000 0 0x10000>; @@ -1406,6 +1419,52 @@ sdhi1_vqmmc: vqmmc-regulator { status = "disabled"; }; }; + + du: display@920c0000 { + compatible = "renesas,r9a09g087-du", "renesas,r9a09g077-du"; + reg = <0 0x920c0000 0 0x10000>; + interrupts = <GIC_SPI 781 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_CORE R9A09G087_CLK_PCLKAH>, + <&cpg CPG_MOD 1204>, + <&cpg CPG_CORE R9A09G087_LCDC_CLKD>; + clock-names = "aclk", "pclk", "vclk"; + power-domains = <&cpg>; + renesas,vsps = <&vspd 0>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + du_out_rgb: endpoint { + }; + }; + }; + }; + + fcpvd: fcp@920d0000 { + compatible = "renesas,r9a09g087-fcpvd", "renesas,fcpv"; + reg = <0 0x920d0000 0 0x10000>; + clocks = <&cpg CPG_CORE R9A09G087_CLK_PCLKAH>, + <&cpg CPG_MOD 1204>, + <&cpg CPG_CORE R9A09G087_LCDC_CLKD>; + clock-names = "aclk", "pclk", "vclk"; + power-domains = <&cpg>; + }; + + vspd: vsp@920e0000 { + compatible = "renesas,r9a09g087-vsp2", "renesas,r9a07g044-vsp2"; + reg = <0 0x920e0000 0 0x8000>; + interrupts = <GIC_SPI 780 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cpg CPG_CORE R9A09G087_CLK_PCLKAH>, + <&cpg CPG_MOD 1204>, + <&cpg CPG_CORE R9A09G087_LCDC_CLKD>; + clock-names = "aclk", "pclk", "vclk"; + power-domains = <&cpg>; + renesas,fcp = <&fcpvd>; + }; }; stmmac_axi_setup: stmmac-axi-config {
diff --git a/arch/arm64/boot/dts/renesas/r9a09g087m44-evk-cn20-lcdc.dtso b/arch/arm64/boot/dts/renesas/r9a09g087m44-evk-cn20-lcdc.dtso new file mode 100644 index 0000000..9c9e4fc --- /dev/null +++ b/arch/arm64/boot/dts/renesas/r9a09g087m44-evk-cn20-lcdc.dtso
@@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DT overlay for the RZ/N2H EVK with ADV7513 transmitter + * connected to DU enabled. + * + * Copyright (C) 2026 Renesas Electronics Corp. + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/interrupt-controller/irq.h> + +#define RZN2H_IRQ5 21 + +/* + * RZ/N2H LCDC configuration: + * ---------------------------------------------------------- + * Function Pin SW Setting + * ---------------------------------------------------------- + * LCDC_DATG0 P11_0, DSW12[3]: ON, DSW12[4]: OFF + * LCDC_DATG3 P14_3, DSW18[5]: OFF, DSW18[6]: ON, DSW19[3]: OFF, DSW19[4]: ON + * LCDC_DATG6 P14_6, DSW15[8]: ON, DSW15[9]: OFF, DSW15[10]: OFF + * LCDC_DATB2 P18_1, DSW18[9]: OFF, DSW18[10]: ON + * I2C_SCL1 P03_3, DSW7[1]: ON, DSW7[2]: OFF + * I2C_SDA1 P03_4, DSW7[3]: ON, DSW7[4]: OFF + * ------------------------------------------------ + */ + +&{/keys/key-1} { + /* P18_2 is used for DU function LCDC_DATB3. */ + status = "disabled"; +}; + +&{/leds/led-4} { + /* P18_1 is used for DU function LCDC_DATB2. */ + status = "disabled"; +}; + +&{/leds/led-7} { + /* P14_3 is used for DU function LCDC_DATG3. */ + status = "disabled"; +}; + +&{/leds/led-8} { + /* P14_6 is used for DU function LCDC_DATG6. */ + status = "disabled"; +}; + +&i2c0 { + /* P14_6 is used for DU function LCDC_DATG6. */ + status = "disabled"; +}; + +#include "rzt2h-n2h-evk-du-adv7513.dtsi" + +&adv7513 { + interrupts-extended = <&icu RZN2H_IRQ5 IRQ_TYPE_LEVEL_LOW>; +}; + +&adv7513_irq_pins { + pinmux = <RZT2H_PORT_PINMUX(14, 0, 0x0)>; /* IRQ5 */ +};
diff --git a/arch/arm64/boot/dts/renesas/r9a09g087m44-rzn2h-evk.dts b/arch/arm64/boot/dts/renesas/r9a09g087m44-rzn2h-evk.dts index 4e57d4f..9d54e76 100644 --- a/arch/arm64/boot/dts/renesas/r9a09g087m44-rzn2h-evk.dts +++ b/arch/arm64/boot/dts/renesas/r9a09g087m44-rzn2h-evk.dts
@@ -120,7 +120,7 @@ leds { compatible = "gpio-leds"; led-3 { - /* DSW18-7: ON, DSW18-8: OFF */ + /* DSW18[7]: ON, DSW18[8]: OFF */ gpios = <&pinctrl RZT2H_GPIO(31, 6) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_GREEN>; function = LED_FUNCTION_DEBUG; @@ -128,7 +128,7 @@ led-3 { }; led-4 { - /* DSW18-9: ON, DSW18-10: OFF */ + /* DSW18[9]: ON, DSW18[10]: OFF */ gpios = <&pinctrl RZT2H_GPIO(18, 1) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_RED>; function = LED_FUNCTION_DEBUG; @@ -136,7 +136,7 @@ led-4 { }; led-5 { - /* DSW18-1: ON, DSW18-2: OFF */ + /* DSW18[1]: ON, DSW18[2]: OFF */ gpios = <&pinctrl RZT2H_GPIO(22, 7) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_GREEN>; function = LED_FUNCTION_DEBUG; @@ -144,7 +144,7 @@ led-5 { }; led-6 { - /* DSW18-3: ON, DSW18-4: OFF */ + /* DSW18[3]: ON, DSW18[4]: OFF */ gpios = <&pinctrl RZT2H_GPIO(23, 0) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_GREEN>; function = LED_FUNCTION_DEBUG; @@ -153,8 +153,8 @@ led-6 { led-7 { /* - * DSW18-5: ON, DSW18-6: OFF - * DSW19-3: OFF, DSW19-4: ON + * DSW18[5]: ON, DSW18[6]: OFF + * DSW19[3]: OFF, DSW19[4]: ON */ gpios = <&pinctrl RZT2H_GPIO(14, 3) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_GREEN>; @@ -162,36 +162,40 @@ led-7 { function-enumerator = <8>; }; -#if LED8 led-8 { +#if LED8 /* * USER_LED0 - * DSW15-8: OFF, DSW15-9: OFF, DSW15-10: ON + * DSW15[8]: OFF, DSW15[9]: OFF, DSW15[10]: ON */ gpios = <&pinctrl RZT2H_GPIO(14, 6) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_GREEN>; function = LED_FUNCTION_DEBUG; function-enumerator = <0>; - }; +#else + status = "disabled"; #endif + }; -#if LED9 led-9 { +#if LED9 /* * USER_LED1 - * DSW15-5: OFF, DSW15-6: ON + * DSW15[5]: OFF, DSW15[6]: ON */ gpios = <&pinctrl RZT2H_GPIO(14, 7) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_GREEN>; function = LED_FUNCTION_DEBUG; function-enumerator = <1>; - }; +#else + status = "disabled"; #endif + }; led-10 { /* * USER_LED2 - * DSW17-3: OFF, DSW17-4: ON + * DSW17[3]: OFF, DSW17[4]: ON */ gpios = <&pinctrl RZT2H_GPIO(2, 7) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_YELLOW>; @@ -202,7 +206,7 @@ led-10 { led-11 { /* * USER_LED3 - * DSW17-1: OFF, DSW17-2: ON + * DSW17[1]: OFF, DSW17[2]: ON */ gpios = <&pinctrl RZT2H_GPIO(3, 0) GPIO_ACTIVE_HIGH>; color = <LED_COLOR_ID_RED>;
diff --git a/arch/arm64/boot/dts/renesas/renesas-smarc2.dtsi b/arch/arm64/boot/dts/renesas/renesas-smarc2.dtsi index 696a933..234ca28 100644 --- a/arch/arm64/boot/dts/renesas/renesas-smarc2.dtsi +++ b/arch/arm64/boot/dts/renesas/renesas-smarc2.dtsi
@@ -44,16 +44,9 @@ chosen { stdout-path = "serial3:115200n8"; }; - can_transceiver0: can-phy0 { - compatible = "ti,tcan1042"; - #phy-cells = <0>; - max-bitrate = <8000000>; - status = "disabled"; - }; - - can_transceiver1: can-phy1 { - compatible = "ti,tcan1042"; - #phy-cells = <0>; + can_transceiver: can-phy { + compatible = "ti,tcan1046", "nxp,tja1048"; + #phy-cells = <1>; max-bitrate = <8000000>; status = "disabled"; }; @@ -91,11 +84,36 @@ &canfd { status = "okay"; }; +&ehci0 { + dr_mode = "otg"; + status = "okay"; +}; + +&ehci1 { + dr_mode = "host"; + status = "okay"; +}; + +&hsusb0 { + dr_mode = "otg"; + status = "okay"; +}; + &i2c0 { status = "okay"; clock-frequency = <400000>; }; +&ohci0 { + dr_mode = "otg"; + status = "okay"; +}; + +&ohci1 { + dr_mode = "host"; + status = "okay"; +}; + &pcie { status = "okay"; };
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot-common.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot-common.dtsi new file mode 100644 index 0000000..9f46c73 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot-common.dtsi
@@ -0,0 +1,560 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> +/ { + /* power for M.2 B-Key connector (J6) */ + regulator-m2-b { + compatible = "regulator-fixed"; + regulator-name = "m2-b"; + gpios = <&tca6416_u20 5 GPIO_ACTIVE_HIGH>; + regulator-always-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + enable-active-high; + }; + + /* power for M.2 M-Key connector (J4) */ + regulator-m2-m { + compatible = "regulator-fixed"; + regulator-name = "m2-m"; + gpios = <&tca6416_u20 6 GPIO_ACTIVE_HIGH>; + regulator-always-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + enable-active-high; + }; + + /* power for USB-A J27 behind USB Hub Port 3 */ + regulator-vbus-2 { + compatible = "regulator-fixed"; + regulator-name = "vbus2"; + regulator-always-on; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + gpios = <&tca6416_u20 12 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + /* power for USB-A J27 behind USB Hub Port 4 */ + regulator-vbus-3 { + compatible = "regulator-fixed"; + regulator-name = "vbus3"; + regulator-always-on; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + gpios = <&tca6416_u20 13 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + aliases { + i2c3 = &i2c_exp; + i2c4 = &i2c_csi; + i2c5 = &i2c_dsi; + i2c6 = &i2c_lvds; + rtc0 = &carrier_rtc; + rtc1 = &pmic; + serial3 = &scif3; + }; + + gpio-keys { + compatible = "gpio-keys"; + + wakeup-event { + interrupts-extended = <&tca6416_u21 11 IRQ_TYPE_EDGE_FALLING>; + label = "m2-m-wakeup"; + wakeup-source; + linux,code = <KEY_WAKEUP>; + }; + }; + + can_mux: mux-controller-1 { + compatible = "gpio-mux"; + /* default J9-55/57/59/61 to on-board transceivers */ + idle-state = <0>; + #mux-control-cells = <0>; + /* + * Mux routes CAN bus signals between SoM connector pins, + * expansion connector (J22) and on-board transceivers using + * two GPIO: + * - IO3: 0 = on-board transceivers, 1 = expansion connector + * - IO4: 0 = J9-55/57/59/61, 1 = J7-12/16 & J9-54/56 + */ + mux-gpios = <&tca6416_u20 3 GPIO_ACTIVE_HIGH>, + <&tca6416_u20 4 GPIO_ACTIVE_HIGH>; + }; + + spi_mux: mux-controller-2 { + compatible = "gpio-mux"; + /* default on-board */ + idle-state = <0>; + /* + * Mux switches spi bus between on-board tpm + * and expansion connector (J22). + */ + mux-gpios = <&tca6416_u21 0 GPIO_ACTIVE_HIGH>; + #mux-control-cells = <0>; + }; + + scif1_scif3_b2b_mux: mux-controller-3 { + compatible = "gpio-mux"; + /* default on-board */ + idle-state = <0>; + #mux-control-cells = <0>; + /* + * Mux switches both scif1 and scif3 tx/rx between expansion + * connector (J22) and on-board rs232/rs485 transceivers + * using one GPIO: 0 = on-board, 1 = connector. + */ + mux-gpios = <&tca6416_u20 0 GPIO_ACTIVE_HIGH>; + }; + + scif1_rs_232_485_mux: mux-controller-4 { + compatible = "gpio-mux"; + /* default rs232 */ + idle-state = <0>; + #mux-control-cells = <0>; + /* + * Mux switches scif1 tx/rx between rs232 and rs485 + * transceivers. using one GPIO: 0 = rs232, 1 = rs485. + */ + mux-gpios = <&tca6416_u20 1 GPIO_ACTIVE_HIGH>; + }; + + scif3_rs_232_485_mux: mux-controller-5 { + compatible = "gpio-mux"; + /* default rs232 */ + idle-state = <0>; + #mux-control-cells = <0>; + /* + * Mux switches scif3 tx/rx between rs232 and rs485 + * transceivers. using one GPIO: 0 = rs232, 1 = rs485. + */ + mux-gpios = <&tca6416_u20 2 GPIO_ACTIVE_HIGH>; + }; + + v_1_2: regulator-1v2 { + compatible = "regulator-fixed"; + regulator-name = "1v2"; + regulator-max-microvolt = <1200000>; + regulator-min-microvolt = <1200000>; + }; + + v_3_3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3v3"; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + }; + + reg_dsi_panel: regulator-dsi-panel { + compatible = "regulator-fixed"; + regulator-name = "dsi-panel"; + gpios = <&tca6416_u20 15 GPIO_ACTIVE_HIGH>; + regulator-max-microvolt = <11200000>; + regulator-min-microvolt = <11200000>; + enable-active-high; + }; + + vmmc: regulator-mmc { + compatible = "regulator-fixed"; + regulator-name = "vmmc"; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + startup-delay-us = <250>; + vin-supply = <&v_3_3>; + gpios = <&pinctrl RZG2L_GPIO(4, 1) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + /* power for USB-A J5003 */ + vbus1: regulator-vbus-1 { + compatible = "regulator-fixed"; + regulator-name = "vbus1"; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + gpios = <&tca6416_u20 14 GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + rfkill-m2-b-gnss { + compatible = "rfkill-gpio"; + /* rfkill-gpio inverts internally */ + shutdown-gpios = <&tca6416_u20 10 GPIO_ACTIVE_LOW>; + label = "m2-b gnss"; + radio-type = "gps"; + }; + + rfkill-m2-b-wwan { + compatible = "rfkill-gpio"; + /* rfkill-gpio inverts internally */ + shutdown-gpios = <&tca6416_u20 9 GPIO_ACTIVE_HIGH>; + label = "m2-b radio"; + radio-type = "wwan"; + }; +}; + +&ehci1 { + #address-cells = <1>; + #size-cells = <0>; + + hub_2_0: hub@1 { + compatible = "usb4b4,6502", "usb4b4,6506"; + reg = <1>; + reset-gpios = <&tca6416_u20 11 GPIO_ACTIVE_LOW>; + vdd2-supply = <&v_3_3>; + vdd-supply = <&v_1_2>; + }; +}; + +&i2c0 { + /* highest i2c clock supported by all peripherals is 400kHz */ + + tca6416_u20: gpio@20 { + compatible = "ti,tcal6416"; + reg = <0x20>; + #gpio-cells = <2>; + gpio-controller; + gpio-line-names = "TCA_INT/EXT_UART", "TCA_UARTA_232/485", + "TCA_UARTB_232/485", "TCA_INT/EXT_CAN", + "TCA_NXP/REN", "TCA_M.2B_3V3_EN", + "TCA_M.2M_3V3_EN", "TCA_M.2M_RESET#", + "TCA_M.2B_RESET#", "TCA_M.2B_W_DIS#", + "TCA_M.2B_GPS_EN#", "TCA_USB-HUB_RST#", + "TCA_USB_HUB3_PWR_EN", "TCA_USB_HUB4_PWR_EN", + "TCA_USB1_PWR_EN", "TCA_VIDEO_PWR_EN"; + + m2-b-reset-hog { + gpios = <8 GPIO_ACTIVE_LOW>; + gpio-hog; + line-name = "m2-b-reset"; + output-low; + }; + + m2-m-reset-hog { + gpios = <7 GPIO_ACTIVE_LOW>; + gpio-hog; + line-name = "m2-m-reset"; + /* + * M.2 Key-M connector only supports PCI, + * but RZ/G2L(C) has no pci controller. + * Keep any card in reset. + */ + output-high; + }; + }; + + tca6416_u21: gpio@21 { + compatible = "ti,tcal6416"; + reg = <0x21>; + #interrupt-cells = <2>; + interrupt-controller; + #gpio-cells = <2>; + gpio-controller; + gpio-line-names = "TCA_SPI_TPM/EXT", "TCA_TPM_RST#", + "TCA_I2C_RST", "TCA_RS232_SHTD#", + "TCA_LCD_I2C_RST", "TCA_DIG_OUT1", + "TCA_bDIG_IN1", "TCA_SENS_INT", + "TCA_ALERT#", "TCA_TPM_PIRQ#", + "TCA_RTC_INT", "TCA_M.2M_WAKW_ON_LAN", + "TCA_M.2M_CLKREQ#", "TCA_LVDS_INT#", + "", "TCA_POE_AT"; + /* + * Level interrupts are typical for gpio expander but not supported on rz/g2l + * gpios. However since TCAL6416 latches interrupts and clears only on reading + * port register, falling edge trigger doesn't lose events. + */ + interrupts-extended = <&pinctrl RZG2L_GPIO(4, 0) IRQ_TYPE_EDGE_FALLING>; + + lcd-i2c-reset-hog { + gpios = <4 (GPIO_ACTIVE_LOW|GPIO_PULL_UP|GPIO_OPEN_DRAIN)>; + line-name = "lcd-i2c-reset"; + output-low; + /* + * reset shared between U37 and U48, to be + * supported once gpio-pca953x switches to + * reset framework. + */ + gpio-hog; + }; + + lvds-irq-hog { + gpios = <13 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + gpio-hog; + input; + line-name = "lvds-irq"; + }; + + m2-m-clkreq-hog { + gpios = <12 GPIO_ACTIVE_LOW>; + gpio-hog; + input; + line-name = "m2-m-clkreq"; + }; + + rs232_shutdown: rs232-shutdown-hog { + gpios = <3 GPIO_ACTIVE_LOW>; + gpio-hog; + line-name = "rs232-shutdown"; + output-low; + }; + + sensor-irq-hog { + gpios = <7 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + gpio-hog; + input; + line-name = "sensor-irq"; + }; + + tpm-irq-hog { + gpios = <9 (GPIO_ACTIVE_LOW | GPIO_PULL_UP)>; + gpio-hog; + input; + line-name = "tpm-irq"; + }; + }; + + led-controller@30 { + compatible = "ti,lp5562"; + reg = <0x30>; + #address-cells = <1>; + #size-cells = <0>; + /* use internal clock, could use external generated by rtc */ + clock-mode = /bits/ 8 <1>; + + multi-led@0 { + reg = <0x0>; + #address-cells = <1>; + #size-cells = <0>; + color = <LED_COLOR_ID_RGB>; + label = "D7"; + + led@0 { + reg = <0x0>; + color = <LED_COLOR_ID_RED>; + led-cur = /bits/ 8 <0x32>; + max-cur = /bits/ 8 <0x64>; + }; + + led@1 { + reg = <0x1>; + color = <LED_COLOR_ID_GREEN>; + led-cur = /bits/ 8 <0x19>; + max-cur = /bits/ 8 <0x32>; + }; + + led@2 { + reg = <0x2>; + color = <LED_COLOR_ID_BLUE>; + led-cur = /bits/ 8 <0x19>; + max-cur = /bits/ 8 <0x32>; + }; + }; + + led@3 { + reg = <0x3>; + chan-name = "D8"; + color = <LED_COLOR_ID_GREEN>; + label = "D8"; + led-cur = /bits/ 8 <0x19>; + max-cur = /bits/ 8 <0x64>; + }; + }; + + light-sensor@44 { + compatible = "isil,isl29023"; + reg = <0x44>; + /* IRQ shared between accelerometer, light-sensor and Tamper input (J5007) */ + interrupts-extended = <&tca6416_u21 7 IRQ_TYPE_LEVEL_LOW>; + }; + + accelerometer@53 { + compatible = "adi,adxl345"; + reg = <0x53>; + interrupts-extended = <&tca6416_u21 7 IRQ_TYPE_LEVEL_LOW>; + /* IRQ shared between accelerometer, light-sensor and Tamper input (J5007) */ + interrupt-names = "INT1"; + }; + + carrier_eeprom: eeprom@57 { + compatible = "atmel,24c02"; + reg = <0x57>; + pagesize = <8>; + }; + + carrier_rtc: rtc@69 { + compatible = "abracon,ab1805"; + reg = <0x69>; + /* + * AM1805 RTC used on this board has only nTIRQ pins wired, + * which is for countdown timer irqs only. + * Driver does not support this, disable for now. + * + * interrupts-extended = <&tca6416_u21 10 IRQ_TYPE_LEVEL_LOW>; + */ + abracon,tc-diode = "schottky"; + abracon,tc-resistor = <3>; + }; +}; + +&i2c1 { + /* highest i2c clock supported by all peripherals is 400kHz */ + + i2c-mux@70 { + compatible = "nxp,pca9546"; + reg = <0x70>; + #address-cells = <1>; + #size-cells = <0>; + /* + * This reset is open drain with HW 10k pull-up resistor, + * but reset core does not support GPIO_OPEN_DRAIN flag. + * The pull-up and GPIO voltages match, push-pull is safe. + */ + reset-gpios = <&tca6416_u21 2 GPIO_ACTIVE_LOW>; + + /* channel 0 routed to expansion connector (J22) */ + i2c_exp: i2c@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + /* channel 1 routed to mipi-csi connector (J23) */ + i2c_csi: i2c@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + }; + + /* channel 2 routed to mipi-dsi connector (J25) */ + i2c_dsi: i2c@2 { + reg = <2>; + #address-cells = <1>; + #size-cells = <0>; + + tca6408_u48: gpio@21 { + compatible = "ti,tca6408"; + reg = <0x21>; + #gpio-cells = <2>; + gpio-line-names = "CAM_RST#", "DSI_RESET", + "DSI_STBYB", "DSI_PWM_BL", + "DSI_L/R", "DSI_U/D", + "DSI_CTP_/RST", "CAM_TRIG"; + /* + * reset shared between U37 and U48, to be + * supported once gpio-pca953x switches to + * reset framework. + * + * reset-gpios = <&tca6416_u21 4 + * (GPIO_ACTIVE_LOW|GPIO_PULL_UP|GPIO_OPEN_DRAIN)>; + */ + gpio-controller; + }; + }; + + /* channel 3 routed to lvds connector (J24) */ + i2c_lvds: i2c@3 { + reg = <3>; + #address-cells = <1>; + #size-cells = <0>; + + tca6408_u37: gpio@20 { + compatible = "ti,tca6408"; + reg = <0x20>; + #gpio-cells = <2>; + gpio-line-names = "SELB", "LVDS_RESET", + "LVDS_STBYB", "LVDS_PWM_BL", + "LVDS_L/R", "LVDS_U/D", + "LVDS_CTP_/RST", ""; + /* + * reset shared between U37 and U48, to be + * supported once gpio-pca953x switches to + * reset framework. + * + * reset-gpios = <&tca6416_u21 4 + * (GPIO_ACTIVE_LOW|GPIO_PULL_UP|GPIO_OPEN_DRAIN)>; + */ + gpio-controller; + }; + }; + }; +}; + +&ohci0 { + dr_mode = "host"; +}; + +&phy0 { + leds { + #address-cells = <1>; + #size-cells = <0>; + + /* LED_0 pin */ + led@0 { + reg = <0>; + color = <LED_COLOR_ID_GREEN>; + default-state = "keep"; + function = LED_FUNCTION_LAN; + }; + }; +}; + +&pinctrl { + /* UARTA */ + scif1_pins: scif1 { + pinmux = <RZG2L_PORT_PINMUX(40, 1, 1)>, /* SCIF1_RXD */ + <RZG2L_PORT_PINMUX(40, 0, 1)>; /* SCIF1_TXD */ + }; + + /* UARTB */ + scif3_pins: scif3 { + pinmux = <RZG2L_PORT_PINMUX(0, 1, 5)>, /* SCIF3_RXD */ + <RZG2L_PORT_PINMUX(0, 0, 5)>; /* SCIF3_TXD */ + }; +}; + +&scif1 { + pinctrl-0 = <&scif1_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&scif3 { + pinctrl-0 = <&scif3_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&spi1 { + /* native cs does not support cs persistence required for tpm */ + cs-gpios = <&pinctrl RZG2L_GPIO(44, 3) GPIO_ACTIVE_LOW>; + num-cs = <1>; + pinctrl-0 = <&spi1_pins>; + pinctrl-names = "default"; + status = "okay"; + + spi1_muxed: spi@0 { + compatible = "spi-mux"; + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + mux-controls = <&spi_mux>; + /* mux bandwidth is 2GHz, soc max. spi clock is P0/2 = 50MHz */ + spi-max-frequency = <50000000>; + + tpm@0 { + compatible = "infineon,slb9670", "tcg,tpm_tis-spi"; + reg = <0>; + interrupts-extended = <&tca6416_u21 9 IRQ_TYPE_LEVEL_LOW>; + reset-gpios = <&tca6416_u21 1 (GPIO_ACTIVE_LOW | GPIO_OPEN_DRAIN)>; + spi-max-frequency = <43000000>; + }; + }; +}; + +&usb2_phy0 { + vbus-supply = <&vbus1>; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot-microsd.dtso b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot-microsd.dtso new file mode 100644 index 0000000..0f92a9d --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot-microsd.dtso
@@ -0,0 +1,26 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Overlay for the RZ/G2L(C) Solidrun SOM SD + * + * Copyright (C) 2024 SolidRun Ltd. + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/pinctrl/rzg2l-pinctrl.h> + +&sdhi0 { + bus-width = <4>; + full-pwr-cycle; + mux-states = <&sdhi0_mux 1>; + pinctrl-0 = <&sdhi0_4bit_pins>, <&sdhi0_cd_pins>; + pinctrl-1 = <&sdhi0_4bit_uhs_pins>, <&sdhi0_cd_pins>; + pinctrl-names = "default", "state_uhs"; + sd-uhs-sdr104; + sd-uhs-sdr50; + vmmc-supply = <&vmmc>; + vqmmc-supply = <®_pmic_ldo1>; + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot-panel-dsi-WJ70N3TYJHMNG0.dtso b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot-panel-dsi-WJ70N3TYJHMNG0.dtso new file mode 100644 index 0000000..f8584c4 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot-panel-dsi-WJ70N3TYJHMNG0.dtso
@@ -0,0 +1,79 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright 2025 Josua Mayer <josua@solid-run.com> + * + * Overlay for enabling HummingBoard IIoT MIPI-DSI connector + * with Winstar WJ70N3TYJHMNG0 panel. + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> + +&{/} { + dsi_backlight: dsi-backlight { + compatible = "gpio-backlight"; + gpios = <&tca6408_u48 3 GPIO_ACTIVE_LOW>; + }; +}; + +&i2c_dsi { + #address-cells = <1>; + #size-cells = <0>; + + touchscreen@41 { + compatible = "ilitek,ili2130"; + reg = <0x41>; + /* + * Touchscreen fires short active-low pulses which level trigger + * on i2c gpio expander can miss. Trigger on falling edge instead. + */ + interrupts-extended = <&tca6416_u21 13 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&tca6408_u48 6 GPIO_ACTIVE_LOW>; + }; +}; + +&dsi { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + panel@0 { + /* This is a Winstar panel, but the ronbo panel uses same controls. */ + compatible = "ronbo,rb070d30"; + reg = <0>; + /* reset is active-low but driver inverts it internally */ + reset-gpios = <&tca6408_u48 1 GPIO_ACTIVE_HIGH>; + backlight = <&dsi_backlight>; + power-gpios = <&tca6408_u48 2 GPIO_ACTIVE_HIGH>; + shlr-gpios = <&tca6408_u48 4 GPIO_ACTIVE_LOW>; + updn-gpios = <&tca6408_u48 5 GPIO_ACTIVE_HIGH>; + vcc-lcd-supply = <®_dsi_panel>; + + port { + dsi_in_panel: endpoint { + remote-endpoint = <&mipi_dsi_out>; + }; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@1 { + reg = <1>; + + mipi_dsi_out: endpoint { + data-lanes = <1 2 3 4>; + remote-endpoint = <&dsi_in_panel>; + }; + }; + }; +}; + +&du { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot-rs485-a.dtso b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot-rs485-a.dtso new file mode 100644 index 0000000..4bcb22d --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot-rs485-a.dtso
@@ -0,0 +1,17 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright 2025 Josua Mayer <josua@solid-run.com> + * + * Overlay for enabling HummingBoard IIoT on-board RS485 Port A on connector J5004. + * + * Because Renesas uart driver does not support rs485, + * users must manually toggle P41_1 between RX & TX. + */ + +/dts-v1/; +/plugin/; + +&scif1_rs_232_485_mux { + /* select rs485 */ + idle-state = <1>; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot-rs485-b.dtso b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot-rs485-b.dtso new file mode 100644 index 0000000..6f460b3 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot-rs485-b.dtso
@@ -0,0 +1,17 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright 2025 Josua Mayer <josua@solid-run.com> + * + * Overlay for enabling HummingBoard IIoT on-board RS485 Port B on connector J5004. + * + * Because Renesas uart driver does not support rs485, + * users must manually toggle P41_0 between RX & TX. + */ + +/dts-v1/; +/plugin/; + +&scif3_rs_232_485_mux { + /* select rs485 */ + idle-state = <1>; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot.dtsi new file mode 100644 index 0000000..22f0660 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-iiot.dtsi
@@ -0,0 +1,49 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +#include "rzg2l-hummingboard-iiot-common.dtsi" + +&canfd { + pinctrl-names = "default"; + pinctrl-0 = <&can0_pins>, <&can1_pins>; + status = "okay"; + + channel0 { + status = "okay"; + }; + + channel1 { + status = "okay"; + }; +}; + +&phy1 { + leds { + #address-cells = <1>; + #size-cells = <0>; + + /* LED_0 pin */ + led@0 { + reg = <0>; + color = <LED_COLOR_ID_GREEN>; + function = LED_FUNCTION_LAN; + default-state = "keep"; + }; + }; +}; + +&pinctrl { + /* CANA */ + can0_pins: can0 { + pinmux = <RZG2L_PORT_PINMUX(10, 1, 2)>, /* CAN0_TX */ + <RZG2L_PORT_PINMUX(11, 0, 2)>; /* CAN0_RX */ + }; + + /* CANB */ + can1_pins: can1 { + pinmux = <RZG2L_PORT_PINMUX(12, 1, 2)>, /* CAN1_TX */ + <RZG2L_PORT_PINMUX(13, 0, 2)>; /* CAN1_RX */ + }; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-pulse-common.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-pulse-common.dtsi new file mode 100644 index 0000000..3fd4933 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-pulse-common.dtsi
@@ -0,0 +1,116 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +#include <dt-bindings/leds/common.h> + +/ { + aliases { + rtc0 = &carrier_rtc; + rtc1 = &pmic; + }; + + v_1_2: regulator-1v2 { + compatible = "regulator-fixed"; + regulator-name = "1v2"; + regulator-max-microvolt = <1200000>; + regulator-min-microvolt = <1200000>; + vin-supply = <®_pmic_buck4>; + }; + + vmmc: regulator-mmc { + compatible = "regulator-fixed"; + regulator-name = "vmmc"; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + startup-delay-us = <250>; + vin-supply = <®_pmic_buck4>; + }; + + vmpcie: regulator-mpcie { + /* supplies mpcie and m2 connectors */ + regulator-name = "vmpcie"; + compatible = "regulator-fixed"; + regulator-always-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + enable-active-high; + }; +}; + +&ehci1 { + #address-cells = <1>; + #size-cells = <0>; + + hub_2_0: hub@1 { + compatible = "usb4b4,6502", "usb4b4,6506"; + reg = <1>; + vdd2-supply = <®_pmic_buck4>; + vdd-supply = <&v_1_2>; + }; +}; + +&i2c0 { + carrier_eeprom: eeprom@57 { + compatible = "st,24c02", "atmel,24c02"; + reg = <0x57>; + pagesize = <16>; + }; + + carrier_rtc: rtc@69 { + compatible = "abracon,ab1805"; + reg = <0x69>; + abracon,tc-diode = "schottky"; + abracon,tc-resistor = <3>; + }; +}; + +&ohci0 { + dr_mode = "host"; +}; + +&ohci1 { + dr_mode = "host"; +}; + +&phy0 { + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = <LED_COLOR_ID_ORANGE>; + default-state = "keep"; + function = LED_FUNCTION_LAN; + }; + + led@1 { + reg = <1>; + color = <LED_COLOR_ID_GREEN>; + default-state = "keep"; + function = LED_FUNCTION_LAN; + }; + }; +}; + +/* mikrobus uart */ +&scif1 { + pinctrl-0 = <&mikro_uart_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +/* mikrobus spi */ +&spi1 { + num-cs = <1>; + pinctrl-0 = <&spi1_pins>, <&spi1_cs_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&usb2_phy0 { + pinctrl-0 = <&usb0_vbus_pins>; + pinctrl-names = "default"; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-pulse-micro-hdmi.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-pulse-micro-hdmi.dtsi new file mode 100644 index 0000000..80e4351 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-pulse-micro-hdmi.dtsi
@@ -0,0 +1,79 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +/ { + hdmi-connector { + compatible = "hdmi-connector"; + label = "hdmi"; + type = "d"; + + port { + hdmi_connector_in: endpoint { + remote-endpoint = <&adv7535_out>; + }; + }; + }; + + vmipi: regulator-mipi-1-8 { + compatible = "regulator-fixed"; + regulator-name = "vmipi"; + regulator-always-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + vin-supply = <®_pmic_buck4>; + }; +}; + +&dsi { + status = "okay"; + + ports { + port@1 { + mipi_dsi_out: endpoint { + data-lanes = <1 2 3 4>; + remote-endpoint = <&adv7535_from_dsim>; + }; + }; + }; +}; + +&du { + status = "okay"; +}; + +&i2c0 { + hdmi: hdmi@3d { + compatible = "adi,adv7535"; + reg = <0x3d>, <0x3f>, <0x3c>, <0x38>; + reg-names = "main", "edid", "cec", "packet"; + a2vdd-supply = <&vmipi>; + avdd-supply = <&vmipi>; + dvdd-supply = <&vmipi>; + pvdd-supply = <&vmipi>; + v3p3-supply = <®_pmic_buck4>; + adi,dsi-lanes = <4>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + adv7535_from_dsim: endpoint { + remote-endpoint = <&mipi_dsi_out>; + }; + }; + + port@1 { + reg = <1>; + + adv7535_out: endpoint { + remote-endpoint = <&hdmi_connector_in>; + }; + }; + }; + }; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-ripple.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-ripple.dtsi new file mode 100644 index 0000000..aeb9263 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzg2l-hummingboard-ripple.dtsi
@@ -0,0 +1,122 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +/ { + aliases { + /* this board does not use second phy / ethernet on SoM */ + /delete-property/ ethernet1; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + color = <LED_COLOR_ID_GREEN>; + default-state = "on"; + gpios = <&pinctrl RZG2L_GPIO(0, 1) GPIO_ACTIVE_LOW>; + label = "D30"; + }; + + led-1 { + color = <LED_COLOR_ID_GREEN>; + default-state = "on"; + gpios = <&pinctrl RZG2L_GPIO(47, 2) GPIO_ACTIVE_LOW>; + label = "D31"; + }; + + led-2 { + color = <LED_COLOR_ID_GREEN>; + default-state = "on"; + gpios = <&pinctrl RZG2L_GPIO(47, 1) GPIO_ACTIVE_LOW>; + label = "D32"; + }; + + led-3 { + color = <LED_COLOR_ID_GREEN>; + default-state = "on"; + gpios = <&pinctrl RZG2L_GPIO(48, 2) GPIO_ACTIVE_LOW>; + label = "D33"; + }; + + led-4 { + color = <LED_COLOR_ID_GREEN>; + default-state = "on"; + gpios = <&pinctrl RZG2L_GPIO(7, 2) GPIO_ACTIVE_LOW>; + label = "D34"; + }; + }; + + rfkill-mpcie { + /* rfkill-gpio inverts internally */ + shutdown-gpios = <&pinctrl RZG2L_GPIO(14, 1) GPIO_ACTIVE_HIGH>; + label = "mpcie radio"; + /* + * The mpcie connector only has USB, + * therefore this rfkill is for cellular radios only. + */ + radio-type = "wwan"; + compatible = "rfkill-gpio"; + }; +}; + +ð1 { + /* this board does not use second phy / ethernet on SoM */ + status = "disabled"; +}; + +&gpt { + /* mikrobus header pwm pin is pwm channel 6 */ + pinctrl-0 = <&mikro_pwm_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&hdmi { + interrupts-extended = <&pinctrl RZG2L_GPIO(9, 1) IRQ_TYPE_EDGE_FALLING>; + pd-gpios = <&pinctrl RZG2L_GPIO(3, 0) GPIO_ACTIVE_LOW>; +}; + +&hub_2_0 { + reset-gpios = <&pinctrl RZG2L_GPIO(39, 1) GPIO_ACTIVE_LOW>; +}; + +&pinctrl { + mpcie_rst_hog: mpcie-reset-hog { + gpios = <RZG2L_GPIO(42, 2) GPIO_ACTIVE_LOW>; + gpio-hog; + line-name = "mpcie-reset"; + output-low; + }; + + mikro_pwm_pins: pinctrl-mikro-pwm-grp { + pinmux = <RZG2L_PORT_PINMUX(41, 0, 4)>; /* GTIOC3A */ + }; + + mikro_uart_pins: pinctrl-mikro-uart-grp { + pinmux = <RZG2L_PORT_PINMUX(40, 1, 1)>, /* SCIF1_RXD */ + <RZG2L_PORT_PINMUX(40, 0, 1)>; /* SCIF1_TXD */ + }; + + usb0_vbus_pins: usb0-vbus { + pinmux = <RZG2L_PORT_PINMUX(4, 0, 1)>; /* USB0_VBUSEN */ + }; + + usb1_vbus_pins: usb1-vbus { + pinmux = <RZG2L_PORT_PINMUX(42, 0, 1)>; /* USB1_VBUSEN */ + }; +}; + +&usb2_phy1 { + pinctrl-0 = <&usb1_vbus_pins>; + pinctrl-names = "default"; +}; + +&vmmc { + gpios = <&pinctrl RZG2L_GPIO(4, 1) GPIO_ACTIVE_LOW>; +}; + +&vmpcie { + gpios = <&pinctrl RZG2L_GPIO(17, 0) GPIO_ACTIVE_HIGH>; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-smarc-pinfunction.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-smarc-pinfunction.dtsi index 2616dbd..ee14199 100644 --- a/arch/arm64/boot/dts/renesas/rzg2l-smarc-pinfunction.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg2l-smarc-pinfunction.dtsi
@@ -98,38 +98,38 @@ sd1-pwr-en-hog { }; sdhi1_pins: sd1 { - sd1_data { + sd1-data { pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3"; power-source = <3300>; }; - sd1_ctrl { + sd1-ctrl { pins = "SD1_CLK", "SD1_CMD"; power-source = <3300>; }; - sd1_mux { + sd1-mux { pinmux = <RZG2L_PORT_PINMUX(19, 0, 1)>; /* SD1_CD */ }; }; - sdhi1_pins_uhs: sd1_uhs { - sd1_data_uhs { + sdhi1_pins_uhs: sd1-uhs { + sd1-data-uhs { pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3"; power-source = <1800>; }; - sd1_ctrl_uhs { + sd1-ctrl-uhs { pins = "SD1_CLK", "SD1_CMD"; power-source = <1800>; }; - sd1_mux_uhs { + sd1-mux-uhs { pinmux = <RZG2L_PORT_PINMUX(19, 0, 1)>; /* SD1_CD */ }; }; - sound_clk_pins: sound_clk { + sound_clk_pins: sound-clk { pins = "AUDIO_CLK1", "AUDIO_CLK2"; input-enable; };
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi index 7eccdaf..b5f20ff 100644 --- a/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg2l-smarc-som.dtsi
@@ -269,51 +269,51 @@ sd0-dev-sel-hog { }; sdhi0_emmc_pins: sd0emmc { - sd0_emmc_data { + sd0-emmc-data { pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3", "SD0_DATA4", "SD0_DATA5", "SD0_DATA6", "SD0_DATA7"; power-source = <1800>; }; - sd0_emmc_ctrl { + sd0-emmc-ctrl { pins = "SD0_CLK", "SD0_CMD"; power-source = <1800>; }; - sd0_emmc_rst { + sd0-emmc-rst { pins = "SD0_RST#"; power-source = <1800>; }; }; sdhi0_pins: sd0 { - sd0_data { + sd0-data { pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3"; power-source = <3300>; }; - sd0_ctrl { + sd0-ctrl { pins = "SD0_CLK", "SD0_CMD"; power-source = <3300>; }; - sd0_mux { + sd0-mux { pinmux = <RZG2L_PORT_PINMUX(47, 0, 2)>; /* SD0_CD */ }; }; - sdhi0_pins_uhs: sd0_uhs { - sd0_data_uhs { + sdhi0_pins_uhs: sd0-uhs { + sd0-data-uhs { pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3"; power-source = <1800>; }; - sd0_ctrl_uhs { + sd0-ctrl-uhs { pins = "SD0_CLK", "SD0_CMD"; power-source = <1800>; }; - sd0_mux_uhs { + sd0-mux-uhs { pinmux = <RZG2L_PORT_PINMUX(47, 0, 2)>; /* SD0_CD */ }; };
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi index b76b55e..1411e61 100644 --- a/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg2l-smarc.dtsi
@@ -31,7 +31,7 @@ hdmi_con_out: endpoint { }; }; - sound_card { + sound-card { compatible = "audio-graph-card"; label = "HDMI-Audio"; dais = <&i2s2_port>;
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-sr-som-emmc.dtso b/arch/arm64/boot/dts/renesas/rzg2l-sr-som-emmc.dtso new file mode 100644 index 0000000..92e3406 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzg2l-sr-som-emmc.dtso
@@ -0,0 +1,44 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Overlay for the RZ/G2L(C) Solidrun SOM eMMC + * + * Copyright (C) 2024 SolidRun Ltd. + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/pinctrl/rzg2l-pinctrl.h> + +®_pmic_ldo1 { + /* + * This ldo can switch mmc host controller io voltage between + * 1.8V and 3.3V. The eMMC IO voltage however is supplied from + * reg_pmic_buck3 which is fixed at 1.8V. + * Lower this ldo maximum voltage to 1.8V to prevent setting 3.3V. + */ + regulator-max-microvolt = <1800000>; +}; + +&sdhi0 { + /* + * Host controller and eMMC have separate io voltage regulators: + * reg_pmic_ldo1 (1.8V/3.3V); reg_pmic_buck3 (1.8V only). + * Link to the switchable regulator ensuring that it gets configured. + */ + vqmmc-supply = <®_pmic_ldo1>; + bus-width = <8>; + cap-mmc-hw-reset; + mmc-hs200-1_8v; + mux-states = <&sdhi0_mux 0>; + non-removable; + no-sdio; + pinctrl-0 = <&sdhi0_8bit_uhs_pins>, <&sdhi0_rst_pins>; + pinctrl-1 = <&sdhi0_8bit_uhs_pins>, <&sdhi0_rst_pins>; + pinctrl-names = "default", "state_uhs"; + vmmc-supply = <®_pmic_buck4>; + /* emmc io voltage is hard-wired for 1.8V, disable sd modes */ + no-sd; + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg2l-sr-som.dtsi b/arch/arm64/boot/dts/renesas/rzg2l-sr-som.dtsi new file mode 100644 index 0000000..2e9bd3d --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzg2l-sr-som.dtsi
@@ -0,0 +1,473 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Source for the RZ/G2L Solidrun SoM + * + * Copyright 2023 SolidRun Ltd. + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/pinctrl/rzg2l-pinctrl.h> + +/ { + aliases { + ethernet0 = ð0; + ethernet1 = ð1; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c3; + mmc0 = &sdhi0; + mmc1 = &sdhi1; + rtc0 = &pmic; + serial0 = &scif0; + serial1 = &scif1; + serial2 = &scif2; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@48000000 { + /* + * Physical RAM starts at 0x40000000, but Renesas RZ/G2 BSPs + * reserve and hide the first 128MB for TrustZone by default. + * + * Minimum size for this SoM is 1GB, and the bootloader patches + * the dtb according to the actual RAM size and reservations. + */ + reg = <0x0 0x48000000 0x0 0x38000000>; + device_type = "memory"; + }; + + sdhi0_mux: mux-controller-0 { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + #mux-state-cells = <1>; + /* + * Mux switches SD0_DATA[0-3], SD0_CMD & SD0_CLK between + * on-SoM eMMC and board-to-board connector using one gpio: + * Low = connector, High = eMMC. + * Define active-low for logical mux state 0 = eMMC, 1 = connector. + */ + mux-gpios = <&pinctrl RZG2L_GPIO(22, 1) GPIO_ACTIVE_LOW>; + }; + + reg_pmic_buck1: regulator-pmic-buck1 { + compatible = "regulator-fixed"; + regulator-name = "pmic-buck1"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1100000>; + regulator-min-microvolt = <1100000>; + }; + + reg_pmic_buck3: regulator-pmic-buck3 { + compatible = "regulator-fixed"; + regulator-name = "pmic-buck3"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + }; + + reg_pmic_buck4: regulator-pmic-buck4 { + compatible = "regulator-fixed"; + regulator-name = "pmic-buck4"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + }; + + reg_pmic_ldo1: regulator-pmic-ldo1 { + compatible = "regulator-gpio"; + regulator-name = "pmic-ldo1"; + gpios = <&pinctrl RZG2L_GPIO(39, 0) GPIO_ACTIVE_HIGH>; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + states = <3300000 1>, <1800000 0>; + }; + + reg_pmic_ldo2: regulator-pmic-ldo2 { + compatible = "regulator-fixed"; + regulator-name = "pmic-ldo2"; + /* + * This ldo can switch mmc host controller io voltage between + * 1.8V and 3.3V by assembly option of pull-up / pull-dow. + * Default assembly is 3.3V. + */ + regulator-min-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + }; + + reserved-memory { + ranges; + #address-cells = <2>; + #size-cells = <2>; + + global_cma: linux,cma@58000000 { + compatible = "shared-dma-pool"; + reg = <0x0 0x58000000 0x0 0x10000000>; + reusable; + linux,cma-default; + }; + }; + + sdhi1_pwrseq: sdhi1-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&pinctrl RZG2L_GPIO(23, 1) GPIO_ACTIVE_LOW>; + }; + + /* 32.768kHz crystal */ + x2: x2-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +ð0 { + phy-handle = <&phy0>; + pinctrl-0 = <ð0_pins>; + pinctrl-names = "default"; + /* + * ravb driver does not configure mac internal delays for RZ/G2L(C), + * instead delays are added by the MxL86110 phy driver. + */ + phy-mode = "rgmii-id"; + status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + /* Level interrupts are typical for phy but not supported on RZ/G2L gpios. */ + interrupts-extended = <&pinctrl RZG2L_GPIO(27, 0) IRQ_TYPE_EDGE_FALLING>; + }; +}; + +ð1 { + phy-handle = <&phy1>; + pinctrl-0 = <ð1_pins>; + pinctrl-names = "default"; + /* + * ravb driver does not configure mac internal delays for RZ/G2L(C), + * instead delays are added by the MxL86110 phy driver. + */ + phy-mode = "rgmii-id"; + status = "okay"; + + phy1: ethernet-phy@4 { + reg = <4>; + /* Level interrupts are typical for phy but not supported on RZ/G2L gpios. */ + interrupts-extended = <&pinctrl RZG2L_GPIO(42, 4) IRQ_TYPE_EDGE_FALLING>; + }; +}; + +&extal_clk { + clock-frequency = <24000000>; +}; + +&gpu { + mali-supply = <®_pmic_buck1>; +}; + +&i2c0 { + clock-frequency = <400000>; + pinctrl-0 = <&i2c0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c1 { + clock-frequency = <400000>; + pinctrl-0 = <&i2c1_pins>; + pinctrl-names = "default"; + status = "okay"; + + eeprom: eeprom@50 { + compatible = "atmel,24c01"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +&i2c3 { + clock-frequency = <400000>; + pinctrl-0 = <&i2c3_pins>; + pinctrl-names = "default"; + status = "okay"; + + pmic: pmic@12 { + compatible = "renesas,raa215300"; + reg = <0x12>, <0x6f>; + reg-names = "main", "rtc"; + clocks = <&x2>; + clock-names = "xin"; + }; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&ostm1 { + status = "okay"; +}; + +&ostm2 { + status = "okay"; +}; + +&phyrst { + status = "okay"; +}; + +&pinctrl { + eth0_pins: eth0 { + pinmux = <RZG2L_PORT_PINMUX(28, 1, 1)>, /* ET0_LINKSTA */ + <RZG2L_PORT_PINMUX(27, 1, 1)>, /* ET0_MDC */ + <RZG2L_PORT_PINMUX(28, 0, 1)>, /* ET0_MDIO */ + <RZG2L_PORT_PINMUX(20, 0, 1)>, /* ET0_TXC */ + <RZG2L_PORT_PINMUX(20, 1, 1)>, /* ET0_TX_CTL */ + <RZG2L_PORT_PINMUX(20, 2, 1)>, /* ET0_TXD0 */ + <RZG2L_PORT_PINMUX(21, 0, 1)>, /* ET0_TXD1 */ + <RZG2L_PORT_PINMUX(21, 1, 1)>, /* ET0_TXD2 */ + <RZG2L_PORT_PINMUX(22, 0, 1)>, /* ET0_TXD3 */ + <RZG2L_PORT_PINMUX(24, 0, 1)>, /* ET0_RXC */ + <RZG2L_PORT_PINMUX(24, 1, 1)>, /* ET0_RX_CTL */ + <RZG2L_PORT_PINMUX(25, 0, 1)>, /* ET0_RXD0 */ + <RZG2L_PORT_PINMUX(25, 1, 1)>, /* ET0_RXD1 */ + <RZG2L_PORT_PINMUX(26, 0, 1)>, /* ET0_RXD2 */ + <RZG2L_PORT_PINMUX(26, 1, 1)>; /* ET0_RXD3 */ + }; + + eth1_pins: eth1 { + pinmux = <RZG2L_PORT_PINMUX(37, 2, 1)>, /* ET1_LINKSTA */ + <RZG2L_PORT_PINMUX(37, 0, 1)>, /* ET1_MDC */ + <RZG2L_PORT_PINMUX(37, 1, 1)>, /* ET1_MDIO */ + <RZG2L_PORT_PINMUX(29, 0, 1)>, /* ET1_TXC */ + <RZG2L_PORT_PINMUX(29, 1, 1)>, /* ET1_TX_CTL */ + <RZG2L_PORT_PINMUX(30, 0, 1)>, /* ET1_TXD0 */ + <RZG2L_PORT_PINMUX(30, 1, 1)>, /* ET1_TXD1 */ + <RZG2L_PORT_PINMUX(31, 0, 1)>, /* ET1_TXD2 */ + <RZG2L_PORT_PINMUX(31, 1, 1)>, /* ET1_TXD3 */ + <RZG2L_PORT_PINMUX(33, 1, 1)>, /* ET1_RXC */ + <RZG2L_PORT_PINMUX(34, 0, 1)>, /* ET1_RX_CTL */ + <RZG2L_PORT_PINMUX(34, 1, 1)>, /* ET1_RXD0 */ + <RZG2L_PORT_PINMUX(35, 0, 1)>, /* ET1_RXD1 */ + <RZG2L_PORT_PINMUX(35, 1, 1)>, /* ET1_RXD2 */ + <RZG2L_PORT_PINMUX(36, 0, 1)>; /* ET1_RXD3 */ + }; + + i2c0_pins: i2c0 { + input-enable; + pins = "RIIC0_SDA", "RIIC0_SCL"; + }; + + i2c1_pins: i2c1 { + input-enable; + pins = "RIIC1_SDA", "RIIC1_SCL"; + }; + + i2c3_pins: i2c3 { + pinmux = <RZG2L_PORT_PINMUX(18, 0, 3)>, /* RIIC3_SDA */ + <RZG2L_PORT_PINMUX(18, 1, 3)>; /* RIIC3_SCL */ + }; + + qspi0_pins: qspi0 { + pins = "QSPI0_IO0", "QSPI0_IO1", "QSPI0_IO2", "QSPI0_IO3", + "QSPI0_SPCLK", "QSPI0_SSL"; + power-source = <1800>; + }; + + scif0_pins: scif0 { + pinmux = <RZG2L_PORT_PINMUX(38, 0, 1)>, /* SCIF0_TXD */ + <RZG2L_PORT_PINMUX(38, 1, 1)>; /* SCIF0_RXD */ + }; + + scif2_pins: scif2 { + pinmux = <RZG2L_PORT_PINMUX(48, 0, 1)>, /* SCIF2_TXD */ + <RZG2L_PORT_PINMUX(48, 1, 1)>, /* SCIF2_RXD */ + <RZG2L_PORT_PINMUX(48, 3, 1)>, /* SCIF2_CTS# */ + <RZG2L_PORT_PINMUX(48, 4, 1)>; /* SCIF2_RTS# */ + }; + + sdhi0_4bit_pins: sdhi0-4bit { + sd0-ctrl-dat03 { + pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3", + "SD0_CLK", "SD0_CMD"; + power-source = <3300>; + }; + + /* + * Pins 4-7 are hard-wired to eMMC with 1.8V IO voltage, + * with all pins sharing a single voltage domain. + * + * These pins are fixed-function lacking independently configurable + * pull-up, pull-down or output-disable. + * + * While unused, disable the input buffers to avoid sampling the still + * physically connected but unused eMMC lines. + * For output direction rely on correct controller bus-width configuration + * to avoid over-voltage to eMMC e.g. when operating at 3.3V for a 4-bit microSD. + */ + sd0-dat47 { + input-disable; + pins = "SD0_DATA4", "SD0_DATA5", "SD0_DATA6", "SD0_DATA7"; + }; + }; + + sdhi0_4bit_uhs_pins: sdhi0-4bit-uhs { + sd0-ctrl-dat03 { + pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3", + "SD0_CLK", "SD0_CMD"; + power-source = <1800>; + }; + + /* + * Pins 4-7 are hard-wired to eMMC with 1.8V IO voltage, + * with all pins sharing a single voltage domain. + * + * These pins are fixed-function, lacking configurable pull-up, pull-down or + * output-disable, while sharing the voltage domain with all SD0_* pins. + * + * While unused, disable the input buffers to avoid sampling the still + * physically connected but unused eMMC lines. + * For output direction rely on correct controller bus-width configuration + * to avoid over-voltage to eMMC e.g. when operating at 3.3V for a 4-bit microSD. + */ + sd0-dat47 { + input-disable; + pins = "SD0_DATA4", "SD0_DATA5", "SD0_DATA6", "SD0_DATA7"; + }; + }; + + sdhi0_8bit_uhs_pins: sdhi0-8bit-uhs { + sd0-ctrl { + pins = "SD0_CLK", "SD0_CMD"; + power-source = <1800>; + }; + + sd0-dat { + input-enable; + pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3", + "SD0_DATA4", "SD0_DATA5", "SD0_DATA6", "SD0_DATA7"; + }; + }; + + sdhi0_cd_pins: sdhi0-cd { + pinmux = <RZG2L_PORT_PINMUX(47, 0, 2)>; /* SD0_CD */ + }; + + /* SD0_RST is only routed to eMMC which uses fixed 1.8V IO voltage */ + sdhi0_rst_pins: sdhi0-rst { + pins = "SD0_RST#"; + power-source = <1800>; + }; + + sdhi1_pins: sdhi1 { + pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3", + "SD1_CLK", "SD1_CMD"; + power-source = <3300>; + }; + + spi1_pins: spi1 { + pinmux = <RZG2L_PORT_PINMUX(44, 2, 1)>, /* RSPI1_MISO */ + <RZG2L_PORT_PINMUX(44, 1, 1)>, /* RSPI1_MOSI */ + <RZG2L_PORT_PINMUX(44, 0, 1)>; /* RSPI1_CK */ + }; + + spi1_cs_pins: spi1-cs { + pinmux = <RZG2L_PORT_PINMUX(44, 3, 1)>; /* RSPI1_SSL */ + }; +}; + +&sbc { + pinctrl-0 = <&qspi0_pins>; + pinctrl-names = "default"; + status = "okay"; + + flash@0 { + compatible = "winbond,w25q80bl", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + m25p,fast-read; + }; +}; + +&scif0 { + pinctrl-0 = <&scif0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&scif2 { + pinctrl-0 = <&scif2_pins>; + pinctrl-names = "default"; + uart-has-rtscts; + status = "okay"; + + bluetooth { + /* + * The BT is based on BCM4345C0. Murata 1MW variant seems to + * require driving RTS on open. + * Use compatible bcm43438 to accomplish this. + */ + compatible = "brcm,bcm43438-bt"; + max-speed = <115200>; + shutdown-gpios = <&pinctrl RZG2L_GPIO(23, 0) GPIO_ACTIVE_HIGH>; + vbat-supply = <®_pmic_buck4>; + vddio-supply = <®_pmic_buck4>; + }; +}; + +/* WiFi */ +&sdhi1 { + /* Murata 1MW max rate is 50MHz */ + max-frequency = <50000000>; + bus-width = <4>; + cap-sdio-irq; + mmc-pwrseq = <&sdhi1_pwrseq>; + non-removable; + no-1-8-v; + no-sd; + pinctrl-0 = <&sdhi1_pins>; + pinctrl-names = "default"; + vmmc-supply = <®_pmic_buck4>; + /* + * Host controller IO voltage is provided from reg_pmic_ldo2, + * WiFi module IO voltage from reg_pmic_buck4. + * Neither is configurable at run-time so either can be set here. + */ + vqmmc-supply = <®_pmic_ldo2>; + status = "okay"; +}; + +&usb2_phy0 { + vbus-supply = <&usb0_vbus_otg>; + status = "okay"; +}; + +&usb2_phy1 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg2lc-hummingboard-pulse-leds.dtso b/arch/arm64/boot/dts/renesas/rzg2lc-hummingboard-pulse-leds.dtso new file mode 100644 index 0000000..a257271 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzg2lc-hummingboard-pulse-leds.dtso
@@ -0,0 +1,48 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Overlay for SolidRun RZ/G2LC HummingBoard Pulse + * enabling LEDs D31-34 in exchange for on-SoM Bluetooth. + * + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/pinctrl/rzg2l-pinctrl.h> + +&leds { + led-1 { + label = "D31"; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pinctrl RZG2L_GPIO(5, 2) GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + + led-2 { + label = "D32"; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pinctrl RZG2L_GPIO(5, 1) GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + + led-3 { + label = "D33"; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pinctrl RZG2L_GPIO(42, 0) GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + + led-4 { + label = "D34"; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pinctrl RZG2L_GPIO(42, 1) GPIO_ACTIVE_LOW>; + default-state = "on"; + }; +}; + +&scif2 { + status = "disabled"; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg2lc-smarc-pinfunction.dtsi b/arch/arm64/boot/dts/renesas/rzg2lc-smarc-pinfunction.dtsi index 92c64d5..92ec793 100644 --- a/arch/arm64/boot/dts/renesas/rzg2lc-smarc-pinfunction.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg2lc-smarc-pinfunction.dtsi
@@ -79,38 +79,38 @@ sd1-pwr-en-hog { }; sdhi1_pins: sd1 { - sd1_data { + sd1-data { pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3"; power-source = <3300>; }; - sd1_ctrl { + sd1-ctrl { pins = "SD1_CLK", "SD1_CMD"; power-source = <3300>; }; - sd1_mux { + sd1-mux { pinmux = <RZG2L_PORT_PINMUX(19, 0, 1)>; /* SD1_CD */ }; }; - sdhi1_pins_uhs: sd1_uhs { - sd1_data_uhs { + sdhi1_pins_uhs: sd1-uhs { + sd1-data-uhs { pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3"; power-source = <1800>; }; - sd1_ctrl_uhs { + sd1-ctrl-uhs { pins = "SD1_CLK", "SD1_CMD"; power-source = <1800>; }; - sd1_mux_uhs { + sd1-mux-uhs { pinmux = <RZG2L_PORT_PINMUX(19, 0, 1)>; /* SD1_CD */ }; }; - sound_clk_pins: sound_clk { + sound_clk_pins: sound-clk { pins = "AUDIO_CLK1", "AUDIO_CLK2"; input-enable; };
diff --git a/arch/arm64/boot/dts/renesas/rzg2lc-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg2lc-smarc-som.dtsi index 15f2e9e..a043f2f 100644 --- a/arch/arm64/boot/dts/renesas/rzg2lc-smarc-som.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg2lc-smarc-som.dtsi
@@ -189,51 +189,51 @@ gpio-sd0-dev-sel-hog { }; sdhi0_emmc_pins: sd0emmc { - sd0_emmc_data { + sd0-emmc-data { pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3", "SD0_DATA4", "SD0_DATA5", "SD0_DATA6", "SD0_DATA7"; power-source = <1800>; }; - sd0_emmc_ctrl { + sd0-emmc-ctrl { pins = "SD0_CLK", "SD0_CMD"; power-source = <1800>; }; - sd0_emmc_rst { + sd0-emmc-rst { pins = "SD0_RST#"; power-source = <1800>; }; }; sdhi0_pins: sd0 { - sd0_data { + sd0-data { pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3"; power-source = <3300>; }; - sd0_ctrl { + sd0-ctrl { pins = "SD0_CLK", "SD0_CMD"; power-source = <3300>; }; - sd0_mux { + sd0-mux { pinmux = <RZG2L_PORT_PINMUX(18, 0, 1)>; /* SD0_CD */ }; }; - sdhi0_pins_uhs: sd0_uhs { - sd0_data_uhs { + sdhi0_pins_uhs: sd0-uhs { + sd0-data-uhs { pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3"; power-source = <1800>; }; - sd0_ctrl_uhs { + sd0-ctrl-uhs { pins = "SD0_CLK", "SD0_CMD"; power-source = <1800>; }; - sd0_mux_uhs { + sd0-mux-uhs { pinmux = <RZG2L_PORT_PINMUX(18, 0, 1)>; /* SD0_CD */ }; };
diff --git a/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi index f3d7eff..0d4c6b3 100644 --- a/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg2lc-smarc.dtsi
@@ -37,7 +37,7 @@ hdmi_con_out: endpoint { #if (SW_I2S0_I2S1) /delete-node/ sound; - sound_card { + sound-card { compatible = "audio-graph-card"; label = "HDMI-Audio"; dais = <&i2s2_port>;
diff --git a/arch/arm64/boot/dts/renesas/rzg2lc-sr-som.dtsi b/arch/arm64/boot/dts/renesas/rzg2lc-sr-som.dtsi new file mode 100644 index 0000000..4ec8e7b --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzg2lc-sr-som.dtsi
@@ -0,0 +1,436 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Source for the RZ/G2LC Solidrun SOM + * + * Copyright 2023 SolidRun Ltd. + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/pinctrl/rzg2l-pinctrl.h> + +/ { + aliases { + ethernet0 = ð0; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + mmc0 = &sdhi0; + mmc1 = &sdhi1; + rtc0 = &pmic; + serial0 = &scif0; + serial1 = &scif1; + serial2 = &scif2; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@48000000 { + /* + * Physical RAM starts at 0x40000000, but Renesas RZ/G2 BSPs + * reserve and hide the first 128MB for TrustZone by default. + * + * Minimum size for this SoM is 1GB, and the bootloader patches + * the dtb according to the actual RAM size and reservations. + */ + reg = <0x0 0x48000000 0x0 0x38000000>; + device_type = "memory"; + }; + + sdhi0_mux: mux-controller-0 { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + #mux-state-cells = <1>; + /* + * Mux switches SD0_DATA[0-3], SD0_CMD & SD0_CLK between + * on-SoM eMMC and board-to-board connector using one gpio: + * High = connector, Low = eMMC. + * Define active-high for logical mux state 0 = eMMC, 1 = connector. + */ + mux-gpios = <&pinctrl RZG2L_GPIO(22, 1) GPIO_ACTIVE_HIGH>; + }; + + reg_pmic_buck1: regulator-pmic-buck1 { + compatible = "regulator-fixed"; + regulator-name = "pmic-buck1"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1100000>; + regulator-min-microvolt = <1100000>; + }; + + reg_pmic_buck3: regulator-pmic-buck3 { + compatible = "regulator-fixed"; + regulator-name = "pmic-buck3"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + }; + + reg_pmic_buck4: regulator-pmic-buck4 { + compatible = "regulator-fixed"; + regulator-name = "pmic-buck4"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + }; + + reg_pmic_ldo1: regulator-pmic-ldo1 { + compatible = "regulator-gpio"; + regulator-name = "pmic-ldo1"; + gpios = <&pinctrl RZG2L_GPIO(39, 0) GPIO_ACTIVE_HIGH>; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + states = <3300000 1>, <1800000 0>; + }; + + reg_pmic_ldo2: regulator-pmic-ldo2 { + compatible = "regulator-fixed"; + regulator-name = "pmic-ldo2"; + /* + * This ldo can switch mmc host controller io voltage between + * 1.8V and 3.3V by assembly option of pull-up / pull-dow. + * Default assembly is 3.3V. + */ + regulator-min-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + }; + + reserved-memory { + ranges; + #address-cells = <2>; + #size-cells = <2>; + + global_cma: linux,cma@58000000 { + compatible = "shared-dma-pool"; + reg = <0x0 0x58000000 0x0 0x10000000>; + reusable; + linux,cma-default; + }; + }; + + sdhi1_pwrseq: sdhi1-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&pinctrl RZG2L_GPIO(23, 0) GPIO_ACTIVE_LOW>; + }; + + /* 32.768kHz crystal */ + x2: x2-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +ð0 { + phy-handle = <&phy0>; + pinctrl-0 = <ð0_pins>; + pinctrl-names = "default"; + /* + * ravb driver does not configure mac internal delays for RZ/G2L(C), + * instead delays are added by the ADIN1200 phy driver. + */ + phy-mode = "rgmii-id"; + status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + /* Level interrupts are typical for phy but not supported on RZ/G2L gpios. */ + interrupts-extended = <&pinctrl RZG2L_GPIO(27, 0) IRQ_TYPE_EDGE_FALLING>; + }; +}; + +&extal_clk { + clock-frequency = <24000000>; +}; + +&gpu { + mali-supply = <®_pmic_buck1>; +}; + +&i2c0 { + clock-frequency = <400000>; + pinctrl-0 = <&i2c0_pins>; + pinctrl-names = "default"; + status = "okay"; + + eeprom: eeprom@50 { + compatible = "atmel,24c01"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +&i2c1 { + clock-frequency = <400000>; + pinctrl-0 = <&i2c1_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c2 { + clock-frequency = <400000>; + pinctrl-0 = <&i2c2_pins>; + pinctrl-names = "default"; + status = "okay"; + + pmic: pmic@12 { + compatible = "renesas,raa215300"; + reg = <0x12>, <0x6f>; + reg-names = "main", "rtc"; + clocks = <&x2>; + clock-names = "xin"; + }; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&ostm1 { + status = "okay"; +}; + +&ostm2 { + status = "okay"; +}; + +&phyrst { + status = "okay"; +}; + +&pinctrl { + eth0_pins: eth0 { + pinmux = <RZG2L_PORT_PINMUX(28, 1, 1)>, /* ET0_LINKSTA */ + <RZG2L_PORT_PINMUX(27, 1, 1)>, /* ET0_MDC */ + <RZG2L_PORT_PINMUX(28, 0, 1)>, /* ET0_MDIO */ + <RZG2L_PORT_PINMUX(20, 0, 1)>, /* ET0_TXC */ + <RZG2L_PORT_PINMUX(20, 1, 1)>, /* ET0_TX_CTL */ + <RZG2L_PORT_PINMUX(20, 2, 1)>, /* ET0_TXD0 */ + <RZG2L_PORT_PINMUX(21, 0, 1)>, /* ET0_TXD1 */ + <RZG2L_PORT_PINMUX(21, 1, 1)>, /* ET0_TXD2 */ + <RZG2L_PORT_PINMUX(22, 0, 1)>, /* ET0_TXD3 */ + <RZG2L_PORT_PINMUX(24, 0, 1)>, /* ET0_RXC */ + <RZG2L_PORT_PINMUX(24, 1, 1)>, /* ET0_RX_CTL */ + <RZG2L_PORT_PINMUX(25, 0, 1)>, /* ET0_RXD0 */ + <RZG2L_PORT_PINMUX(25, 1, 1)>, /* ET0_RXD1 */ + <RZG2L_PORT_PINMUX(26, 0, 1)>, /* ET0_RXD2 */ + <RZG2L_PORT_PINMUX(26, 1, 1)>; /* ET0_RXD3 */ + }; + + i2c0_pins: i2c0 { + input-enable; + pins = "RIIC0_SDA", "RIIC0_SCL"; + }; + + i2c1_pins: i2c1 { + input-enable; + pins = "RIIC1_SDA", "RIIC1_SCL"; + }; + + i2c2_pins: i2c2 { + pinmux = <RZG2L_PORT_PINMUX(42, 3, 1)>, /* RIIC2_SDA */ + <RZG2L_PORT_PINMUX(42, 4, 1)>; /* RIIC2_SCL */ + }; + + qspi0_pins: qspi0 { + pins = "QSPI0_IO0", "QSPI0_IO1", "QSPI0_IO2", "QSPI0_IO3", + "QSPI0_SPCLK", "QSPI0_SSL"; + power-source = <1800>; + }; + + scif0_pins: scif0 { + pinmux = <RZG2L_PORT_PINMUX(38, 0, 1)>, /* SCIF0_TXD */ + <RZG2L_PORT_PINMUX(38, 1, 1)>; /* SCIF0_RXD */ + }; + + scif2_pins: scif2 { + pinmux = <RZG2L_PORT_PINMUX(42, 0, 4)>, /* SCIF2_TXD */ + <RZG2L_PORT_PINMUX(42, 1, 4)>, /* SCIF2_RXD */ + <RZG2L_PORT_PINMUX(5, 1, 2)>, /* SCIF2_CTS# */ + <RZG2L_PORT_PINMUX(5, 2, 2)>; /* SCIF2_RTS# */ + }; + + sdhi0_4bit_pins: sdhi0-4bit { + sd0-ctrl-dat03 { + pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3", + "SD0_CLK", "SD0_CMD"; + power-source = <3300>; + }; + + /* + * Pins 4-7 are hard-wired to eMMC with 1.8V IO voltage, + * with all pins sharing a single voltage domain. + * + * These pins are fixed-function lacking independently configurable + * pull-up, pull-down or output-disable. + * + * While unused, disable the input buffers to avoid sampling the still + * physically connected but unused eMMC lines. + * For output direction rely on correct controller bus-width configuration + * to avoid over-voltage to eMMC e.g. when operating at 3.3V for a 4-bit microSD. + */ + sd0-dat47 { + input-disable; + pins = "SD0_DATA4", "SD0_DATA5", "SD0_DATA6", "SD0_DATA7"; + }; + }; + + sdhi0_4bit_uhs_pins: sdhi0-4bit-uhs { + sd0-ctrl-dat03 { + pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3", + "SD0_CLK", "SD0_CMD"; + power-source = <1800>; + }; + + /* + * Pins 4-7 are hard-wired to eMMC with 1.8V IO voltage, + * with all pins sharing a single voltage domain. + * + * These pins are fixed-function, lacking configurable pull-up, pull-down or + * output-disable, while sharing the voltage domain with all SD0_* pins. + * + * While unused, disable the input buffers to avoid sampling the still + * physically connected but unused eMMC lines. + * For output direction rely on correct controller bus-width configuration + * to avoid over-voltage to eMMC e.g. when operating at 3.3V for a 4-bit microSD. + */ + sd0-dat47 { + input-disable; + pins = "SD0_DATA4", "SD0_DATA5", "SD0_DATA6", "SD0_DATA7"; + }; + }; + + sdhi0_8bit_uhs_pins: sdhi0-8bit-uhs { + sd0-ctrl { + pins = "SD0_CLK", "SD0_CMD"; + power-source = <1800>; + }; + + sd0-dat { + input-enable; + pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3", + "SD0_DATA4", "SD0_DATA5", "SD0_DATA6", "SD0_DATA7"; + }; + }; + + sdhi0_cd_pins: sdhi0-cd { + pinmux = <RZG2L_PORT_PINMUX(18, 0, 1)>; /* SD0_CD */ + }; + + /* SD0_RST is only routed to eMMC which uses fixed 1.8V IO voltage */ + sdhi0_rst_pins: sdhi0-rst { + pins = "SD0_RST#"; + power-source = <1800>; + }; + + sdhi1_pins: sdhi1 { + pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3", + "SD1_CLK", "SD1_CMD"; + power-source = <3300>; + }; + + spi1_pins: spi1 { + pinmux = <RZG2L_PORT_PINMUX(44, 2, 1)>, /* RSPI1_MISO */ + <RZG2L_PORT_PINMUX(44, 1, 1)>, /* RSPI1_MOSI */ + <RZG2L_PORT_PINMUX(44, 0, 1)>; /* RSPI1_CK */ + }; + + spi1_cs_pins: spi1-cs { + pinmux = <RZG2L_PORT_PINMUX(44, 3, 1)>; /* RSPI1_SSL */ + }; +}; + +&sbc { + pinctrl-0 = <&qspi0_pins>; + pinctrl-names = "default"; + status = "okay"; + + flash@0 { + compatible = "winbond,w25q80bl", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + m25p,fast-read; + }; +}; + +&scif0 { + pinctrl-0 = <&scif0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&scif2 { + pinctrl-0 = <&scif2_pins>; + pinctrl-names = "default"; + uart-has-rtscts; + status = "okay"; + + bluetooth { + /* + * The BT is based on BCM4343A2. Murata 1YN variant seems to + * require driving RTS on open. + * Use compatible bcm43438 to accomplish this. + */ + compatible = "brcm,bcm43438-bt"; + max-speed = <115200>; + shutdown-gpios = <&pinctrl RZG2L_GPIO(23, 1) GPIO_ACTIVE_HIGH>; + vbat-supply = <®_pmic_buck4>; + vddio-supply = <®_pmic_buck4>; + }; +}; + +/* WiFi */ +&sdhi1 { + /* Murata 1YN max rate is 50MHz */ + max-frequency = <50000000>; + bus-width = <4>; + cap-sdio-irq; + mmc-pwrseq = <&sdhi1_pwrseq>; + non-removable; + no-1-8-v; + no-sd; + pinctrl-0 = <&sdhi1_pins>; + pinctrl-names = "default"; + vmmc-supply = <®_pmic_buck4>; + /* + * Host controller IO voltage is provided from reg_pmic_ldo2, + * WiFi module IO voltage from reg_pmic_buck4. + * Neither is configurable at run-time so either can be set here. + */ + vqmmc-supply = <®_pmic_ldo2>; + status = "okay"; +}; + +&usb2_phy0 { + vbus-supply = <&usb0_vbus_otg>; + status = "okay"; +}; + +&usb2_phy1 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg2ul-hummingboard-pulse-leds.dtso b/arch/arm64/boot/dts/renesas/rzg2ul-hummingboard-pulse-leds.dtso new file mode 100644 index 0000000..ab7f826 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzg2ul-hummingboard-pulse-leds.dtso
@@ -0,0 +1,48 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Overlay for SolidRun RZ/G2UL HummingBoard Pulse + * enabling LEDs D31-34 in exchange for on-SoM Bluetooth. + * + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/pinctrl/rzg2l-pinctrl.h> + +&leds { + led-1 { + label = "D31"; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pinctrl RZG2L_GPIO(5, 4) GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + + led-2 { + label = "D32"; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pinctrl RZG2L_GPIO(5, 3) GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + + led-3 { + label = "D33"; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pinctrl RZG2L_GPIO(6, 0) GPIO_ACTIVE_LOW>; + default-state = "on"; + }; + + led-4 { + label = "D34"; + color = <LED_COLOR_ID_GREEN>; + gpios = <&pinctrl RZG2L_GPIO(6, 1) GPIO_ACTIVE_LOW>; + default-state = "on"; + }; +}; + +&scif2 { + status = "disabled"; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg2ul-smarc-pinfunction.dtsi b/arch/arm64/boot/dts/renesas/rzg2ul-smarc-pinfunction.dtsi index 355694f..0be666c 100644 --- a/arch/arm64/boot/dts/renesas/rzg2ul-smarc-pinfunction.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg2ul-smarc-pinfunction.dtsi
@@ -69,38 +69,38 @@ sd1-pwr-en-hog { }; sdhi1_pins: sd1 { - sd1_data { + sd1-data { pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3"; power-source = <3300>; }; - sd1_ctrl { + sd1-ctrl { pins = "SD1_CLK", "SD1_CMD"; power-source = <3300>; }; - sd1_mux { + sd1-mux { pinmux = <RZG2L_PORT_PINMUX(0, 2, 1)>; /* SD1_CD */ }; }; - sdhi1_pins_uhs: sd1_uhs { - sd1_data_uhs { + sdhi1_pins_uhs: sd1-uhs { + sd1-data-uhs { pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3"; power-source = <1800>; }; - sd1_ctrl_uhs { + sd1-ctrl-uhs { pins = "SD1_CLK", "SD1_CMD"; power-source = <1800>; }; - sd1_mux_uhs { + sd1-mux-uhs { pinmux = <RZG2L_PORT_PINMUX(0, 2, 1)>; /* SD1_CD */ }; }; - sound_clk_pins: sound_clk { + sound_clk_pins: sound-clk { pins = "AUDIO_CLK1", "AUDIO_CLK2"; input-enable; };
diff --git a/arch/arm64/boot/dts/renesas/rzg2ul-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg2ul-smarc-som.dtsi index 0f917d7..99d30fa 100644 --- a/arch/arm64/boot/dts/renesas/rzg2ul-smarc-som.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg2ul-smarc-som.dtsi
@@ -204,51 +204,51 @@ qspi0_pins: qspi0 { }; sdhi0_emmc_pins: sd0emmc { - sd0_emmc_data { + sd0-emmc-data { pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3", "SD0_DATA4", "SD0_DATA5", "SD0_DATA6", "SD0_DATA7"; power-source = <1800>; }; - sd0_emmc_ctrl { + sd0-emmc-ctrl { pins = "SD0_CLK", "SD0_CMD"; power-source = <1800>; }; - sd0_emmc_rst { + sd0-emmc-rst { pins = "SD0_RST#"; power-source = <1800>; }; }; sdhi0_pins: sd0 { - sd0_data { + sd0-data { pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3"; power-source = <3300>; }; - sd0_ctrl { + sd0-ctrl { pins = "SD0_CLK", "SD0_CMD"; power-source = <3300>; }; - sd0_mux { + sd0-mux { pinmux = <RZG2L_PORT_PINMUX(0, 0, 1)>; /* SD0_CD */ }; }; - sdhi0_pins_uhs: sd0_uhs { - sd0_data_uhs { + sdhi0_pins_uhs: sd0-uhs { + sd0-data-uhs { pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3"; power-source = <1800>; }; - sd0_ctrl_uhs { + sd0-ctrl-uhs { pins = "SD0_CLK", "SD0_CMD"; power-source = <1800>; }; - sd0_mux_uhs { + sd0-mux-uhs { pinmux = <RZG2L_PORT_PINMUX(0, 0, 1)>; /* SD0_CD */ }; };
diff --git a/arch/arm64/boot/dts/renesas/rzg2ul-sr-som.dtsi b/arch/arm64/boot/dts/renesas/rzg2ul-sr-som.dtsi new file mode 100644 index 0000000..e371228 --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzg2ul-sr-som.dtsi
@@ -0,0 +1,418 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +/* + * Device Tree Source for the RZ/G2UL Solidrun SOM + * + * Copyright 2025 Josua Mayer <josua@solid-run.com> + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/pinctrl/rzg2l-pinctrl.h> + +/ { + aliases { + ethernet0 = ð0; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + mmc0 = &sdhi0; + mmc1 = &sdhi1; + rtc0 = &pmic; + serial0 = &scif0; + serial1 = &scif1; + serial2 = &scif2; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@48000000 { + /* + * Physical RAM starts at 0x40000000, but Renesas RZ/G2 BSPs + * reserve and hide the first 128MB for TrustZone by default. + * + * Minimum size for this SoM is 512MB, and the bootloader patches + * the dtb according to the actual RAM size and reservations. + */ + reg = <0x0 0x48000000 0x0 0x18000000>; + device_type = "memory"; + }; + + sdhi0_mux: mux-controller-0 { + compatible = "gpio-mux"; + #mux-control-cells = <0>; + #mux-state-cells = <1>; + /* + * Mux switches SD0_DATA[0-3], SD0_CMD & SD0_CLK between + * on-SoM eMMC and board-to-board connector using one gpio: + * High = connector, Low = eMMC. + * Define active-high for logical mux state 0 = eMMC, 1 = connector. + */ + mux-gpios = <&pinctrl RZG2L_GPIO(2, 1) GPIO_ACTIVE_HIGH>; + }; + + reg_pmic_buck1: regulator-pmic-buck1 { + compatible = "regulator-fixed"; + regulator-name = "pmic-buck1"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1100000>; + regulator-min-microvolt = <1100000>; + }; + + reg_pmic_buck3: regulator-pmic-buck3 { + compatible = "regulator-fixed"; + regulator-name = "pmic-buck3"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + }; + + reg_pmic_buck4: regulator-pmic-buck4 { + compatible = "regulator-fixed"; + regulator-name = "pmic-buck4"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + }; + + reg_pmic_ldo1: regulator-pmic-ldo1 { + compatible = "regulator-gpio"; + regulator-name = "pmic-ldo1"; + gpios = <&pinctrl RZG2L_GPIO(13, 2) GPIO_ACTIVE_HIGH>; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + states = <3300000 1>, <1800000 0>; + }; + + reg_pmic_ldo2: regulator-pmic-ldo2 { + compatible = "regulator-fixed"; + regulator-name = "pmic-ldo2"; + /* + * This ldo can switch mmc host controller io voltage between + * 1.8V and 3.3V by assembly option of pull-up / pull-dow. + * Default assembly is 3.3V. + */ + regulator-min-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + }; + + sdhi1_pwrseq: sdhi1-pwrseq { + compatible = "mmc-pwrseq-simple"; + reset-gpios = <&pinctrl RZG2L_GPIO(2, 2) GPIO_ACTIVE_LOW>; + }; + + /* 32.768kHz crystal */ + x2: x2-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + }; +}; + +&ehci0 { + status = "okay"; +}; + +&ehci1 { + status = "okay"; +}; + +ð0 { + phy-handle = <&phy0>; + pinctrl-0 = <ð0_pins>; + pinctrl-names = "default"; + /* + * ravb driver does not configure mac internal delays for RZ/G2(UL/L/C), + * instead delays are added by the ADIN1200 phy driver. + */ + phy-mode = "rgmii-id"; + status = "okay"; + + phy0: ethernet-phy@0 { + reg = <0>; + /* Level interrupts are typical for phy but not supported on rz/g2l gpios. */ + interrupts-extended = <&pinctrl RZG2L_GPIO(4, 2) IRQ_TYPE_EDGE_FALLING>; + }; +}; + +&extal_clk { + clock-frequency = <24000000>; +}; + +&i2c0 { + clock-frequency = <400000>; + pinctrl-0 = <&i2c0_pins>; + pinctrl-names = "default"; + status = "okay"; + + eeprom: eeprom@50 { + compatible = "atmel,24c01"; + reg = <0x50>; + pagesize = <16>; + }; +}; + +&i2c1 { + clock-frequency = <400000>; + pinctrl-0 = <&i2c1_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2c2 { + clock-frequency = <400000>; + pinctrl-0 = <&i2c2_pins>; + pinctrl-names = "default"; + status = "okay"; + + pmic: pmic@12 { + compatible = "renesas,raa215300"; + reg = <0x12>, <0x6f>; + reg-names = "main", "rtc"; + clocks = <&x2>; + clock-names = "xin"; + }; +}; + +&ohci0 { + status = "okay"; +}; + +&ohci1 { + status = "okay"; +}; + +&ostm1 { + status = "okay"; +}; + +&ostm2 { + status = "okay"; +}; + +&phyrst { + status = "okay"; +}; + +&pinctrl { + eth0_pins: eth0 { + pinmux = <RZG2L_PORT_PINMUX(4, 5, 1)>, /* ET0_LINKSTA */ + <RZG2L_PORT_PINMUX(4, 3, 1)>, /* ET0_MDC */ + <RZG2L_PORT_PINMUX(4, 4, 1)>, /* ET0_MDIO */ + <RZG2L_PORT_PINMUX(1, 0, 1)>, /* ET0_TXC */ + <RZG2L_PORT_PINMUX(1, 1, 1)>, /* ET0_TX_CTL */ + <RZG2L_PORT_PINMUX(1, 2, 1)>, /* ET0_TXD0 */ + <RZG2L_PORT_PINMUX(1, 3, 1)>, /* ET0_TXD1 */ + <RZG2L_PORT_PINMUX(1, 4, 1)>, /* ET0_TXD2 */ + <RZG2L_PORT_PINMUX(2, 0, 1)>, /* ET0_TXD3 */ + <RZG2L_PORT_PINMUX(3, 0, 1)>, /* ET0_RXC */ + <RZG2L_PORT_PINMUX(3, 1, 1)>, /* ET0_RX_CTL */ + <RZG2L_PORT_PINMUX(3, 2, 1)>, /* ET0_RXD0 */ + <RZG2L_PORT_PINMUX(3, 3, 1)>, /* ET0_RXD1 */ + <RZG2L_PORT_PINMUX(4, 0, 1)>, /* ET0_RXD2 */ + <RZG2L_PORT_PINMUX(4, 1, 1)>; /* ET0_RXD3 */ + }; + + i2c0_pins: i2c0 { + input-enable; + pins = "RIIC0_SDA", "RIIC0_SCL"; + }; + + i2c1_pins: i2c1 { + input-enable; + pins = "RIIC1_SDA", "RIIC1_SCL"; + }; + + i2c2_pins: i2c2 { + pinmux = <RZG2L_PORT_PINMUX(6, 3, 1)>, /* RIIC2_SDA */ + <RZG2L_PORT_PINMUX(6, 4, 1)>; /* RIIC2_SCL */ + }; + + qspi0_pins: qspi0 { + pins = "QSPI0_IO0", "QSPI0_IO1", "QSPI0_IO2", "QSPI0_IO3", + "QSPI0_SPCLK", "QSPI0_SSL"; + power-source = <1800>; + }; + + scif0_pins: scif0 { + pinmux = <RZG2L_PORT_PINMUX(13, 0, 1)>, /* SCIF0_TXD */ + <RZG2L_PORT_PINMUX(13, 1, 1)>; /* SCIF0_RXD */ + }; + + scif2_pins: scif2 { + pinmux = <RZG2L_PORT_PINMUX(6, 0, 4)>, /* SCIF2_TXD */ + <RZG2L_PORT_PINMUX(6, 1, 4)>, /* SCIF2_RXD */ + <RZG2L_PORT_PINMUX(5, 3, 2)>, /* SCIF2_CTS# */ + <RZG2L_PORT_PINMUX(5, 4, 2)>; /* SCIF2_RTS# */ + }; + + sdhi0_4bit_pins: sdhi0-4bit { + sd0-ctrl-dat03 { + pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3", + "SD0_CLK", "SD0_CMD"; + power-source = <3300>; + }; + + /* + * Pins 4-7 are hard-wired to eMMC with 1.8V IO voltage, + * with all pins sharing a single voltage domain. + * + * These pins are fixed-function lacking independently configurable + * pull-up, pull-down or output-disable. + * + * While unused, disable the input buffers to avoid sampling the still + * physically connected but unused eMMC lines. + * For output direction rely on correct controller bus-width configuration + * to avoid over-voltage to eMMC e.g. when operating at 3.3V for a 4-bit microSD. + */ + sd0-dat47 { + input-disable; + pins = "SD0_DATA4", "SD0_DATA5", "SD0_DATA6", "SD0_DATA7"; + }; + }; + + sdhi0_4bit_uhs_pins: sdhi0-4bit-uhs { + sd0-ctrl-dat03 { + pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3", + "SD0_CLK", "SD0_CMD"; + power-source = <1800>; + }; + + /* + * Pins 4-7 are hard-wired to eMMC with 1.8V IO voltage, + * with all pins sharing a single voltage domain. + * + * These pins are fixed-function, lacking configurable pull-up, pull-down or + * output-disable, while sharing the voltage domain with all SD0_* pins. + * + * While unused, disable the input buffers to avoid sampling the still + * physically connected but unused eMMC lines. + * For output direction rely on correct controller bus-width configuration + * to avoid over-voltage to eMMC e.g. when operating at 3.3V for a 4-bit microSD. + */ + sd0-dat47 { + input-disable; + pins = "SD0_DATA4", "SD0_DATA5", "SD0_DATA6", "SD0_DATA7"; + }; + }; + + sdhi0_8bit_uhs_pins: sdhi0-8bit-uhs { + sd0-ctrl { + pins = "SD0_CLK", "SD0_CMD"; + power-source = <1800>; + }; + + sd0-dat { + input-enable; + pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3", + "SD0_DATA4", "SD0_DATA5", "SD0_DATA6", "SD0_DATA7"; + }; + }; + + sdhi0_cd_pins: sdhi0-cd { + pinmux = <RZG2L_PORT_PINMUX(0, 0, 1)>; /* SD0_CD */ + }; + + /* SD0_RST is only routed to eMMC which uses fixed 1.8V IO voltage */ + sdhi0_rst_pins: sdhi0-rst { + pins = "SD0_RST#"; + power-source = <1800>; + }; + + sdhi1_pins: sdhi1 { + pins = "SD1_DATA0", "SD1_DATA1", "SD1_DATA2", "SD1_DATA3", + "SD1_CLK", "SD1_CMD"; + power-source = <3300>; + }; + + spi1_pins: spi1 { + pinmux = <RZG2L_PORT_PINMUX(17, 2, 1)>, /* RSPI1_MISO */ + <RZG2L_PORT_PINMUX(17, 1, 1)>, /* RSPI1_MOSI */ + <RZG2L_PORT_PINMUX(17, 0, 1)>; /* RSPI1_CK */ + }; + + spi1_cs_pins: spi1-cs { + pinmux = <RZG2L_PORT_PINMUX(17, 3, 1)>; /* RSPI1_SSL */ + }; +}; + +&sbc { + pinctrl-0 = <&qspi0_pins>; + pinctrl-names = "default"; + status = "okay"; + + flash@0 { + compatible = "winbond,w25q80bl", "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <50000000>; + m25p,fast-read; + }; +}; + +&scif0 { + pinctrl-0 = <&scif0_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&scif2 { + pinctrl-0 = <&scif2_pins>; + pinctrl-names = "default"; + uart-has-rtscts; + status = "okay"; + + bluetooth { + /* + * The BT is based on BCM4343A2. Murata 1YN variant seems to + * require driving RTS on open. + * Use compatible bcm43438 to accomplish this. + */ + compatible = "brcm,bcm43438-bt"; + max-speed = <115200>; + shutdown-gpios = <&pinctrl RZG2L_GPIO(2, 3) GPIO_ACTIVE_HIGH>; + vbat-supply = <®_pmic_buck4>; + vddio-supply = <®_pmic_buck4>; + }; +}; + +/* WiFi */ +&sdhi1 { + /* Murata 1YN max rate is 50MHz */ + max-frequency = <50000000>; + bus-width = <4>; + cap-sdio-irq; + mmc-pwrseq = <&sdhi1_pwrseq>; + non-removable; + no-1-8-v; + no-sd; + pinctrl-0 = <&sdhi1_pins>; + pinctrl-names = "default"; + vmmc-supply = <®_pmic_buck4>; + /* + * Host controller IO voltage is provided from reg_pmic_ldo2, + * WiFi module IO voltage from reg_pmic_buck4. + * Neither is configurable at run-time so either can be set here. + */ + vqmmc-supply = <®_pmic_ldo2>; + status = "okay"; +}; + +&usb2_phy0 { + vbus-supply = <&usb0_vbus_otg>; + status = "okay"; +}; + +&usb2_phy1 { + status = "okay"; +}; + +&wdt0 { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/renesas/rzg3l-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg3l-smarc-som.dtsi index 091a227..91b2d0d 100644 --- a/arch/arm64/boot/dts/renesas/rzg3l-smarc-som.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg3l-smarc-som.dtsi
@@ -45,6 +45,21 @@ memory@48000000 { reg = <0x0 0x48000000 0x0 0x78000000>; }; + pcie_refclk: pcie-ref-clock { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + }; + + reg_1p0v: regulator-1p0v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.0V"; + regulator-min-microvolt = <1000000>; + regulator-max-microvolt = <1000000>; + regulator-boot-on; + regulator-always-on; + }; + reg_1p8v: regulator-1p8v { compatible = "regulator-fixed"; regulator-name = "fixed-1.8V"; @@ -100,6 +115,11 @@ &extal_clk { clock-frequency = <24000000>; }; +&gpu { + status = "okay"; + mali-supply = <®_1p0v>; +}; + &i2c0 { pinctrl-0 = <&i2c0_pins>; pinctrl-names = "default"; @@ -157,6 +177,11 @@ phy1: ethernet-phy@7 { }; }; +&pcie_port0 { + clocks = <&pcie_refclk>; + clock-names = "ref"; +}; + &pinctrl { eth0_pins: eth0 { txc {
diff --git a/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi b/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi index b45acfe..462102a 100644 --- a/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg3s-smarc-som.dtsi
@@ -168,6 +168,14 @@ a0 80 30 30 9c }; }; +&i3c { + pinctrl-names = "default"; + pinctrl-0 = <&i3c_pins>; + i2c-scl-hz = <400000>; + i3c-scl-hz = <12500000>; + status = "okay"; +}; + &pcie_port0 { clocks = <&versa3 5>; clock-names = "ref"; @@ -184,7 +192,6 @@ &sdhi0 { bus-width = <4>; sd-uhs-sdr50; sd-uhs-sdr104; - max-frequency = <125000000>; status = "okay"; }; #else @@ -199,7 +206,6 @@ &sdhi0 { mmc-hs200-1_8v; non-removable; fixed-emmc-driver-type = <1>; - max-frequency = <125000000>; status = "okay"; }; #endif @@ -210,7 +216,6 @@ &sdhi2 { pinctrl-names = "default"; vmmc-supply = <&vcc_sdhi2>; bus-width = <4>; - max-frequency = <50000000>; status = "okay"; }; #endif @@ -234,7 +239,7 @@ txc { drive-strength-microamp = <5200>; }; - tx_ctl { + tx-ctl { pinmux = <RZG2L_PORT_PINMUX(1, 1, 1)>; /* ET0_TX_CTL */ power-source = <1800>; output-enable; @@ -277,7 +282,7 @@ txc { drive-strength-microamp = <5200>; }; - tx_ctl { + tx-ctl { pinmux = <RZG2L_PORT_PINMUX(7, 1, 1)>; /* ET1_TX_CTL */ power-source = <1800>; output-enable; @@ -302,6 +307,16 @@ mux { }; }; + i3c_pins: i3c { + pins = "I3C_SDA", "I3C_SCL"; +#if SW_CONFIG4 == SW_ON + power-source = <1200>; +#else + power-source = <1800>; +#endif + input-enable; + }; + sdhi0_pins: sd0 { data { pins = "SD0_DATA0", "SD0_DATA1", "SD0_DATA2", "SD0_DATA3";
diff --git a/arch/arm64/boot/dts/renesas/rzg3s-smarc-switches.h b/arch/arm64/boot/dts/renesas/rzg3s-smarc-switches.h index bbf908a..9cccc87 100644 --- a/arch/arm64/boot/dts/renesas/rzg3s-smarc-switches.h +++ b/arch/arm64/boot/dts/renesas/rzg3s-smarc-switches.h
@@ -25,9 +25,13 @@ * @SW_CONFIG3: * SW_OFF - SD2 is connected to SoC * SW_ON - SCIF1, SSI0, IRQ0, IRQ1 connected to SoC + * @SW_CONFIG4: + * SW_OFF - I3C voltage is 1.8V + * SW_ON - I3C voltage is 1.2V */ #define SW_CONFIG2 SW_OFF #define SW_CONFIG3 SW_ON +#define SW_CONFIG4 SW_OFF /* * SW_OPT_MUX[x] switches' states:
diff --git a/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi b/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi index 70af605..e3821d8 100644 --- a/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi +++ b/arch/arm64/boot/dts/renesas/rzg3s-smarc.dtsi
@@ -285,7 +285,6 @@ &sdhi1 { bus-width = <4>; sd-uhs-sdr50; sd-uhs-sdr104; - max-frequency = <125000000>; status = "okay"; };
diff --git a/arch/arm64/boot/dts/renesas/rzt2h-n2h-evk-common.dtsi b/arch/arm64/boot/dts/renesas/rzt2h-n2h-evk-common.dtsi index ffcc096..224d133 100644 --- a/arch/arm64/boot/dts/renesas/rzt2h-n2h-evk-common.dtsi +++ b/arch/arm64/boot/dts/renesas/rzt2h-n2h-evk-common.dtsi
@@ -20,6 +20,7 @@ aliases { i2c1 = &i2c1; mmc0 = &sdhi0; mmc1 = &sdhi1; + rtc0 = &rtc0; serial0 = &sci0; spi0 = &xspi0; spi1 = &xspi1; @@ -514,6 +515,10 @@ xspi1_pins: xspi1-pins { }; }; +&rtc0 { + status = "okay"; +}; + &sci0 { pinctrl-0 = <&sci0_pins>; pinctrl-names = "default"; @@ -647,11 +652,13 @@ partitions { partition@0 { label = "bl2-1"; reg = <0x00000000 0x00060000>; + read-only; }; partition@60000 { label = "fip-1"; reg = <0x00060000 0x007a0000>; + read-only; }; partition@800000 {
diff --git a/arch/arm64/boot/dts/renesas/rzt2h-n2h-evk-du-adv7513.dtsi b/arch/arm64/boot/dts/renesas/rzt2h-n2h-evk-du-adv7513.dtsi new file mode 100644 index 0000000..d0242dc --- /dev/null +++ b/arch/arm64/boot/dts/renesas/rzt2h-n2h-evk-du-adv7513.dtsi
@@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DT overlay common parts for the RZ/{T2H/N2H} EVKs with ADV7513 + * transmitter connected to DU enabled. + * + * Copyright (C) 2026 Renesas Electronics Corp. + */ + +#include <dt-bindings/pinctrl/renesas,r9a09g077-pinctrl.h> + +#define ADV7513_PARENT_I2C i2c1 +#include "rz-smarc-du-adv7513.dtsi" + +&pinctrl { + du_pins: du-group { + du-data-pins { + pinmux = <RZT2H_PORT_PINMUX(10, 0, 0x28)>, /* LCDC_DATR0 */ + <RZT2H_PORT_PINMUX(10, 1, 0x28)>, /* LCDC_DATR1 */ + <RZT2H_PORT_PINMUX(10, 2, 0x28)>, /* LCDC_DATR2 */ + <RZT2H_PORT_PINMUX(10, 3, 0x28)>, /* LCDC_DATR3 */ + <RZT2H_PORT_PINMUX(10, 4, 0x28)>, /* LCDC_DATR4 */ + <RZT2H_PORT_PINMUX(10, 5, 0x28)>, /* LCDC_DATR5 */ + <RZT2H_PORT_PINMUX(10, 6, 0x28)>, /* LCDC_DATR6 */ + <RZT2H_PORT_PINMUX(10, 7, 0x28)>, /* LCDC_DATR7 */ + <RZT2H_PORT_PINMUX(11, 0, 0x28)>, /* LCDC_DATG0 */ + <RZT2H_PORT_PINMUX(14, 1, 0x28)>, /* LCDC_DATG1 */ + <RZT2H_PORT_PINMUX(14, 2, 0x28)>, /* LCDC_DATG2 */ + <RZT2H_PORT_PINMUX(14, 3, 0x28)>, /* LCDC_DATG3 */ + <RZT2H_PORT_PINMUX(14, 4, 0x28)>, /* LCDC_DATG4 */ + <RZT2H_PORT_PINMUX(14, 5, 0x28)>, /* LCDC_DATG5 */ + <RZT2H_PORT_PINMUX(14, 6, 0x28)>, /* LCDC_DATG6 */ + <RZT2H_PORT_PINMUX(17, 6, 0x28)>, /* LCDC_DATG7 */ + <RZT2H_PORT_PINMUX(17, 7, 0x28)>, /* LCDC_DATB0 */ + <RZT2H_PORT_PINMUX(18, 0, 0x28)>, /* LCDC_DATB1 */ + <RZT2H_PORT_PINMUX(18, 1, 0x28)>, /* LCDC_DATB2 */ + <RZT2H_PORT_PINMUX(18, 2, 0x28)>, /* LCDC_DATB3 */ + <RZT2H_PORT_PINMUX(18, 3, 0x28)>, /* LCDC_DATB4 */ + <RZT2H_PORT_PINMUX(18, 4, 0x28)>, /* LCDC_DATB5 */ + <RZT2H_PORT_PINMUX(18, 5, 0x28)>, /* LCDC_DATB6 */ + <RZT2H_PORT_PINMUX(18, 6, 0x28)>; /* LCDC_DATB7 */ + drive-strength-microamp = <11800>; + slew-rate = <1>; + }; + + du-clk-pins { + pinmux = <RZT2H_PORT_PINMUX(9, 4, 0x28)>; /* LCDC_CLK */ + drive-strength-microamp = <11800>; + slew-rate = <1>; + }; + + du-sync-pins { + pinmux = <RZT2H_PORT_PINMUX(9, 5, 0x28)>, /* LCDC_HSYNC */ + <RZT2H_PORT_PINMUX(9, 6, 0x28)>; /* LCDC_VSYNC */ + drive-strength-microamp = <11800>; + slew-rate = <0>; + }; + + du-de-pins { + pinmux = <RZT2H_PORT_PINMUX(9, 7, 0x28)>; /* LCDC_DE */ + drive-strength-microamp = <11800>; + slew-rate = <0>; + }; + }; + + adv7513_irq_pins: adv7513-irq-pins { + }; +}; + +&adv7513 { + pinctrl-0 = <&adv7513_irq_pins>; + pinctrl-names = "default"; +};
diff --git a/arch/arm64/boot/dts/renesas/salvator-common.dtsi b/arch/arm64/boot/dts/renesas/salvator-common.dtsi index 1317ede2..b9bdc36 100644 --- a/arch/arm64/boot/dts/renesas/salvator-common.dtsi +++ b/arch/arm64/boot/dts/renesas/salvator-common.dtsi
@@ -543,7 +543,7 @@ video-receiver@70 { reg = <0x70 0x71 0x72 0x73 0x74 0x75 0x60 0x61 0x62 0x63 0x64 0x65>; reg-names = "main", "dpll", "cp", "hdmi", "edid", "repeater", - "infoframe", "cbus", "cec", "sdp", "txa", "txb" ; + "infoframe", "cbus", "cec", "sdp", "txa", "txb"; interrupts-extended = <&gpio6 30 IRQ_TYPE_LEVEL_LOW>, <&gpio6 31 IRQ_TYPE_LEVEL_LOW>; @@ -686,12 +686,12 @@ mux { function = "avb"; }; - pins_mdio { + pins-mdio { groups = "avb_mdio"; drive-strength = <24>; }; - pins_mii_tx { + pins-mii-tx { pins = "PIN_AVB_TX_CTL", "PIN_AVB_TXC", "PIN_AVB_TD0", "PIN_AVB_TD1", "PIN_AVB_TD2", "PIN_AVB_TD3"; drive-strength = <12>; @@ -738,7 +738,7 @@ scif2_pins: scif2 { function = "scif2"; }; - scif_clk_pins: scif_clk { + scif_clk_pins: scif-clk { groups = "scif_clk_a"; function = "scif_clk"; }; @@ -749,7 +749,7 @@ sdhi0_pins: sd0 { power-source = <3300>; }; - sdhi0_pins_uhs: sd0_uhs { + sdhi0_pins_uhs: sd0-uhs { groups = "sdhi0_data4", "sdhi0_ctrl"; function = "sdhi0"; power-source = <1800>; @@ -767,7 +767,7 @@ sdhi3_pins: sd3 { power-source = <3300>; }; - sdhi3_pins_uhs: sd3_uhs { + sdhi3_pins_uhs: sd3-uhs { groups = "sdhi3_data4", "sdhi3_ctrl"; function = "sdhi3"; power-source = <1800>; @@ -778,7 +778,7 @@ sound_pins: sound { function = "ssi"; }; - sound_clk_pins: sound_clk { + sound_clk_pins: sound-clk { groups = "audio_clk_a_a", "audio_clk_b_a", "audio_clk_c_a", "audio_clkout_a", "audio_clkout3_a"; function = "audio_clk";
diff --git a/arch/arm64/boot/dts/renesas/salvator-xs.dtsi b/arch/arm64/boot/dts/renesas/salvator-xs.dtsi index 1d18ded..f515794 100644 --- a/arch/arm64/boot/dts/renesas/salvator-xs.dtsi +++ b/arch/arm64/boot/dts/renesas/salvator-xs.dtsi
@@ -72,7 +72,7 @@ &pfc { * - Connect GP6_3[01] to BD082065 (USB2.0 ch3's host power). * - Connect GP6_{04,21} to ADV7842. */ - usb2_ch3_pins: usb2_ch3 { + usb2_ch3_pins: usb2-ch3 { groups = "usb2_ch3"; function = "usb2_ch3"; };
diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card2-mix+split.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card2-mix+split.dtsi index 67a0057..2460ad8 100644 --- a/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card2-mix+split.dtsi +++ b/arch/arm64/boot/dts/renesas/ulcb-kf-audio-graph-card2-mix+split.dtsi
@@ -76,14 +76,14 @@ ports@0 { * (H) CPU7 * (I) CPU8 */ - fe_c: port@2 { reg = <2>; fe_c_ep: endpoint { remote-endpoint = <&rsnd_c_ep>; }; }; - fe_d: port@3 { reg = <3>; fe_d_ep: endpoint { remote-endpoint = <&rsnd_d_ep>; }; }; - fe_e: port@4 { reg = <4>; fe_e_ep: endpoint { remote-endpoint = <&rsnd_e_ep>; }; }; - fe_f: port@5 { reg = <5>; fe_f_ep: endpoint { remote-endpoint = <&rsnd_f_ep>; }; }; + fe_c: port@2 { reg = <2>; fe_c_ep: endpoint { remote-endpoint = <&rsnd_c_ep>; }; }; + fe_d: port@3 { reg = <3>; fe_d_ep: endpoint { remote-endpoint = <&rsnd_d_ep>; }; }; + fe_e: port@4 { reg = <4>; fe_e_ep: endpoint { remote-endpoint = <&rsnd_e_ep>; }; }; + fe_f: port@5 { reg = <5>; fe_f_ep: endpoint { remote-endpoint = <&rsnd_f_ep>; }; }; - fe_g: port@6 { reg = <6>; fe_g_ep: endpoint { remote-endpoint = <&rsnd_g_ep>; }; }; - fe_h: port@7 { reg = <7>; fe_h_ep: endpoint { remote-endpoint = <&rsnd_h_ep>; }; }; - fe_i: port@8 { reg = <8>; fe_i_ep: endpoint { remote-endpoint = <&rsnd_i_ep>; }; }; + fe_g: port@6 { reg = <6>; fe_g_ep: endpoint { remote-endpoint = <&rsnd_g_ep>; }; }; + fe_h: port@7 { reg = <7>; fe_h_ep: endpoint { remote-endpoint = <&rsnd_h_ep>; }; }; + fe_i: port@8 { reg = <8>; fe_i_ep: endpoint { remote-endpoint = <&rsnd_i_ep>; }; }; }; ports@1 { @@ -96,8 +96,8 @@ ports@1 { * (Y) PCM3168A-p * (Z) PCM3168A-c */ - be_y: port@0 { reg = <0>; be_y_ep: endpoint { remote-endpoint = <&pcm3168a_y_ep>; }; }; - be_z: port@1 { reg = <1>; be_z_ep: endpoint { remote-endpoint = <&pcm3168a_z_ep>; }; }; + be_y: port@0 { reg = <0>; be_y_ep: endpoint { remote-endpoint = <&pcm3168a_y_ep>; }; }; + be_z: port@1 { reg = <1>; be_z_ep: endpoint { remote-endpoint = <&pcm3168a_z_ep>; }; }; }; }; };
diff --git a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi index 97014bc..603c791 100644 --- a/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi +++ b/arch/arm64/boot/dts/renesas/ulcb-kf.dtsi
@@ -84,7 +84,7 @@ reg_5v: regulator-5v { regulator-always-on; }; - wlan_en: regulator-wlan_en { + wlan_en: regulator-wlan-en { compatible = "regulator-fixed"; regulator-name = "wlan-en-regulator";
diff --git a/arch/arm64/boot/dts/renesas/ulcb.dtsi b/arch/arm64/boot/dts/renesas/ulcb.dtsi index 119f2b5..cedff8e 100644 --- a/arch/arm64/boot/dts/renesas/ulcb.dtsi +++ b/arch/arm64/boot/dts/renesas/ulcb.dtsi
@@ -311,12 +311,12 @@ mux { function = "avb"; }; - pins_mdio { + pins-mdio { groups = "avb_mdio"; drive-strength = <24>; }; - pins_mii_tx { + pins-mii-tx { pins = "PIN_AVB_TX_CTL", "PIN_AVB_TXC", "PIN_AVB_TD0", "PIN_AVB_TD1", "PIN_AVB_TD2", "PIN_AVB_TD3"; drive-strength = <12>; @@ -338,7 +338,7 @@ scif2_pins: scif2 { function = "scif2"; }; - scif_clk_pins: scif_clk { + scif_clk_pins: scif-clk { groups = "scif_clk_a"; function = "scif_clk"; }; @@ -349,7 +349,7 @@ sdhi0_pins: sd0 { power-source = <3300>; }; - sdhi0_pins_uhs: sd0_uhs { + sdhi0_pins_uhs: sd0-uhs { groups = "sdhi0_data4", "sdhi0_ctrl"; function = "sdhi0"; power-source = <1800>;
diff --git a/arch/arm64/boot/dts/renesas/white-hawk-cpu-common.dtsi b/arch/arm64/boot/dts/renesas/white-hawk-cpu-common.dtsi index c5045bd..2bcd486 100644 --- a/arch/arm64/boot/dts/renesas/white-hawk-cpu-common.dtsi +++ b/arch/arm64/boot/dts/renesas/white-hawk-cpu-common.dtsi
@@ -320,12 +320,12 @@ mux { function = "avb0"; }; - pins_mdio { + pins-mdio { groups = "avb0_mdio"; drive-strength = <21>; }; - pins_mii { + pins-mii { groups = "avb0_rgmii"; drive-strength = <21>; }; @@ -368,7 +368,7 @@ qspi0_pins: qspi0 { function = "qspi0"; }; - scif_clk_pins: scif_clk { + scif_clk_pins: scif-clk { groups = "scif_clk"; function = "scif_clk"; };
diff --git a/arch/arm64/boot/dts/rockchip/Makefile b/arch/arm64/boot/dts/rockchip/Makefile index e7936a2..442d322 100644 --- a/arch/arm64/boot/dts/rockchip/Makefile +++ b/arch/arm64/boot/dts/rockchip/Makefile
@@ -19,6 +19,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-rock-pi-s.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-rock-s0.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-sakurapi-rk3308b.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3308-unihiker-m10-v1.2.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3318-a95x-z2.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-anbernic-rg351m.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3326-anbernic-rg351v.dtb @@ -94,6 +95,8 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3399pro-rock-pi-n10.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3528-armsom-sige1.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3528-hinlink-h28k.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3528-mangopi-m28k.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3528-nanopi-r28s.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3528-nanopi-zero2.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3528-radxa-e20c.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3528-rock-2a.dtb @@ -183,7 +186,9 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-nanopi-r76s.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-roc-pc.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-rock-4d.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-rock-4d-radxa-cam4k.dtbo dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3582-radxa-e52c.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3582-radxa-e54c.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-armsom-sige7.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-armsom-w3.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-coolpi-cm5-evb.dtb @@ -197,8 +202,10 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-friendlyelec-cm3588-nas.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-h96-max-v58.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar-can1-can2-uart4.dtbo dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar-ethernet-switch.dtbo dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar-pre-ict-tester.dtbo +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-lubancat-5io.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-mnt-reform2.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-nanopc-t6-lts.dtb @@ -216,6 +223,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b-plus-radxa-cam4k-cam0.dtbo dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5b-plus-radxa-cam4k-cam1.dtbo dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-rock-5t.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-tiger-displayport-carrier.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-tiger-haikou.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-tiger-haikou-video-demo.dtbo dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-toybrick-x0.dtb @@ -229,6 +237,7 @@ dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-indiedroid-nova.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-khadas-edge2.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-lubancat-4.dtb +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-m6v1.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6s.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-nanopi-r6c.dtb dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588s-odroid-m2.dtb @@ -311,6 +320,10 @@ rk3576-evb1-v10-pcie1-dtbs := rk3576-evb1-v10.dtb \ rk3576-evb1-v10-pcie1.dtbo +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3576-rock-4d-radxa-4k-cam.dtb +rk3576-rock-4d-radxa-4k-cam-dtbs := rk3576-rock-4d.dtb \ + rk3576-rock-4d-radxa-cam4k.dtbo + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-edgeble-neu6a-wifi.dtb rk3588-edgeble-neu6a-wifi-dtbs := rk3588-edgeble-neu6a-io.dtb \ rk3588-edgeble-neu6a-wifi.dtbo @@ -319,6 +332,10 @@ rk3588-edgeble-neu6b-wifi-dtbs := rk3588-edgeble-neu6b-io.dtb \ rk3588-edgeble-neu6a-wifi.dtbo +dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar-can1-can2-uart4.dtb +rk3588-jaguar-can1-can2-uart4-dtbs := rk3588-jaguar.dtb \ + rk3588-jaguar-can1-can2-uart4.dtbo + dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3588-jaguar-ethernet-switch.dtb rk3588-jaguar-ethernet-switch-dtbs := rk3588-jaguar.dtb \ rk3588-jaguar-ethernet-switch.dtbo
diff --git a/arch/arm64/boot/dts/rockchip/rk3308-unihiker-m10-v1.2.dts b/arch/arm64/boot/dts/rockchip/rk3308-unihiker-m10-v1.2.dts new file mode 100644 index 0000000..270ea97 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3308-unihiker-m10-v1.2.dts
@@ -0,0 +1,248 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2026 Mizuno Miotsuki <founder@crepuse.com> + */ + +/dts-v1/; + +#include <dt-bindings/input/input.h> +#include "rk3308.dtsi" + +/ { + model = "DFRobot UNIHIKER M10 V1.2"; + compatible = "dfrobot,unihiker-m10-v1.2", "rockchip,rk3308"; + + aliases { + mmc0 = &emmc; + mmc1 = &sdmmc; + mmc2 = &sdio; + }; + + chosen { + stdout-path = "serial0:1500000n8"; + }; + + keys { + compatible = "gpio-keys"; + + key-a { + debounce-interval = <20>; + gpios = <&gpio0 RK_PC1 GPIO_ACTIVE_LOW>; + label = "A"; + linux,code = <KEY_A>; + }; + + key-b { + debounce-interval = <20>; + gpios = <&gpio0 RK_PC2 GPIO_ACTIVE_LOW>; + label = "B"; + linux,code = <KEY_B>; + }; + + key-home { + debounce-interval = <20>; + gpios = <&gpio1 RK_PA0 GPIO_ACTIVE_LOW>; + label = "Home"; + linux,code = <KEY_HOME>; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_h>; + reset-gpios = <&gpio0 RK_PA2 GPIO_ACTIVE_LOW>; + }; + + vcc_1v8: regulator-vcc-1v8 { + compatible = "regulator-fixed"; + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_io>; + }; + + vcc_io: regulator-vcc-io { + compatible = "regulator-fixed"; + regulator-name = "vcc_io"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc_sd: regulator-vcc-sd { + compatible = "regulator-fixed"; + gpios = <&gpio4 RK_PD6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&sd_vcc_en>; + regulator-name = "vcc_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + vcc5v0_sys: regulator-vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vcc5v0_usb_host: regulator-vcc5v0-usb-host { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb_host_vbus_en>; + regulator-name = "vcc5v0_usb_host"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_sys>; + }; + + vdd_core: regulator-vdd-core { + compatible = "pwm-regulator"; + pwms = <&pwm0 0 5000 1>; + regulator-name = "vdd_core"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <827000>; + regulator-max-microvolt = <1340000>; + regulator-settling-time-up-us = <250>; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_core>; +}; + +&emmc { + cap-mmc-highspeed; + no-1-8-v; + non-removable; + pinctrl-names = "default"; + pinctrl-0 = <&emmc_bus8 &emmc_clk &emmc_cmd>; + vmmc-supply = <&vcc_io>; + status = "okay"; +}; + +&io_domains { + vccio0-supply = <&vcc_io>; + vccio1-supply = <&vcc_io>; + vccio2-supply = <&vcc_io>; + vccio3-supply = <&vcc_io>; + vccio4-supply = <&vcc_1v8>; + vccio5-supply = <&vcc_io>; + status = "okay"; +}; + +&otp { + status = "disabled"; +}; + +&pinctrl { + pinctrl-names = "default"; + pinctrl-0 = <&rtc_32k>; + + sdmmc { + sd_vcc_en: sd-vcc-en { + rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb { + usb_host_vbus_en: usb-host-vbus-en { + rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + wifi { + wifi_enable_h: wifi-enable-h { + rockchip,pins = <0 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + wifi_host_wake: wifi-host-wake { + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; +}; + +&pwm0 { + pinctrl-names = "default"; + pinctrl-0 = <&pwm0_pin_pull_down>; + status = "okay"; +}; + +&sdio { + #address-cells = <1>; + #size-cells = <0>; + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; + no-mmc; + no-sd; + non-removable; + vmmc-supply = <&vcc_io>; + vqmmc-supply = <&vcc_1v8>; + status = "okay"; + + wifi@1 { + reg = <1>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PA0 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "host-wake"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_host_wake>; + }; +}; + +&sdmmc { + cap-sd-highspeed; + disable-wp; + no-1-8-v; + vmmc-supply = <&vcc_sd>; + vqmmc-supply = <&vcc_io>; + status = "okay"; +}; + +&u2phy { + status = "okay"; +}; + +&u2phy_host { + phy-supply = <&vcc5v0_usb_host>; + status = "okay"; +}; + +&u2phy_otg { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_xfer>; + status = "okay"; +}; + +&usb20_otg { + dr_mode = "peripheral"; + status = "okay"; +}; + +&usb_host_ehci { + status = "okay"; +}; + +&usb_host_ohci { + status = "okay"; +}; + +&wdt { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/rockchip/rk3328.dtsi b/arch/arm64/boot/dts/rockchip/rk3328.dtsi index 03b7c43..26c9f45 100644 --- a/arch/arm64/boot/dts/rockchip/rk3328.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3328.dtsi
@@ -207,7 +207,7 @@ hdmi_sound: hdmi-sound { compatible = "simple-audio-card"; simple-audio-card,format = "i2s"; simple-audio-card,mclk-fs = <128>; - simple-audio-card,name = "HDMI"; + simple-audio-card,name = "RK3328 HDMI"; status = "disabled"; simple-audio-card,cpu {
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi index 49c68fe..c46e58d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399-base.dtsi
@@ -2008,7 +2008,7 @@ hdmi_sound: hdmi-sound { compatible = "simple-audio-card"; simple-audio-card,format = "i2s"; simple-audio-card,mclk-fs = <256>; - simple-audio-card,name = "hdmi-sound"; + simple-audio-card,name = "RK3399 HDMI"; status = "disabled"; simple-audio-card,cpu {
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts index 70aee1a..d337f69 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-evb-ind.dts
@@ -387,7 +387,6 @@ &sdhci { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; no-sdio;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts index 0568dfa..3d22ae6 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-firefly.dts
@@ -96,6 +96,15 @@ key-power { }; }; + /* GPIO that enables the headphone output path */ + headphones_amp: headphones-amp { + compatible = "simple-audio-amplifier"; + enable-gpios = <&gpio4 RK_PC5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&rt5640_hpcon>; + sound-name-prefix = "Headphone Amp"; + }; + ir-receiver { compatible = "gpio-ir-receiver"; gpios = <&gpio0 RK_PA6 GPIO_ACTIVE_LOW>; @@ -132,8 +141,11 @@ rt5640-sound { simple-audio-card,routing = "Mic Jack", "MICBIAS1", "IN1P", "Mic Jack", - "Headphone Jack", "HPOL", - "Headphone Jack", "HPOR"; + "Headphone Amp INL", "HPOL", + "Headphone Amp INR", "HPOR", + "Headphone Jack", "Headphone Amp OUTL", + "Headphone Jack", "Headphone Amp OUTR"; + simple-audio-card,aux-devs = <&headphones_amp>; simple-audio-card,cpu { sound-dai = <&i2s1>; @@ -311,6 +323,10 @@ &hdmi { status = "okay"; }; +&hdmi_sound { + status = "okay"; +}; + &i2c0 { clock-frequency = <400000>; i2c-scl-rising-time-ns = <168>; @@ -547,8 +563,6 @@ rt5640: rt5640@1c { clock-names = "mclk"; realtek,in1-differential; #sound-dai-cells = <0>; - pinctrl-names = "default"; - pinctrl-0 = <&rt5640_hpcon>; }; }; @@ -618,13 +632,9 @@ accelerometer@68 { }; }; -&i2s0 { - rockchip,playback-channels = <8>; - rockchip,capture-channels = <8>; - status = "okay"; -}; - &i2s1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2s_8ch_mclk_pin>, <&i2s1_2ch_bus>; rockchip,playback-channels = <2>; rockchip,capture-channels = <2>; status = "okay"; @@ -679,6 +689,12 @@ ir_int: ir-int { }; }; + i2s1 { + i2s_8ch_mclk_pin: i2s-8ch-mclk-pin { + rockchip,pins = <4 RK_PA0 1 &pcfg_pull_none>; + }; + }; + lcd-panel { lcd_panel_reset: lcd-panel-reset { rockchip,pins = <4 RK_PD6 RK_FUNC_GPIO &pcfg_pull_up>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts index b2de018..63ad79b 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts
@@ -11,6 +11,7 @@ */ /dts-v1/; +#include <dt-bindings/input/input.h> #include "rk3399.dtsi" / { @@ -23,6 +24,20 @@ aliases { mmc1 = &sdhci; }; + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-recovery { + label = "Recovery"; + linux,code = <BTN_1>; + press-threshold-microvolt = <100000>; + }; + }; + avdd_0v9_s0: regulator-avdd-0v9-s0 { compatible = "regulator-fixed"; regulator-name = "avdd_0v9_s0"; @@ -59,6 +74,10 @@ fan1 { compatible = "pwm-fan"; pwms = <&pwm0 0 40000 0>; cooling-levels = <0 80 170 255>; + interrupt-parent = <&gpio4>; + interrupts = <RK_PC5 IRQ_TYPE_EDGE_FALLING>; + pinctrl-names = "default"; + pinctrl-0 = <&fan1_sense>; }; fan2 { @@ -66,6 +85,31 @@ fan2 { compatible = "pwm-fan"; pwms = <&pwm1 0 40000 0>; cooling-levels = <0 80 170 255>; + interrupt-parent = <&gpio4>; + interrupts = <RK_PC7 IRQ_TYPE_EDGE_FALLING>; + pinctrl-names = "default"; + pinctrl-0 = <&fan2_sense>; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&pwr_btn &user1_btn>; + + button-power { + debounce-interval = <100>; + gpios = <&gpio0 RK_PA5 GPIO_ACTIVE_LOW>; + label = "Power"; + linux,code = <KEY_POWER>; + wakeup-source; + }; + + button-user1 { + debounce-interval = <100>; + gpios = <&gpio0 RK_PA3 GPIO_ACTIVE_LOW>; + label = "User Button 1"; + linux,code = <BTN_0>; + }; }; leds { @@ -352,6 +396,19 @@ regulator-state-mem { }; }; + vcc1v8_s3: LDO_REG3 { + regulator-name = "vcc1v8_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + vcc_sdio_s0: LDO_REG4 { regulator-name = "vcc_sdio_s0"; regulator-always-on; @@ -434,6 +491,26 @@ &pcie0 { }; &pinctrl { + buttons { + pwr_btn: pwr-btn { + rockchip,pins = <0 RK_PA5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + user1_btn: user1-btn { + rockchip,pins = <0 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + fan { + fan1_sense: fan1-sense { + rockchip,pins = <4 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + fan2_sense: fan2-sense { + rockchip,pins = <4 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + gmac { gphy_reset: gphy-reset { rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_output_low>; @@ -503,6 +580,11 @@ &pwm1 { status = "okay"; }; +&saradc { + vref-supply = <&vcc1v8_s3>; + status = "okay"; +}; + &sdhci { bus-width = <8>; mmc-hs200-1_8v;
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts index f21fcdc..f728e6f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-pinebook-pro.dts
@@ -656,6 +656,10 @@ es8316: audio-codec@11 { reg = <0x11>; clocks = <&cru SCLK_I2S_8CH_OUT>; clock-names = "mclk"; + avdd-supply = <&vcca3v0_codec>; + cpvdd-supply = <&vcca1v8_codec>; + dvdd-supply = <&vcca1v8_codec>; + pvdd-supply = <&vcc_3v0>; #sound-dai-cells = <0>; }; };
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64-v2.dts b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64-v2.dts index 883d9bc..37124ad 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64-v2.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64-v2.dts
@@ -19,6 +19,10 @@ es8316: codec@10 { reg = <0x10>; clocks = <&cru SCLK_I2S_8CH_OUT>; clock-names = "mclk"; + avdd-supply = <&vcca3v0_codec>; + cpvdd-supply = <&vcca1v8_codec>; + dvdd-supply = <&vcca1v8_codec>; + pvdd-supply = <&vcc_3v0>; #sound-dai-cells = <0>; port {
diff --git a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts index ae3ee91..1449885 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts +++ b/arch/arm64/boot/dts/rockchip/rk3399-rockpro64.dts
@@ -19,6 +19,10 @@ es8316: codec@11 { reg = <0x11>; clocks = <&cru SCLK_I2S_8CH_OUT>; clock-names = "mclk"; + avdd-supply = <&vcca3v0_codec>; + cpvdd-supply = <&vcca1v8_codec>; + dvdd-supply = <&vcca1v8_codec>; + pvdd-supply = <&vcc_3v0>; #sound-dai-cells = <0>; port {
diff --git a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi index 64e6ba3..074f09c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3399pro-vmarc-som.dtsi
@@ -296,6 +296,8 @@ &i2c1 { &i2c2 { clock-frequency = <400000>; + i2c-scl-falling-time-ns = <15>; + i2c-scl-rising-time-ns = <450>; status = "okay"; hym8563: rtc@51 {
diff --git a/arch/arm64/boot/dts/rockchip/rk3528-mangopi-m28k.dts b/arch/arm64/boot/dts/rockchip/rk3528-mangopi-m28k.dts new file mode 100644 index 0000000..3d53d9df --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3528-mangopi-m28k.dts
@@ -0,0 +1,412 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; + +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/pwm/pwm.h> +#include "rk3528.dtsi" + +/ { + model = "MangoPi M28K"; + compatible = "widora,mangopi-m28k", "rockchip,rk3528"; + + aliases { + ethernet0 = &gmac1; + i2c6 = &i2c6; + mmc0 = &sdhci; + mmc1 = &sdmmc; + mmc2 = &sdio0; + serial0 = &uart0; + serial2 = &uart2; + serial3 = &uart3; + }; + + chosen { + stdout-path = "serial0:1500000n8"; + }; + + ir-receiver { + compatible = "gpio-ir-receiver"; + gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pwm3_m0_ir_rx>; + }; + + keys-0 { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-boot { + label = "BOOT"; + linux,code = <KEY_SETUP>; + press-threshold-microvolt = <0>; + }; + }; + + keys-1 { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-recover { + label = "RECOVER"; + linux,code = <KEY_VENDOR>; + press-threshold-microvolt = <0>; + }; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&lan_led>, <&wan_led>, <&work_led>; + + led-0 { + color = <LED_COLOR_ID_WHITE>; + function = LED_FUNCTION_LAN; + gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_LOW>; + linux,default-trigger = "netdev"; + }; + + led-1 { + color = <LED_COLOR_ID_WHITE>; + function = LED_FUNCTION_WAN; + gpios = <&gpio4 RK_PC0 GPIO_ACTIVE_LOW>; + linux,default-trigger = "netdev"; + }; + + led-2 { + color = <LED_COLOR_ID_GREEN>; + function = LED_FUNCTION_STATUS; + gpios = <&gpio4 RK_PB7 GPIO_ACTIVE_LOW>; + linux,default-trigger = "default-on"; + }; + }; + + vdd_0v9: regulator-0v9-vdd { + compatible = "regulator-fixed"; + regulator-name = "vdd_0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + vin-supply = <&vcc_sys>; + }; + + vcc_ddr: regulator-1v1-vcc-ddr { + compatible = "regulator-fixed"; + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + vin-supply = <&vcc_sys>; + }; + + vcc_1v8: regulator-1v8-vcc { + compatible = "regulator-fixed"; + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_3v3>; + }; + + vcc_3v3: regulator-3v3-vcc { + compatible = "regulator-fixed"; + regulator-name = "vcc_3v3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_sys>; + }; + + vcc3v3_sd: regulator-3v3-vcc-sd { + compatible = "regulator-fixed"; + gpios = <&gpio4 RK_PA1 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_pwren_l>; + regulator-name = "vcc3v3_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_3v3>; + }; + + vcc_sys: regulator-5v0-vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vccio_sd: regulator-vccio-sd { + compatible = "regulator-gpio"; + gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_vol_ctrl_h>; + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + states = <1800000 0x0>, <3300000 0x1>; + vin-supply = <&vcc_sys>; + }; + + vdd_arm: regulator-vdd-arm { + compatible = "pwm-regulator"; + pwms = <&pwm1 0 5000 PWM_POLARITY_INVERTED>; + pwm-supply = <&vcc_sys>; + regulator-name = "vdd_arm"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <746000>; + regulator-max-microvolt = <1201000>; + regulator-settling-time-up-us = <250>; + }; + + vdd_logic: regulator-vdd-logic { + compatible = "pwm-regulator"; + pwms = <&pwm2 0 5000 PWM_POLARITY_INVERTED>; + pwm-supply = <&vcc_sys>; + regulator-name = "vdd_logic"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <705000>; + regulator-max-microvolt = <1006000>; + regulator-settling-time-up-us = <250>; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_reg_on_h>; + post-power-on-delay-ms = <100>; + power-off-delay-us = <5000000>; + reset-gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_LOW>; + }; +}; + +&combphy { + status = "okay"; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&gmac1 { + clock_in_out = "output"; + phy-handle = <&rgmii_phy>; + phy-mode = "rgmii-id"; + phy-supply = <&vcc_3v3>; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_miim>, + <&rgmii_tx_bus2>, + <&rgmii_rx_bus2>, + <&rgmii_rgmii_clk>, + <&rgmii_rgmii_bus>; + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&i2c6 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c6m0_xfer>; + status = "okay"; +}; + +&mdio1 { + rgmii_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x1>; + pinctrl-names = "default"; + pinctrl-0 = <&gmac1_rstn_l>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio4 RK_PC2 GPIO_ACTIVE_LOW>; + }; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&rtl8111hs_isolateb_l>; + reset-gpios = <&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc_3v3>; + status = "okay"; +}; + +&pinctrl { + gmac { + gmac1_rstn_l: gmac1-rstn-l { + rockchip,pins = <4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + ir { + pwm3_m0_ir_rx: pwm3-m0-ir-rx { + rockchip,pins = <4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + leds { + lan_led: lan-led { + rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + wan_led: wan-led { + rockchip,pins = <4 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + work_led: work-led { + rockchip,pins = <4 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pcie { + rtl8111hs_isolateb_l: rtl8111hs-isolateb-l { + rockchip,pins = <4 RK_PA6 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + sdmmc { + sdmmc_pwren_l: sdmmc-pwren-l { + rockchip,pins = <4 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + sdmmc_vol_ctrl_h: sdmmc-vol-ctrl-h { + rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + wifi { + wifi_reg_on_h: wifi-reg-on-h { + rockchip,pins = <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + wifi_wake_host_h: wifi-wake-host-h { + rockchip,pins = <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pwm1m0_pins>; + status = "okay"; +}; + +&pwm2 { + pinctrl-names = "default"; + pinctrl-0 = <&pwm2m0_pins>; + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + non-removable; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdio0 { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; + non-removable; + sd-uhs-sdr104; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-sd-highspeed; + disable-wp; + sd-uhs-sdr104; + vmmc-supply = <&vcc3v3_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0m0_xfer>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2m1_ctsn>, <&uart2m1_rtsn>, <&uart2m1_xfer>; + uart-has-rtscts; + status = "okay"; +}; + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&uart3m0_xfer>; + status = "disabled"; +}; + +&usb2phy { + status = "okay"; +}; + +&usb2phy_host { + phy-supply = <&vcc_sys>; + status = "okay"; +}; + +&usb2phy_otg { + phy-supply = <&vcc_sys>; + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host0_xhci { + dr_mode = "host"; + extcon = <&usb2phy>; + maximum-speed = "high-speed"; + phys = <&usb2phy_otg>; + phy-names = "usb2-phy"; + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/rockchip/rk3528-nanopi-r28s.dts b/arch/arm64/boot/dts/rockchip/rk3528-nanopi-r28s.dts new file mode 100644 index 0000000..294b66f --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3528-nanopi-r28s.dts
@@ -0,0 +1,160 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2022 Rockchip Electronics Co., Ltd. + * Copyright (c) 2026 FriendlyElec Computer Tech. Co., Ltd. + * Copyright (c) 2026 安容 <HystericalDragons@proton.me> + */ + +/dts-v1/; + +#include "rk3528-nanopi.dtsi" + +/ { + model = "FriendlyElec NanoPi R28S"; + compatible = "friendlyarm,nanopi-r28s", "rockchip,rk3528"; + + aliases { + mmc2 = &sdio0; + serial2 = &uart2; + }; + + gpio-keys { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&gpio4_b2_usr_btn>; + + button-user { + debounce-interval = <50>; + gpios = <&gpio4 RK_PB2 GPIO_ACTIVE_LOW>; + label = "USER"; + linux,code = <BTN_1>; + wakeup-source; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&pwr_wf>; + post-power-on-delay-ms = <100>; + reset-gpios = <&gpio1 RK_PC2 GPIO_ACTIVE_LOW>; + }; +}; + +&combphy { + status = "okay"; +}; + +&led1 { + default-state = "off"; + function = LED_FUNCTION_WAN; + linux,default-trigger = "netdev"; +}; + +&leds { + pinctrl-names = "default"; + pinctrl-0 = <&led_sys_pin>, <&led1_pin>, <&led2_pin>; + + led-2 { + color = <LED_COLOR_ID_GREEN>; + default-state = "off"; + function = LED_FUNCTION_LAN; + gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "netdev"; + }; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pcie_eth_perstb>; + reset-gpios = <&gpio4 RK_PC0 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc_3v3>; + status = "okay"; +}; + +&pinctrl { + bluetooth { + bt_wake_host: bt-wake-host { + rockchip,pins = <1 RK_PB5 RK_FUNC_GPIO &pcfg_pull_down>; + }; + + host_wake_bt: host-wake-bt { + rockchip,pins = <1 RK_PB4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + gpio-keys { + gpio4_b2_usr_btn: gpio4-b2-usr-btn { + rockchip,pins = <4 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + leds { + led2_pin: led2-pin { + rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pcie { + pcie_eth_perstb: pcie-eth-perstb { + rockchip,pins = <4 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + wifi { + host_wake_wl: host-wake-wl { + rockchip,pins = <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pwr_wf: pwr-wf { + rockchip,pins = <1 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + wl_wake_host: wl-wake-host { + rockchip,pins = <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_down>; + }; + }; +}; + +&sdio0 { + bus-width = <4>; + cap-sd-highspeed; + cap-sdio-irq; + keep-power-in-suspend; + mmc-pwrseq = <&sdio_pwrseq>; + no-mmc; + no-sd; + non-removable; + sd-uhs-sdr104; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vcc_1v8>; + status = "okay"; +}; + +&uart2 { + dma-names = "tx", "rx"; + pinctrl-names = "default"; + pinctrl-0 = <&uart2m1_xfer>, <&uart2m1_ctsn>, <&uart2m1_rtsn>; + uart-has-rtscts; + status = "okay"; +}; + +&usb_host0_xhci { + /* + * The Type-C port is also the 5V power input, so it comes up as a + * device, but host mode works with an externally powered hub. + */ + extcon = <&usb2phy>; + maximum-speed = "high-speed"; + phys = <&usb2phy_otg>; + phy-names = "usb2-phy"; + status = "okay"; +}; + +&usb2phy { + status = "okay"; +}; + +&usb2phy_otg { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/rockchip/rk3528-nanopi-zero2.dts b/arch/arm64/boot/dts/rockchip/rk3528-nanopi-zero2.dts index 97d8512..05ae036 100644 --- a/arch/arm64/boot/dts/rockchip/rk3528-nanopi-zero2.dts +++ b/arch/arm64/boot/dts/rockchip/rk3528-nanopi-zero2.dts
@@ -2,41 +2,12 @@ /dts-v1/; -#include <dt-bindings/input/input.h> -#include <dt-bindings/leds/common.h> -#include <dt-bindings/pwm/pwm.h> -#include "rk3528.dtsi" +#include "rk3528-nanopi.dtsi" / { model = "FriendlyElec NanoPi Zero2"; compatible = "friendlyarm,nanopi-zero2", "rockchip,rk3528"; - aliases { - ethernet0 = &gmac1; - i2c1 = &i2c1; - mmc0 = &sdhci; - mmc1 = &sdmmc; - serial0 = &uart0; - }; - - chosen { - stdout-path = "serial0:1500000n8"; - }; - - adc-keys-0 { - compatible = "adc-keys"; - io-channels = <&saradc 0>; - io-channel-names = "buttons"; - keyup-threshold-microvolt = <1800000>; - poll-interval = <100>; - - button-maskrom { - label = "MASK"; - linux,code = <KEY_SETUP>; - press-threshold-microvolt = <0>; - }; - }; - adc-keys-1 { compatible = "adc-keys"; io-channels = <&saradc 1>; @@ -51,28 +22,6 @@ button-recovery { }; }; - leds { - compatible = "gpio-leds"; - pinctrl-names = "default"; - pinctrl-0 = <&led1>, <&led_sys>; - - led-0 { - color = <LED_COLOR_ID_RED>; - default-state = "on"; - function = LED_FUNCTION_HEARTBEAT; - gpios = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "heartbeat"; - }; - - led-1 { - color = <LED_COLOR_ID_GREEN>; - default-state = "on"; - function = LED_FUNCTION_STATUS; - gpios = <&gpio4 RK_PB1 GPIO_ACTIVE_HIGH>; - linux,default-trigger = "default-on"; - }; - }; - vcc0v6_ddr: regulator-0v6-vcc-ddr { compatible = "regulator-fixed"; regulator-name = "vcc0v6_ddr"; @@ -83,66 +32,6 @@ vcc0v6_ddr: regulator-0v6-vcc-ddr { vin-supply = <&vcc5v0_sys>; }; - vdd_0v9: regulator-0v9-vdd { - compatible = "regulator-fixed"; - regulator-name = "vdd_0v9"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <900000>; - regulator-max-microvolt = <900000>; - vin-supply = <&vcc5v0_sys>; - }; - - vcc_ddr: regulator-1v1-vcc-ddr { - compatible = "regulator-fixed"; - regulator-name = "vcc_ddr"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1100000>; - regulator-max-microvolt = <1100000>; - vin-supply = <&vcc5v0_sys>; - }; - - vcc_1v8: regulator-1v8-vcc { - compatible = "regulator-fixed"; - regulator-name = "vcc_1v8"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - vin-supply = <&vcc_3v3>; - }; - - vcc_3v3: regulator-3v3-vcc { - compatible = "regulator-fixed"; - regulator-name = "vcc_3v3"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - vin-supply = <&vcc5v0_sys>; - }; - - vcc3v3_sd: regulator-3v3-vcc-sd { - compatible = "regulator-fixed"; - gpios = <&gpio4 RK_PA1 GPIO_ACTIVE_LOW>; - pinctrl-names = "default"; - pinctrl-0 = <&sdmmc_pwren_l>; - regulator-name = "vcc3v3_sd"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - vin-supply = <&vcc_3v3>; - }; - - vcc5v0_sys: regulator-5v0-vcc-sys { - compatible = "regulator-fixed"; - regulator-name = "vcc5v0_sys"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - }; - usb2_host_5v: regulator-5v0-usb2-host { compatible = "regulator-fixed"; enable-active-high; @@ -154,138 +43,15 @@ usb2_host_5v: regulator-5v0-usb2-host { regulator-max-microvolt = <5000000>; vin-supply = <&vcc5v0_sys>; }; - - vccio_sd: regulator-vccio-sd { - compatible = "regulator-gpio"; - gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&sdmmc_vol_ctrl_h>; - regulator-name = "vccio_sd"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - states = <1800000 0x0>, <3300000 0x1>; - vin-supply = <&vcc5v0_sys>; - }; - - vdd_arm: regulator-vdd-arm { - compatible = "pwm-regulator"; - pwms = <&pwm1 0 5000 PWM_POLARITY_INVERTED>; - pwm-supply = <&vcc5v0_sys>; - regulator-name = "vdd_arm"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <746000>; - regulator-max-microvolt = <1201000>; - regulator-settling-time-up-us = <250>; - }; - - vdd_logic: regulator-vdd-logic { - compatible = "pwm-regulator"; - pwms = <&pwm2 0 5000 PWM_POLARITY_INVERTED>; - pwm-supply = <&vcc5v0_sys>; - regulator-name = "vdd_logic"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <705000>; - regulator-max-microvolt = <1006000>; - regulator-settling-time-up-us = <250>; - }; }; -&cpu0 { - cpu-supply = <&vdd_arm>; -}; - -&cpu1 { - cpu-supply = <&vdd_arm>; -}; - -&cpu2 { - cpu-supply = <&vdd_arm>; -}; - -&cpu3 { - cpu-supply = <&vdd_arm>; -}; - -&gmac1 { - clock_in_out = "output"; - phy-handle = <&rgmii_phy>; - phy-mode = "rgmii-id"; - phy-supply = <&vcc_3v3>; - pinctrl-names = "default"; - pinctrl-0 = <&rgmii_miim>, <&rgmii_tx_bus2>, <&rgmii_rx_bus2>, - <&rgmii_rgmii_clk>, <&rgmii_rgmii_bus>; - status = "okay"; -}; - -&gpu { - mali-supply = <&vdd_logic>; - status = "okay"; -}; - -&i2c1 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c1m0_xfer>; - status = "okay"; - - hym8563: rtc@51 { - compatible = "haoyu,hym8563"; - reg = <0x51>; - #clock-cells = <0>; - interrupt-parent = <&gpio4>; - interrupts = <RK_PC1 IRQ_TYPE_LEVEL_LOW>; - pinctrl-names = "default"; - pinctrl-0 = <&rtc_int_l>; - wakeup-source; - }; -}; - -&mdio1 { - rgmii_phy: ethernet-phy@1 { - compatible = "ethernet-phy-ieee802.3-c22"; - reg = <0x1>; - pinctrl-names = "default"; - pinctrl-0 = <&gmac1_rstn_l>; - reset-assert-us = <20000>; - reset-deassert-us = <100000>; - reset-gpios = <&gpio4 RK_PC2 GPIO_ACTIVE_LOW>; - }; +&led1 { + default-state = "on"; + function = LED_FUNCTION_STATUS; + linux,default-trigger = "default-on"; }; &pinctrl { - ethernet { - gmac1_rstn_l: gmac1-rstn-l { - rockchip,pins = <4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - - leds { - led1: led1 { - rockchip,pins = <4 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; - }; - - led_sys: led-sys { - rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - - rtc { - rtc_int_l: rtc-int-l { - rockchip,pins = <4 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; - - sdmmc { - sdmmc_vol_ctrl_h: sdmmc-vol-ctrl-h { - rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; - }; - - sdmmc_pwren_l: sdmmc-pwren-l { - rockchip,pins = <4 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - usb { usb20_host1_pwren: usb20-host1-pwren { rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; @@ -293,52 +59,6 @@ usb20_host1_pwren: usb20-host1-pwren { }; }; -&pwm1 { - pinctrl-names = "default"; - pinctrl-0 = <&pwm1m0_pins>; - status = "okay"; -}; - -&pwm2 { - pinctrl-names = "default"; - pinctrl-0 = <&pwm2m0_pins>; - status = "okay"; -}; - -&saradc { - vref-supply = <&vcc_1v8>; - status = "okay"; -}; - -&sdhci { - bus-width = <8>; - cap-mmc-highspeed; - mmc-hs200-1_8v; - no-sd; - no-sdio; - non-removable; - vmmc-supply = <&vcc_3v3>; - vqmmc-supply = <&vcc_1v8>; - status = "okay"; -}; - -&sdmmc { - bus-width = <4>; - cap-mmc-highspeed; - cap-sd-highspeed; - disable-wp; - sd-uhs-sdr104; - vmmc-supply = <&vcc3v3_sd>; - vqmmc-supply = <&vccio_sd>; - status = "okay"; -}; - -&uart0 { - pinctrl-names = "default"; - pinctrl-0 = <&uart0m0_xfer>; - status = "okay"; -}; - &usb_host0_ehci { status = "okay"; };
diff --git a/arch/arm64/boot/dts/rockchip/rk3528-nanopi.dtsi b/arch/arm64/boot/dts/rockchip/rk3528-nanopi.dtsi new file mode 100644 index 0000000..4b3f26d --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3528-nanopi.dtsi
@@ -0,0 +1,291 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/pwm/pwm.h> +#include "rk3528.dtsi" + +/ { + aliases { + ethernet0 = &gmac1; + i2c1 = &i2c1; + mmc0 = &sdhci; + mmc1 = &sdmmc; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:1500000n8"; + }; + + adc-keys-0 { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-maskrom { + label = "MASK"; + linux,code = <KEY_SETUP>; + press-threshold-microvolt = <0>; + }; + }; + + leds: leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&led_sys_pin>, <&led1_pin>; + + led-0 { + color = <LED_COLOR_ID_RED>; + default-state = "on"; + function = LED_FUNCTION_HEARTBEAT; + gpios = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + + /* The purpose of the second LED differs per board. */ + led1: led-1 { + color = <LED_COLOR_ID_GREEN>; + gpios = <&gpio4 RK_PB1 GPIO_ACTIVE_HIGH>; + }; + }; + + vdd_0v9: regulator-0v9-vdd { + compatible = "regulator-fixed"; + regulator-name = "vdd_0v9"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <900000>; + regulator-max-microvolt = <900000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc_ddr: regulator-1v1-vcc-ddr { + compatible = "regulator-fixed"; + regulator-name = "vcc_ddr"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc_1v8: regulator-1v8-vcc { + compatible = "regulator-fixed"; + regulator-name = "vcc_1v8"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + vin-supply = <&vcc_3v3>; + }; + + vcc_3v3: regulator-3v3-vcc { + compatible = "regulator-fixed"; + regulator-name = "vcc_3v3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc3v3_sd: regulator-3v3-vcc-sd { + compatible = "regulator-fixed"; + gpios = <&gpio4 RK_PA1 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_pwren_l>; + regulator-name = "vcc3v3_sd"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_3v3>; + }; + + vcc5v0_sys: regulator-5v0-vcc-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vccio_sd: regulator-vccio-sd { + compatible = "regulator-gpio"; + gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_vol_ctrl_h>; + regulator-name = "vccio_sd"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + states = <1800000 0x0>, <3300000 0x1>; + vin-supply = <&vcc5v0_sys>; + }; + + vdd_arm: regulator-vdd-arm { + compatible = "pwm-regulator"; + pwms = <&pwm1 0 5000 PWM_POLARITY_INVERTED>; + pwm-supply = <&vcc5v0_sys>; + regulator-name = "vdd_arm"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <746000>; + regulator-max-microvolt = <1201000>; + regulator-settling-time-up-us = <250>; + }; + + vdd_logic: regulator-vdd-logic { + compatible = "pwm-regulator"; + pwms = <&pwm2 0 5000 PWM_POLARITY_INVERTED>; + pwm-supply = <&vcc5v0_sys>; + regulator-name = "vdd_logic"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <705000>; + regulator-max-microvolt = <1006000>; + regulator-settling-time-up-us = <250>; + }; +}; + +&cpu0 { + cpu-supply = <&vdd_arm>; +}; + +&cpu1 { + cpu-supply = <&vdd_arm>; +}; + +&cpu2 { + cpu-supply = <&vdd_arm>; +}; + +&cpu3 { + cpu-supply = <&vdd_arm>; +}; + +&gmac1 { + clock_in_out = "output"; + phy-handle = <&rgmii_phy>; + phy-mode = "rgmii-id"; + phy-supply = <&vcc_3v3>; + pinctrl-names = "default"; + pinctrl-0 = <&rgmii_miim>, <&rgmii_tx_bus2>, <&rgmii_rx_bus2>, + <&rgmii_rgmii_clk>, <&rgmii_rgmii_bus>; + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_logic>; + status = "okay"; +}; + +&i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c1m0_xfer>; + status = "okay"; + + hym8563: rtc@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + #clock-cells = <0>; + interrupt-parent = <&gpio4>; + interrupts = <RK_PC1 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&rtc_int_l>; + wakeup-source; + }; +}; + +&mdio1 { + rgmii_phy: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x1>; + pinctrl-names = "default"; + pinctrl-0 = <&gmac1_rstn_l>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio4 RK_PC2 GPIO_ACTIVE_LOW>; + }; +}; + +&pinctrl { + ethernet { + gmac1_rstn_l: gmac1-rstn-l { + rockchip,pins = <4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + leds { + led_sys_pin: led-sys-pin { + rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + led1_pin: led1-pin { + rockchip,pins = <4 RK_PB1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + rtc { + rtc_int_l: rtc-int-l { + rockchip,pins = <4 RK_PC1 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + sdmmc { + sdmmc_pwren_l: sdmmc-pwren-l { + rockchip,pins = <4 RK_PA1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + sdmmc_vol_ctrl_h: sdmmc-vol-ctrl-h { + rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pwm1m0_pins>; + status = "okay"; +}; + +&pwm2 { + pinctrl-names = "default"; + pinctrl-0 = <&pwm2m0_pins>; + status = "okay"; +}; + +&saradc { + vref-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + cap-mmc-highspeed; + mmc-hs200-1_8v; + no-sd; + no-sdio; + non-removable; + vmmc-supply = <&vcc_3v3>; + vqmmc-supply = <&vcc_1v8>; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + disable-wp; + sd-uhs-sdr104; + vmmc-supply = <&vcc3v3_sd>; + vqmmc-supply = <&vccio_sd>; + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0m0_xfer>; + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/rockchip/rk3562-evb2-v10.dts b/arch/arm64/boot/dts/rockchip/rk3562-evb2-v10.dts index 387062e..04b673a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3562-evb2-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3562-evb2-v10.dts
@@ -418,7 +418,6 @@ &sdmmc0 { no-sdio; no-mmc; bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; pinctrl-names = "default";
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3566-base.dtsi index e56e0b6..3c365a1 100644 --- a/arch/arm64/boot/dts/rockchip/rk3566-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3566-base.dtsi
@@ -6,6 +6,10 @@ / { compatible = "rockchip,rk3566"; }; +&hdmi_sound { + simple-audio-card,name = "RK3566 HDMI"; +}; + &pipegrf { compatible = "rockchip,rk3566-pipe-grf", "syscon"; };
diff --git a/arch/arm64/boot/dts/rockchip/rk3566-nanopi-r3s.dts b/arch/arm64/boot/dts/rockchip/rk3566-nanopi-r3s.dts index fb1f65c..840de17 100644 --- a/arch/arm64/boot/dts/rockchip/rk3566-nanopi-r3s.dts +++ b/arch/arm64/boot/dts/rockchip/rk3566-nanopi-r3s.dts
@@ -500,7 +500,6 @@ &sdhci { &sdmmc0 { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; no-sdio;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dts b/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dts index 8e5c182..34b2c0e 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-fastrhino-r66s.dts
@@ -17,7 +17,6 @@ &pmu_io_domains { &sdmmc0 { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; no-sdio;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-lubancat-2.dts b/arch/arm64/boot/dts/rockchip/rk3568-lubancat-2.dts index a7fe5655..ce5b517 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-lubancat-2.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-lubancat-2.dts
@@ -597,7 +597,6 @@ &sdmmc0 { no-sdio; no-mmc; bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; sd-uhs-sdr104;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi index e3f44ea..8bad11b 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3568-nanopi-r5s.dtsi
@@ -515,7 +515,6 @@ &sdmmc0 { no-sdio; no-mmc; bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; vmmc-supply = <&vcc3v3_sd>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts b/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts index 149a530..b9f0908 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts +++ b/arch/arm64/boot/dts/rockchip/rk3568-rock-3b.dts
@@ -24,6 +24,14 @@ chosen { stdout-path = "serial2:1500000n8"; }; + fan: fan { + compatible = "pwm-fan"; + cooling-levels = <0 64 128 192 255>; + fan-supply = <&vcc5v0_sys>; + pwms = <&pwm8 0 10000 0>; + #cooling-cells = <2>; + }; + hdmi-con { compatible = "hdmi-connector"; type = "a"; @@ -186,6 +194,45 @@ &cpu3 { cpu-supply = <&vdd_cpu>; }; +&cpu_thermal { + trips { + cpu_fan0: cpu-fan0 { + hysteresis = <5000>; + temperature = <50000>; + type = "active"; + }; + + cpu_fan1: cpu-fan1 { + hysteresis = <5000>; + temperature = <60000>; + type = "active"; + }; + + cpu_fan2: cpu-fan2 { + hysteresis = <5000>; + temperature = <70000>; + type = "active"; + }; + }; + + cooling-maps { + map1 { + trip = <&cpu_fan0>; + cooling-device = <&fan THERMAL_NO_LIMIT 1>; + }; + + map2 { + trip = <&cpu_fan1>; + cooling-device = <&fan 2 3>; + }; + + map3 { + trip = <&cpu_fan2>; + cooling-device = <&fan 4 THERMAL_NO_LIMIT>; + }; + }; +}; + &gmac0 { assigned-clocks = <&cru SCLK_GMAC0_RX_TX>, <&cru SCLK_GMAC0>; assigned-clock-parents = <&cru SCLK_GMAC0_RGMII_SPEED>, <&cru CLK_MAC0_2TOP>; @@ -670,6 +717,10 @@ &pmu_io_domains { status = "okay"; }; +&pwm8 { + status = "okay"; +}; + &saradc { vref-supply = <&vcca_1v8>; status = "okay";
diff --git a/arch/arm64/boot/dts/rockchip/rk3568.dtsi b/arch/arm64/boot/dts/rockchip/rk3568.dtsi index 3bc653f..2f42bf2 100644 --- a/arch/arm64/boot/dts/rockchip/rk3568.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3568.dtsi
@@ -382,6 +382,10 @@ &gpu { operating-points-v2 = <&gpu_opp_table>; }; +&hdmi_sound { + simple-audio-card,name = "RK3568 HDMI"; +}; + &pipegrf { compatible = "rockchip,rk3568-pipe-grf", "syscon"; };
diff --git a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi index a583289..1a4562d 100644 --- a/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk356x-base.dtsi
@@ -150,7 +150,6 @@ scmi_clk: protocol@14 { hdmi_sound: hdmi-sound { compatible = "simple-audio-card"; - simple-audio-card,name = "HDMI"; simple-audio-card,format = "i2s"; simple-audio-card,mclk-fs = <256>; status = "disabled";
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts index 05fb4a7..41c9041 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts +++ b/arch/arm64/boot/dts/rockchip/rk3576-100ask-dshanpi-a1.dts
@@ -278,9 +278,6 @@ &gpu { }; &hdmi { - frl-enable-gpios = <&gpio2 RK_PB0 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&hdmi_txm0_pins &hdmi_tx_scl &hdmi_tx_sda &hdmi_tx_on_h>; - pinctrl-names = "default"; status = "okay"; }; @@ -741,12 +738,6 @@ hp_det: hp-det { }; }; - hdmi { - hdmi_tx_on_h: hdmi-tx-on-h { - rockchip,pins = <2 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - pcie { pcie_reset: pcie-reset { rockchip,pins = <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-anbernic-rg-vita-pro.dts b/arch/arm64/boot/dts/rockchip/rk3576-anbernic-rg-vita-pro.dts index 358dea4..e66803b 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576-anbernic-rg-vita-pro.dts +++ b/arch/arm64/boot/dts/rockchip/rk3576-anbernic-rg-vita-pro.dts
@@ -1134,7 +1134,6 @@ &saradc { &sdio { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; max-frequency = <150000000>; @@ -1165,7 +1164,6 @@ &sdhci { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; max-frequency = <150000000>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-armsom-cm5-io.dts b/arch/arm64/boot/dts/rockchip/rk3576-armsom-cm5-io.dts index ebb2312..5958b39 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576-armsom-cm5-io.dts +++ b/arch/arm64/boot/dts/rockchip/rk3576-armsom-cm5-io.dts
@@ -5,8 +5,8 @@ * Carrier provides: * - Full-size HDMI 2.1 (HDMI TX via HDPTX PHY) * - Gigabit Ethernet RJ45 (GMAC0 + on-module YT8531) - * - 2x USB-A behind a USB3 hub (combphy1 + u2phy1) - * - USB-C with PD/altmode (FUSB302 on i2c0, combphy0 + USBDP PHY) + * - 4x USB-A behind a USB3 hub (combphy1 + u2phy1) + * - USB-C with PD/altmode (FUSB302 on i2c0, USBDP PHY) * - M.2 PCIe 2.0 x1 slot (combphy0 as PCIe lane) * - microSD card slot * - Green/red status LEDs, 40-pin RPi-compatible header @@ -290,7 +290,6 @@ &sai6 { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; max-frequency = <200000000>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts b/arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts index 4ac4465..c5b2f22 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts +++ b/arch/arm64/boot/dts/rockchip/rk3576-armsom-sige5.dts
@@ -944,7 +944,6 @@ &sdio { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; max-frequency = <200000000>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts index 4c82980..f83d129 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3576-evb1-v10.dts
@@ -984,7 +984,6 @@ &sdhci { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; disable-wp;
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-nanopi-m5.dts b/arch/arm64/boot/dts/rockchip/rk3576-nanopi-m5.dts index 227fe6f..3a30540 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576-nanopi-m5.dts +++ b/arch/arm64/boot/dts/rockchip/rk3576-nanopi-m5.dts
@@ -892,7 +892,6 @@ &saradc { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; no-mmc;
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-nanopi-r76s.dts b/arch/arm64/boot/dts/rockchip/rk3576-nanopi-r76s.dts index 0a5cd5f..7f356fd 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576-nanopi-r76s.dts +++ b/arch/arm64/boot/dts/rockchip/rk3576-nanopi-r76s.dts
@@ -757,7 +757,6 @@ &sai6 { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA7 GPIO_ACTIVE_LOW>; disable-wp;
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-roc-pc.dts b/arch/arm64/boot/dts/rockchip/rk3576-roc-pc.dts index 8411c16..f6bec47f 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576-roc-pc.dts +++ b/arch/arm64/boot/dts/rockchip/rk3576-roc-pc.dts
@@ -714,7 +714,6 @@ &sdmmc { no-sdio; no-mmc; bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; sd-uhs-sdr104;
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d-radxa-cam4k.dtso b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d-radxa-cam4k.dtso new file mode 100644 index 0000000..62f1c59 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d-radxa-cam4k.dtso
@@ -0,0 +1,105 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Device tree overlay for the Radxa Camera 4K attached to the camera + * connector of the Radxa ROCK 4D. + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/clock/rockchip,rk3576-cru.h> +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/media/video-interfaces.h> +#include <dt-bindings/pinctrl/rockchip.h> + +&{/} { + savdd_cam: regulator-savdd-cam { + compatible = "regulator-fixed"; + enable-active-high; + gpio = <&gpio3 RK_PD0 GPIO_ACTIVE_HIGH>; + regulator-min-microvolt = <2900000>; + regulator-max-microvolt = <2900000>; + regulator-name = "savdd_cam"; + vin-supply = <&vcc_3v3_s0>; + }; + + sdvdd_cam: regulator-sdvdd-cam { + compatible = "regulator-fixed"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-name = "sdvdd_cam"; + vin-supply = <&vcc_5v0_device>; + }; + + siovdd_cam: regulator-siovdd-cam { + compatible = "regulator-fixed"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "siovdd_cam"; + vin-supply = <&vcc_3v3_s0>; + }; +}; + +&csi1 { + status = "okay"; +}; + +&csi1_in { + csi1_input: endpoint { + bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>; + data-lanes = <1 2 3 4>; + link-frequencies = /bits/ 64 <445500000>; + remote-endpoint = <&imx415_output>; + }; +}; + +&csi_dphy0 { + status = "okay"; +}; + +&i2c5 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c5m3_xfer>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + imx415: camera-sensor@1a { + compatible = "sony,imx415"; + reg = <0x1a>; + assigned-clocks = <&cru CLK_MIPI_CAMERAOUT_M1>; + assigned-clock-rates = <37125000>; + avdd-supply = <&savdd_cam>; + clocks = <&cru CLK_MIPI_CAMERAOUT_M1>; + dvdd-supply = <&sdvdd_cam>; + orientation = <2>; /* External */ + ovdd-supply = <&siovdd_cam>; + pinctrl-names = "default"; + pinctrl-0 = <&cam_rstn &cam_clk1m0_clk1>; + reset-gpios = <&gpio3 RK_PC7 GPIO_ACTIVE_LOW>; + + port { + imx415_output: endpoint { + data-lanes = <1 2 3 4>; + link-frequencies = /bits/ 64 <445500000>; + remote-endpoint = <&csi1_input>; + }; + }; + }; +}; + +&pinctrl { + cam { + cam_rstn: cam-rstn-pinctrl { + rockchip,pins = <3 RK_PC7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&vicap { + status = "okay"; +}; + +&vicap_mmu { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts index 272af10..f068794 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts +++ b/arch/arm64/boot/dts/rockchip/rk3576-rock-4d.dts
@@ -785,7 +785,6 @@ &sai6 { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; max-frequency = <200000000>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3576.dtsi b/arch/arm64/boot/dts/rockchip/rk3576.dtsi index b0c0d3c..9d9e9d7 100644 --- a/arch/arm64/boot/dts/rockchip/rk3576.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3576.dtsi
@@ -21,6 +21,11 @@ / { #size-cells = <2>; aliases { + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + gpio4 = &gpio4; i2c0 = &i2c0; i2c1 = &i2c1; i2c2 = &i2c2; @@ -410,7 +415,7 @@ scmi_clk: protocol@14 { hdmi_sound: hdmi-sound { compatible = "simple-audio-card"; - simple-audio-card,name = "HDMI"; + simple-audio-card,name = "RK3576 HDMI"; simple-audio-card,format = "i2s"; simple-audio-card,mclk-fs = <256>; status = "disabled"; @@ -970,7 +975,12 @@ vo1_grf: syscon@26036000 { sdgmac_grf: syscon@26038000 { compatible = "rockchip,rk3576-sdgmac-grf", "syscon"; - reg = <0x0 0x26038000 0x0 0x1000>; + reg = <0x0 0x26038000 0x0 0x2000>; + }; + + csidphy0_grf: syscon@2603a000 { + compatible = "rockchip,rk3576-csidphy-grf", "syscon"; + reg = <0x0 0x2603a000 0x0 0x2000>; }; ioc_grf: syscon@26040000 { @@ -978,6 +988,11 @@ ioc_grf: syscon@26040000 { reg = <0x0 0x26040000 0x0 0xc000>; }; + csidphy1_grf: syscon@2604c000 { + compatible = "rockchip,rk3576-csidphy-grf", "syscon"; + reg = <0x0 0x2604c000 0x0 0x2000>; + }; + cru: clock-controller@27200000 { compatible = "rockchip,rk3576-cru"; reg = <0x0 0x27200000 0x0 0x50000>; @@ -1314,6 +1329,142 @@ vdec_mmu: iommu@27b00800 { #iommu-cells = <0>; }; + vicap: video-capture@27c10000 { + compatible = "rockchip,rk3576-vicap"; + reg = <0x0 0x27c10000 0x0 0x800>; + interrupts = <GIC_SPI 318 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru ACLK_VICAP>, <&cru HCLK_VICAP>, + <&cru DCLK_VICAP>, + <&cru CLK_VICAP_I0CLK>, <&cru CLK_VICAP_I1CLK>, + <&cru CLK_VICAP_I2CLK>, <&cru CLK_VICAP_I3CLK>, + <&cru CLK_VICAP_I4CLK>; + clock-names = "aclk", "hclk", "dclk", + "iclk", "iclk1", "iclk2", "iclk3", "iclk4"; + iommus = <&vicap_mmu>; + power-domains = <&power RK3576_PD_VI>; + resets = <&cru SRST_A_VICAP>, <&cru SRST_H_VICAP>, + <&cru SRST_D_VICAP>, + <&cru SRST_VICAP_I0CLK>, <&cru SRST_VICAP_I1CLK>, + <&cru SRST_VICAP_I2CLK>, <&cru SRST_VICAP_I3CLK>, + <&cru SRST_VICAP_I4CLK>; + reset-names = "arst", "hrst", "drst", + "irst0", "irst1", "irst2", "irst3", "irst4"; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + vicap_dvp: port@0 { + reg = <0x0>; + }; + + vicap_mipi0: port@1 { + reg = <0x1>; + }; + + vicap_mipi1: port@2 { + reg = <0x2>; + + vicap_mipi1_input: endpoint { + remote-endpoint = <&csi1_output>; + }; + }; + + vicap_mipi2: port@3 { + reg = <0x3>; + }; + + vicap_mipi3: port@4 { + reg = <0x4>; + + vicap_mipi3_input: endpoint { + remote-endpoint = <&csi3_output>; + }; + }; + + vicap_mipi4: port@5 { + reg = <0x5>; + }; + + vicap_toisp0: port@10 { + reg = <0x10>; + }; + }; + }; + + vicap_mmu: iommu@27c10800 { + compatible = "rockchip,rk3576-iommu", "rockchip,rk3568-iommu"; + reg = <0x0 0x27c10800 0x0 0x100>; + interrupts = <GIC_SPI 319 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&cru ACLK_VICAP>, <&cru HCLK_VICAP>; + clock-names = "aclk", "iface"; + power-domains = <&power RK3576_PD_VI>; + rockchip,disable-mmu-reset; + #iommu-cells = <0>; + status = "disabled"; + }; + + csi1: csi@27c90000 { + compatible = "rockchip,rk3576-mipi-csi2", "rockchip,rk3568-mipi-csi2"; + reg = <0x0 0x27c90000 0x0 0x10000>; + interrupts = <GIC_SPI 314 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 315 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "err1", "err2"; + clocks = <&cru PCLK_CSI_HOST_1>; + phys = <&csi_dphy0>; + power-domains = <&power RK3576_PD_VI>; + resets = <&cru SRST_P_CSI_HOST_1>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + csi1_in: port@0 { + reg = <0>; + }; + + csi1_out: port@1 { + reg = <1>; + + csi1_output: endpoint { + remote-endpoint = <&vicap_mipi1_input>; + }; + }; + }; + }; + + csi3: csi@27cb0000 { + compatible = "rockchip,rk3576-mipi-csi2", "rockchip,rk3568-mipi-csi2"; + reg = <0x0 0x27cb0000 0x0 0x10000>; + interrupts = <GIC_SPI 383 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 384 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "err1", "err2"; + clocks = <&cru PCLK_CSI_HOST_3>; + phys = <&csi_dphy1>; + power-domains = <&power RK3576_PD_VI>; + resets = <&cru SRST_P_CSI_HOST_3>; + status = "disabled"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + csi3_in: port@0 { + reg = <0>; + }; + + csi3_out: port@1 { + reg = <1>; + + csi3_output: endpoint { + remote-endpoint = <&vicap_mipi3_input>; + }; + }; + }; + }; + vop: vop@27d00000 { compatible = "rockchip,rk3576-vop"; reg = <0x0 0x27d00000 0x0 0x3000>, <0x0 0x27d05000 0x0 0x1000>; @@ -2848,6 +2999,30 @@ hdptxphy: hdmiphy@2b000000 { status = "disabled"; }; + csi_dphy0: phy@2b030000 { + compatible = "rockchip,rk3576-csi-dphy"; + reg = <0x0 0x2b030000 0x0 0x10000>; + clocks = <&cru PCLK_CSIDPHY>; + clock-names = "pclk"; + #phy-cells = <0>; + resets = <&cru SRST_P_CSIPHY>; + reset-names = "apb"; + rockchip,grf = <&csidphy0_grf>; + status = "disabled"; + }; + + csi_dphy1: phy@2b070000 { + compatible = "rockchip,rk3576-csi-dphy"; + reg = <0x0 0x2b070000 0x0 0x10000>; + clocks = <&cru PCLK_CSIDPHY1>; + clock-names = "pclk"; + #phy-cells = <0>; + resets = <&cru SRST_P_CSIDPHY1>; + reset-names = "apb"; + rockchip,grf = <&csidphy1_grf>; + status = "disabled"; + }; + sram: sram@3ff88000 { compatible = "mmio-sram"; reg = <0x0 0x3ff88000 0x0 0x78000>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts index 854c118..a168107 100644 --- a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts +++ b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e52c.dts
@@ -29,7 +29,7 @@ keys-0 { compatible = "adc-keys"; io-channels = <&saradc 0>; io-channel-names = "buttons"; - keyup-threshold-microvolt = <18000>; + keyup-threshold-microvolt = <1800000>; poll-interval = <100>; button-0 { @@ -253,8 +253,6 @@ vdd_npu_s0: regulator@42 { reg = <0x42>; fcs,suspend-voltage-selector = <1>; regulator-name = "vdd_npu_s0"; - regulator-always-on; - regulator-boot-on; regulator-min-microvolt = <550000>; regulator-max-microvolt = <950000>; regulator-ramp-delay = <2300>; @@ -300,6 +298,10 @@ &pcie2x1l2 { status = "okay"; }; +&pd_npu { + domain-supply = <&vdd_npu_s0>; +}; + &pinctrl { keys { pwm15_ir_m1: pwm15-ir-m1 { @@ -354,6 +356,36 @@ &pwm14 { status = "okay"; }; +&rknn_core_0 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_core_1 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_core_2 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_mmu_0 { + status = "okay"; +}; + +&rknn_mmu_1 { + status = "okay"; +}; + +&rknn_mmu_2 { + status = "okay"; +}; + &saradc { vref-supply = <&vcca_1v8_s0>; status = "okay";
diff --git a/arch/arm64/boot/dts/rockchip/rk3582-radxa-e54c.dts b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e54c.dts new file mode 100644 index 0000000..ac663a4 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3582-radxa-e54c.dts
@@ -0,0 +1,1172 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/pinctrl/rockchip.h> +#include <dt-bindings/soc/rockchip,vop2.h> +#include <dt-bindings/usb/pd.h> +#include "rk3588s.dtsi" + +/ { + model = "Radxa E54C"; + compatible = "radxa,e54c", "rockchip,rk3582", "rockchip,rk3588s"; + + aliases { + ethernet0 = &gmac1; + mmc0 = &sdhci; + mmc1 = &sdmmc; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + hdmi0-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi0_con_in: endpoint { + remote-endpoint = <&hdmi0_out_con>; + }; + }; + }; + + keys-0 { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-0 { + label = "Maskrom"; + linux,code = <KEY_VENDOR>; + press-threshold-microvolt = <0>; + }; + }; + + keys-1 { + compatible = "gpio-keys"; + pinctrl-names = "default"; + pinctrl-0 = <&user_key>; + + button-1 { + label = "User"; + linux,code = <BTN_0>; + gpios = <&gpio0 RK_PB2 GPIO_ACTIVE_LOW>; + wakeup-source; + }; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + color = <LED_COLOR_ID_GREEN>; + function = LED_FUNCTION_STATUS; + gpios = <&gpio0 RK_PC6 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + pinctrl-names = "default"; + pinctrl-0 = <&sys_led>; + }; + + led-1 { + color = <LED_COLOR_ID_GREEN>; + function = LED_FUNCTION_LAN; + function-enumerator = <1>; + gpios = <&gpio0 RK_PD3 GPIO_ACTIVE_LOW>; + linux,default-trigger = "netdev"; + pinctrl-names = "default"; + pinctrl-0 = <&lan1_led>; + }; + + led-2 { + color = <LED_COLOR_ID_GREEN>; + function = LED_FUNCTION_LAN; + function-enumerator = <2>; + gpios = <&gpio1 RK_PB6 GPIO_ACTIVE_LOW>; + linux,default-trigger = "netdev"; + pinctrl-names = "default"; + pinctrl-0 = <&lan2_led>; + }; + + led-3 { + color = <LED_COLOR_ID_GREEN>; + function = LED_FUNCTION_LAN; + function-enumerator = <3>; + gpios = <&gpio1 RK_PB7 GPIO_ACTIVE_LOW>; + linux,default-trigger = "netdev"; + pinctrl-names = "default"; + pinctrl-0 = <&lan3_led>; + }; + + led-4 { + color = <LED_COLOR_ID_GREEN>; + function = LED_FUNCTION_WAN; + gpios = <&gpio3 RK_PC4 GPIO_ACTIVE_LOW>; + linux,default-trigger = "netdev"; + pinctrl-names = "default"; + pinctrl-0 = <&wan_led>; + }; + }; + + dc_12v: regulator-12v-dc { + compatible = "regulator-fixed"; + regulator-name = "dc_12v"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + vcc_1v1_nldo_s3: regulator-1v1-vcc-nldo-s3 { + compatible = "regulator-fixed"; + regulator-name = "vcc_1v1_nldo_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + vin-supply = <&vcc_sysin>; + }; + + vcc3v3_pcie: regulator-3v3-pcie { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_pcie"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_sysin>; + }; + + vcc_3v3_s0: regulator-3v3-vcc-s0 { + compatible = "regulator-fixed"; + regulator-name = "vcc_3v3_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc_3v3_s3>; + }; + + vcc5v_usb3: regulator-5v0-usb3 { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio0 RK_PD4 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb_otg_pwren_h>; + regulator-name = "vcc5v_usb3"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_sysin>; + }; + + vcc5v_usb_hub: regulator-5v0-usb-hub { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&usb_host_pwren_h>; + regulator-name = "vcc5v_usb_hub"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_sysin>; + }; + + vbus_typec0: regulator-5v0-vbus-typec0 { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&typec5v_pwren_h>; + regulator-name = "vbus_typec0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_sysin>; + }; + + vcc_sysin: vcca: regulator-5v0-vcc-sysin { + compatible = "regulator-fixed"; + regulator-name = "vcc_sysin"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&typec_vin>; + }; + + vcc_5v0: regulator-5v0-vcc { + compatible = "regulator-fixed"; + regulator-name = "vcc_5v0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc_sysin>; + }; + + avddh_3v3: regulator-avdd-3v3 { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio3 RK_PA6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&rtl8367_en>; + regulator-name = "avddh_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + startup-delay-us = <10000>; + vin-supply = <&vcc_5v0>; + }; + + typec_vin: regulator-typec-vin { + compatible = "regulator-fixed"; + regulator-name = "typec_vin"; + regulator-always-on; + regulator-boot-on; + vin-supply = <&dc_12v>; + }; +}; + +&combphy0_ps { + status = "okay"; +}; + +&combphy2_psu { + status = "okay"; +}; + +/* + * In the Rockchip RK3582 SoC, some CPU cores end up disabled + * and unused because they're marked in the efuses as defective. + * The disabling in the DT is performed by the boot loader. + */ +&cpu_b0 { + cpu-supply = <&vdd_cpu_big0_s0>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_big0_s0>; +}; + +&cpu_b2 { + cpu-supply = <&vdd_cpu_big1_s0>; +}; + +&cpu_b3 { + cpu-supply = <&vdd_cpu_big1_s0>; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&gmac1 { + clock_in_out = "output"; + phy-mode = "rgmii-id"; + phy-supply = <&avddh_3v3>; + pinctrl-names = "default"; + pinctrl-0 = <&gmac1_miim + &gmac1_tx_bus2 + &gmac1_rx_bus2 + &gmac1_rgmii_clk + &gmac1_rgmii_bus>; + /delete-property/ snps,tso; + status = "okay"; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&hdmi0 { + frl-enable-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&hdmim0_tx0_cec + &hdmim1_tx0_hpd + &hdmim0_tx0_scl + &hdmim0_tx0_sda + &hdmi0_tx_on_h>; + status = "okay"; +}; + +&hdmi0_in { + hdmi0_in_vp0: endpoint { + remote-endpoint = <&vp0_out_hdmi0>; + }; +}; + +&hdmi0_out { + hdmi0_out_con: endpoint { + remote-endpoint = <&hdmi0_con_in>; + }; +}; + +&hdmi0_sound { + status = "okay"; +}; + +&hdptxphy0 { + status = "okay"; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0m2_xfer>; + status = "okay"; + + vdd_cpu_big0_s0: regulator@42 { + compatible = "rockchip,rk8602"; + reg = <0x42>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu_big0_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <1050000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc_sysin>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_big1_s0: regulator@43 { + compatible = "rockchip,rk8603", "rockchip,rk8602"; + reg = <0x43>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu_big1_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <1050000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc_sysin>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + eeprom@50 { + compatible = "belling,bl24c16a", "atmel,24c16"; + reg = <0x50>; + pagesize = <16>; + read-only; + vcc-supply = <&vcc_3v3_s3>; + + nvmem-layout { + compatible = "fixed-layout"; + #address-cells = <1>; + #size-cells = <1>; + + eth_mac0: macaddr@9e { + reg = <0x9e 0x06>; + }; + + eth_mac1: macaddr@a4 { + reg = <0xa4 0x06>; + }; + + eth_mac2: macaddr@aa { + reg = <0xaa 0x06>; + }; + + eth_mac3: macaddr@b0 { + reg = <0xb0 0x06>; + }; + }; + }; +}; + +&i2c2 { + status = "okay"; + + vdd_npu_s0: regulator@42 { + compatible = "rockchip,rk8602"; + reg = <0x42>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_npu_s0"; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc_sysin>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + +&i2c4 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c4m2_xfer>; + status = "okay"; + + usbc0: usb-typec@22 { + compatible = "fcs,fusb302"; + reg = <0x22>; + interrupt-parent = <&gpio1>; + interrupts = <RK_PA7 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&cc_int_l>; + vbus-supply = <&vbus_typec0>; + + usb_con: connector { + compatible = "usb-c-connector"; + label = "USB-C"; + data-role = "dual"; + op-sink-microwatt = <1000000>; + power-role = "dual"; + pd-revision = /bits/ 8 <0x2 0x0 0x1 0x2>; + sink-pdos = <PDO_FIXED(5000, 1000, PDO_FIXED_USB_COMM)>; + source-pdos = <PDO_FIXED(5000, 3000, PDO_FIXED_USB_COMM)>; + try-power-role = "sink"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + usbc0_hs: endpoint { + remote-endpoint = <&usb_host0_xhci_drd_sw>; + }; + }; + + port@1 { + reg = <1>; + usbc0_ss: endpoint { + remote-endpoint = <&usbdp_phy0_typec_ss>; + }; + }; + + port@2 { + reg = <2>; + usbc0_sbu: endpoint { + remote-endpoint = <&usbdp_phy0_typec_sbu>; + }; + }; + }; + }; + }; + + hym8563: rtc@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + #clock-cells = <0>; + clock-output-names = "rtcic_32kout"; + interrupt-parent = <&gpio0>; + interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&rtc_int_l>; + wakeup-source; + }; +}; + +&i2s5_8ch { + status = "okay"; +}; + +&mdio1 { + ethernet-switch@29 { + compatible = "realtek,rtl8365mb"; + reg = <29>; + pinctrl-names = "default"; + pinctrl-0 = <&gmac1_rstn_l>; + reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + + switch_intc: interrupt-controller { + interrupt-parent = <&gpio3>; + interrupts = <RK_PB6 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <1>; + }; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + + phy0: ethernet-phy@0 { + reg = <0>; + interrupt-parent = <&switch_intc>; + interrupts = <0>; + }; + + phy1: ethernet-phy@1 { + reg = <1>; + interrupt-parent = <&switch_intc>; + interrupts = <1>; + }; + + phy2: ethernet-phy@2 { + reg = <2>; + interrupt-parent = <&switch_intc>; + interrupts = <2>; + }; + + phy3: ethernet-phy@3 { + reg = <3>; + interrupt-parent = <&switch_intc>; + interrupts = <3>; + }; + + phy4: ethernet-phy@4 { + reg = <4>; + interrupt-parent = <&switch_intc>; + interrupts = <4>; + }; + }; + + ethernet-ports { + #address-cells = <1>; + #size-cells = <0>; + + ethernet-port@0 { + reg = <0>; + label = "lan3"; + nvmem-cells = <ð_mac3>; + nvmem-cell-names = "mac-address"; + phy-handle = <&phy0>; + }; + + ethernet-port@1 { + reg = <1>; + label = "lan2"; + nvmem-cells = <ð_mac2>; + nvmem-cell-names = "mac-address"; + phy-handle = <&phy1>; + }; + + ethernet-port@2 { + reg = <2>; + label = "lan1"; + nvmem-cells = <ð_mac1>; + nvmem-cell-names = "mac-address"; + phy-handle = <&phy2>; + }; + + ethernet-port@3 { + reg = <3>; + label = "wan"; + nvmem-cells = <ð_mac0>; + nvmem-cell-names = "mac-address"; + phy-handle = <&phy3>; + }; + + ethernet-port@6 { + reg = <6>; + ethernet = <&gmac1>; + phy-mode = "rgmii"; + rx-internal-delay-ps = <2000>; + tx-internal-delay-ps = <2000>; + + fixed-link { + speed = <1000>; + full-duplex; + }; + }; + }; + }; +}; + +&pcie2x1l2 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie20x1_2_perstn_m0>; + reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_pcie>; + status = "okay"; +}; + +&pd_npu { + domain-supply = <&vdd_npu_s0>; +}; + +&pinctrl { + ethernet { + gmac1_rstn_l: gmac1-rstn-l { + rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + rtl8367_en: rtl8367-en { + rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + hdmi { + hdmi0_tx_on_h: hdmi0-tx-on-h { + rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + keys { + user_key: user-key { + rockchip,pins = <0 RK_PB2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + leds { + lan1_led: lan1-led { + rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + lan2_led: lan2-led { + rockchip,pins = <1 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + lan3_led: lan3-led { + rockchip,pins = <1 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + sys_led: sys-led { + rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + wan_led: wan-led { + rockchip,pins = <3 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pcie { + pcie20x1_2_perstn_m0: pcie-perstn { + rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + rtc { + rtc_int_l: rtc-int-l { + rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + typec { + cc_int_l: cc-int-l { + rockchip,pins = <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + typec5v_pwren_h: typec5v-pwren-h { + rockchip,pins = <3 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb { + usb_host_pwren_h: usb-host-pwren-h { + rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + usb_otg_pwren_h: usb-otg-pwren-h { + rockchip,pins = <0 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pwm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pwm3m1_pins>; + status = "okay"; +}; + +&rknn_core_0 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_core_1 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_core_2 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_mmu_0 { + status = "okay"; +}; + +&rknn_mmu_1 { + status = "okay"; +}; + +&rknn_mmu_2 { + status = "okay"; +}; + +&saradc { + vref-supply = <&vcca_1v8_s0>; + status = "okay"; +}; + +/* Conflict with SFC */ +&sdhci { + bus-width = <8>; + cap-mmc-highspeed; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + non-removable; + vmmc-supply = <&vcc_3v3_s0>; + vqmmc-supply = <&vcc_1v8_s3>; + status = "disabled"; +}; + +&sdmmc { + bus-width = <4>; + cap-mmc-highspeed; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; + disable-wp; + sd-uhs-sdr104; + vmmc-supply = <&vcc_3v3_s3>; + vqmmc-supply = <&vccio_sd_s0>; + status = "okay"; +}; + +&sfc { + pinctrl-names = "default"; + pinctrl-0 = <&fspim0_pins>; + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <104000000>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <1>; + vcc-supply = <&vcc_1v8_s3>; + }; +}; + +&spi2 { + assigned-clocks = <&cru CLK_SPI2>; + assigned-clock-rates = <200000000>; + num-cs = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>; + status = "okay"; + + pmic@0 { + compatible = "rockchip,rk806"; + reg = <0>; + gpio-controller; + #gpio-cells = <2>; + interrupt-parent = <&gpio0>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + pinctrl-names = "default"; + pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, + <&rk806_dvs2_null>, <&rk806_dvs3_null>; + spi-max-frequency = <1000000>; + system-power-controller; + + vcc1-supply = <&vcc_sysin>; + vcc2-supply = <&vcc_sysin>; + vcc3-supply = <&vcc_sysin>; + vcc4-supply = <&vcc_sysin>; + vcc5-supply = <&vcc_sysin>; + vcc6-supply = <&vcc_sysin>; + vcc7-supply = <&vcc_sysin>; + vcc8-supply = <&vcc_sysin>; + vcc9-supply = <&vcc_sysin>; + vcc10-supply = <&vcc_sysin>; + vcc11-supply = <&vcc_2v0_pldo_s3>; + vcc12-supply = <&vcc_sysin>; + vcc13-supply = <&vcc_1v1_nldo_s3>; + vcc14-supply = <&vcc_1v1_nldo_s3>; + vcca-supply = <&vcca>; + + rk806_dvs1_null: dvs1-null-pins { + pins = "gpio_pwrctrl1"; + function = "pin_fun0"; + }; + + rk806_dvs2_null: dvs2-null-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun0"; + }; + + rk806_dvs3_null: dvs3-null-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun0"; + }; + + regulators { + vdd_gpu_s0: dcdc-reg1 { + regulator-name = "vdd_gpu_s0"; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <12500>; + regulator-enable-ramp-delay = <400>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_lit_s0: dcdc-reg2 { + regulator-name = "vdd_cpu_lit_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_logic_s0: dcdc-reg3 { + regulator-name = "vdd_logic_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <675000>; + regulator-max-microvolt = <750000>; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdd_vdenc_s0: dcdc-reg4 { + regulator-name = "vdd_vdenc_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_ddr_s0: dcdc-reg5 { + regulator-name = "vdd_ddr_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <675000>; + regulator-max-microvolt = <900000>; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd2_ddr_s3: dcdc-reg6 { + regulator-name = "vdd2_ddr_s3"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_2v0_pldo_s3: dcdc-reg7 { + regulator-name = "vcc_2v0_pldo_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <2000000>; + regulator-max-microvolt = <2000000>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_3v3_s3: dcdc-reg8 { + regulator-name = "vcc_3v3_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vddq_ddr_s0: dcdc-reg9 { + regulator-name = "vddq_ddr_s0"; + regulator-always-on; + regulator-boot-on; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8_s3: dcdc-reg10 { + regulator-name = "vcc_1v8_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_1v8_s0: pldo-reg1 { + regulator-name = "vcc_1v8_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcca_1v8_s0: pldo-reg2 { + regulator-name = "vcca_1v8_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdda_1v2_s0: pldo-reg3 { + regulator-name = "vdda_1v2_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcca_3v3_s0: pldo-reg4 { + regulator-name = "vcca_3v3_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vccio_sd_s0: pldo-reg5 { + regulator-name = "vccio_sd_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + pldo6_s3: pldo-reg6 { + regulator-name = "pldo6_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdd_0v75_s3: nldo-reg1 { + regulator-name = "vdd_0v75_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdda_ddr_pll_s0: nldo-reg2 { + regulator-name = "vdda_ddr_pll_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdda_0v75_s0: nldo-reg3 { + regulator-name = "vdda_0v75_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vdda_0v85_s0: nldo-reg4 { + regulator-name = "vdda_0v85_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_0v75_s0: nldo-reg5 { + regulator-name = "vdd_0v75_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy0 { + status = "okay"; +}; + +&u2phy0_otg { + status = "okay"; +}; + +&u2phy2 { + status = "okay"; +}; + +&u2phy2_host { + phy-supply = <&vcc5v_usb_hub>; + status = "okay"; +}; + +&u2phy3 { + status = "okay"; +}; + +&u2phy3_host { + phy-supply = <&vcc5v_usb3>; + status = "okay"; +}; + +&uart2 { + pinctrl-0 = <&uart2m0_xfer>; + status = "okay"; +}; + +&usbdp_phy0 { + mode-switch; + orientation-switch; + sbu1-dc-gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_HIGH>; + sbu2-dc-gpios = <&gpio3 RK_PD5 GPIO_ACTIVE_HIGH>; + status = "okay"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + usbdp_phy0_typec_ss: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_ss>; + }; + + usbdp_phy0_typec_sbu: endpoint@1 { + reg = <1>; + remote-endpoint = <&usbc0_sbu>; + }; + }; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_xhci { + usb-role-switch; + status = "okay"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + usb_host0_xhci_drd_sw: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_hs>; + }; + }; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usb_host2_xhci { + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vop { + status = "okay"; +}; + +&vp0 { + vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { + reg = <ROCKCHIP_VOP2_EP_HDMI0>; + remote-endpoint = <&hdmi0_in_vp0>; + }; +};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts index 1005b15..48effab 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-armsom-sige7.dts
@@ -419,7 +419,6 @@ &sdhci { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; max-frequency = <200000000>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-armsom-w3.dts b/arch/arm64/boot/dts/rockchip/rk3588-armsom-w3.dts index faeddcf..127be31 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-armsom-w3.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-armsom-w3.dts
@@ -403,7 +403,6 @@ &pwm1 { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; disable-wp;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi index 376ad04..aa69fd3 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-base.dtsi
@@ -376,7 +376,7 @@ hdmi0_sound: hdmi0-sound { compatible = "simple-audio-card"; simple-audio-card,format = "i2s"; simple-audio-card,mclk-fs = <128>; - simple-audio-card,name = "hdmi0"; + simple-audio-card,name = "RK3588 HDMI0"; status = "disabled"; simple-audio-card,codec { @@ -2648,6 +2648,45 @@ dmac1: dma-controller@fea30000 { #dma-cells = <1>; }; + can0: can@fea50000 { + compatible = "rockchip,rk3588-canfd"; + reg = <0x0 0xfea50000 0x0 0x1000>; + interrupts = <GIC_SPI 341 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&cru CLK_CAN0>, <&cru PCLK_CAN0>; + clock-names = "baud", "pclk"; + resets = <&cru SRST_CAN0>, <&cru SRST_P_CAN0>; + reset-names = "core", "apb"; + pinctrl-names = "default"; + pinctrl-0 = <&can0m0_pins>; + status = "disabled"; + }; + + can1: can@fea60000 { + compatible = "rockchip,rk3588-canfd"; + reg = <0x0 0xfea60000 0x0 0x1000>; + interrupts = <GIC_SPI 342 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&cru CLK_CAN1>, <&cru PCLK_CAN1>; + clock-names = "baud", "pclk"; + resets = <&cru SRST_CAN1>, <&cru SRST_P_CAN1>; + reset-names = "core", "apb"; + pinctrl-names = "default"; + pinctrl-0 = <&can1m0_pins>; + status = "disabled"; + }; + + can2: can@fea70000 { + compatible = "rockchip,rk3588-canfd"; + reg = <0x0 0xfea70000 0x0 0x1000>; + interrupts = <GIC_SPI 343 IRQ_TYPE_LEVEL_HIGH 0>; + clocks = <&cru CLK_CAN2>, <&cru PCLK_CAN2>; + clock-names = "baud", "pclk"; + resets = <&cru SRST_CAN2>, <&cru SRST_P_CAN2>; + reset-names = "core", "apb"; + pinctrl-names = "default"; + pinctrl-0 = <&can2m0_pins>; + status = "disabled"; + }; + i2c1: i2c@fea90000 { compatible = "rockchip,rk3588-i2c", "rockchip,rk3399-i2c"; reg = <0x0 0xfea90000 0x0 0x1000>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts index 66e3c20..c269fdb 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5-evb.dts
@@ -198,6 +198,7 @@ &pcie2x1l1 { }; &pcie30phy { + data-lanes = <1 1 2 2>; status = "okay"; };
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi index 33dacaa..48aeb22 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-coolpi-cm5.dtsi
@@ -322,7 +322,6 @@ &sdhci { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; disable-wp;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dtsi index 2751f84..21a9af7 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-edgeble-neu6a-io.dtsi
@@ -239,7 +239,6 @@ &sata0 { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; no-sdio;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi index b251bb1..2bcf30d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-extra.dtsi
@@ -11,7 +11,7 @@ hdmi1_sound: hdmi1-sound { compatible = "simple-audio-card"; simple-audio-card,format = "i2s"; simple-audio-card,mclk-fs = <128>; - simple-audio-card,name = "hdmi1"; + simple-audio-card,name = "RK3588 HDMI1"; status = "disabled"; simple-audio-card,codec {
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-jaguar-can1-can2-uart4.dtso b/arch/arm64/boot/dts/rockchip/rk3588-jaguar-can1-can2-uart4.dtso new file mode 100644 index 0000000..6c21bf7 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588-jaguar-can1-can2-uart4.dtso
@@ -0,0 +1,26 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2026 Cherry Embedded Solutions GmbH + * + * Device Tree Overlay for CAN1-CAN2-UART4 adapter for the Mezzanine connector + * on RK3588 Jaguar. + * + * This adapter has two CAN transceivers and one RS232 transceiver. + */ + +/dts-v1/; +/plugin/; + +&can1 { + status = "okay"; +}; + +&can2 { + status = "okay"; +}; + +/* RS232 */ +&uart4 { + /* ST3232B only guarantees 250Kbps */ + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts b/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts index 41758fe..0446834 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-jaguar.dts
@@ -195,6 +195,22 @@ vcc5v0_usb: regulator-vcc5v0-usb { }; }; +&can0 { + assigned-clocks = <&cru CLK_CAN0>; + assigned-clock-rates = <300000000>; + status = "okay"; +}; + +&can1 { + assigned-clocks = <&cru CLK_CAN1>; + assigned-clock-rates = <300000000>; +}; + +&can2 { + assigned-clocks = <&cru CLK_CAN2>; + assigned-clock-rates = <300000000>; +}; + &combphy1_ps { status = "okay"; };
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-lubancat-5-btb.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-lubancat-5-btb.dtsi new file mode 100644 index 0000000..106d0c4 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588-lubancat-5-btb.dtsi
@@ -0,0 +1,534 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 Cunhao Lu <1579567540@qq.com> + */ + +#include <dt-bindings/gpio/gpio.h> + +/ { + compatible = "embedfire,lubancat-5-btb", "rockchip,rk3588"; + + aliases { + mmc0 = &sdhci; + }; + + combophy_avdd0v85: regulator-combophy-avdd0v85 { + compatible = "regulator-fixed"; + regulator-boot-on; + regulator-max-microvolt = <850000>; + regulator-min-microvolt = <850000>; + regulator-name = "combophy_avdd0v85"; + vin-supply = <&avdd_0v85_s0>; + }; + + combophy_avdd1v8: regulator-combophy-avdd1v8 { + compatible = "regulator-fixed"; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "combophy_avdd1v8"; + vin-supply = <&avcc_1v8_s0>; + }; + + vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1100000>; + regulator-min-microvolt = <1100000>; + regulator-name = "vcc_1v1_nldo_s3"; + vin-supply = <&vcc4v0_sys>; + }; +}; + +&can1 { + assigned-clock-rates = <300000000>; + assigned-clocks = <&cru CLK_CAN1>; +}; + +&can2 { + assigned-clock-rates = <300000000>; + assigned-clocks = <&cru CLK_CAN2>; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_big0_s0>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_big0_s0>; +}; + +&cpu_b2 { + cpu-supply = <&vdd_cpu_big1_s0>; +}; + +&cpu_b3 { + cpu-supply = <&vdd_cpu_big1_s0>; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&gpu { + mali-supply = <&vdd_gpu_s0>; + status = "okay"; +}; + +&i2c0 { + pinctrl-0 = <&i2c0m2_xfer>; + pinctrl-names = "default"; + status = "okay"; + + vdd_cpu_big0_s0: regulator@42 { + compatible = "rockchip,rk8602"; + reg = <0x42>; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1050000>; + regulator-min-microvolt = <550000>; + regulator-name = "vdd_cpu_big0_s0"; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc4v0_sys>; + fcs,suspend-voltage-selector = <1>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_big1_s0: regulator@43 { + compatible = "rockchip,rk8603", "rockchip,rk8602"; + reg = <0x43>; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1050000>; + regulator-min-microvolt = <550000>; + regulator-name = "vdd_cpu_big1_s0"; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc4v0_sys>; + fcs,suspend-voltage-selector = <1>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + +&i2c1 { + pinctrl-0 = <&i2c1m2_xfer>; + pinctrl-names = "default"; + status = "okay"; + + vdd_npu_s0: regulator@42 { + compatible = "rockchip,rk8602"; + reg = <0x42>; + regulator-boot-on; + regulator-max-microvolt = <950000>; + regulator-min-microvolt = <550000>; + regulator-name = "vdd_npu_s0"; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc4v0_sys>; + fcs,suspend-voltage-selector = <1>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + +&pd_gpu { + domain-supply = <&vdd_gpu_s0>; +}; + +&pd_npu { + domain-supply = <&vdd_npu_s0>; +}; + +&rknn_core_0 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_core_1 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_core_2 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_mmu_0 { + status = "okay"; +}; + +&rknn_mmu_1 { + status = "okay"; +}; + +&rknn_mmu_2 { + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + max-frequency = <200000000>; + mmc-hs400-1_8v; + mmc-hs400-enhanced-strobe; + no-sd; + no-sdio; + non-removable; + status = "okay"; +}; + +&sfc { + status = "disabled"; +}; + +&spi2 { + assigned-clock-rates = <200000000>; + assigned-clocks = <&cru CLK_SPI2>; + num-cs = <1>; + pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>; + pinctrl-names = "default"; + status = "okay"; + + pmic@0 { + compatible = "rockchip,rk806"; + reg = <0x0>; + #gpio-cells = <2>; + gpio-controller; + interrupt-parent = <&gpio0>; + interrupts = <RK_PA7 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, + <&rk806_dvs2_null>, <&rk806_dvs3_null>; + pinctrl-names = "default"; + spi-max-frequency = <1000000>; + system-power-controller; + + vcc1-supply = <&vcc4v0_sys>; + vcc2-supply = <&vcc4v0_sys>; + vcc3-supply = <&vcc4v0_sys>; + vcc4-supply = <&vcc4v0_sys>; + vcc5-supply = <&vcc4v0_sys>; + vcc6-supply = <&vcc4v0_sys>; + vcc7-supply = <&vcc4v0_sys>; + vcc8-supply = <&vcc4v0_sys>; + vcc9-supply = <&vcc4v0_sys>; + vcc10-supply = <&vcc4v0_sys>; + vcc11-supply = <&vcc_2v0_pldo_s3>; + vcc12-supply = <&vcc4v0_sys>; + vcc13-supply = <&vcc_1v1_nldo_s3>; + vcc14-supply = <&vcc_1v1_nldo_s3>; + vcca-supply = <&vcc4v0_sys>; + + rk806_dvs1_null: dvs1-null-pins { + function = "pin_fun0"; + pins = "gpio_pwrctrl1"; + }; + + rk806_dvs2_null: dvs2-null-pins { + function = "pin_fun0"; + pins = "gpio_pwrctrl2"; + }; + + rk806_dvs3_null: dvs3-null-pins { + function = "pin_fun0"; + pins = "gpio_pwrctrl3"; + }; + + regulators { + vdd_gpu_s0: dcdc-reg1 { + regulator-boot-on; + regulator-enable-ramp-delay = <400>; + regulator-max-microvolt = <950000>; + regulator-min-microvolt = <550000>; + regulator-name = "vdd_gpu_s0"; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_lit_s0: dcdc-reg2 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <950000>; + regulator-min-microvolt = <550000>; + regulator-name = "vdd_cpu_lit_s0"; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_log_s0: dcdc-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <800000>; + regulator-min-microvolt = <675000>; + regulator-name = "vdd_log_s0"; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <750000>; + }; + }; + + vdd_vdenc_s0: dcdc-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <950000>; + regulator-min-microvolt = <550000>; + regulator-name = "vdd_vdenc_s0"; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_ddr_s0: dcdc-reg5 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <900000>; + regulator-min-microvolt = <675000>; + regulator-name = "vdd_ddr_s0"; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <850000>; + }; + }; + + vdd2_ddr_s3: dcdc-reg6 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vdd2_ddr_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_2v0_pldo_s3: dcdc-reg7 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <2000000>; + regulator-min-microvolt = <2000000>; + regulator-name = "vcc_2v0_pldo_s3"; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <2000000>; + }; + }; + + vcc_3v3_s3: dcdc-reg8 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_3v3_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vddq_ddr_s0: dcdc-reg9 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vddq_ddr_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8_s3: dcdc-reg10 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "vcc_1v8_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_0v75_s3: nldo-reg1 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <750000>; + regulator-min-microvolt = <750000>; + regulator-name = "vdd_0v75_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <750000>; + }; + }; + + avdd_ddr_pll_s0: nldo-reg2 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <850000>; + regulator-min-microvolt = <850000>; + regulator-name = "avdd_ddr_pll_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <850000>; + }; + }; + + avdd_0v75_s0: nldo-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <837500>; + regulator-min-microvolt = <837500>; + regulator-name = "avdd_0v75_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + avdd_0v85_s0: nldo-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <850000>; + regulator-min-microvolt = <850000>; + regulator-name = "avdd_0v85_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_0v75_s0: nldo-reg5 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <750000>; + regulator-min-microvolt = <750000>; + regulator-name = "vdd_0v75_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + avcc_1v8_s0: pldo-reg1 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "avcc_1v8_s0"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_1v8_s0: pldo-reg2 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "vcc_1v8_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + avdd_1v2_s0: pldo-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1200000>; + regulator-min-microvolt = <1200000>; + regulator-name = "avdd_1v2_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + avcc_3v3_s0: pldo-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "avcc_3v3_s0"; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd_s0: pldo-reg5 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <1800000>; + regulator-name = "vccio_sd_s0"; + regulator-ramp-delay = <12500>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + pldo6_s3: pldo-reg6 { + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <1800000>; + regulator-min-microvolt = <1800000>; + regulator-name = "pldo6_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + }; + }; +}; + +&tsadc { + status = "okay"; +}; + +&wdt { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-lubancat-5io.dts b/arch/arm64/boot/dts/rockchip/rk3588-lubancat-5io.dts new file mode 100644 index 0000000..eb5d27b --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588-lubancat-5io.dts
@@ -0,0 +1,1031 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2025 Cunhao Lu <1579567540@qq.com> + */ + +/dts-v1/; + +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/soc/rockchip,vop2.h> +#include <dt-bindings/usb/pd.h> +#include "rk3588.dtsi" +#include "rk3588-lubancat-5-btb.dtsi" + +/ { + compatible = "embedfire,lubancat-5io", "embedfire,lubancat-5-btb", + "rockchip,rk3588"; + model = "EmbedFire LubanCat 5IO"; + + aliases { + ethernet0 = &gmac0; + ethernet1 = &gmac1; + mmc1 = &sdmmc; + rtc0 = &hym8563; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-recovery { + label = "Recovery"; + press-threshold-microvolt = <1750>; + linux,code = <KEY_VENDOR>; + }; + }; + + analog-sound { + compatible = "simple-audio-card"; + pinctrl-0 = <&hp_detect>; + pinctrl-names = "default"; + simple-audio-card,format = "i2s"; + simple-audio-card,hp-det-gpios = + <&gpio0 RK_PA0 GPIO_ACTIVE_HIGH>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "rk3588-es8388"; + simple-audio-card,pin-switches = "Headphones", "Speaker"; + simple-audio-card,routing = + "Headphones", "LOUT1", + "Headphones", "ROUT1", + "Speaker", "LOUT2", + "Speaker", "ROUT2", + "LINPUT1", "Main Mic", + "LINPUT2", "Main Mic", + "RINPUT1", "Headset Mic", + "RINPUT2", "Headset Mic"; + simple-audio-card,widgets = + "Headphone", "Headphones", + "Speaker", "Speaker", + "Microphone", "Main Mic", + "Microphone", "Headset Mic"; + + simple-audio-card,codec { + sound-dai = <&es8388>; + system-clock-frequency = <12288000>; + }; + + simple-audio-card,cpu { + sound-dai = <&i2s0_8ch>; + }; + }; + + hdmi0-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi0_con_in: endpoint { + remote-endpoint = <&hdmi0_out_con>; + }; + }; + }; + + hdmi1-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi1_con_in: endpoint { + remote-endpoint = <&hdmi1_out_con>; + }; + }; + }; + + ir-receiver { + compatible = "gpio-ir-receiver"; + gpios = <&gpio0 RK_PD0 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&ir_receiver_pin>; + pinctrl-names = "default"; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-0 = <&sys_led_pin>; + pinctrl-names = "default"; + + led-0 { + color = <LED_COLOR_ID_GREEN>; + function = LED_FUNCTION_STATUS; + gpios = <&gpio1 RK_PC6 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + }; + }; + + fan: pwm-fan { + compatible = "pwm-fan"; + #cooling-cells = <2>; + cooling-levels = <0 100 150 200 255>; + fan-supply = <&vcc_5v0_s0>; + pwms = <&pwm11 0 5000 0>; + }; + + regulator-mipi-dsi0-power { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio1 RK_PC0 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&mipi_dsi0_power_en>; + pinctrl-names = "default"; + regulator-always-on; + regulator-boot-on; + regulator-name = "mipi_dsi0_power"; + vin-supply = <&vcc_5v0_s0>; + }; + + regulator-mipi-dsi1-power { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio1 RK_PC1 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&mipi_dsi1_power_en>; + pinctrl-names = "default"; + regulator-always-on; + regulator-boot-on; + regulator-name = "mipi_dsi1_power"; + vin-supply = <&vcc_5v0_s0>; + }; + + sata_power: regulator-sata-power { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio1 RK_PD3 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&sata_power_en>; + pinctrl-names = "default"; + regulator-always-on; + regulator-boot-on; + regulator-name = "sata_power"; + vin-supply = <&vcc12v_dcin>; + }; + + vbus5v0_typec: regulator-vbus5v0-typec { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&typec_vbus_en>; + pinctrl-names = "default"; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + regulator-name = "vbus5v0_typec"; + vin-supply = <&vcc5v0_usb_s0>; + }; + + vcc3v3_ekey_pcie: regulator-vcc3v3-ekey-pcie { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio0 RK_PB7 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&vcc3v3_ekey_pcie_en>; + pinctrl-names = "default"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc3v3_ekey_pcie"; + vin-supply = <&vcc12v_dcin>; + }; + + vcc3v3_m2_pcie: regulator-vcc3v3-m2-pcie { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&vcc3v3_m2_pcie_en>; + pinctrl-names = "default"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc3v3_m2_pcie"; + vin-supply = <&vcc12v_dcin>; + }; + + vcc3v3_mini_pcie: regulator-vcc3v3-mini-pcie { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio1 RK_PD5 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&vcc3v3_mini_pcie_en>; + pinctrl-names = "default"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc3v3_mini_pcie"; + vin-supply = <&vcc12v_dcin>; + }; + + vcc3v3_pciex4: regulator-vcc3v3-pciex4 { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio4 RK_PC6 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&vcc3v3_pcie_en>; + pinctrl-names = "default"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc3v3_pciex4"; + vin-supply = <&vcc12v_dcin>; + }; + + vcc4v0_sys: regulator-vcc4v0-sys { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <4000000>; + regulator-min-microvolt = <4000000>; + regulator-name = "vcc4v0_sys"; + vin-supply = <&vcc12v_dcin>; + }; + + vcc5v0_usb20_host: regulator-vcc5v0-usb20-host { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio2 RK_PC3 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&vcc5v0_usb20_host_en>; + pinctrl-names = "default"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + regulator-name = "vcc5v0_usb20_host"; + vin-supply = <&vcc5v0_usb_s0>; + }; + + vcc5v0_usb20_hub: regulator-vcc5v0-usb20-hub { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio4 RK_PA5 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&vcc5v0_usb20_hub_en>; + pinctrl-names = "default"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + regulator-name = "vcc5v0_usb20_hub"; + vin-supply = <&vcc5v0_usb_s0>; + }; + + vcc5v0_usb30_otg: regulator-vcc5v0-usb30-otg { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&vcc5v0_usb30_otg_en>; + pinctrl-names = "default"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + regulator-name = "vcc5v0_usb30_otg"; + vin-supply = <&vcc5v0_usb_s0>; + }; + + vcc5v0_usb_s0: regulator-vcc5v0-usb-s0 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + regulator-name = "vcc5v0_usb_s0"; + vin-supply = <&vcc12v_dcin>; + }; + + vcc12v_dcin: regulator-vcc12v-dcin { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <12000000>; + regulator-min-microvolt = <12000000>; + regulator-name = "vcc12v_dcin"; + }; + + vcc_3v3_s0: regulator-vcc-3v3-s0 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_3v3_s0"; + vin-supply = <&vcc12v_dcin>; + }; + + vcc_3v3_sd_s3: regulator-vcc-3v3-sd-s3 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <3300000>; + regulator-min-microvolt = <3300000>; + regulator-name = "vcc_3v3_sd_s3"; + vin-supply = <&vcc_3v3_s3>; + }; + + vcc_5v0_s0: regulator-vcc-5v0-s0 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-max-microvolt = <5000000>; + regulator-min-microvolt = <5000000>; + regulator-name = "vcc_5v0_s0"; + vin-supply = <&vcc12v_dcin>; + }; +}; + +&can1 { + pinctrl-0 = <&can1m1_pins>; + status = "okay"; +}; + +&can2 { + pinctrl-0 = <&can2m0_pins>; + status = "okay"; +}; + +&combphy0_ps { + status = "okay"; +}; + +&combphy1_ps { + status = "okay"; +}; + +&combphy2_psu { + status = "okay"; +}; + +&dp0 { + status = "okay"; +}; + +&dp0_in { + dp0_in_vp2: endpoint { + remote-endpoint = <&vp2_out_dp0>; + }; +}; + +&dp0_out { + dp0_out_con: endpoint { + remote-endpoint = <&usbdp_phy0_dp_in>; + }; +}; + +&gmac0 { + clock_in_out = "output"; + phy-handle = <&rgmii_phy0>; + phy-mode = "rgmii-id"; + phy-supply = <&vcc_3v3_s0>; + pinctrl-0 = <&gmac0_miim + &gmac0_tx_bus2 + &gmac0_rx_bus2 + &gmac0_rgmii_clk + &gmac0_rgmii_bus>; + pinctrl-names = "default"; + status = "okay"; +}; + +&gmac1 { + clock_in_out = "output"; + phy-handle = <&rgmii_phy1>; + phy-mode = "rgmii-id"; + phy-supply = <&vcc_3v3_s0>; + pinctrl-0 = <&gmac1_miim + &gmac1_tx_bus2 + &gmac1_rx_bus2 + &gmac1_rgmii_clk + &gmac1_rgmii_bus>; + pinctrl-names = "default"; + status = "okay"; +}; + +&hdmi0 { + frl-enable-gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&hdmim0_tx0_cec &hdmim0_tx0_hpd + &hdmim0_tx0_scl &hdmim0_tx0_sda &hdmi0_tx_on_h>; + pinctrl-names = "default"; + status = "okay"; +}; + +&hdmi0_in { + hdmi0_in_vp0: endpoint { + remote-endpoint = <&vp0_out_hdmi0>; + }; +}; + +&hdmi0_out { + hdmi0_out_con: endpoint { + remote-endpoint = <&hdmi0_con_in>; + }; +}; + +&hdmi0_sound { + status = "okay"; +}; + +&hdmi1 { + frl-enable-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&hdmim0_tx1_cec &hdmim0_tx1_hpd + &hdmim0_tx1_scl &hdmim0_tx1_sda &hdmi1_tx_on_h>; + pinctrl-names = "default"; + status = "okay"; +}; + +&hdmi1_in { + hdmi1_in_vp1: endpoint { + remote-endpoint = <&vp1_out_hdmi1>; + }; +}; + +&hdmi1_out { + hdmi1_out_con: endpoint { + remote-endpoint = <&hdmi1_con_in>; + }; +}; + +&hdmi1_sound { + status = "okay"; +}; + +&hdmi_receiver_cma { + status = "okay"; +}; + +&hdmi_receiver { + hpd-gpios = <&gpio1 RK_PD2 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&hdmim1_rx_cec &hdmim1_rx_hpdin + &hdmim1_rx_scl &hdmim1_rx_sda + &hdmirx_det>; + pinctrl-names = "default"; + status = "okay"; +}; + +&hdptxphy0 { + status = "okay"; +}; + +&hdptxphy1 { + status = "okay"; +}; + +&i2c0 { + gpio@21 { + compatible = "nxp,pca9535"; + reg = <0x21>; + #gpio-cells = <2>; + gpio-controller; + vcc-supply = <&vcc_3v3_s0>; + }; + + hym8563: rtc@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + #clock-cells = <0>; + clock-output-names = "hym8563"; + interrupt-parent = <&gpio0>; + interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&hym8563_int>; + pinctrl-names = "default"; + wakeup-source; + }; +}; + +&i2c1 { + usb-typec@22 { + compatible = "fcs,fusb302"; + reg = <0x22>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PD3 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&usbc0_int>; + pinctrl-names = "default"; + vbus-supply = <&vbus5v0_typec>; + status = "okay"; + + connector { + compatible = "usb-c-connector"; + data-role = "dual"; + label = "USB-C"; + op-sink-microwatt = <1000000>; + power-role = "dual"; + sink-pdos = <PDO_FIXED(5000, 1000, PDO_FIXED_USB_COMM)>; + source-pdos = + <PDO_FIXED(5000, 2000, PDO_FIXED_USB_COMM)>; + try-power-role = "source"; + + altmodes { + displayport { + svid = /bits/ 16 <0xff01>; + vdo = <0xffffffff>; + }; + }; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usbc0_hs: endpoint { + remote-endpoint = <&usb_host0_xhci_hs>; + }; + }; + + port@1 { + reg = <1>; + + usbc0_ss: endpoint { + remote-endpoint = <&usbdp_phy0_ss_out>; + }; + }; + + port@2 { + reg = <2>; + + usbc0_sbu: endpoint { + remote-endpoint = <&usbdp_phy0_dp_out>; + }; + }; + }; + }; + }; +}; + +&i2c7 { + pinctrl-0 = <&i2c7m0_xfer>; + pinctrl-names = "default"; + status = "okay"; + + es8388: audio-codec@11 { + compatible = "everest,es8388", "everest,es8328"; + reg = <0x11>; + AVDD-supply = <&avcc_3v3_s0>; + DVDD-supply = <&vcc_1v8_s3>; + HPVDD-supply = <&avcc_3v3_s0>; + PVDD-supply = <&vcc_1v8_s3>; + assigned-clock-rates = <12288000>; + assigned-clocks = <&cru I2S0_8CH_MCLKOUT>; + clocks = <&cru I2S0_8CH_MCLKOUT>; + #sound-dai-cells = <0>; + }; +}; + +&i2s0_8ch { + pinctrl-0 = <&i2s0_lrck + &i2s0_mclk + &i2s0_sclk + &i2s0_sdi0 + &i2s0_sdo0>; + pinctrl-names = "default"; + status = "okay"; +}; + +&i2s5_8ch { + status = "okay"; +}; + +&i2s6_8ch { + status = "okay"; +}; + +&mdio0 { + rgmii_phy0: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x0>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio3 RK_PC0 GPIO_ACTIVE_LOW>; + }; +}; + +&mdio1 { + rgmii_phy1: ethernet-phy@0 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <0x0>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio3 RK_PC1 GPIO_ACTIVE_LOW>; + }; +}; + +&package_thermal { + polling-delay = <1000>; + + cooling-maps { + map0 { + cooling-device = <&fan THERMAL_NO_LIMIT 1>; + trip = <&package_fan0>; + }; + + map1 { + cooling-device = <&fan 2 THERMAL_NO_LIMIT>; + trip = <&package_fan1>; + }; + }; + + trips { + package_fan0: package-fan0 { + hysteresis = <2000>; + temperature = <55000>; + type = "active"; + }; + + package_fan1: package-fan1 { + hysteresis = <2000>; + temperature = <65000>; + type = "active"; + }; + }; +}; + +&pcie30phy { + data-lanes = <1 1 2 2>; + status = "okay"; +}; + +/* M.2 M-Key (NVMe) */ +&pcie3x4 { + num-lanes = <2>; + pinctrl-0 = <&pcie3x4_rst>; + pinctrl-names = "default"; + reset-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_m2_pcie>; + status = "okay"; +}; + +/* PCIe x4 slot */ +&pcie3x2 { + pinctrl-0 = <&pcie3x2_rst>; + pinctrl-names = "default"; + reset-gpios = <&gpio4 RK_PB0 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_pciex4>; + status = "okay"; +}; + +/* M.2 E-Key (WiFi/BT) */ +&pcie2x1l0 { + pinctrl-0 = <&pcie2x1l0_rst &ekey_disable>; + pinctrl-names = "default"; + reset-gpios = <&gpio0 RK_PC5 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_ekey_pcie>; + status = "okay"; +}; + +/* Mini-PCIe */ +&pcie2x1l1 { + pinctrl-0 = <&pcie2x1l1_rst &minipcie_disable>; + pinctrl-names = "default"; + reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc3v3_mini_pcie>; + status = "okay"; +}; + +&pinctrl { + hdmi-tx { + hdmi0_tx_on_h: hdmi0-tx-on-h { + rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + hdmi1_tx_on_h: hdmi1-tx-on-h { + rockchip,pins = <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + hdmirx { + hdmirx_det: hdmirx-det { + rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + hym8563 { + hym8563_int: hym8563-int { + rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + ir-receiver { + ir_receiver_pin: ir-receiver-pin { + rockchip,pins = <0 RK_PD0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + leds { + sys_led_pin: sys-led-pin { + rockchip,pins = <1 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + mipi { + mipi_dsi0_power_en: mipi-dsi0-power-en { + rockchip,pins = <1 RK_PC0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + mipi_dsi1_power_en: mipi-dsi1-power-en { + rockchip,pins = <1 RK_PC1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pcie2 { + ekey_disable: ekey-disable { + rockchip,pins = <0 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + minipcie_disable: minipcie-disable { + rockchip,pins = <3 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pcie2x1l0_rst: pcie2x1l0-rst { + rockchip,pins = <0 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pcie2x1l1_rst: pcie2x1l1-rst { + rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pcie3 { + pcie3x2_rst: pcie3x2-rst { + rockchip,pins = <4 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pcie3x4_rst: pcie3x4-rst { + rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + sata { + sata_power_en: sata-power-en { + rockchip,pins = <1 RK_PD3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + sound { + hp_detect: hp-detect { + rockchip,pins = <0 RK_PA0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb-typec { + typec_vbus_en: typec-vbus-en { + rockchip,pins = <4 RK_PA3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + usbc0_int: usbc0-int { + rockchip,pins = <0 RK_PD3 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + vcc3v3_ekey_pcie_en: vcc3v3-ekey-pcie-en { + rockchip,pins = <0 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + vcc3v3_m2_pcie_en: vcc3v3-m2-pcie-en { + rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + vcc3v3_mini_pcie_en: vcc3v3-mini-pcie-en { + rockchip,pins = <1 RK_PD5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + vcc3v3_pcie_en: vcc3v3-pcie-en { + rockchip,pins = <4 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + vcc5v0_usb20_host_en: vcc5v0-usb20-host-en { + rockchip,pins = <2 RK_PC3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + vcc5v0_usb20_hub_en: vcc5v0-usb20-hub-en { + rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + vcc5v0_usb30_otg_en: vcc5v0-usb30-otg-en { + rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&pwm0 { + pinctrl-0 = <&pwm0m2_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&pwm1 { + pinctrl-0 = <&pwm1m2_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&pwm7 { + status = "disabled"; +}; + +&pwm11 { + pinctrl-0 = <&pwm11m2_pins>; + pinctrl-names = "default"; + status = "okay"; +}; + +&saradc { + vref-supply = <&avcc_1v8_s0>; + status = "okay"; +}; + +&sata0 { + status = "okay"; + + sata-port@0 { + target-supply = <&sata_power>; + }; +}; + +&sdmmc { + bus-width = <4>; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; + disable-wp; + max-frequency = <200000000>; + no-mmc; + no-sdio; + pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det>; + pinctrl-names = "default"; + sd-uhs-sdr104; + vmmc-supply = <&vcc_3v3_sd_s3>; + vqmmc-supply = <&vccio_sd_s0>; + status = "okay"; +}; + +&u2phy0 { + status = "okay"; +}; + +&u2phy0_otg { + status = "okay"; +}; + +&u2phy1 { + status = "okay"; +}; + +&u2phy1_otg { + phy-supply = <&vcc5v0_usb30_otg>; + status = "okay"; +}; + +&u2phy2 { + status = "okay"; +}; + +&u2phy2_host { + phy-supply = <&vcc5v0_usb20_host>; + status = "okay"; +}; + +&u2phy3 { + status = "okay"; +}; + +&u2phy3_host { + phy-supply = <&vcc5v0_usb20_hub>; + status = "okay"; +}; + +&uart2 { + pinctrl-0 = <&uart2m0_xfer>; + pinctrl-names = "default"; + status = "okay"; +}; + +&uart4 { + pinctrl-0 = <&uart4m2_xfer>; + pinctrl-names = "default"; + status = "okay"; +}; + +&uart7 { + pinctrl-0 = <&uart7m2_xfer>; + pinctrl-names = "default"; + status = "okay"; +}; + +&usbdp_phy0 { + mode-switch; + orientation-switch; + sbu1-dc-gpios = <&gpio1 RK_PB0 GPIO_ACTIVE_HIGH>; + sbu2-dc-gpios = <&gpio1 RK_PB1 GPIO_ACTIVE_HIGH>; + status = "okay"; + + port { + #address-cells = <1>; + #size-cells = <0>; + + usbdp_phy0_ss_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_ss>; + }; + + usbdp_phy0_ss_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&usb_host0_xhci_ss>; + }; + + usbdp_phy0_dp_in: endpoint@2 { + reg = <2>; + remote-endpoint = <&dp0_out_con>; + }; + + usbdp_phy0_dp_out: endpoint@3 { + reg = <3>; + remote-endpoint = <&usbc0_sbu>; + }; + }; +}; + +&usbdp_phy1 { + rockchip,dp-lane-mux = <2 3>; + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host0_xhci { + usb-role-switch; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usb_host0_xhci_hs: endpoint { + remote-endpoint = <&usbc0_hs>; + }; + }; + + port@1 { + reg = <1>; + + usb_host0_xhci_ss: endpoint { + remote-endpoint = <&usbdp_phy0_ss_in>; + }; + }; + }; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usb_host1_xhci { + dr_mode = "host"; + status = "okay"; +}; + +/* + * combphy2_psu is shared between usb_host2_xhci (USB3) and pcie2x1l1 (PCIe). + * Disable USB3 host2 so the PHY can be used for the Mini-PCIe slot. + */ +&usb_host2_xhci { + status = "disabled"; +}; + +&vop { + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vp0 { + vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { + reg = <ROCKCHIP_VOP2_EP_HDMI0>; + remote-endpoint = <&hdmi0_in_vp0>; + }; +}; + +&vp1 { + vp1_out_hdmi1: endpoint@ROCKCHIP_VOP2_EP_HDMI1 { + reg = <ROCKCHIP_VOP2_EP_HDMI1>; + remote-endpoint = <&hdmi1_in_vp1>; + }; +}; + +&vp2 { + vp2_out_dp0: endpoint@a { + reg = <ROCKCHIP_VOP2_EP_DP0>; + remote-endpoint = <&dp0_in_vp2>; + }; +};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6-lts.dts b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6-lts.dts index ff85506..0ee67ee 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6-lts.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6-lts.dts
@@ -38,23 +38,6 @@ usb20_host_pwren: usb20-host-pwren { }; }; -&u2phy1 { - status = "okay"; -}; - -&u2phy1_otg { - status = "okay"; -}; - &u2phy2_host { phy-supply = <&vcc5v0_usb20_host>; }; - -&usbdp_phy1 { - status = "okay"; -}; - -&usb_host1_xhci { - dr_mode = "host"; - status = "okay"; -};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi index cfdb5c1..13be56a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-nanopc-t6.dtsi
@@ -100,14 +100,14 @@ fan: pwm-fan { sound { compatible = "simple-audio-card"; - pinctrl-names = "default"; + label = "Onboard Analog Realtek ALC5616"; pinctrl-0 = <&hp_det>; + pinctrl-names = "default"; - simple-audio-card,name = "realtek,rt5616-codec"; simple-audio-card,format = "i2s"; - simple-audio-card,mclk-fs = <256>; - simple-audio-card,hp-det-gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_LOW>; + simple-audio-card,mclk-fs = <256>; + simple-audio-card,name = "realtek,rt5616-codec"; simple-audio-card,widgets = "Headphone", "Headphones", @@ -121,6 +121,7 @@ sound { simple-audio-card,cpu { sound-dai = <&i2s0_8ch>; }; + simple-audio-card,codec { sound-dai = <&rt5616>; }; @@ -167,16 +168,6 @@ vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 { vin-supply = <&vcc4v0_sys>; }; - vcc_3v3_pcie20: regulator-vcc3v3-pcie20 { - compatible = "regulator-fixed"; - regulator-name = "vcc_3v3_pcie20"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - vin-supply = <&vcc_3v3_s3>; - }; - vbus5v0_typec: regulator-vbus5v0-typec { compatible = "regulator-fixed"; enable-active-high; @@ -205,8 +196,8 @@ vdd_mpcie_3v3: regulator-vdd-mpcie-3v3 { compatible = "regulator-fixed"; enable-active-high; gpio = <&gpio4 RK_PC2 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&pcie_m2_1_pwren_pin>; pinctrl-names = "default"; - pinctrl-0 = <&pcie_m2_1_pwren>; regulator-name = "vdd_mpcie_3v3"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; @@ -217,8 +208,8 @@ vcc3v3_pcie_m2_0: regulator-vcc3v3-pcie-m2-0 { compatible = "regulator-fixed"; enable-active-high; gpios = <&gpio2 RK_PC5 GPIO_ACTIVE_HIGH>; + pinctrl-0 = <&pcie_m2_0_pwren_pin>; pinctrl-names = "default"; - pinctrl-0 = <&pcie_m2_0_pwren>; regulator-name = "vcc3v3_pcie_m2_0"; regulator-min-microvolt = <3300000>; regulator-max-microvolt = <3300000>; @@ -546,10 +537,10 @@ hym8563: rtc@51 { reg = <0x51>; #clock-cells = <0>; clock-output-names = "hym8563"; - pinctrl-names = "default"; - pinctrl-0 = <&hym8563_int>; interrupt-parent = <&gpio0>; interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>; + pinctrl-0 = <&rtc_int_l_pin>; + pinctrl-names = "default"; wakeup-source; }; }; @@ -561,17 +552,11 @@ &i2c7 { rt5616: codec@1b { compatible = "realtek,rt5616"; reg = <0x1b>; - clocks = <&cru I2S0_8CH_MCLKOUT>; + assigned-clocks = <&cru I2S0_8CH_MCLKOUT_TO_IO>; + assigned-clock-rates = <12288000>; + clocks = <&cru I2S0_8CH_MCLKOUT_TO_IO>; clock-names = "mclk"; #sound-dai-cells = <0>; - assigned-clocks = <&cru I2S0_8CH_MCLKOUT>; - assigned-clock-rates = <12288000>; - - port { - rt5616_p0_0: endpoint { - remote-endpoint = <&i2s0_8ch_p0_0>; - }; - }; }; /* connected with MIPI-CSI1 */ @@ -583,21 +568,9 @@ &i2c8 { }; &i2s0_8ch { + pinctrl-0 = <&i2s0_lrck &i2s0_mclk &i2s0_sclk &i2s0_sdi0 &i2s0_sdo0>; pinctrl-names = "default"; - pinctrl-0 = <&i2s0_lrck - &i2s0_mclk - &i2s0_sclk - &i2s0_sdi0 - &i2s0_sdo0>; status = "okay"; - - i2s0_8ch_p0: port { - i2s0_8ch_p0_0: endpoint { - dai-format = "i2s"; - mclk-fs = <256>; - remote-endpoint = <&rt5616_p0_0>; - }; - }; }; &i2s5_8ch { @@ -639,26 +612,26 @@ map1 { }; &pcie2x1l0 { - reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>; - vpcie3v3-supply = <&vcc_3v3_pcie20>; + pinctrl-0 = <&pcie_25glan_perstb_b_pin>; pinctrl-names = "default"; - pinctrl-0 = <&pcie2_0_rst>; + reset-gpios = <&gpio4 RK_PB3 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc_3v3_s3>; status = "okay"; }; &pcie2x1l1 { + pinctrl-0 = <&pcie_wifi_perstn_pin>; + pinctrl-names = "default"; reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>; vpcie3v3-supply = <&vdd_mpcie_3v3>; - pinctrl-names = "default"; - pinctrl-0 = <&pcie2_1_rst>; status = "okay"; }; &pcie2x1l2 { - reset-gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>; - vpcie3v3-supply = <&vcc_3v3_pcie20>; + pinctrl-0 = <&pcie_25glan_perstb_pin>; pinctrl-names = "default"; - pinctrl-0 = <&pcie2_2_rst>; + reset-gpios = <&gpio4 RK_PA4 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc_3v3_s3>; status = "okay"; }; @@ -714,8 +687,8 @@ hp_det: hp-det { }; hym8563 { - hym8563_int: hym8563-int { - rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; + rtc_int_l_pin: rtc-int-l-pin { + rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; }; }; @@ -726,25 +699,25 @@ ir_receiver_pin: ir-receiver-pin { }; pcie { - pcie2_0_rst: pcie2-0-rst { - rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; - }; - - pcie2_1_rst: pcie2-1-rst { - rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; - }; - - pcie2_2_rst: pcie2-2-rst { + pcie_25glan_perstb_pin: pcie-25glan-perstb-pin { rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; }; - pcie_m2_0_pwren: pcie-m20-pwren { + pcie_25glan_perstb_b_pin: pcie-25glan-perstb-b-pin { + rockchip,pins = <4 RK_PB3 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pcie_m2_0_pwren_pin: pcie-m2-0-pwren-pin { rockchip,pins = <2 RK_PC5 RK_FUNC_GPIO &pcfg_pull_none>; }; - pcie_m2_1_pwren: pcie-m21-pwren { + pcie_m2_1_pwren_pin: pcie-m2-1-pwren-pin { rockchip,pins = <4 RK_PC2 RK_FUNC_GPIO &pcfg_pull_none>; }; + + pcie_wifi_perstn_pin: pcie-wifi-perstn-pin { + rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; }; usb { @@ -817,7 +790,6 @@ &sdhci { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; disable-wp; @@ -1174,12 +1146,6 @@ &tsadc { status = "okay"; }; -&uart2 { - pinctrl-0 = <&uart2m0_xfer>; - pinctrl-names = "default"; - status = "okay"; -}; - &u2phy0 { status = "okay"; }; @@ -1196,19 +1162,57 @@ &u2phy1_otg { status = "okay"; }; +&u2phy2 { + status = "okay"; +}; + &u2phy2_host { status = "okay"; }; +&u2phy3 { + status = "okay"; +}; + &u2phy3_host { status = "okay"; }; -&u2phy2 { +&uart2 { + pinctrl-0 = <&uart2m0_xfer>; + pinctrl-names = "default"; status = "okay"; }; -&u2phy3 { +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host0_xhci { + usb-role-switch; + status = "okay"; + + port { + usb_host0_xhci_drd_sw: endpoint { + remote-endpoint = <&usbc0_hs>; + }; + }; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +}; + +&usb_host1_xhci { + dr_mode = "host"; status = "okay"; }; @@ -1240,38 +1244,6 @@ &usbdp_phy1 { status = "okay"; }; -&usb_host0_ehci { - status = "okay"; -}; - -&usb_host0_ohci { - status = "okay"; -}; - -&usb_host0_xhci { - usb-role-switch; - status = "okay"; - - port { - usb_host0_xhci_drd_sw: endpoint { - remote-endpoint = <&usbc0_hs>; - }; - }; -}; - -&usb_host1_xhci { - dr_mode = "host"; - status = "okay"; -}; - -&usb_host1_ehci { - status = "okay"; -}; - -&usb_host1_ohci { - status = "okay"; -}; - &vop_mmu { status = "okay"; };
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts b/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts index fbe1d5c..e03d22c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-ok3588-c.dts
@@ -366,7 +366,6 @@ &saradc { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; disable-wp;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts index 6f25e08..9d3d26d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5-itx.dts
@@ -732,7 +732,7 @@ pcie20x1_2_perstn: pcie20x1-2-perstn { }; pcie30x1_0_perstn_m1_l: pcie30x1-0-perstn-m1-l { - rockchip,pins = <4 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + rockchip,pins = <4 RK_PA5 RK_FUNC_GPIO &pcfg_pull_none>; }; pcie30x1_1_perstn: pcie30x1-1-perstn { @@ -879,7 +879,6 @@ &sdhci { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; disable-wp; @@ -895,7 +894,6 @@ &sdmmc { /* M.2 E-KEY */ &sdio { - broken-cd; bus-width = <4>; cap-sdio-irq; keep-power-in-suspend;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi index 13aaf63..b8d90936 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-rock-5b-5bp-5t.dtsi
@@ -617,7 +617,6 @@ &sdmmc { no-sdio; no-mmc; bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; disable-wp;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-tiger-displayport-carrier.dts b/arch/arm64/boot/dts/rockchip/rk3588-tiger-displayport-carrier.dts new file mode 100644 index 0000000..fee3dec --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588-tiger-displayport-carrier.dts
@@ -0,0 +1,110 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) +/* + * Copyright (c) 2024 Cherry Embedded Solutions GmbH + */ + +/dts-v1/; +#include <dt-bindings/soc/rockchip,vop2.h> +#include "rk3588-tiger.dtsi" + +/ { + model = "Theobroma Systems RK3588-Q7 SoM on Tiger Displayport Carrier v1"; + compatible = "tsd,rk3588-tiger-displayport-carrier", "tsd,rk3588-tiger", "rockchip,rk3588"; + + aliases { + ethernet0 = &gmac0; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + dp-connector { + compatible = "dp-connector"; + dp-pwr-supply = <&vcc3v3_baseboard>; + hpd-gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&edp0_hpd_l>; + pinctrl-names = "default"; + type = "full-size"; + + port { + dp_con_in: endpoint { + remote-endpoint = <&edp0_out_con>; + }; + }; + }; + + vcc3v3_baseboard: regulator-vcc3v3-baseboard { + compatible = "regulator-fixed"; + regulator-name = "vcc3v3_baseboard"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_baseboard>; + }; + + vcc5v0_baseboard: regulator-vcc5v0-baseboard { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_baseboard"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; +}; + +&edp0 { + status = "okay"; +}; + +&edp0_in { + edp0_in_vp2: endpoint { + remote-endpoint = <&vp2_out_edp0>; + }; +}; + +&edp0_out { + edp0_out_con: endpoint { + remote-endpoint = <&dp_con_in>; + }; +}; + +&gmac0 { + status = "okay"; +}; + +&hdptxphy0 { + status = "okay"; +}; + +&mmu600_pcie { + status = "disabled"; +}; + +&pinctrl { + edp0 { + edp0_hpd_l: edp0-hpd-l-pin { + rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; +}; + +&uart2 { + status = "okay"; +}; + +&vop { + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vp2 { + vp2_out_edp0: endpoint@ROCKCHIP_VOP2_EP_EDP0 { + reg = <ROCKCHIP_VOP2_EP_EDP0>; + remote-endpoint = <&edp0_in_vp2>; + }; +};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts b/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts index 935c40c..ea63bf2 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-tiger-haikou.dts
@@ -155,6 +155,10 @@ vddd_audio_1v6: regulator-vddd-audio-1v6 { }; }; +&can0 { + status = "okay"; +}; + &combphy2_psu { status = "okay"; };
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi b/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi index 139f70e7..161c89c 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588-tiger.dtsi
@@ -90,6 +90,11 @@ vcc5v0_sys: regulator-vcc5v0-sys { }; }; +&can0 { + assigned-clocks = <&cru CLK_CAN0>; + assigned-clock-rates = <300000000>; +}; + &cpu_b0 { cpu-supply = <&vdd_cpu_big0_s0>; };
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vicharak-axon.dts b/arch/arm64/boot/dts/rockchip/rk3588-vicharak-axon.dts index 9a540bd..6a97973 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-vicharak-axon.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-vicharak-axon.dts
@@ -374,7 +374,6 @@ &sdhci { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; disable-wp;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-vicharak-vaaman2.dts b/arch/arm64/boot/dts/rockchip/rk3588-vicharak-vaaman2.dts index f5b0cfc..5e0b9ce 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-vicharak-vaaman2.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-vicharak-vaaman2.dts
@@ -187,7 +187,6 @@ &sdhci { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; disable-wp;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588-youyeetoo-yy3588.dts b/arch/arm64/boot/dts/rockchip/rk3588-youyeetoo-yy3588.dts index b03dc0a..3f20fa0 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588-youyeetoo-yy3588.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588-youyeetoo-yy3588.dts
@@ -717,7 +717,6 @@ &sdhci { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; max-frequency = <150000000>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts b/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts index 2e8661a..c162abe 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-coolpi-4b.dts
@@ -517,7 +517,6 @@ &sdio { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; disable-wp;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts index c4ddb78..4ec7923 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-evb1-v10.dts
@@ -478,7 +478,6 @@ &sdhci { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; disable-wp;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts b/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts index 230aac0..5ffc94b 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-gameforce-ace.dts
@@ -596,6 +596,7 @@ regulator-state-mem { &i2c3 { status = "okay"; + /* Touchscreen is rotated 90 degrees with 0,0 position near home button. */ touchscreen@14 { compatible = "goodix,gt911"; reg = <0x14>; @@ -605,10 +606,8 @@ touchscreen@14 { pinctrl-0 = <&touch_int>, <&touch_rst>; pinctrl-names = "default"; reset-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>; - touchscreen-inverted-x; touchscreen-size-x = <1080>; touchscreen-size-y = <1920>; - touchscreen-swapped-x-y; }; }; @@ -641,11 +640,15 @@ channel@7 { }; }; + /* IMU oriented relative to panel, which is rotated 90 degrees. */ imu@68 { compatible = "invensense,mpu6880"; reg = <0x68>; interrupt-parent = <&gpio0>; interrupts = <RK_PD3 IRQ_TYPE_EDGE_RISING>; + mount-matrix = "-1", "0", "0", + "0", "-1", "0", + "0", "0", "1"; }; }; @@ -1112,7 +1115,6 @@ brcmf: wifi@1 { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; max-frequency = <150000000>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts index ed36c27c..db6adeeb 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-indiedroid-nova.dts
@@ -637,7 +637,6 @@ sdio_wifi: wifi@1 { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; no-sdio;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-lubancat-4.dts b/arch/arm64/boot/dts/rockchip/rk3588s-lubancat-4.dts index 586741a..0d28c61 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-lubancat-4.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-lubancat-4.dts
@@ -371,7 +371,6 @@ &sdhci { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; disable-wp; max-frequency = <150000000>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-m6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-m6.dtsi new file mode 100644 index 0000000..6644d3b --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-m6.dtsi
@@ -0,0 +1,142 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +#include "rk3588s-nanopi.dtsi" + +/ { + adc-keys-1 { + compatible = "adc-keys"; + io-channels = <&saradc 1>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-maskrom { + label = "Recovery"; + linux,code = <KEY_VENDOR>; + press-threshold-microvolt = <1800>; + }; + }; + + leds { + compatible = "gpio-leds"; + + sys_led: led-0 { + label = "sys_led"; + gpios = <&gpio1 RK_PA4 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + pinctrl-names = "default"; + pinctrl-0 = <&sys_led_pin>; + }; + + user_led: led-1 { + label = "user_led"; + gpios = <&gpio1 RK_PA6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&user_led_pin>; + }; + }; + + vcc_3v3_pcie: regulator-vcc-3v3-pcie { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pcie2_2_pwren>; + regulator-name = "vcc_3v3_pcie"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc5v0_usb_otg0: regulator-vcc5v0-usb-otg0 { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&typec5v_pwren>; + regulator-name = "vcc5v0_usb_otg0"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_sys>; + }; + + vdd_mpcie_3v3: regulator-vdd-mpcie-3v3 { + compatible = "regulator-fixed"; + /* Controlled by EXT_EN on RK806 */ + regulator-name = "vdd_mpcie_3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + vin-supply = <&vcc5v0_sys>; + }; +}; + +&i2c7 { + clock-frequency = <200000>; + status = "okay"; +}; + +&i2s0_8ch { + pinctrl-names = "default"; + pinctrl-0 = <&i2s0_lrck + &i2s0_mclk + &i2s0_sclk + &i2s0_sdi0 + &i2s0_sdo0>; + status = "okay"; +}; + +&pcie2x1l1 { /* M.2 E-key 2230 */ + vpcie3v3-supply = <&vdd_mpcie_3v3>; +}; + +&pcie2x1l2 { /* M.2 M-key 2280 */ + pinctrl-0 = <&pcie20x1_2_perstn_m0>, <&pcie20x1m0_clkreqn>, <&pcie20x1m0_waken>; + vpcie3v3-supply = <&vcc_3v3_pcie>; +}; + +&pinctrl { + gpio-leds { + sys_led_pin: sys-led-pin { + rockchip,pins = <1 RK_PA4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + user_led_pin: user-led-pin { + rockchip,pins = <1 RK_PA6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + headphone { + hp_det: hp-det { + rockchip,pins = <1 RK_PC4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pcie { + pcie2_2_pwren: pcie2-2-pwren { + rockchip,pins = <3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + usb { + typec5v_pwren: typec5v-pwren { + rockchip,pins = <3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&u2phy3 { + status = "okay"; +}; + +&u2phy3_host { + phy-supply = <&vcc5v0_host_20>; + status = "okay"; +}; + +&usb_host1_ehci { + status = "okay"; +}; + +&usb_host1_ohci { + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-m6v1.dts b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-m6v1.dts new file mode 100644 index 0000000..2a22435 --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-m6v1.dts
@@ -0,0 +1,57 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +/dts-v1/; + +#include "rk3588s-nanopi-m6.dtsi" + +/ { + model = "FriendlyElec NanoPi M6"; + compatible = "friendlyarm,nanopi-m6", "rockchip,rk3588s"; + + analog-sound { + compatible = "audio-graph-card"; + label = "rk3588s-rt5616"; + + pinctrl-names = "default"; + pinctrl-0 = <&hp_det>; + hp-det-gpios = <&gpio1 RK_PC4 GPIO_ACTIVE_LOW>; + + dais = <&i2s0_8ch_p0>; + routing = + "Headphones", "HPOL", + "Headphones", "HPOR", + "MIC1", "Microphone Jack", + "Microphone Jack", "micbias1"; + widgets = + "Headphone", "Headphones", + "Microphone", "Microphone Jack"; + }; +}; + +&i2c7 { + audio-codec@1b { + compatible = "realtek,rt5616"; + reg = <0x1b>; + assigned-clocks = <&cru I2S0_8CH_MCLKOUT_TO_IO>; + assigned-clock-rates = <12288000>; + clocks = <&cru I2S0_8CH_MCLKOUT_TO_IO>; + clock-names = "mclk"; + #sound-dai-cells = <0>; + + port { + rt5616_p0: endpoint { + remote-endpoint = <&i2s0_8ch_p0_0>; + }; + }; + }; +}; + +&i2s0_8ch { + i2s0_8ch_p0: port { + i2s0_8ch_p0_0: endpoint { + dai-format = "i2s"; + mclk-fs = <256>; + remote-endpoint = <&rt5616_p0>; + }; + }; +};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi index 91b6eef..ac9eebd 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi-r6.dtsi
@@ -1,38 +1,8 @@ // SPDX-License-Identifier: (GPL-2.0+ OR MIT) -/dts-v1/; - -#include <dt-bindings/pinctrl/rockchip.h> -#include <dt-bindings/gpio/gpio.h> -#include <dt-bindings/input/input.h> -#include <dt-bindings/soc/rockchip,vop2.h> -#include "rk3588s.dtsi" +#include "rk3588s-nanopi.dtsi" / { - aliases { - ethernet0 = &gmac1; - mmc0 = &sdmmc; - mmc1 = &sdhci; - }; - - chosen { - stdout-path = "serial2:1500000n8"; - }; - - adc-keys { - compatible = "adc-keys"; - io-channels = <&saradc 0>; - io-channel-names = "buttons"; - keyup-threshold-microvolt = <1800000>; - poll-interval = <100>; - - button-maskrom { - label = "Maskrom"; - linux,code = <KEY_VENDOR>; - press-threshold-microvolt = <1800>; - }; - }; - gpio-keys { compatible = "gpio-keys"; pinctrl-names = "default"; @@ -46,17 +16,6 @@ button-user { }; }; - hdmi-con { - compatible = "hdmi-connector"; - type = "a"; - - port { - hdmi_con_in: endpoint { - remote-endpoint = <&hdmi0_out_con>; - }; - }; - }; - leds { compatible = "gpio-leds"; @@ -89,68 +48,6 @@ lan2_led: led-3 { }; }; - vcc5v0_sys: regulator-vcc5v0-sys { - compatible = "regulator-fixed"; - regulator-name = "vcc5v0_sys"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - }; - - vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 { - compatible = "regulator-fixed"; - regulator-name = "vcc_1v1_nldo_s3"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1100000>; - regulator-max-microvolt = <1100000>; - vin-supply = <&vcc5v0_sys>; - }; - - vcc_3v3_s0: regulator-vcc-3v3-s0 { - compatible = "regulator-fixed"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-name = "vcc_3v3_s0"; - vin-supply = <&vcc_3v3_s3>; - }; - - vcc_3v3_sd_s0: regulator-vcc-3v3-sd-s0 { - compatible = "regulator-fixed"; - enable-active-high; - gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&sd_s0_pwr>; - regulator-name = "vcc_3v3_sd_s0"; - regulator-boot-on; - regulator-max-microvolt = <3000000>; - regulator-min-microvolt = <3000000>; - vin-supply = <&vcc_3v3_s3>; - }; - - vcc_3v3_pcie20: regulator-vcc3v3-pcie20 { - compatible = "regulator-fixed"; - regulator-name = "vcc_3v3_pcie20"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - vin-supply = <&vcc_3v3_s3>; - }; - - vcc5v0_usb: regulator-vcc5v0-usb { - compatible = "regulator-fixed"; - regulator-name = "vcc5v0_usb"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <&vcc5v0_sys>; - }; - vcc5v0_usb_otg0: regulator-vcc5v0-usb-otg0 { compatible = "regulator-fixed"; enable-active-high; @@ -160,223 +57,8 @@ vcc5v0_usb_otg0: regulator-vcc5v0-usb-otg0 { regulator-name = "vcc5v0_usb_otg0"; regulator-min-microvolt = <5000000>; regulator-max-microvolt = <5000000>; - vin-supply = <&vcc5v0_usb>; - }; - - vcc5v0_host_20: regulator-vcc5v0-host-20 { - compatible = "regulator-fixed"; - enable-active-high; - gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>; - pinctrl-names = "default"; - pinctrl-0 = <&vcc5v0_host20_en>; - regulator-name = "vcc5v0_host_20"; - regulator-min-microvolt = <5000000>; - regulator-max-microvolt = <5000000>; - vin-supply = <&vcc5v0_usb>; - }; -}; - -&combphy0_ps { - status = "okay"; -}; - -&combphy2_psu { - status = "okay"; -}; - -&cpu_b0 { - cpu-supply = <&vdd_cpu_big0_s0>; -}; - -&cpu_b1 { - cpu-supply = <&vdd_cpu_big0_s0>; -}; - -&cpu_b2 { - cpu-supply = <&vdd_cpu_big1_s0>; -}; - -&cpu_b3 { - cpu-supply = <&vdd_cpu_big1_s0>; -}; - -&cpu_l0 { - cpu-supply = <&vdd_cpu_lit_s0>; -}; - -&cpu_l1 { - cpu-supply = <&vdd_cpu_lit_s0>; -}; - -&cpu_l2 { - cpu-supply = <&vdd_cpu_lit_s0>; -}; - -&cpu_l3 { - cpu-supply = <&vdd_cpu_lit_s0>; -}; - -&gmac1 { - clock_in_out = "output"; - phy-handle = <&rgmii_phy1>; - phy-mode = "rgmii-rxid"; - pinctrl-0 = <&gmac1_miim - &gmac1_tx_bus2 - &gmac1_rx_bus2 - &gmac1_rgmii_clk - &gmac1_rgmii_bus>; - pinctrl-names = "default"; - tx_delay = <0x42>; - status = "okay"; -}; - -&gpu { - mali-supply = <&vdd_gpu_s0>; - status = "okay"; -}; - -&hdmi0 { - frl-enable-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_LOW>; - pinctrl-0 = <&hdmim0_tx0_cec &hdmim0_tx0_hpd - &hdmim0_tx0_scl &hdmim0_tx0_sda &hdmi0_tx_on_h>; - pinctrl-names = "default"; - status = "okay"; -}; - -&hdmi0_in { - hdmi0_in_vp0: endpoint { - remote-endpoint = <&vp0_out_hdmi0>; - }; -}; - -&hdmi0_out { - hdmi0_out_con: endpoint { - remote-endpoint = <&hdmi_con_in>; - }; -}; - -&hdmi0_sound { - status = "okay"; -}; - -&hdptxphy0 { - status = "okay"; -}; - -&i2c0 { - pinctrl-names = "default"; - pinctrl-0 = <&i2c0m2_xfer>; - status = "okay"; - - vdd_cpu_big0_s0: regulator@42 { - compatible = "rockchip,rk8602"; - reg = <0x42>; - fcs,suspend-voltage-selector = <1>; - regulator-name = "vdd_cpu_big0_s0"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <550000>; - regulator-max-microvolt = <1050000>; - regulator-ramp-delay = <2300>; vin-supply = <&vcc5v0_sys>; - - regulator-state-mem { - regulator-off-in-suspend; - }; }; - - vdd_cpu_big1_s0: regulator@43 { - compatible = "rockchip,rk8603", "rockchip,rk8602"; - reg = <0x43>; - fcs,suspend-voltage-selector = <1>; - regulator-name = "vdd_cpu_big1_s0"; - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <550000>; - regulator-max-microvolt = <1050000>; - regulator-ramp-delay = <2300>; - vin-supply = <&vcc5v0_sys>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; -}; - -&i2c2 { - status = "okay"; - - vdd_npu_s0: regulator@42 { - compatible = "rockchip,rk8602"; - reg = <0x42>; - fcs,suspend-voltage-selector = <1>; - regulator-name = "vdd_npu_s0"; - regulator-min-microvolt = <550000>; - regulator-max-microvolt = <950000>; - regulator-ramp-delay = <2300>; - regulator-boot-on; - regulator-always-on; - vin-supply = <&vcc5v0_sys>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; -}; - -&i2c6 { - clock-frequency = <200000>; - pinctrl-names = "default"; - pinctrl-0 = <&i2c6m0_xfer>; - status = "okay"; - - hym8563: rtc@51 { - compatible = "haoyu,hym8563"; - reg = <0x51>; - #clock-cells = <0>; - clock-output-names = "hym8563"; - pinctrl-names = "default"; - pinctrl-0 = <&rtc_int>; - interrupt-parent = <&gpio0>; - interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>; - wakeup-source; - }; -}; - -&i2s5_8ch { - status = "okay"; -}; - -&mdio1 { - rgmii_phy1: ethernet-phy@1 { - compatible = "ethernet-phy-id001c.c916"; - reg = <0x1>; - pinctrl-names = "default"; - pinctrl-0 = <&rtl8211f_rst>; - reset-assert-us = <20000>; - reset-deassert-us = <100000>; - reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; - }; -}; - -&pcie2x1l1 { - reset-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>; - vpcie3v3-supply = <&vcc_3v3_pcie20>; - status = "okay"; -}; - -&pcie2x1l2 { - reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>; - vpcie3v3-supply = <&vcc_3v3_pcie20>; - status = "okay"; -}; - -&pd_gpu { - domain-supply = <&vdd_gpu_s0>; -}; - -&pd_npu { - domain-supply = <&vdd_npu_s0>; }; &pinctrl { @@ -408,481 +90,9 @@ lan2_led_pin: lan2-led-pin { }; }; - hdmi { - hdmi0_tx_on_h: hdmi0-tx-on-h { - rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - - hym8563 { - rtc_int: rtc-int { - rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; - - sdmmc { - sd_s0_pwr: sd-s0-pwr { - rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; - }; - }; - usb { typec5v_pwren: typec5v-pwren { rockchip,pins = <1 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>; }; - - vcc5v0_host20_en: vcc5v0-host20-en { - rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; - - rtl8211f { - rtl8211f_rst: rtl8211f-rst { - rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; - }; - }; -}; - -&rknn_core_0 { - npu-supply = <&vdd_npu_s0>; - sram-supply = <&vdd_npu_s0>; - status = "okay"; -}; - -&rknn_core_1 { - npu-supply = <&vdd_npu_s0>; - sram-supply = <&vdd_npu_s0>; - status = "okay"; -}; - -&rknn_core_2 { - npu-supply = <&vdd_npu_s0>; - sram-supply = <&vdd_npu_s0>; - status = "okay"; -}; - -&rknn_mmu_0 { - status = "okay"; -}; - -&rknn_mmu_1 { - status = "okay"; -}; - -&rknn_mmu_2 { - status = "okay"; -}; - -&saradc { - vref-supply = <&avcc_1v8_s0>; - status = "okay"; -}; - -&sdhci { - bus-width = <8>; - no-sdio; - no-sd; - non-removable; - mmc-hs200-1_8v; - status = "okay"; -}; - -&sdmmc { - bus-width = <4>; - cap-sd-highspeed; - cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; - disable-wp; - max-frequency = <150000000>; - no-mmc; - no-sdio; - sd-uhs-sdr104; - vmmc-supply = <&vcc_3v3_sd_s0>; - vqmmc-supply = <&vccio_sd_s0>; - status = "okay"; -}; - -&spi2 { - status = "okay"; - assigned-clocks = <&cru CLK_SPI2>; - assigned-clock-rates = <200000000>; - pinctrl-names = "default"; - pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>; - num-cs = <1>; - - pmic@0 { - compatible = "rockchip,rk806"; - spi-max-frequency = <1000000>; - reg = <0x0>; - - interrupt-parent = <&gpio0>; - interrupts = <7 IRQ_TYPE_LEVEL_LOW>; - - pinctrl-names = "default"; - pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, - <&rk806_dvs2_null>, <&rk806_dvs3_null>; - - system-power-controller; - - vcc1-supply = <&vcc5v0_sys>; - vcc2-supply = <&vcc5v0_sys>; - vcc3-supply = <&vcc5v0_sys>; - vcc4-supply = <&vcc5v0_sys>; - vcc5-supply = <&vcc5v0_sys>; - vcc6-supply = <&vcc5v0_sys>; - vcc7-supply = <&vcc5v0_sys>; - vcc8-supply = <&vcc5v0_sys>; - vcc9-supply = <&vcc5v0_sys>; - vcc10-supply = <&vcc5v0_sys>; - vcc11-supply = <&vcc_2v0_pldo_s3>; - vcc12-supply = <&vcc5v0_sys>; - vcc13-supply = <&vcc_1v1_nldo_s3>; - vcc14-supply = <&vcc_1v1_nldo_s3>; - vcca-supply = <&vcc5v0_sys>; - - gpio-controller; - #gpio-cells = <2>; - - rk806_dvs1_null: dvs1-null-pins { - pins = "gpio_pwrctrl1"; - function = "pin_fun0"; - }; - - rk806_dvs2_null: dvs2-null-pins { - pins = "gpio_pwrctrl2"; - function = "pin_fun0"; - }; - - rk806_dvs3_null: dvs3-null-pins { - pins = "gpio_pwrctrl3"; - function = "pin_fun0"; - }; - - regulators { - vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 { - regulator-boot-on; - regulator-min-microvolt = <550000>; - regulator-max-microvolt = <950000>; - regulator-ramp-delay = <12500>; - regulator-name = "vdd_gpu_s0"; - regulator-enable-ramp-delay = <400>; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <550000>; - regulator-max-microvolt = <950000>; - regulator-ramp-delay = <12500>; - regulator-name = "vdd_cpu_lit_s0"; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vdd_log_s0: dcdc-reg3 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <675000>; - regulator-max-microvolt = <750000>; - regulator-ramp-delay = <12500>; - regulator-name = "vdd_log_s0"; - - regulator-state-mem { - regulator-off-in-suspend; - regulator-suspend-microvolt = <750000>; - }; - }; - - vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <550000>; - regulator-max-microvolt = <950000>; - regulator-ramp-delay = <12500>; - regulator-name = "vdd_vdenc_s0"; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vdd_ddr_s0: dcdc-reg5 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <675000>; - regulator-max-microvolt = <900000>; - regulator-ramp-delay = <12500>; - regulator-name = "vdd_ddr_s0"; - - regulator-state-mem { - regulator-off-in-suspend; - regulator-suspend-microvolt = <850000>; - }; - }; - - vdd2_ddr_s3: dcdc-reg6 { - regulator-always-on; - regulator-boot-on; - regulator-name = "vdd2_ddr_s3"; - - regulator-state-mem { - regulator-on-in-suspend; - }; - }; - - vcc_2v0_pldo_s3: dcdc-reg7 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <2000000>; - regulator-max-microvolt = <2000000>; - regulator-ramp-delay = <12500>; - regulator-name = "vdd_2v0_pldo_s3"; - - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <2000000>; - }; - }; - - vcc_3v3_s3: dcdc-reg8 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-name = "vcc_3v3_s3"; - - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <3300000>; - }; - }; - - vddq_ddr_s0: dcdc-reg9 { - regulator-always-on; - regulator-boot-on; - regulator-name = "vddq_ddr_s0"; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vcc_1v8_s3: dcdc-reg10 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-name = "vcc_1v8_s3"; - - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <1800000>; - }; - }; - - avcc_1v8_s0: pldo-reg1 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-name = "avcc_1v8_s0"; - - regulator-state-mem { - regulator-off-in-suspend; - regulator-suspend-microvolt = <1800000>; - }; - }; - - vcc_1v8_s0: pldo-reg2 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-name = "vcc_1v8_s0"; - - regulator-state-mem { - regulator-off-in-suspend; - regulator-suspend-microvolt = <1800000>; - }; - }; - - avdd_1v2_s0: pldo-reg3 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - regulator-name = "avdd_1v2_s0"; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - avcc_3v3_s0: pldo-reg4 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-ramp-delay = <12500>; - regulator-name = "avcc_3v3_s0"; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vccio_sd_s0: pldo-reg5 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <3300000>; - regulator-ramp-delay = <12500>; - regulator-name = "vccio_sd_s0"; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - pldo6_s3: pldo-reg6 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-name = "pldo6_s3"; - - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <1800000>; - }; - }; - - vdd_0v75_s3: nldo-reg1 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <750000>; - regulator-name = "vdd_0v75_s3"; - - regulator-state-mem { - regulator-on-in-suspend; - regulator-suspend-microvolt = <750000>; - }; - }; - - avdd_ddr_pll_s0: nldo-reg2 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <850000>; - regulator-max-microvolt = <850000>; - regulator-name = "avdd_ddr_pll_s0"; - - regulator-state-mem { - regulator-off-in-suspend; - regulator-suspend-microvolt = <850000>; - }; - }; - - avdd_0v75_s0: nldo-reg3 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <750000>; - regulator-name = "avdd_0v75_s0"; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - avdd_0v85_s0: nldo-reg4 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <850000>; - regulator-max-microvolt = <850000>; - regulator-name = "avdd_0v85_s0"; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - - vdd_0v75_s0: nldo-reg5 { - regulator-always-on; - regulator-boot-on; - regulator-min-microvolt = <750000>; - regulator-max-microvolt = <750000>; - regulator-name = "vdd_0v75_s0"; - - regulator-state-mem { - regulator-off-in-suspend; - }; - }; - }; - }; -}; - -&tsadc { - status = "okay"; -}; - -&u2phy0 { - status = "okay"; -}; - -&u2phy0_otg { - phy-supply = <&vcc5v0_usb_otg0>; - status = "okay"; -}; - -&u2phy2 { - status = "okay"; -}; - -&u2phy2_host { - phy-supply = <&vcc5v0_host_20>; - status = "okay"; -}; - -&uart2 { - pinctrl-0 = <&uart2m0_xfer>; - pinctrl-names = "default"; - status = "okay"; -}; - -&usb_host0_ehci { - status = "okay"; -}; - -&usb_host0_ohci { - status = "okay"; -}; - -&usb_host0_xhci { - dr_mode = "host"; - status = "okay"; -}; - -&usbdp_phy0 { - status = "okay"; -}; - -&vop { - status = "okay"; -}; - -&vop_mmu { - status = "okay"; -}; - -&vp0 { - vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { - reg = <ROCKCHIP_VOP2_EP_HDMI0>; - remote-endpoint = <&hdmi0_in_vp0>; }; };
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-nanopi.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi.dtsi new file mode 100644 index 0000000..22b0cde --- /dev/null +++ b/arch/arm64/boot/dts/rockchip/rk3588s-nanopi.dtsi
@@ -0,0 +1,797 @@ +// SPDX-License-Identifier: (GPL-2.0+ OR MIT) + +#include <dt-bindings/pinctrl/rockchip.h> +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/soc/rockchip,vop2.h> +#include "rk3588s.dtsi" + +/ { + aliases { + ethernet0 = &gmac1; + mmc0 = &sdmmc; + mmc1 = &sdhci; + }; + + chosen { + stdout-path = "serial2:1500000n8"; + }; + + adc-keys { + compatible = "adc-keys"; + io-channels = <&saradc 0>; + io-channel-names = "buttons"; + keyup-threshold-microvolt = <1800000>; + poll-interval = <100>; + + button-maskrom { + label = "Maskrom"; + linux,code = <KEY_VENDOR>; + press-threshold-microvolt = <1800>; + }; + }; + + hdmi-con { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi0_out_con>; + }; + }; + }; + + vcc5v0_sys: regulator-vcc5v0-sys { + compatible = "regulator-fixed"; + regulator-name = "vcc5v0_sys"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + }; + + vcc_1v1_nldo_s3: regulator-vcc-1v1-nldo-s3 { + compatible = "regulator-fixed"; + regulator-name = "vcc_1v1_nldo_s3"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + vin-supply = <&vcc5v0_sys>; + }; + + vcc_3v3_s0: regulator-vcc-3v3-s0 { + compatible = "regulator-fixed"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc_3v3_s0"; + vin-supply = <&vcc_3v3_s3>; + }; + + vcc_3v3_sd_s0: regulator-vcc-3v3-sd-s0 { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio4 RK_PB4 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&sd_s0_pwr>; + regulator-name = "vcc_3v3_sd_s0"; + regulator-boot-on; + regulator-max-microvolt = <3000000>; + regulator-min-microvolt = <3000000>; + vin-supply = <&vcc_3v3_s3>; + }; + + vcc5v0_host_20: regulator-vcc5v0-host-20 { + compatible = "regulator-fixed"; + enable-active-high; + gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&vcc5v0_host20_en>; + regulator-name = "vcc5v0_host_20"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <&vcc5v0_sys>; + }; +}; + +&combphy0_ps { + status = "okay"; +}; + +&combphy2_psu { + status = "okay"; +}; + +&cpu_b0 { + cpu-supply = <&vdd_cpu_big0_s0>; +}; + +&cpu_b1 { + cpu-supply = <&vdd_cpu_big0_s0>; +}; + +&cpu_b2 { + cpu-supply = <&vdd_cpu_big1_s0>; +}; + +&cpu_b3 { + cpu-supply = <&vdd_cpu_big1_s0>; +}; + +&cpu_l0 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l1 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l2 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&cpu_l3 { + cpu-supply = <&vdd_cpu_lit_s0>; +}; + +&gmac1 { + clock_in_out = "output"; + phy-handle = <&rgmii_phy1>; + phy-mode = "rgmii-rxid"; /* Vendor provided tx delay value below */ + phy-supply = <&vcc_3v3_s3>; + pinctrl-0 = <&gmac1_miim + &gmac1_tx_bus2 + &gmac1_rx_bus2 + &gmac1_rgmii_clk + &gmac1_rgmii_bus>; + pinctrl-names = "default"; + tx_delay = <0x42>; + status = "okay"; +}; + +&gpu { + mali-supply = <&vdd_gpu_s0>; + status = "okay"; +}; + +&hdmi0 { + frl-enable-gpios = <&gpio4 RK_PB6 GPIO_ACTIVE_LOW>; + pinctrl-0 = <&hdmim0_tx0_cec &hdmim0_tx0_hpd + &hdmim0_tx0_scl &hdmim0_tx0_sda &hdmi0_tx_on_h>; + pinctrl-names = "default"; + status = "okay"; +}; + +&hdmi0_in { + hdmi0_in_vp0: endpoint { + remote-endpoint = <&vp0_out_hdmi0>; + }; +}; + +&hdmi0_out { + hdmi0_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + +&hdmi0_sound { + status = "okay"; +}; + +&hdptxphy0 { + status = "okay"; +}; + +&i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c0m2_xfer>; + status = "okay"; + + vdd_cpu_big0_s0: regulator@42 { + compatible = "rockchip,rk8602"; + reg = <0x42>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu_big0_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <1050000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc5v0_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_big1_s0: regulator@43 { + compatible = "rockchip,rk8603", "rockchip,rk8602"; + reg = <0x43>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_cpu_big1_s0"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <1050000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc5v0_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + +&i2c2 { + status = "okay"; + + vdd_npu_s0: regulator@42 { + compatible = "rockchip,rk8602"; + reg = <0x42>; + fcs,suspend-voltage-selector = <1>; + regulator-name = "vdd_npu_s0"; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <2300>; + vin-supply = <&vcc5v0_sys>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; +}; + +&i2c6 { + clock-frequency = <200000>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c6m0_xfer>; + status = "okay"; + + hym8563: rtc@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + #clock-cells = <0>; + clock-output-names = "hym8563"; + pinctrl-names = "default"; + pinctrl-0 = <&rtc_int>; + interrupt-parent = <&gpio0>; + interrupts = <RK_PB0 IRQ_TYPE_LEVEL_LOW>; + wakeup-source; + }; +}; + +&i2s5_8ch { + status = "okay"; +}; + +&mdio1 { + rgmii_phy1: ethernet-phy@1 { + compatible = "ethernet-phy-id001c.c916"; + reg = <0x1>; + pinctrl-names = "default"; + pinctrl-0 = <&rtl8211f_rst>; + reset-assert-us = <20000>; + reset-deassert-us = <100000>; + reset-gpios = <&gpio3 RK_PB7 GPIO_ACTIVE_LOW>; + }; +}; + +&pcie2x1l1 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie20x1_1_perstn_m2>; + reset-gpios = <&gpio1 RK_PA7 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc_3v3_s3>; + status = "okay"; +}; + +&pcie2x1l2 { + pinctrl-names = "default"; + pinctrl-0 = <&pcie20x1_2_perstn_m0>, <&pcie20x1m0_clkreqn>; + supports-clkreq; + reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>; + vpcie3v3-supply = <&vcc_3v3_s3>; + status = "okay"; +}; + +&pd_gpu { + domain-supply = <&vdd_gpu_s0>; +}; + +&pd_npu { + domain-supply = <&vdd_npu_s0>; +}; + +&pinctrl { + hdmi { + hdmi0_tx_on_h: hdmi0-tx-on-h { + rockchip,pins = <4 RK_PB6 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + hym8563 { + rtc_int: rtc-int { + rockchip,pins = <0 RK_PB0 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + pcie { + pcie20x1_1_perstn_m2: pcie20x1-1-perstn-m2 { + rockchip,pins = <1 RK_PA7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pcie20x1_2_perstn_m0: pcie20x1-2-perstn-m0 { + rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + sdmmc { + sdmmc_det_pin: sdmmc-det-pin { + rockchip,pins = <0 RK_PA4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + + sd_s0_pwr: sd-s0-pwr { + rockchip,pins = <4 RK_PB4 RK_FUNC_GPIO &pcfg_pull_up>; + }; + }; + + usb { + vcc5v0_host20_en: vcc5v0-host20-en { + rockchip,pins = <4 RK_PB5 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + + rtl8211f { + rtl8211f_rst: rtl8211f-rst { + rockchip,pins = <3 RK_PB7 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; +}; + +&rknn_core_0 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_core_1 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_core_2 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_mmu_0 { + status = "okay"; +}; + +&rknn_mmu_1 { + status = "okay"; +}; + +&rknn_mmu_2 { + status = "okay"; +}; + +&saradc { + vref-supply = <&avcc_1v8_s0>; + status = "okay"; +}; + +&sdhci { + bus-width = <8>; + no-sdio; + no-sd; + non-removable; + mmc-hs200-1_8v; + status = "okay"; +}; + +&sdmmc { + bus-width = <4>; + cap-sd-highspeed; + cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; + disable-wp; + max-frequency = <150000000>; + no-mmc; + no-sdio; + sd-uhs-sdr104; + pinctrl-names = "default"; + pinctrl-0 = <&sdmmc_bus4 &sdmmc_clk &sdmmc_cmd &sdmmc_det_pin>; + vmmc-supply = <&vcc_3v3_sd_s0>; + vqmmc-supply = <&vccio_sd_s0>; + status = "okay"; +}; + +&spi2 { + status = "okay"; + assigned-clocks = <&cru CLK_SPI2>; + assigned-clock-rates = <200000000>; + pinctrl-names = "default"; + pinctrl-0 = <&spi2m2_cs0 &spi2m2_pins>; + num-cs = <1>; + + pmic@0 { + compatible = "rockchip,rk806"; + spi-max-frequency = <1000000>; + reg = <0x0>; + + interrupt-parent = <&gpio0>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + + pinctrl-names = "default"; + pinctrl-0 = <&pmic_pins>, <&rk806_dvs1_null>, + <&rk806_dvs2_null>, <&rk806_dvs3_null>; + + system-power-controller; + + vcc1-supply = <&vcc5v0_sys>; + vcc2-supply = <&vcc5v0_sys>; + vcc3-supply = <&vcc5v0_sys>; + vcc4-supply = <&vcc5v0_sys>; + vcc5-supply = <&vcc5v0_sys>; + vcc6-supply = <&vcc5v0_sys>; + vcc7-supply = <&vcc5v0_sys>; + vcc8-supply = <&vcc5v0_sys>; + vcc9-supply = <&vcc5v0_sys>; + vcc10-supply = <&vcc5v0_sys>; + vcc11-supply = <&vcc_2v0_pldo_s3>; + vcc12-supply = <&vcc5v0_sys>; + vcc13-supply = <&vcc_1v1_nldo_s3>; + vcc14-supply = <&vcc_1v1_nldo_s3>; + vcca-supply = <&vcc5v0_sys>; + + gpio-controller; + #gpio-cells = <2>; + + rk806_dvs1_null: dvs1-null-pins { + pins = "gpio_pwrctrl1"; + function = "pin_fun0"; + }; + + rk806_dvs2_null: dvs2-null-pins { + pins = "gpio_pwrctrl2"; + function = "pin_fun0"; + }; + + rk806_dvs3_null: dvs3-null-pins { + pins = "gpio_pwrctrl3"; + function = "pin_fun0"; + }; + + regulators { + vdd_gpu_s0: vdd_gpu_mem_s0: dcdc-reg1 { + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_gpu_s0"; + regulator-enable-ramp-delay = <400>; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_cpu_lit_s0: vdd_cpu_lit_mem_s0: dcdc-reg2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_cpu_lit_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_log_s0: dcdc-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <675000>; + regulator-max-microvolt = <750000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_log_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <750000>; + }; + }; + + vdd_vdenc_s0: vdd_vdenc_mem_s0: dcdc-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <550000>; + regulator-max-microvolt = <950000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_vdenc_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_ddr_s0: dcdc-reg5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <675000>; + regulator-max-microvolt = <900000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_ddr_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <850000>; + }; + }; + + vdd2_ddr_s3: dcdc-reg6 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vdd2_ddr_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + }; + }; + + vcc_2v0_pldo_s3: dcdc-reg7 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <2000000>; + regulator-max-microvolt = <2000000>; + regulator-ramp-delay = <12500>; + regulator-name = "vdd_2v0_pldo_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <2000000>; + }; + }; + + vcc_3v3_s3: dcdc-reg8 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-name = "vcc_3v3_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <3300000>; + }; + }; + + vddq_ddr_s0: dcdc-reg9 { + regulator-always-on; + regulator-boot-on; + regulator-name = "vddq_ddr_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vcc_1v8_s3: dcdc-reg10 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc_1v8_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + avcc_1v8_s0: pldo-reg1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "avcc_1v8_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vcc_1v8_s0: pldo-reg2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "vcc_1v8_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + avdd_1v2_s0: pldo-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-name = "avdd_1v2_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + avcc_3v3_s0: pldo-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <12500>; + regulator-name = "avcc_3v3_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vccio_sd_s0: pldo-reg5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-ramp-delay = <12500>; + regulator-name = "vccio_sd_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + pldo6_s3: pldo-reg6 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-name = "pldo6_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <1800000>; + }; + }; + + vdd_0v75_s3: nldo-reg1 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; + regulator-name = "vdd_0v75_s3"; + + regulator-state-mem { + regulator-on-in-suspend; + regulator-suspend-microvolt = <750000>; + }; + }; + + avdd_ddr_pll_s0: nldo-reg2 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-name = "avdd_ddr_pll_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + regulator-suspend-microvolt = <850000>; + }; + }; + + avdd_0v75_s0: nldo-reg3 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; + regulator-name = "avdd_0v75_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + avdd_0v85_s0: nldo-reg4 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-name = "avdd_0v85_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + + vdd_0v75_s0: nldo-reg5 { + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <750000>; + regulator-max-microvolt = <750000>; + regulator-name = "vdd_0v75_s0"; + + regulator-state-mem { + regulator-off-in-suspend; + }; + }; + }; + }; +}; + +&tsadc { + status = "okay"; +}; + +&u2phy0 { + status = "okay"; +}; + +&u2phy0_otg { + phy-supply = <&vcc5v0_usb_otg0>; + status = "okay"; +}; + +&u2phy2 { + status = "okay"; +}; + +&u2phy2_host { + phy-supply = <&vcc5v0_host_20>; + status = "okay"; +}; + +&uart2 { + pinctrl-0 = <&uart2m0_xfer>; + pinctrl-names = "default"; + status = "okay"; +}; + +&usb_host0_ehci { + status = "okay"; +}; + +&usb_host0_ohci { + status = "okay"; +}; + +&usb_host0_xhci { + dr_mode = "host"; + status = "okay"; +}; + +&usbdp_phy0 { + status = "okay"; +}; + +&vop { + status = "okay"; +}; + +&vop_mmu { + status = "okay"; +}; + +&vp0 { + vp0_out_hdmi0: endpoint@ROCKCHIP_VOP2_EP_HDMI0 { + reg = <ROCKCHIP_VOP2_EP_HDMI0>; + remote-endpoint = <&hdmi0_in_vp0>; + }; +};
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts b/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts index 4e98fa3..ea4d86a 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-odroid-m2.dts
@@ -320,8 +320,6 @@ vdd_npu_s0: regulator@42 { reg = <0x42>; fcs,suspend-voltage-selector = <1>; regulator-name = "vdd_npu_s0"; - regulator-always-on; - regulator-boot-on; regulator-min-microvolt = <550000>; regulator-max-microvolt = <950000>; regulator-ramp-delay = <2300>; @@ -441,6 +439,10 @@ &pd_gpu { domain-supply = <&vdd_gpu_s0>; }; +&pd_npu { + domain-supply = <&vdd_npu_s0>; +}; + &pinctrl { hdmi { hdmi0_tx_on_h: hdmi0-tx-on-h { @@ -514,6 +516,36 @@ &pwm0 { status = "okay"; }; +&rknn_core_0 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_core_1 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_core_2 { + npu-supply = <&vdd_npu_s0>; + sram-supply = <&vdd_npu_s0>; + status = "okay"; +}; + +&rknn_mmu_0 { + status = "okay"; +}; + +&rknn_mmu_1 { + status = "okay"; +}; + +&rknn_mmu_2 { + status = "okay"; +}; + &saradc { vref-supply = <&vcca_1v8_s0>; status = "okay";
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-pro.dts b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-pro.dts index c9679ba..7836753 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-pro.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-orangepi-5-pro.dts
@@ -188,7 +188,7 @@ package_fan1: package-fan1 { /* NVMe */ &pcie2x1l1 { pinctrl-names = "default"; - pinctrl-0 = <&pcie30x1m1_1_perstn>, <&pcie30x1m1_1_clkreqn>, + pinctrl-0 = <&pcie2_1_rst>, <&pcie30x1m1_1_clkreqn>, <&pcie30x1m1_1_waken>; reset-gpios = <&gpio4 RK_PA2 GPIO_ACTIVE_HIGH>; supports-clkreq; @@ -199,7 +199,7 @@ &pcie2x1l1 { /* NIC */ &pcie2x1l2 { pinctrl-names = "default"; - pinctrl-0 = <&pcie20x1m0_perstn>, <&pcie20x1m0_clkreqn>, + pinctrl-0 = <&pcie2_2_rst>, <&pcie20x1m0_clkreqn>, <&pcie20x1m0_waken>; reset-gpios = <&gpio3 RK_PD1 GPIO_ACTIVE_HIGH>; vpcie3v3-supply = <&vcc3v3_eth>; @@ -223,6 +223,16 @@ ethernet_en: ethernet-en { }; }; + pcie { + pcie2_1_rst: pcie2-1-rst { + rockchip,pins = <4 RK_PA2 RK_FUNC_GPIO &pcfg_pull_none>; + }; + + pcie2_2_rst: pcie2-2-rst { + rockchip,pins = <3 RK_PD1 RK_FUNC_GPIO &pcfg_pull_none>; + }; + }; + usb { vcc5v0_otg_en: vcc5v0-otg-en { rockchip,pins = <0 RK_PC4 RK_FUNC_GPIO &pcfg_pull_down>;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts index a76734d..8d13661 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5a.dts
@@ -445,7 +445,6 @@ &sdhci { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; disable-wp;
diff --git a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts index e478488..3f1b62d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts +++ b/arch/arm64/boot/dts/rockchip/rk3588s-rock-5c.dts
@@ -546,7 +546,6 @@ &sdhci { &sdmmc { bus-width = <4>; - cap-mmc-highspeed; cap-sd-highspeed; cd-gpios = <&gpio0 RK_PA4 GPIO_ACTIVE_LOW>; disable-wp;
diff --git a/arch/arm64/boot/dts/st/Makefile b/arch/arm64/boot/dts/st/Makefile index 6390811..9829a5b 100644 --- a/arch/arm64/boot/dts/st/Makefile +++ b/arch/arm64/boot/dts/st/Makefile
@@ -1,6 +1,29 @@ # SPDX-License-Identifier: GPL-2.0-only + +stm32mp255c-dhcos-dhsbc-overlay-imx219-x10-dtbs := \ + stm32mp255c-dhcos-dhsbc.dtb \ + stm32mp255c-dhcos-dhsbc-overlay-imx219-x10.dtbo + +stm32mp257d-engicam-microgea-rmm-overlay-am-1280800w8tzqw-t00h-dtbs := \ + stm32mp257d-engicam-microgea-rmm.dtb \ + stm32mp257d-engicam-microgea-rmm-overlay-am-1280800w8tzqw-t00h.dtbo + +stm32mp257d-engicam-microgea-rmm-overlay-rk050hr345-ct106a-dtbs := \ + stm32mp257d-engicam-microgea-rmm.dtb \ + stm32mp257d-engicam-microgea-rmm-overlay-rk050hr345-ct106a.dtbo + dtb-$(CONFIG_ARCH_STM32) += \ stm32mp215f-dk.dtb \ stm32mp235f-dk.dtb \ + stm32mp23xx-dhcos-bb.dtb \ + stm32mp25xx-dhcos-bb.dtb \ + stm32mp255c-dhcos-dhsbc.dtb \ + stm32mp255c-dhcos-dhsbc-overlay-imx219-x10.dtb \ + stm32mp255c-dhcos-dhsbc-overlay-imx219-x10.dtbo \ + stm32mp257d-engicam-microgea-rmm.dtb \ + stm32mp257d-engicam-microgea-rmm-overlay-am-1280800w8tzqw-t00h.dtb \ + stm32mp257d-engicam-microgea-rmm-overlay-am-1280800w8tzqw-t00h.dtbo \ + stm32mp257d-engicam-microgea-rmm-overlay-rk050hr345-ct106a.dtb \ + stm32mp257d-engicam-microgea-rmm-overlay-rk050hr345-ct106a.dtbo \ stm32mp257f-dk.dtb \ stm32mp257f-ev1.dtb
diff --git a/arch/arm64/boot/dts/st/stm32mp231.dtsi b/arch/arm64/boot/dts/st/stm32mp231.dtsi index 9e1d240..a60ae27 100644 --- a/arch/arm64/boot/dts/st/stm32mp231.dtsi +++ b/arch/arm64/boot/dts/st/stm32mp231.dtsi
@@ -35,7 +35,7 @@ arm-pmu { arm_wdt: watchdog { compatible = "arm,smc-wdt"; - arm,smc-id = <0xb200005a>; + arm,smc-id = <0xbc000000>; status = "disabled"; }; @@ -222,6 +222,60 @@ hpdma3: dma-controller@40420000 { #dma-cells = <3>; }; + ommanager: ommanager@40500000 { + compatible = "st,stm32mp25-omm"; + reg = <0x40500000 0x400>, <0x60000000 0x10000000>; + reg-names = "regs", "memory_map"; + ranges = <0 0 0x40430000 0x400>, + <1 0 0x40440000 0x400>; + clocks = <&rcc CK_BUS_OSPIIOM>, + <&scmi_clk CK_SCMI_OSPI1>, + <&scmi_clk CK_SCMI_OSPI2>; + clock-names = "omm", "ospi1", "ospi2"; + resets = <&rcc OSPIIOM_R>, + <&scmi_reset RST_SCMI_OSPI1>, + <&scmi_reset RST_SCMI_OSPI2>; + reset-names = "omm", "ospi1", "ospi2"; + access-controllers = <&rifsc 111>; + power-domains = <&cluster_pd>; + #address-cells = <2>; + #size-cells = <1>; + st,syscfg-amcr = <&syscfg 0x2c00 0x7>; + status = "disabled"; + + ospi1: spi@0 { + compatible = "st,stm32mp25-ospi"; + reg = <0 0 0x400>; + interrupts = <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&hpdma 2 0x62 0x3121>, + <&hpdma 2 0x42 0x3112>; + dma-names = "tx", "rx"; + clocks = <&scmi_clk CK_SCMI_OSPI1>; + resets = <&scmi_reset RST_SCMI_OSPI1>, + <&scmi_reset RST_SCMI_OSPI1DLL>; + access-controllers = <&rifsc 74>; + power-domains = <&cluster_pd>; + st,syscfg-dlyb = <&syscfg 0x1000>; + status = "disabled"; + }; + + ospi2: spi@1 { + compatible = "st,stm32mp25-ospi"; + reg = <1 0 0x400>; + interrupts = <GIC_SPI 164 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&hpdma 3 0x62 0x3121>, + <&hpdma 3 0x42 0x3112>; + dma-names = "tx", "rx"; + clocks = <&scmi_clk CK_SCMI_OSPI2>; + resets = <&scmi_reset RST_SCMI_OSPI2>, + <&scmi_reset RST_SCMI_OSPI2DLL>; + access-controllers = <&rifsc 75>; + power-domains = <&cluster_pd>; + st,syscfg-dlyb = <&syscfg 0x1400>; + status = "disabled"; + }; + }; + rifsc: bus@42080000 { compatible = "st,stm32mp25-rifsc", "simple-bus"; reg = <0x42080000 0x1000>; @@ -577,7 +631,7 @@ sai3a: audio-controller@402b0004 { status = "disabled"; }; - sai3b: audio-controller@502b0024 { + sai3b: audio-controller@402b0024 { compatible = "st,stm32-sai-sub-b"; reg = <0x24 0x20>; #sound-dai-cells = <0>; @@ -646,6 +700,20 @@ uart7: serial@40370000 { status = "disabled"; }; + dcmi: dcmi@404a0000 { + compatible = "st,stm32-dcmi"; + reg = <0x404a0000 0x400>; + interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>; + resets = <&rcc CCI_R>; + clocks = <&rcc CK_BUS_CCI>; + clock-names = "mclk"; + dmas = <&hpdma 137 0x60 0x00003012>; + dma-names = "tx"; + access-controllers = <&rifsc 88>; + power-domains = <&cluster_pd>; + status = "disabled"; + }; + rng: rng@42020000 { compatible = "st,stm32mp25-rng"; reg = <0x42020000 0x400>; @@ -720,13 +788,44 @@ sdmmc1: mmc@48220000 { reg = <0x48220000 0x400>, <0x44230400 0x8>; arm,primecell-periphid = <0x00353180>; interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&rcc CK_KER_SDMMC1 >; + clocks = <&rcc CK_KER_SDMMC1>; clock-names = "apb_pclk"; resets = <&rcc SDMMC1_R>; cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <120000000>; access-controllers = <&rifsc 76>; + power-domains = <&cluster_pd>; + status = "disabled"; + }; + + sdmmc2: mmc@48230000 { + compatible = "st,stm32mp25-sdmmc2", "arm,pl18x", "arm,primecell"; + arm,primecell-periphid = <0x00353180>; + reg = <0x48230000 0x400>, <0x44230800 0x8>; + interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc CK_KER_SDMMC2>; + clock-names = "apb_pclk"; + resets = <&rcc SDMMC2_R>; + cap-sd-highspeed; + cap-mmc-highspeed; + max-frequency = <166000000>; + access-controllers = <&rifsc 77>; + status = "disabled"; + }; + + sdmmc3: mmc@48240000 { + compatible = "st,stm32mp25-sdmmc2", "arm,pl18x", "arm,primecell"; + arm,primecell-periphid = <0x00353180>; + reg = <0x48240000 0x400>, <0x44230c00 0x8>; + interrupts = <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc CK_KER_SDMMC3>; + clock-names = "apb_pclk"; + resets = <&rcc SDMMC3_R>; + cap-sd-highspeed; + cap-mmc-highspeed; + max-frequency = <166000000>; + access-controllers = <&rifsc 78>; status = "disabled"; };
diff --git a/arch/arm64/boot/dts/st/stm32mp235f-dk.dts b/arch/arm64/boot/dts/st/stm32mp235f-dk.dts index dd4efbe..f06b334 100644 --- a/arch/arm64/boot/dts/st/stm32mp235f-dk.dts +++ b/arch/arm64/boot/dts/st/stm32mp235f-dk.dts
@@ -9,6 +9,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> #include <dt-bindings/leds/common.h> +#include <dt-bindings/media/video-interfaces.h> #include "stm32mp235.dtsi" #include "stm32mp23xf.dtsi" #include "stm32mp25-pinctrl.dtsi" @@ -27,6 +28,14 @@ chosen { stdout-path = "serial0:115200n8"; }; + clocks { + clk_ext_camera: clk-ext-camera { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <24000000>; + }; + }; + gpio-keys { compatible = "gpio-keys"; @@ -131,6 +140,42 @@ &arm_wdt { status = "okay"; }; +&csi { + vdd-supply = <&scmi_vddcore>; + vdda18-supply = <&scmi_v1v8>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + csi_sink: endpoint { + remote-endpoint = <&imx335_ep>; + data-lanes = <1 2>; + bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>; + }; + }; + port@1 { + reg = <1>; + csi_source: endpoint { + remote-endpoint = <&dcmipp_0>; + }; + }; + }; +}; + +&dcmipp { + status = "okay"; + + port { + dcmipp_0: endpoint { + remote-endpoint = <&csi_source>; + bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>; + }; + }; +}; + ðernet1 { pinctrl-0 = <ð1_rgmii_pins_b>; pinctrl-1 = <ð1_rgmii_sleep_pins_b>; @@ -153,6 +198,16 @@ phy1_eth1: ethernet-phy@1 { }; }; +&gpiob { + /* Enable the IMX335 power line */ + imx335-en-hog { + gpio-hog; + gpios = <11 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "imx335_en"; + }; +}; + &i2c2 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&i2c2_pins_b>; @@ -165,6 +220,26 @@ &i2c2 { /delete-property/dmas; /delete-property/dma-names; + imx335: camera@1a { + compatible = "sony,imx335"; + reg = <0x1a>; + clocks = <&clk_ext_camera>; + avdd-supply = <&scmi_v3v3>; + ovdd-supply = <&scmi_v3v3>; + dvdd-supply = <&scmi_v3v3>; + reset-gpios = <&gpiob 1 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>; + status = "okay"; + + port { + imx335_ep: endpoint { + remote-endpoint = <&csi_sink>; + clock-lanes = <0>; + data-lanes = <1 2>; + link-frequencies = /bits/ 64 <594000000>; + }; + }; + }; + ili2511: ili2511@41 { compatible = "ilitek,ili251x"; reg = <0x41>;
diff --git a/arch/arm64/boot/dts/st/stm32mp23xc.dtsi b/arch/arm64/boot/dts/st/stm32mp23xc.dtsi new file mode 100644 index 0000000..56872fb --- /dev/null +++ b/arch/arm64/boot/dts/st/stm32mp23xc.dtsi
@@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause) +/* + * Copyright (C) 2026 Marek Vasut <marex@nabladev.com> + */ + +/ { +};
diff --git a/arch/arm64/boot/dts/st/stm32mp23xx-dhcos-bb.dts b/arch/arm64/boot/dts/st/stm32mp23xx-dhcos-bb.dts new file mode 100644 index 0000000..125c76f --- /dev/null +++ b/arch/arm64/boot/dts/st/stm32mp23xx-dhcos-bb.dts
@@ -0,0 +1,15 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause) +/* + * Copyright (C) 2026 Marek Vasut <marex@nabladev.com> + */ + +/dts-v1/; + +#include "stm32mp235.dtsi" +#include "stm32mp23xc.dtsi" +#include "stm32mp23xx-dhcos-som.dtsi" + +/ { + model = "DH electronics STM32MP23xx DHCOS Breakout Board"; + compatible = "dh,stm32mp231a-dhcos-bb", "dh,stm32mp231a-dhcos-som", "st,stm32mp231"; +};
diff --git a/arch/arm64/boot/dts/st/stm32mp23xx-dhcos-som.dtsi b/arch/arm64/boot/dts/st/stm32mp23xx-dhcos-som.dtsi new file mode 100644 index 0000000..ffdcceb --- /dev/null +++ b/arch/arm64/boot/dts/st/stm32mp23xx-dhcos-som.dtsi
@@ -0,0 +1,51 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +/* + * Copyright (C) 2025-2026 Marek Vasut <marex@nabladev.com> + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> +#include "stm32mp25-pinctrl.dtsi" +#include "stm32mp25xxak-pinctrl.dtsi" +#include "stm32mp2xxx-dhcos-som.dtsi" + +/ { + model = "DH electronics STM32MP23xx DHCOS SoM"; + compatible = "dh,stm32mp231a-dhcos-som", "st,stm32mp231"; + + aliases { + serial1 = &usart1; + serial2 = &usart2; + }; +}; + +&rv3032 { + interrupts-extended = <&gpiod 10 IRQ_TYPE_EDGE_FALLING>; +}; + +/* Bluetooth */ +&usart1 { + pinctrl-names = "default", "sleep", "idle"; + pinctrl-0 = <&usart1_pins_a>; + pinctrl-1 = <&usart1_sleep_pins_a>; + pinctrl-2 = <&usart1_idle_pins_a>; + uart-has-rtscts; + status = "okay"; + + bluetooth { + compatible = "infineon,cyw55572-bt"; + brcm,requires-autobaud-mode; + max-speed = <3000000>; + shutdown-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>; + }; +}; + +&usart2 { + pinctrl-names = "default", "sleep", "idle"; + pinctrl-0 = <&usart2_pins_b>; + pinctrl-1 = <&usart2_sleep_pins_b>; + pinctrl-2 = <&usart2_idle_pins_b>; + uart-has-rtscts; + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi b/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi index 456ece7..56c2c99 100644 --- a/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi +++ b/arch/arm64/boot/dts/st/stm32mp25-pinctrl.dtsi
@@ -95,6 +95,7 @@ pins1 { bias-disable; drive-push-pull; slew-rate = <3>; + st,io-sync = "data on both edges"; }; pins2 { pinmux = <STM32_PINMUX('H', 9, AF10)>, /* ETH_RGMII_CLK125 */ @@ -112,6 +113,7 @@ pins3 { <STM32_PINMUX('H', 13, AF10)>, /* ETH_RGMII_RXD3 */ <STM32_PINMUX('A', 11, AF10)>; /* ETH_RGMII_RX_CTL */ bias-disable; + st,io-sync = "data on both edges"; }; pins4 { pinmux = <STM32_PINMUX('A', 14, AF10)>; /* ETH_RGMII_RX_CLK */ @@ -183,6 +185,30 @@ pins5 { }; /omit-if-no-ref/ + eth2_mdio_pins_a: eth2-mdio-0 { + pins1 { + pinmux = <STM32_PINMUX('G', 4, AF11)>; /* ETH_MDC */ + bias-disable; + drive-push-pull; + slew-rate = <3>; + }; + pins2 { + pinmux = <STM32_PINMUX('C', 5, AF10)>; /* ETH_MDIO */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + }; + + /omit-if-no-ref/ + eth2_mdio_sleep_pins_a: eth2-mdio-sleep-0 { + pins { + pinmux = <STM32_PINMUX('G', 4, ANALOG)>, /* ETH_MDC */ + <STM32_PINMUX('C', 5, ANALOG)>; /* ETH_MDIO */ + }; + }; + + /omit-if-no-ref/ eth2_rgmii_sleep_pins_a: eth2-rgmii-sleep-0 { pins { pinmux = <STM32_PINMUX('C', 7, ANALOG)>, /* ETH_RGMII_TXD0 */ @@ -204,6 +230,79 @@ pins { }; /omit-if-no-ref/ + eth2_rgmii_pins_b: eth2-rgmii-1 { + pins1 { + pinmux = <STM32_PINMUX('C', 7, AF10)>, /* ETH_RGMII_TXD0 */ + <STM32_PINMUX('C', 8, AF10)>, /* ETH_RGMII_TXD1 */ + <STM32_PINMUX('C', 9, AF10)>, /* ETH_RGMII_TXD2 */ + <STM32_PINMUX('C', 10, AF10)>, /* ETH_RGMII_TXD3 */ + <STM32_PINMUX('C', 4, AF10)>; /* ETH_RGMII_TX_CTL */ + bias-disable; + drive-push-pull; + slew-rate = <3>; + st,io-sync = "data on both edges"; + }; + pins2 { + pinmux = <STM32_PINMUX('F', 8, AF10)>, /* ETH_RGMII_CLK125 */ + <STM32_PINMUX('F', 7, AF10)>; /* ETH_RGMII_GTX_CLK */ + bias-disable; + drive-push-pull; + slew-rate = <3>; + }; + pins3 { + pinmux = <STM32_PINMUX('G', 0, AF10)>, /* ETH_RGMII_RXD0 */ + <STM32_PINMUX('C', 12, AF10)>, /* ETH_RGMII_RXD1 */ + <STM32_PINMUX('F', 9, AF10)>, /* ETH_RGMII_RXD2 */ + <STM32_PINMUX('C', 11, AF10)>, /* ETH_RGMII_RXD3 */ + <STM32_PINMUX('C', 3, AF10)>; /* ETH_RGMII_RX_CTL */ + bias-disable; + st,io-sync = "data on both edges"; + }; + pins4 { + pinmux = <STM32_PINMUX('F', 6, AF10)>; /* ETH_RGMII_RX_CLK */ + bias-disable; + }; + }; + + /omit-if-no-ref/ + eth2_rgmii_sleep_pins_b: eth2-rgmii-sleep-1 { + pins { + pinmux = <STM32_PINMUX('C', 7, ANALOG)>, /* ETH_RGMII_TXD0 */ + <STM32_PINMUX('C', 8, ANALOG)>, /* ETH_RGMII_TXD1 */ + <STM32_PINMUX('C', 9, ANALOG)>, /* ETH_RGMII_TXD2 */ + <STM32_PINMUX('C', 10, ANALOG)>, /* ETH_RGMII_TXD3 */ + <STM32_PINMUX('C', 4, ANALOG)>, /* ETH_RGMII_TX_CTL */ + <STM32_PINMUX('F', 8, ANALOG)>, /* ETH_RGMII_CLK125 */ + <STM32_PINMUX('F', 7, ANALOG)>, /* ETH_RGMII_GTX_CLK */ + <STM32_PINMUX('G', 0, ANALOG)>, /* ETH_RGMII_RXD0 */ + <STM32_PINMUX('C', 12, ANALOG)>, /* ETH_RGMII_RXD1 */ + <STM32_PINMUX('F', 9, ANALOG)>, /* ETH_RGMII_RXD2 */ + <STM32_PINMUX('C', 11, ANALOG)>, /* ETH_RGMII_RXD3 */ + <STM32_PINMUX('C', 3, ANALOG)>, /* ETH_RGMII_RX_CTL */ + <STM32_PINMUX('F', 6, ANALOG)>; /* ETH_RGMII_RX_CLK */ + }; + }; + + /omit-if-no-ref/ + i2c1_pins_a: i2c1-0 { + pins { + pinmux = <STM32_PINMUX('G', 13, AF9)>, /* I2C1_SCL */ + <STM32_PINMUX('A', 2, AF10)>; /* I2C1_SDA */ + bias-disable; + drive-open-drain; + slew-rate = <0>; + }; + }; + + /omit-if-no-ref/ + i2c1_sleep_pins_a: i2c1-sleep-0 { + pins { + pinmux = <STM32_PINMUX('G', 13, ANALOG)>, /* I2C1_SCL */ + <STM32_PINMUX('A', 2, ANALOG)>; /* I2C1_SDA */ + }; + }; + + /omit-if-no-ref/ i2c2_pins_a: i2c2-0 { pins { pinmux = <STM32_PINMUX('B', 5, AF9)>, /* I2C2_SCL */ @@ -242,6 +341,109 @@ pins { }; /omit-if-no-ref/ + ltdc_pins_a: ltdc-0 { + pins { + pinmux = <STM32_PINMUX('C', 6, AF14)>, /* LCD_CLK */ + <STM32_PINMUX('G', 2, AF13)>, /* LCD_HSYNC */ + <STM32_PINMUX('G', 1, AF13)>, /* LCD_VSYNC */ + <STM32_PINMUX('C', 5, AF14)>, /* LCD_DE */ + <STM32_PINMUX('H', 4, AF10)>, /* LCD_R0 */ + <STM32_PINMUX('F', 7, AF13)>, /* LCD_R1 */ + <STM32_PINMUX('C', 11, AF13)>, /* LCD_R2 */ + <STM32_PINMUX('A', 1, AF11)>, /* LCD_R3 */ + <STM32_PINMUX('B', 15, AF13)>, /* LCD_R4 */ + <STM32_PINMUX('G', 3, AF13)>, /* LCD_R5 */ + <STM32_PINMUX('A', 10, AF12)>, /* LCD_R6 */ + <STM32_PINMUX('G', 7, AF13)>, /* LCD_R7 */ + <STM32_PINMUX('F', 8, AF13)>, /* LCD_G0 */ + <STM32_PINMUX('H', 5, AF10)>, /* LCD_G1 */ + <STM32_PINMUX('C', 9, AF13)>, /* LCD_G2 */ + <STM32_PINMUX('C', 10, AF13)>, /* LCD_G3 */ + <STM32_PINMUX('A', 6, AF10)>, /* LCD_G4 */ + <STM32_PINMUX('G', 11, AF13)>, /* LCD_G5 */ + <STM32_PINMUX('G', 12, AF13)>, /* LCD_G6 */ + <STM32_PINMUX('A', 9, AF12)>, /* LCD_G7 */ + <STM32_PINMUX('F', 6, AF13)>, /* LCD_B0 */ + <STM32_PINMUX('A', 3, AF11)>, /* LCD_B1 */ + <STM32_PINMUX('G', 15, AF13)>, /* LCD_B2 */ + <STM32_PINMUX('I', 0, AF13)>, /* LCD_B3 */ + <STM32_PINMUX('I', 1, AF13)>, /* LCD_B4 */ + <STM32_PINMUX('A', 7, AF10)>, /* LCD_B5 */ + <STM32_PINMUX('F', 5, AF13)>, /* LCD_B6 */ + <STM32_PINMUX('I', 4, AF13)>; /* LCD_B7 */ + bias-disable; + drive-push-pull; + slew-rate = <1>; + }; + }; + + /omit-if-no-ref/ + ltdc_sleep_pins_a: ltdc-sleep-0 { + pins { + pinmux = <STM32_PINMUX('C', 6, ANALOG)>, /* LCD_CLK */ + <STM32_PINMUX('G', 2, ANALOG)>, /* LCD_HSYNC */ + <STM32_PINMUX('G', 1, ANALOG)>, /* LCD_VSYNC */ + <STM32_PINMUX('C', 5, ANALOG)>, /* LCD_DE */ + <STM32_PINMUX('H', 4, ANALOG)>, /* LCD_R0 */ + <STM32_PINMUX('F', 7, ANALOG)>, /* LCD_R1 */ + <STM32_PINMUX('C', 11, ANALOG)>, /* LCD_R2 */ + <STM32_PINMUX('A', 1, ANALOG)>, /* LCD_R3 */ + <STM32_PINMUX('B', 15, ANALOG)>, /* LCD_R4 */ + <STM32_PINMUX('G', 3, ANALOG)>, /* LCD_R5 */ + <STM32_PINMUX('A', 10, ANALOG)>, /* LCD_R6 */ + <STM32_PINMUX('G', 7, ANALOG)>, /* LCD_R7 */ + <STM32_PINMUX('F', 8, ANALOG)>, /* LCD_G0 */ + <STM32_PINMUX('H', 5, ANALOG)>, /* LCD_G1 */ + <STM32_PINMUX('C', 9, ANALOG)>, /* LCD_G2 */ + <STM32_PINMUX('C', 10, ANALOG)>, /* LCD_G3 */ + <STM32_PINMUX('A', 6, ANALOG)>, /* LCD_G4 */ + <STM32_PINMUX('G', 11, ANALOG)>, /* LCD_G5 */ + <STM32_PINMUX('G', 12, ANALOG)>, /* LCD_G6 */ + <STM32_PINMUX('A', 9, ANALOG)>, /* LCD_G7 */ + <STM32_PINMUX('F', 6, ANALOG)>, /* LCD_B0 */ + <STM32_PINMUX('A', 3, ANALOG)>, /* LCD_B1 */ + <STM32_PINMUX('G', 15, ANALOG)>, /* LCD_B2 */ + <STM32_PINMUX('I', 0, ANALOG)>, /* LCD_B3 */ + <STM32_PINMUX('I', 1, ANALOG)>, /* LCD_B4 */ + <STM32_PINMUX('A', 7, ANALOG)>, /* LCD_B5 */ + <STM32_PINMUX('F', 5, ANALOG)>, /* LCD_B6 */ + <STM32_PINMUX('I', 4, ANALOG)>; /* LCD_B7 */ + }; + }; + + /omit-if-no-ref/ + m_can1_pins_a: m-can1-0 { + pins1 { + pinmux = <STM32_PINMUX('B', 9, AF7)>; /* CAN1_TX */ + slew-rate = <1>; + drive-push-pull; + bias-disable; + }; + pins2 { + pinmux = <STM32_PINMUX('B', 11, AF7)>; /* CAN1_RX */ + bias-disable; + }; + }; + + /omit-if-no-ref/ + m_can1_sleep_pins_a: m-can1-sleep-0 { + pins { + pinmux = <STM32_PINMUX('B', 9, ANALOG)>, /* CAN1_TX */ + <STM32_PINMUX('B', 11, ANALOG)>; /* CAN1_RX */ + }; + }; + + /omit-if-no-ref/ + mco1_pins_a: mco1-0 { + pins { + pinmux = <STM32_PINMUX('I', 6, AF1)>; /* MCO1 */ + bias-disable; + drive-push-pull; + slew-rate = <2>; + }; + }; + + /omit-if-no-ref/ ospi_port1_clk_pins_a: ospi-port1-clk-0 { pins { pinmux = <STM32_PINMUX('D', 0, AF10)>; /* OSPI1_CLK */ @@ -322,6 +524,23 @@ pins { }; /omit-if-no-ref/ + pwm2_pins_a: pwm2-0 { + pins { + pinmux = <STM32_PINMUX('I', 7, AF7)>; /* TIM2_CH1 */ + bias-pull-down; + drive-push-pull; + slew-rate = <0>; + }; + }; + + /omit-if-no-ref/ + pwm2_sleep_pins_a: pwm2-sleep-0 { + pins { + pinmux = <STM32_PINMUX('I', 7, ANALOG)>; /* TIM2_CH1 */ + }; + }; + + /omit-if-no-ref/ pwm3_pins_a: pwm3-0 { pins { pinmux = <STM32_PINMUX('B', 15, AF7)>; /* TIM3_CH2 */ @@ -339,6 +558,23 @@ pins { }; /omit-if-no-ref/ + pwm4_pins_a: pwm4-0 { + pins { + pinmux = <STM32_PINMUX('A', 12, AF7)>; /* TIM4_CH1 */ + bias-pull-down; + drive-push-pull; + slew-rate = <0>; + }; + }; + + /omit-if-no-ref/ + pwm4_sleep_pins_a: pwm4-sleep-0 { + pins { + pinmux = <STM32_PINMUX('A', 12, ANALOG)>; /* TIM4_CH1 */ + }; + }; + + /omit-if-no-ref/ pwm8_pins_a: pwm8-0 { pins { pinmux = <STM32_PINMUX('J', 5, AF8)>, /* TIM8_CH1 */ @@ -375,6 +611,51 @@ pins { }; /omit-if-no-ref/ + sai1a_pins_a: sai1a-0 { + pins1 { + pinmux = <STM32_PINMUX('D', 9, AF3)>, /* SAI1_SD_A */ + <STM32_PINMUX('D', 8, AF3)>, /* SAI1_FS_A */ + <STM32_PINMUX('D', 10, AF3)>; /* SAI1_SCK_A */ + bias-disable; + drive-push-pull; + slew-rate = <1>; + }; + pins2 { + pinmux = <STM32_PINMUX('D', 11, AF3)>; /* SAI1_MCLK_A */ + bias-disable; + drive-push-pull; + slew-rate = <2>; + }; + }; + + /omit-if-no-ref/ + sai1a_sleep_pins_a: sai1a-sleep-0 { + pins { + pinmux = <STM32_PINMUX('D', 9, ANALOG)>, /* SAI1_SD_A */ + <STM32_PINMUX('D', 8, ANALOG)>, /* SAI1_FS_A */ + <STM32_PINMUX('D', 10, ANALOG)>, /* SAI1_SCK_A */ + <STM32_PINMUX('D', 11, ANALOG)>; /* SAI1_MCLK_A */ + }; + }; + + /omit-if-no-ref/ + sai1b_pins_a: sai1b-0 { + pins { + pinmux = <STM32_PINMUX('D', 4, AF4)>; /* SAI1_SD_B */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + }; + + /omit-if-no-ref/ + sai1b_sleep_pins_a: sai1b-sleep-0 { + pins { + pinmux = <STM32_PINMUX('D', 4, ANALOG)>; /* SAI1_SD_B */ + }; + }; + + /omit-if-no-ref/ sdmmc1_b4_pins_a: sdmmc1-b4-0 { pins1 { pinmux = <STM32_PINMUX('E', 4, AF10)>, /* SDMMC1_D0 */ @@ -432,6 +713,269 @@ pins { }; /omit-if-no-ref/ + sdmmc2_b4_pins_a: sdmmc2-b4-0 { + pins1 { + pinmux = <STM32_PINMUX('E', 13, AF12)>, /* SDMMC2_D0 */ + <STM32_PINMUX('E', 11, AF12)>, /* SDMMC2_D1 */ + <STM32_PINMUX('E', 8, AF12)>, /* SDMMC2_D2 */ + <STM32_PINMUX('E', 12, AF12)>, /* SDMMC2_D3 */ + <STM32_PINMUX('E', 15, AF12)>; /* SDMMC2_CMD */ + slew-rate = <1>; + drive-push-pull; + bias-pull-up; + }; + pins2 { + pinmux = <STM32_PINMUX('E', 14, AF12)>; /* SDMMC2_CK */ + slew-rate = <2>; + drive-push-pull; + bias-disable; + }; + }; + + /omit-if-no-ref/ + sdmmc2_b4_od_pins_a: sdmmc2-b4-od-0 { + pins1 { + pinmux = <STM32_PINMUX('E', 13, AF12)>, /* SDMMC2_D0 */ + <STM32_PINMUX('E', 11, AF12)>, /* SDMMC2_D1 */ + <STM32_PINMUX('E', 8, AF12)>, /* SDMMC2_D2 */ + <STM32_PINMUX('E', 12, AF12)>; /* SDMMC2_D3 */ + slew-rate = <1>; + drive-push-pull; + bias-pull-up; + }; + pins2 { + pinmux = <STM32_PINMUX('E', 14, AF12)>; /* SDMMC2_CK */ + slew-rate = <2>; + drive-push-pull; + bias-disable; + }; + pins3 { + pinmux = <STM32_PINMUX('E', 15, AF12)>; /* SDMMC2_CMD */ + slew-rate = <1>; + drive-open-drain; + bias-pull-up; + }; + }; + + /omit-if-no-ref/ + sdmmc2_b4_pins_b: sdmmc2-b4-1 { + pins1 { + pinmux = <STM32_PINMUX('E', 13, AF12)>, /* SDMMC2_D0 */ + <STM32_PINMUX('E', 11, AF12)>, /* SDMMC2_D1 */ + <STM32_PINMUX('E', 8, AF12)>, /* SDMMC2_D2 */ + <STM32_PINMUX('E', 12, AF12)>, /* SDMMC2_D3 */ + <STM32_PINMUX('E', 15, AF12)>; /* SDMMC2_CMD */ + slew-rate = <2>; + drive-push-pull; + bias-pull-up; + }; + pins2 { + pinmux = <STM32_PINMUX('E', 14, AF12)>; /* SDMMC2_CK */ + slew-rate = <3>; + drive-push-pull; + bias-disable; + }; + }; + + /omit-if-no-ref/ + sdmmc2_b4_od_pins_b: sdmmc2-b4-od-1 { + pins1 { + pinmux = <STM32_PINMUX('E', 13, AF12)>, /* SDMMC2_D0 */ + <STM32_PINMUX('E', 11, AF12)>, /* SDMMC2_D1 */ + <STM32_PINMUX('E', 8, AF12)>, /* SDMMC2_D2 */ + <STM32_PINMUX('E', 12, AF12)>; /* SDMMC2_D3 */ + slew-rate = <2>; + drive-push-pull; + bias-pull-up; + }; + pins2 { + pinmux = <STM32_PINMUX('E', 14, AF12)>; /* SDMMC2_CK */ + slew-rate = <3>; + drive-push-pull; + bias-disable; + }; + pins3 { + pinmux = <STM32_PINMUX('E', 15, AF12)>; /* SDMMC2_CMD */ + slew-rate = <2>; + drive-open-drain; + bias-pull-up; + }; + }; + + /omit-if-no-ref/ + sdmmc2_d47_pins_a: sdmmc2-d47-0 { + pins { + pinmux = <STM32_PINMUX('E', 10, AF12)>, /* SDMMC2_D4 */ + <STM32_PINMUX('E', 9, AF12)>, /* SDMMC2_D5 */ + <STM32_PINMUX('E', 6, AF12)>, /* SDMMC2_D6 */ + <STM32_PINMUX('E', 7, AF12)>; /* SDMMC2_D7 */ + slew-rate = <1>; + drive-push-pull; + bias-pull-up; + }; + }; + + /omit-if-no-ref/ + sdmmc2_b4_sleep_pins_a: sdmmc2-b4-sleep-0 { + pins { + pinmux = <STM32_PINMUX('E', 13, ANALOG)>, /* SDMMC2_D0 */ + <STM32_PINMUX('E', 11, ANALOG)>, /* SDMMC2_D1 */ + <STM32_PINMUX('E', 8, ANALOG)>, /* SDMMC2_D2 */ + <STM32_PINMUX('E', 12, ANALOG)>, /* SDMMC2_D3 */ + <STM32_PINMUX('E', 14, ANALOG)>, /* SDMMC2_CK */ + <STM32_PINMUX('E', 15, ANALOG)>; /* SDMMC2_CMD */ + }; + }; + + /omit-if-no-ref/ + sdmmc2_d47_sleep_pins_a: sdmmc2-d47-sleep-0 { + pins { + pinmux = <STM32_PINMUX('E', 10, ANALOG)>, /* SDMMC2_D4 */ + <STM32_PINMUX('E', 9, ANALOG)>, /* SDMMC2_D5 */ + <STM32_PINMUX('E', 6, ANALOG)>, /* SDMMC2_D6 */ + <STM32_PINMUX('E', 7, ANALOG)>; /* SDMMC2_D7 */ + }; + }; + + /omit-if-no-ref/ + sdmmc3_b4_pins_a: sdmmc3-b4-0 { + pins1 { + pinmux = <STM32_PINMUX('B', 14, AF10)>, /* SDMMC3_D0 */ + <STM32_PINMUX('D', 13, AF10)>, /* SDMMC3_D1 */ + <STM32_PINMUX('B', 12, AF10)>, /* SDMMC3_D2 */ + <STM32_PINMUX('I', 11, AF10)>, /* SDMMC3_D3 */ + <STM32_PINMUX('D', 12, AF10)>; /* SDMMC3_CMD */ + slew-rate = <0>; + drive-push-pull; + bias-pull-up; + }; + pins2 { + pinmux = <STM32_PINMUX('B', 13, AF10)>; /* SDMMC3_CK */ + slew-rate = <1>; + drive-push-pull; + bias-pull-up; + }; + }; + + /omit-if-no-ref/ + sdmmc3_b4_pins_b: sdmmc3-b4-1 { + pins1 { + pinmux = <STM32_PINMUX('B', 14, AF10)>, /* SDMMC3_D0 */ + <STM32_PINMUX('D', 13, AF10)>, /* SDMMC3_D1 */ + <STM32_PINMUX('B', 12, AF10)>, /* SDMMC3_D2 */ + <STM32_PINMUX('D', 14, AF12)>, /* SDMMC3_D3 */ + <STM32_PINMUX('D', 12, AF10)>; /* SDMMC3_CMD */ + slew-rate = <0>; + drive-push-pull; + bias-pull-up; + }; + pins2 { + pinmux = <STM32_PINMUX('B', 13, AF10)>; /* SDMMC3_CK */ + slew-rate = <1>; + drive-push-pull; + bias-pull-up; + }; + }; + + /omit-if-no-ref/ + sdmmc3_b4_od_pins_b: sdmmc3-b4-od-1 { + pins1 { + pinmux = <STM32_PINMUX('B', 14, AF10)>, /* SDMMC3_D0 */ + <STM32_PINMUX('D', 13, AF10)>, /* SDMMC3_D1 */ + <STM32_PINMUX('B', 12, AF10)>, /* SDMMC3_D2 */ + <STM32_PINMUX('D', 14, AF10)>; /* SDMMC3_D3 */ + slew-rate = <2>; + drive-push-pull; + bias-disable; + }; + pins2 { + pinmux = <STM32_PINMUX('B', 13, AF10)>; /* SDMMC3_CK */ + slew-rate = <3>; + drive-push-pull; + bias-disable; + }; + pins3 { + pinmux = <STM32_PINMUX('D', 12, AF10)>; /* SDMMC3_CMD */ + slew-rate = <2>; + drive-open-drain; + bias-disable; + }; + }; + + /omit-if-no-ref/ + sdmmc3_b4_sleep_pins_b: sdmmc3-b4-sleep-1 { + pins { + pinmux = <STM32_PINMUX('B', 14, ANALOG)>, /* SDMMC3_D0 */ + <STM32_PINMUX('D', 13, ANALOG)>, /* SDMMC3_D1 */ + <STM32_PINMUX('B', 12, ANALOG)>, /* SDMMC3_D2 */ + <STM32_PINMUX('D', 14, ANALOG)>, /* SDMMC3_D3 */ + <STM32_PINMUX('B', 13, ANALOG)>, /* SDMMC3_CK */ + <STM32_PINMUX('D', 12, ANALOG)>; /* SDMMC3_CMD */ + }; + }; + + /omit-if-no-ref/ + sdmmc2_d47_pins_b: sdmmc2-d47-1 { + pins { + pinmux = <STM32_PINMUX('E', 10, AF12)>, /* SDMMC2_D4 */ + <STM32_PINMUX('E', 9, AF12)>, /* SDMMC2_D5 */ + <STM32_PINMUX('E', 6, AF12)>, /* SDMMC2_D6 */ + <STM32_PINMUX('E', 7, AF12)>; /* SDMMC2_D7 */ + slew-rate = <2>; + drive-push-pull; + bias-pull-up; + }; + }; + + /omit-if-no-ref/ + spi1_pins_a: spi1-0 { + pins1 { + pinmux = <STM32_PINMUX('G', 6, AF3)>, /* SPI1_SCK */ + <STM32_PINMUX('I', 5, AF3)>; /* SPI1_MOSI */ + drive-push-pull; + bias-disable; + slew-rate = <1>; + }; + pins2 { + pinmux = <STM32_PINMUX('F', 12, AF3)>; /* SPI1_MISO */ + bias-disable; + }; + }; + + /omit-if-no-ref/ + spi1_sleep_pins_a: spi1-sleep-0 { + pins1 { + pinmux = <STM32_PINMUX('G', 6, ANALOG)>, /* SPI1_SCK */ + <STM32_PINMUX('I', 5, ANALOG)>, /* SPI1_MOSI */ + <STM32_PINMUX('F', 12, ANALOG)>; /* SPI1_MISO */ + }; + }; + + /omit-if-no-ref/ + spi1_pins_b: spi1-1 { + pins1 { + pinmux = <STM32_PINMUX('G', 6, AF3)>, /* SPI1_SCK */ + <STM32_PINMUX('H', 7, AF2)>; /* SPI1_MOSI */ + drive-push-pull; + bias-disable; + slew-rate = <1>; + }; + pins2 { + pinmux = <STM32_PINMUX('H', 8, AF2)>; /* SPI1_MISO */ + bias-disable; + }; + }; + + /omit-if-no-ref/ + spi1_sleep_pins_b: spi1-sleep-1 { + pins1 { + pinmux = <STM32_PINMUX('G', 6, ANALOG)>, /* SPI1_SCK */ + <STM32_PINMUX('H', 7, ANALOG)>, /* SPI1_MOSI */ + <STM32_PINMUX('H', 8, ANALOG)>; /* SPI1_MISO */ + }; + }; + + /omit-if-no-ref/ spi3_pins_a: spi3-0 { pins1 { pinmux = <STM32_PINMUX('B', 7, AF1)>, /* SPI3_SCK */ @@ -472,6 +1016,83 @@ pins { }; /omit-if-no-ref/ + usart1_pins_b: usart1-1 { + pins1 { + pinmux = <STM32_PINMUX('B', 8, AF6)>; /* USART1_TX */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = <STM32_PINMUX('B', 10, AF6)>; /* USART1_RX */ + bias-disable; + }; + }; + + /omit-if-no-ref/ + usart1_idle_pins_b: usart1-idle-1 { + pins1 { + pinmux = <STM32_PINMUX('B', 8, ANALOG)>; /* USART1_TX */ + }; + pins2 { + pinmux = <STM32_PINMUX('B', 10, AF6)>; /* USART1_RX */ + bias-disable; + }; + }; + + /omit-if-no-ref/ + usart1_sleep_pins_b: usart1-sleep-1 { + pins { + pinmux = <STM32_PINMUX('B', 8, ANALOG)>, /* USART1_TX */ + <STM32_PINMUX('B', 10, ANALOG)>; /* USART1_RX */ + }; + }; + + /omit-if-no-ref/ + usart1_pins_a: usart1-0 { + pins1 { + pinmux = <STM32_PINMUX('A', 3, AF6)>, /* USART1_TX */ + <STM32_PINMUX('A', 1, AF5)>; /* USART1_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = <STM32_PINMUX('A', 2, AF6)>, /* USART1_RX */ + <STM32_PINMUX('A', 7, AF6)>; /* USART1_CTS_NSS */ + bias-pull-up; + }; + }; + + /omit-if-no-ref/ + usart1_idle_pins_a: usart1-idle-0 { + pins1 { + pinmux = <STM32_PINMUX('A', 3, ANALOG)>, /* USART1_TX */ + <STM32_PINMUX('A', 7, ANALOG)>; /* USART1_CTS_NSS */ + }; + pins2 { + pinmux = <STM32_PINMUX('A', 1, AF5)>; /* USART1_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins3 { + pinmux = <STM32_PINMUX('A', 2, AF6)>; /* USART1_RX */ + bias-pull-up; + }; + }; + + /omit-if-no-ref/ + usart1_sleep_pins_a: usart1-sleep-0 { + pins { + pinmux = <STM32_PINMUX('A', 3, ANALOG)>, /* USART1_TX */ + <STM32_PINMUX('A', 1, ANALOG)>, /* USART1_RTS */ + <STM32_PINMUX('A', 7, ANALOG)>, /* USART1_CTS_NSS */ + <STM32_PINMUX('A', 2, ANALOG)>; /* USART1_RX */ + }; + }; + + /omit-if-no-ref/ usart2_pins_a: usart2-0 { pins1 { pinmux = <STM32_PINMUX('A', 4, AF6)>; /* USART2_TX */ @@ -505,6 +1126,50 @@ pins { }; /omit-if-no-ref/ + usart2_pins_b: usart2-1 { + pins1 { + pinmux = <STM32_PINMUX('A', 4, AF6)>, /* USART2_TX */ + <STM32_PINMUX('A', 5, AF6)>; /* USART2_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = <STM32_PINMUX('A', 8, AF8)>, /* USART2_RX */ + <STM32_PINMUX('A', 9, AF6)>; /* USART2_CTS_NSS */ + bias-disable; + }; + }; + + /omit-if-no-ref/ + usart2_idle_pins_b: usart2-idle-1 { + pins1 { + pinmux = <STM32_PINMUX('A', 4, ANALOG)>, /* USART2_TX */ + <STM32_PINMUX('A', 9, ANALOG)>; /* USART2_CTS_NSS */ + }; + pins2 { + pinmux = <STM32_PINMUX('A', 5, AF6)>; /* USART2_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins3 { + pinmux = <STM32_PINMUX('A', 8, AF8)>; /* USART2_RX */ + bias-pull-up; + }; + }; + + /omit-if-no-ref/ + usart2_sleep_pins_b: usart2-sleep-1 { + pins { + pinmux = <STM32_PINMUX('A', 4, ANALOG)>, /* USART2_TX */ + <STM32_PINMUX('A', 5, ANALOG)>, /* USART2_RTS */ + <STM32_PINMUX('A', 9, ANALOG)>, /* USART2_CTS_NSS */ + <STM32_PINMUX('A', 8, ANALOG)>; /* USART2_RX */ + }; + }; + + /omit-if-no-ref/ usart6_pins_a: usart6-0 { pins1 { pinmux = <STM32_PINMUX('F', 13, AF3)>, /* USART6_TX */ @@ -547,6 +1212,127 @@ pins { <STM32_PINMUX('F', 14, ANALOG)>; /* USART6_RX */ }; }; + + /omit-if-no-ref/ + usart6_pins_b: usart6-1 { + pins1 { + pinmux = <STM32_PINMUX('F', 5, AF6)>; /* USART6_TX */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = <STM32_PINMUX('F', 4, AF6)>; /* USART6_RX */ + bias-disable; + }; + }; + + /omit-if-no-ref/ + usart6_idle_pins_b: usart6-idle-1 { + pins1 { + pinmux = <STM32_PINMUX('F', 5, ANALOG)>; /* USART6_TX */ + }; + pins2 { + pinmux = <STM32_PINMUX('F', 4, AF6)>; /* USART6_RX */ + bias-disable; + }; + }; + + /omit-if-no-ref/ + usart6_sleep_pins_b: usart6-sleep-1 { + pins { + pinmux = <STM32_PINMUX('F', 5, ANALOG)>, /* USART6_TX */ + <STM32_PINMUX('F', 4, ANALOG)>; /* USART6_RX */ + }; + }; + + /omit-if-no-ref/ + uart8_pins_a: uart8-0 { + pins1 { + pinmux = <STM32_PINMUX('I', 11, AF5)>, /* UART8_TX */ + <STM32_PINMUX('B', 15, AF3)>; /* UART8_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = <STM32_PINMUX('F', 11, AF6)>, /* UART8_RX */ + <STM32_PINMUX('H', 5, AF6)>; /* UART8_CTS_NSS */ + bias-pull-up; + }; + }; + + /omit-if-no-ref/ + uart8_idle_pins_a: uart8-idle-0 { + pins1 { + pinmux = <STM32_PINMUX('I', 11, ANALOG)>, /* UART8_TX */ + <STM32_PINMUX('H', 5, ANALOG)>; /* UART8_CTS_NSS */ + }; + pins2 { + pinmux = <STM32_PINMUX('B', 15, AF3)>; /* UART8_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins3 { + pinmux = <STM32_PINMUX('F', 11, AF6)>; /* UART8_RX */ + bias-pull-up; + }; + }; + + /omit-if-no-ref/ + uart8_sleep_pins_a: uart8-sleep-0 { + pins { + pinmux = <STM32_PINMUX('I', 11, ANALOG)>, /* UART8_TX */ + <STM32_PINMUX('B', 15, ANALOG)>, /* UART8_RTS */ + <STM32_PINMUX('H', 5, ANALOG)>, /* UART8_CTS_NSS */ + <STM32_PINMUX('F', 11, ANALOG)>; /* UART8_RX */ + }; + }; + + /omit-if-no-ref/ + uart9_pins_a: uart9-0 { + pins1 { + pinmux = <STM32_PINMUX('G', 8, AF6)>, /* UART9_TX */ + <STM32_PINMUX('F', 12, AF6)>; /* UART9_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins2 { + pinmux = <STM32_PINMUX('I', 5, AF6)>, /* UART9_RX */ + <STM32_PINMUX('G', 7, AF6)>; /* UART9_CTS_NSS */ + bias-pull-up; + }; + }; + + /omit-if-no-ref/ + uart9_idle_pins_a: uart9-idle-0 { + pins1 { + pinmux = <STM32_PINMUX('G', 8, ANALOG)>, /* UART9_TX */ + <STM32_PINMUX('G', 7, ANALOG)>; /* UART9_CTS_NSS */ + }; + pins2 { + pinmux = <STM32_PINMUX('F', 12, AF6)>; /* UART9_RTS */ + bias-disable; + drive-push-pull; + slew-rate = <0>; + }; + pins3 { + pinmux = <STM32_PINMUX('I', 5, AF6)>; /* UART9_RX */ + bias-pull-up; + }; + }; + + /omit-if-no-ref/ + uart9_sleep_pins_a: uart9-sleep-0 { + pins { + pinmux = <STM32_PINMUX('G', 8, ANALOG)>, /* UART9_TX */ + <STM32_PINMUX('F', 12, ANALOG)>, /* UART9_RTS */ + <STM32_PINMUX('G', 7, ANALOG)>, /* UART9_CTS_NSS */ + <STM32_PINMUX('I', 5, ANALOG)>; /* UART9_RX */ + }; + }; }; &pinctrl_z { @@ -570,6 +1356,25 @@ pins { }; /omit-if-no-ref/ + i2c8_pins_b: i2c8-1 { + pins { + pinmux = <STM32_PINMUX('Z', 4, AF8)>, /* I2C1_SCL */ + <STM32_PINMUX('Z', 9, AF8)>; /* I2C1_SDA */ + bias-disable; + drive-open-drain; + slew-rate = <0>; + }; + }; + + /omit-if-no-ref/ + i2c8_sleep_pins_b: i2c8-sleep-1 { + pins { + pinmux = <STM32_PINMUX('Z', 4, ANALOG)>, /* I2C1_SCL */ + <STM32_PINMUX('Z', 9, ANALOG)>; /* I2C1_SDA */ + }; + }; + + /omit-if-no-ref/ spi8_pins_a: spi8-0 { pins1 { pinmux = <STM32_PINMUX('Z', 2, AF3)>, /* SPI8_SCK */ @@ -592,4 +1397,28 @@ pins1 { <STM32_PINMUX('Z', 1, ANALOG)>; /* SPI8_MISO */ }; }; + + /omit-if-no-ref/ + spi8_pins_b: spi8-1 { + pins1 { + pinmux = <STM32_PINMUX('Z', 5, AF3)>, /* SPI8_SCK */ + <STM32_PINMUX('Z', 7, AF3)>; /* SPI8_MOSI */ + drive-push-pull; + bias-disable; + slew-rate = <1>; + }; + pins2 { + pinmux = <STM32_PINMUX('Z', 8, AF3)>; /* SPI8_MISO */ + bias-disable; + }; + }; + + /omit-if-no-ref/ + spi8_sleep_pins_b: spi8-sleep-1 { + pins1 { + pinmux = <STM32_PINMUX('Z', 5, ANALOG)>, /* SPI8_SCK */ + <STM32_PINMUX('Z', 7, ANALOG)>, /* SPI8_MOSI */ + <STM32_PINMUX('Z', 8, ANALOG)>; /* SPI8_MISO */ + }; + }; };
diff --git a/arch/arm64/boot/dts/st/stm32mp251.dtsi b/arch/arm64/boot/dts/st/stm32mp251.dtsi index 9c63fdb5..b624f99 100644 --- a/arch/arm64/boot/dts/st/stm32mp251.dtsi +++ b/arch/arm64/boot/dts/st/stm32mp251.dtsi
@@ -36,7 +36,7 @@ arm-pmu { arm_wdt: watchdog { compatible = "arm,smc-wdt"; - arm,smc-id = <0xb200005a>; + arm,smc-id = <0xbc000000>; status = "disabled"; }; @@ -1291,7 +1291,7 @@ sai3a: audio-controller@402b0004 { status = "disabled"; }; - sai3b: audio-controller@502b0024 { + sai3b: audio-controller@402b0024 { compatible = "st,stm32-sai-sub-b"; reg = <0x24 0x20>; #sound-dai-cells = <0>; @@ -1450,6 +1450,20 @@ uart8: serial@40380000 { status = "disabled"; }; + dcmi: dcmi@404a0000 { + compatible = "st,stm32-dcmi"; + reg = <0x404a0000 0x400>; + interrupts = <GIC_SPI 141 IRQ_TYPE_LEVEL_HIGH>; + resets = <&rcc CCI_R>; + clocks = <&rcc CK_BUS_CCI>; + clock-names = "mclk"; + dmas = <&hpdma 137 0x60 0x00003012>; + dma-names = "tx"; + access-controllers = <&rifsc 88>; + power-domains = <&CLUSTER_PD>; + status = "disabled"; + }; + rng: rng@42020000 { compatible = "st,stm32mp25-rng"; reg = <0x42020000 0x400>; @@ -1657,13 +1671,45 @@ sdmmc1: mmc@48220000 { arm,primecell-periphid = <0x00353180>; reg = <0x48220000 0x400>, <0x44230400 0x8>; interrupts = <GIC_SPI 123 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&rcc CK_KER_SDMMC1 >; + clocks = <&rcc CK_KER_SDMMC1>; clock-names = "apb_pclk"; resets = <&rcc SDMMC1_R>; cap-sd-highspeed; cap-mmc-highspeed; max-frequency = <120000000>; access-controllers = <&rifsc 76>; + power-domains = <&CLUSTER_PD>; + status = "disabled"; + }; + + sdmmc2: mmc@48230000 { + compatible = "st,stm32mp25-sdmmc2", "arm,pl18x", "arm,primecell"; + arm,primecell-periphid = <0x00353180>; + reg = <0x48230000 0x400>, <0x44230800 0x8>; + interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc CK_KER_SDMMC2>; + clock-names = "apb_pclk"; + resets = <&rcc SDMMC2_R>; + cap-sd-highspeed; + cap-mmc-highspeed; + max-frequency = <166000000>; + access-controllers = <&rifsc 77>; + power-domains = <&CLUSTER_PD>; + status = "disabled"; + }; + + sdmmc3: mmc@48240000 { + compatible = "st,stm32mp25-sdmmc2", "arm,pl18x", "arm,primecell"; + arm,primecell-periphid = <0x00353180>; + reg = <0x48240000 0x400>, <0x44230c00 0x8>; + interrupts = <GIC_SPI 214 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&rcc CK_KER_SDMMC3>; + clock-names = "apb_pclk"; + resets = <&rcc SDMMC3_R>; + cap-sd-highspeed; + cap-mmc-highspeed; + max-frequency = <166000000>; + access-controllers = <&rifsc 78>; status = "disabled"; }; @@ -1783,6 +1829,21 @@ package-otp@1e8 { }; }; + dts: thermal-sensor@44070000 { + compatible = "moortec,mr75203"; + reg = <0x44070000 0x80>, + <0x44070080 0xc0>, + <0x44070180 0x80>, + <0x44070400 0x400>; + reg-names = "common", "ts", "pd", "vm"; + clocks = <&rcc CK_KER_DTS>; + resets = <&rcc DTS_R>; + #thermal-sensor-cells = <1>; + moortec,ts-coeff-g = <58500>; + moortec,ts-coeff-h = <201200>; + moortec,ts-coeff-j = <0>; + }; + hdp: pinctrl@44090000 { compatible = "st,stm32mp251-hdp"; reg = <0x44090000 0x400>;
diff --git a/arch/arm64/boot/dts/st/stm32mp253.dtsi b/arch/arm64/boot/dts/st/stm32mp253.dtsi index eeceb08..7e82f01 100644 --- a/arch/arm64/boot/dts/st/stm32mp253.dtsi +++ b/arch/arm64/boot/dts/st/stm32mp253.dtsi
@@ -43,6 +43,22 @@ &optee { }; &rifsc { + m_can1: can@402d0000 { + compatible = "bosch,m_can"; + reg = <0x402d0000 0x400>, <0x40310000 0xd50>; + reg-names = "m_can", "message_ram"; + interrupts = <GIC_SPI 91 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "int0", "int1"; + clocks = <&rcc CK_BUS_FDCAN>, <&rcc CK_KER_FDCAN>; + clock-names = "hclk", "cclk"; + resets = <&rcc FDCAN_R>; + bosch,mram-cfg = <0x0 0 0 32 0 0 2 2>; + access-controllers = <&rifsc 56>; + power-domains = <&CLUSTER_PD>; + status = "disabled"; + }; + ethernet2: ethernet@482d0000 { compatible = "st,stm32mp25-dwmac", "snps,dwmac-5.20"; reg = <0x482d0000 0x4000>;
diff --git a/arch/arm64/boot/dts/st/stm32mp255c-dhcos-dhsbc-overlay-imx219-x10.dtso b/arch/arm64/boot/dts/st/stm32mp255c-dhcos-dhsbc-overlay-imx219-x10.dtso new file mode 100644 index 0000000..fbec84e --- /dev/null +++ b/arch/arm64/boot/dts/st/stm32mp255c-dhcos-dhsbc-overlay-imx219-x10.dtso
@@ -0,0 +1,111 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause) +/* + * Copyright (C) 2026 Marek Vasut <marex@nabladev.com> + * + * Set up pipeline for raw bayer capture: + * $ media-ctl -d platform:48030000.dcmipp -r + * $ media-ctl -d platform:48030000.dcmipp -l '"48020000.csi":1->"dcmipp_input":0[1]' + * $ media-ctl -d platform:48030000.dcmipp -l "'dcmipp_input':1->'dcmipp_dump_postproc':0[1]" + * $ media-ctl -d platform:48030000.dcmipp --set-v4l2 "'imx219 0-0010':0[fmt:SRGGB8_1X8/1920x1080]" + * $ media-ctl -d platform:48030000.dcmipp --set-v4l2 "'48020000.csi':1[fmt:SRGGB8_1X8/1920x1080]" + * $ media-ctl -d platform:48030000.dcmipp --set-v4l2 "'dcmipp_input':1[fmt:SRGGB8_1X8/1920x1080 field:none]" + * $ media-ctl -d platform:48030000.dcmipp --set-v4l2 "'dcmipp_dump_postproc':0[compose:(0,0)/1920x1080]" + * $ media-ctl -d platform:48030000.dcmipp --set-v4l2 "'dcmipp_dump_postproc':1[fmt:SRGGB8_1X8/1920x1080]" + * $ v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=RGGB + * + * Capture frame using v4l2-ctl: + * $ v4l2-ctl -d /dev/video0 --stream-mmap --stream-count=1 --stream-to=/frame.raw + * + * Capture frame using gstreamer: + * $ gst-launch-1.0 v4l2src device=/dev/video0 num-buffers=1 ! \ + * video/x-bayer,width=1920,height=1080,format=rggb ! \ + * bayer2rgb ! jpegenc ! filesink location=/test.jpg + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> + +&{/} { + clk_cam_x10: clk-cam-j1 { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + }; + + /* Page 29 / CSI_IF_CN / J1 */ + reg_cam_x10: reg-cam-j1 { + compatible = "regulator-fixed"; + regulator-name = "cam-X10"; + enable-active-high; + gpios = <&ioexp 13 GPIO_ACTIVE_HIGH>; + }; +}; + +&csi { + vdd-supply = <&scmi_vddcore>; + vdda18-supply = <&scmi_v1v8>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + csi_sink: endpoint { + remote-endpoint = <&imx219_x10_out>; + data-lanes = <1 2>; + bus-type = <4>; + }; + }; + port@1 { + reg = <1>; + + csi_source: endpoint { + remote-endpoint = <&dcmipp_0>; + }; + }; + }; +}; + +&dcmipp { + status = "okay"; + + port { + dcmipp_0: endpoint { + remote-endpoint = <&csi_source>; + bus-type = <4>; + }; + }; +}; + +&i2c2 { + #address-cells = <1>; + #size-cells = <0>; + + cam@10 { + compatible = "sony,imx219"; + reg = <0x10>; + + clocks = <&clk_cam_x10>; + + VANA-supply = <®_cam_x10>; + VDIG-supply = <®_cam_x10>; + VDDL-supply = <®_cam_x10>; + + orientation = <2>; + rotation = <0>; + + port { + imx219_x10_out: endpoint { + clock-noncontinuous; + link-frequencies = /bits/ 64 <456000000>; + data-lanes = <1 2>; + remote-endpoint = <&csi_sink>; + }; + }; + }; +};
diff --git a/arch/arm64/boot/dts/st/stm32mp255c-dhcos-dhsbc.dts b/arch/arm64/boot/dts/st/stm32mp255c-dhcos-dhsbc.dts new file mode 100644 index 0000000..eea7a76 --- /dev/null +++ b/arch/arm64/boot/dts/st/stm32mp255c-dhcos-dhsbc.dts
@@ -0,0 +1,213 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause) +/* + * Copyright (C) 2025-2026 Marek Vasut <marex@nabladev.com> + */ + +/dts-v1/; + +#include "stm32mp255.dtsi" +#include "stm32mp25xc.dtsi" +#include "stm32mp25xx-dhcos-som.dtsi" + +/ { + model = "DH electronics STM32MP255C DHCOS DHSBC"; + compatible = "dh,stm32mp255c-dhcos-dhsbc", "dh,stm32mp255c-dhcos-som", "st,stm32mp255"; + + aliases { + ethernet0 = ðernet1; + ethernet1 = ðernet2; + }; +}; + +ðernet1 { + phy-handle = <ðphy1>; + phy-mode = "rgmii-id"; + pinctrl-0 = <ð1_mdio_pins_a ð1_rgmii_pins_a>; + pinctrl-1 = <ð1_mdio_sleep_pins_a ð1_rgmii_sleep_pins_a>; + pinctrl-names = "default", "sleep"; + st,ext-phyclk; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + + ethphy1: ethernet-phy@1 { + /* RTL8211F */ + compatible = "ethernet-phy-id001c.c916"; + interrupt-parent = <&gpioc>; + interrupts = <6 IRQ_TYPE_LEVEL_LOW>; + reg = <1>; + realtek,clkout-disable; + realtek,clkout-ssc-enable; + realtek,rxc-ssc-enable; + realtek,sysclk-ssc-enable; + reset-assert-us = <15000>; + reset-deassert-us = <55000>; + reset-gpios = <&ioexp 1 GPIO_ACTIVE_LOW>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = <LED_COLOR_ID_GREEN>; + function = LED_FUNCTION_WAN; + linux,default-trigger = "netdev"; + }; + + led@1 { + reg = <1>; + color = <LED_COLOR_ID_YELLOW>; + function = LED_FUNCTION_WAN; + linux,default-trigger = "netdev"; + }; + }; + }; + }; +}; + +ðernet2 { + phy-handle = <ðphy2>; + phy-mode = "rgmii-id"; + pinctrl-0 = <ð2_mdio_pins_a ð2_rgmii_pins_b>; + pinctrl-1 = <ð2_mdio_sleep_pins_a ð2_rgmii_sleep_pins_b>; + pinctrl-names = "default", "sleep"; + st,ext-phyclk; + status = "okay"; + + mdio { + #address-cells = <1>; + #size-cells = <0>; + compatible = "snps,dwmac-mdio"; + + ethphy2: ethernet-phy@1 { + /* RTL8211F */ + compatible = "ethernet-phy-id001c.c916"; + interrupt-parent = <&gpiog>; + interrupts = <3 IRQ_TYPE_LEVEL_LOW>; + reg = <1>; + realtek,clkout-disable; + realtek,clkout-ssc-enable; + realtek,rxc-ssc-enable; + realtek,sysclk-ssc-enable; + reset-assert-us = <15000>; + reset-deassert-us = <55000>; + reset-gpios = <&ioexp 0 GPIO_ACTIVE_LOW>; + + leds { + #address-cells = <1>; + #size-cells = <0>; + + led@0 { + reg = <0>; + color = <LED_COLOR_ID_GREEN>; + function = LED_FUNCTION_LAN; + linux,default-trigger = "netdev"; + }; + + led@1 { + reg = <1>; + color = <LED_COLOR_ID_YELLOW>; + function = LED_FUNCTION_LAN; + linux,default-trigger = "netdev"; + }; + }; + }; + }; +}; + +&gpioa { + gpio-line-names = "DHSBC_HW-CODE_0", "DHSBC_HW-CODE_1", "DHSBC_HW-CODE_2", "", + "DHCOS-E", "DHCOS-J", "", "", + "DHCOS-D", "", "", "", + "", "", "", ""; +}; + +&i2c2 { + #address-cells = <1>; + #size-cells = <0>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&i2c2_pins_a>; + pinctrl-1 = <&i2c2_sleep_pins_a>; + i2c-scl-rising-time-ns = <57>; + i2c-scl-falling-time-ns = <7>; + clock-frequency = <400000>; + status = "okay"; +}; + +&scmi_vddio1 { + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-settling-time-up-us = <1000>; + regulator-settling-time-down-us = <100000>; +}; + +&sdmmc1_b4_pins_a { + pins1 { + slew-rate = <1>; + }; + + pins2 { + slew-rate = <2>; + }; +}; + +&sdmmc1_b4_od_pins_a { + pins1 { + slew-rate = <1>; + }; + + pins2 { + slew-rate = <2>; + }; + + pins3 { + slew-rate = <1>; + }; +}; + +&sdmmc1 { + pinctrl-names = "default", "opendrain", "sleep"; + pinctrl-0 = <&sdmmc1_b4_pins_a>; + pinctrl-1 = <&sdmmc1_b4_od_pins_a>; + pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>; + cd-gpios = <&ioexp 8 GPIO_ACTIVE_HIGH>; + disable-wp; + st,neg-edge; + bus-width = <4>; + vmmc-supply = <&scmi_v3v3>; + vqmmc-supply = <&scmi_vddio1>; + sd-uhs-sdr12; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-ddr50; + sd-uhs-sdr104; + status = "okay"; +}; + +&spi1 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&spi1_pins_b>; + pinctrl-1 = <&spi1_sleep_pins_b>; + cs-gpios = <&gpioh 3 0>; + status = "okay"; + + st33htph: tpm@0 { + compatible = "st,st33htpm-spi", "tcg,tpm_tis-spi"; + reg = <0>; + interrupt-parent = <&gpioa>; + interrupts = <5 IRQ_TYPE_LEVEL_LOW>; + reset-gpios = <&gpioh 2 GPIO_ACTIVE_LOW>; + spi-max-frequency = <24000000>; + }; +}; + +&spi8 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&spi8_pins_b>; + pinctrl-1 = <&spi8_sleep_pins_b>; + cs-gpios = <&gpioz 6 0>; +};
diff --git a/arch/arm64/boot/dts/st/stm32mp257-engicam-microgea.dtsi b/arch/arm64/boot/dts/st/stm32mp257-engicam-microgea.dtsi new file mode 100644 index 0000000..5b4287e --- /dev/null +++ b/arch/arm64/boot/dts/st/stm32mp257-engicam-microgea.dtsi
@@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2026 Amarula Solutions, Dario Binacchi <dario.binacchi@amarulasolutions.com> + * Copyright (C) 2026 Engicam srl + */ + +/dts-v1/; + +#include <dt-bindings/regulator/st,stm32mp25-regulator.h> +#include "stm32mp257.dtsi" +#include "stm32mp25-pinctrl.dtsi" +#include "stm32mp25xxai-pinctrl.dtsi" + +/ { + model = "Engicam MicroGEA STM32MP257 SoM"; + compatible = "engicam,microgea-stm32mp257", "st,stm32mp257"; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x0 0x80000000>; + }; +}; + +&scmi_regu { + scmi_vddio1: regulator@0 { + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + scmi_vddcore: regulator@b { + reg = <VOLTD_SCMI_STPMIC2_BUCK2>; + regulator-name = "vddcore"; + }; + scmi_v1v8: regulator@e { + reg = <VOLTD_SCMI_STPMIC2_BUCK5>; + regulator-name = "v1v8"; + }; + scmi_v3v3: regulator@10 { + reg = <VOLTD_SCMI_STPMIC2_BUCK7>; + regulator-name = "v3v3"; + }; + scmi_vdd3v3_usb: regulator@14 { + reg = <VOLTD_SCMI_STPMIC2_LDO4>; + regulator-name = "vdd3v3_usb"; + }; +}; + +/* eMMC */ +&sdmmc2 { + pinctrl-names = "default", "opendrain", "sleep"; + pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>; + pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_a>; + pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_a>; + non-removable; + no-sd; + no-sdio; + st,neg-edge; + bus-width = <8>; + vmmc-supply = <&scmi_v3v3>; + vqmmc-supply = <&scmi_vddio2>; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/st/stm32mp257d-engicam-microgea-rmm-overlay-am-1280800w8tzqw-t00h.dtso b/arch/arm64/boot/dts/st/stm32mp257d-engicam-microgea-rmm-overlay-am-1280800w8tzqw-t00h.dtso new file mode 100644 index 0000000..7655c1b --- /dev/null +++ b/arch/arm64/boot/dts/st/stm32mp257d-engicam-microgea-rmm-overlay-am-1280800w8tzqw-t00h.dtso
@@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2026 Amarula Solutions, Dario Binacchi <dario.binacchi@amarulasolutions.com> + * Copyright (C) 2026 Engicam srl + * + * Ampire AM-1280800W8TZQW-T00H 10.1" 1280x800 LVDS panel. Its touchscreen + * controller is connected over USB. + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/clock/st,stm32mp25-rcc.h> + +&{/} { + panel-lvds { + compatible = "ampire,am-1280800w8tzqw-t00h"; + backlight = <&backlight>; + power-supply = <®_3v3>; + + port { + panel_in: endpoint { + remote-endpoint = <&lvds_out>; + }; + }; + }; +}; + +&framebuffer { + clocks = <&rcc CK_BUS_LTDC>, <&rcc CK_KER_LTDC>, + <&rcc CK_BUS_LVDS>, <&rcc CK_KER_LVDSPHY>; +}; + +<dc { + status = "okay"; + + port { + ltdc_out: endpoint { + remote-endpoint = <&lvds_in>; + }; + }; +}; + +&lvds { + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + lvds_in: endpoint { + remote-endpoint = <<dc_out>; + }; + }; + + port@1 { + reg = <1>; + + lvds_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; + }; +};
diff --git a/arch/arm64/boot/dts/st/stm32mp257d-engicam-microgea-rmm-overlay-rk050hr345-ct106a.dtso b/arch/arm64/boot/dts/st/stm32mp257d-engicam-microgea-rmm-overlay-rk050hr345-ct106a.dtso new file mode 100644 index 0000000..f89641b --- /dev/null +++ b/arch/arm64/boot/dts/st/stm32mp257d-engicam-microgea-rmm-overlay-rk050hr345-ct106a.dtso
@@ -0,0 +1,68 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2026 Amarula Solutions, Dario Binacchi <dario.binacchi@amarulasolutions.com> + * Copyright (C) 2026 Engicam srl + * + * Rocktech RK050HR345-CT106A 5" 480x854 RGB panel with EDT FT5306 + * I2C touchscreen controller. + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> + +&i2c1 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&i2c1_pins_a>; + pinctrl-1 = <&i2c1_sleep_pins_a>; + i2c-scl-rising-time-ns = <185>; + i2c-scl-falling-time-ns = <20>; + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + + touchscreen@38 { + compatible = "edt,edt-ft5306"; + reg = <0x38>; + interrupt-parent = <&gpiob>; + interrupts = <0 IRQ_TYPE_EDGE_FALLING>; + reset-gpios = <&gpiod 1 GPIO_ACTIVE_LOW>; + touchscreen-size-x = <480>; + touchscreen-size-y = <854>; + }; +}; + +<dc { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <<dc_pins_a>; + pinctrl-1 = <<dc_sleep_pins_a>; + status = "okay"; + + port { + ltdc_out: endpoint { + remote-endpoint = <&panel_in>; + }; + }; +}; + +&spi1 { + #address-cells = <1>; + #size-cells = <0>; + + display@0 { + compatible = "rocktech,rk050hr345-ct106a", "ilitek,ili9806e"; + reg = <0>; + vdd-supply = <®_3v3>; + spi-max-frequency = <10000000>; + reset-gpios = <&gpiob 6 GPIO_ACTIVE_LOW>; + backlight = <&backlight>; + + port { + panel_in: endpoint { + remote-endpoint = <<dc_out>; + }; + }; + }; +};
diff --git a/arch/arm64/boot/dts/st/stm32mp257d-engicam-microgea-rmm.dts b/arch/arm64/boot/dts/st/stm32mp257d-engicam-microgea-rmm.dts new file mode 100644 index 0000000..96b7cb6 --- /dev/null +++ b/arch/arm64/boot/dts/st/stm32mp257d-engicam-microgea-rmm.dts
@@ -0,0 +1,275 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2026 Amarula Solutions, Dario Binacchi <dario.binacchi@amarulasolutions.com> + * Copyright (C) 2026 Engicam srl + */ + +/dts-v1/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> + +#include "stm32mp257-engicam-microgea.dtsi" + +/ { + model = "Engicam MicroGEA STM32MP257D RMM Board"; + compatible = "engicam,microgea-stm32mp257d-rmm", + "engicam,microgea-stm32mp257", "st,stm32mp257"; + + aliases { + mmc0 = &sdmmc1; + mmc1 = &sdmmc2; + serial0 = &usart2; + serial1 = &usart1; + }; + + backlight: backlight { + compatible = "pwm-backlight"; + brightness-levels = <0 100>; + num-interpolated-steps = <100>; + default-brightness-level = <85>; + pwms = <&pwm2 0 100000 0>; + }; + + buzzer { + compatible = "pwm-beeper"; + pwms = <&pwm4 0 1000000 0>; + }; + + chosen { + stdout-path = "serial0:115200n8"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + + framebuffer: framebuffer { + compatible = "simple-framebuffer"; + clocks = <&rcc CK_BUS_LTDC>, <&rcc CK_KER_LTDC>; + lcd-supply = <®_3v3>; + status = "disabled"; + }; + }; + + leds { + compatible = "gpio-leds"; + + led-0 { + gpios = <&gpioh 2 GPIO_ACTIVE_HIGH>; + default-state = "off"; + status = "okay"; + }; + + led-1 { + gpios = <&gpioh 6 GPIO_ACTIVE_HIGH>; + default-state = "off"; + status = "okay"; + }; + }; + + mclk: clock-mclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <24000000>; + }; + + reg_1v8: regulator-1v8 { + compatible = "regulator-fixed"; + regulator-name = "1v8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + }; + + reg_3v3: regulator-3v3 { + compatible = "regulator-fixed"; + regulator-name = "3v3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + }; + + reg_ext_pwr: regulator-ext-pwr { + compatible = "regulator-fixed"; + regulator-name = "ext-pwr"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&gpiog 0 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + }; + + sound { + compatible = "audio-graph-card"; + label = "STM32MP25-RMM"; + widgets = "Headphone", "Headphone Jack", + "Microphone", "Microphone Jack"; + routing = "Headphone Jack", "HP_OUT", + "MIC_IN", "Microphone Jack", + "Microphone Jack", "Mic Bias"; + dais = <&sai1a_port &sai1b_port>; + status = "okay"; + }; +}; + +&arm_wdt { + timeout-sec = <32>; + status = "okay"; +}; + +&i2c1 { + /* dt overlays don't support /delete-property/ */ + /delete-property/dmas; + /delete-property/dma-names; +}; + +&i2c2 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&i2c2_pins_a>; + pinctrl-1 = <&i2c2_sleep_pins_a>; + i2c-scl-rising-time-ns = <185>; + i2c-scl-falling-time-ns = <20>; + status = "okay"; + /* spare dmas for other usage */ + /delete-property/dmas; + /delete-property/dma-names; + + sgtl5000: codec@a { + compatible = "fsl,sgtl5000"; + reg = <0x0a>; + #sound-dai-cells = <0>; + clocks = <&mclk>; + + VDDA-supply = <®_3v3>; + VDDIO-supply = <®_3v3>; + VDDD-supply = <®_1v8>; + + sgtl5000_port: port { + #address-cells = <1>; + #size-cells = <0>; + + sgtl5000_tx_endpoint: endpoint@0 { + reg = <0>; + remote-endpoint = <&sai1a_endpoint>; + frame-master = <&sgtl5000_tx_endpoint>; + bitclock-master = <&sgtl5000_tx_endpoint>; + }; + + sgtl5000_rx_endpoint: endpoint@1 { + reg = <1>; + remote-endpoint = <&sai1b_endpoint>; + frame-master = <&sgtl5000_rx_endpoint>; + bitclock-master = <&sgtl5000_rx_endpoint>; + }; + }; + }; +}; + +&m_can1 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&m_can1_pins_a>; + pinctrl-1 = <&m_can1_sleep_pins_a>; + status = "okay"; +}; + +&sai1 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&sai1a_pins_a>, <&sai1b_pins_a>; + pinctrl-1 = <&sai1a_sleep_pins_a>, <&sai1b_sleep_pins_a>; + status = "okay"; +}; + +&sai1a { + dma-names = "tx"; + status = "okay"; + + sai1a_port: port { + sai1a_endpoint: endpoint { + remote-endpoint = <&sgtl5000_tx_endpoint>; + dai-format = "i2s"; + mclk-fs = <512>; + }; + }; +}; + +&sai1b { + dma-names = "rx"; + st,sync = <&sai1a 2>; + clocks = <&rcc CK_KER_SAI1>; + clock-names = "sai_ck"; + status = "okay"; + + sai1b_port: port { + sai1b_endpoint: endpoint { + remote-endpoint = <&sgtl5000_rx_endpoint>; + dai-format = "i2s"; + mclk-fs = <512>; + }; + }; +}; + +/* MicroSD */ +&sdmmc1 { + pinctrl-names = "default", "opendrain", "sleep"; + pinctrl-0 = <&sdmmc1_b4_pins_a>; + pinctrl-1 = <&sdmmc1_b4_od_pins_a>; + pinctrl-2 = <&sdmmc1_b4_sleep_pins_a>; + broken-cd; + disable-wp; + st,neg-edge; + bus-width = <4>; + vmmc-supply = <&scmi_v3v3>; + vqmmc-supply = <&scmi_vddio1>; + no-1-8-v; + status = "okay"; +}; + +&spi1 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&spi1_pins_a>; + pinctrl-1 = <&spi1_sleep_pins_a>; + #address-cells = <1>; + #size-cells = <0>; + cs-gpios = <&gpioh 8 GPIO_ACTIVE_LOW>, <&gpioh 3 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&timers2 { + status = "okay"; + + pwm2: pwm { + pinctrl-0 = <&pwm2_pins_a>; + pinctrl-1 = <&pwm2_sleep_pins_a>; + pinctrl-names = "default", "sleep"; + status = "okay"; + }; +}; + +&timers4 { + status = "okay"; + + pwm4: pwm { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&pwm4_pins_a>; + pinctrl-1 = <&pwm4_sleep_pins_a>; + status = "okay"; + }; +}; + +&usart1 { + pinctrl-names = "default", "idle", "sleep"; + pinctrl-0 = <&usart1_pins_b>; + pinctrl-1 = <&usart1_idle_pins_b>; + pinctrl-2 = <&usart1_sleep_pins_b>; + /delete-property/ dmas; + /delete-property/ dma-names; + status = "okay"; +}; + +&usart2 { + pinctrl-names = "default", "idle", "sleep"; + pinctrl-0 = <&usart2_pins_a>; + pinctrl-1 = <&usart2_idle_pins_a>; + pinctrl-2 = <&usart2_sleep_pins_a>; + /delete-property/ dmas; + /delete-property/ dma-names; + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/st/stm32mp257f-dk.dts b/arch/arm64/boot/dts/st/stm32mp257f-dk.dts index 8daf3df..a8f1850 100644 --- a/arch/arm64/boot/dts/st/stm32mp257f-dk.dts +++ b/arch/arm64/boot/dts/st/stm32mp257f-dk.dts
@@ -9,6 +9,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/input/input.h> #include <dt-bindings/leds/common.h> +#include <dt-bindings/media/video-interfaces.h> #include "stm32mp257.dtsi" #include "stm32mp25xf.dtsi" #include "stm32mp25-pinctrl.dtsi" @@ -21,12 +22,22 @@ / { aliases { ethernet0 = ðernet1; serial0 = &usart2; + mmc0 = &sdmmc1; + mmc1 = &sdmmc2; }; chosen { stdout-path = "serial0:115200n8"; }; + clocks { + clk_ext_camera: clk-ext-camera { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <24000000>; + }; + }; + gpio-keys { compatible = "gpio-keys"; @@ -138,6 +149,42 @@ &arm_wdt { status = "okay"; }; +&csi { + vdd-supply = <&scmi_vddcore>; + vdda18-supply = <&scmi_v1v8>; + status = "okay"; + + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + csi_sink: endpoint { + remote-endpoint = <&imx335_ep>; + data-lanes = <1 2>; + bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>; + }; + }; + port@1 { + reg = <1>; + csi_source: endpoint { + remote-endpoint = <&dcmipp_0>; + }; + }; + }; +}; + +&dcmipp { + status = "okay"; + + port { + dcmipp_0: endpoint { + remote-endpoint = <&csi_source>; + bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>; + }; + }; +}; + ðernet1 { pinctrl-0 = <ð1_rgmii_pins_b>; pinctrl-1 = <ð1_rgmii_sleep_pins_b>; @@ -160,6 +207,16 @@ phy1_eth1: ethernet-phy@1 { }; }; +&gpiob { + /* Enable the IMX335 power line */ + imx335-en-hog { + gpio-hog; + gpios = <11 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "imx335_en"; + }; +}; + &i2c2 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&i2c2_pins_b>; @@ -172,6 +229,25 @@ &i2c2 { /delete-property/dmas; /delete-property/dma-names; + imx335: camera@1a { + compatible = "sony,imx335"; + reg = <0x1a>; + clocks = <&clk_ext_camera>; + avdd-supply = <&scmi_v3v3>; + ovdd-supply = <&scmi_v3v3>; + dvdd-supply = <&scmi_v3v3>; + reset-gpios = <&gpiob 1 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>; + + port { + imx335_ep: endpoint { + remote-endpoint = <&csi_sink>; + clock-lanes = <0>; + data-lanes = <1 2>; + link-frequencies = /bits/ 64 <594000000>; + }; + }; + }; + ili2511: ili2511@41 { compatible = "ilitek,ili251x"; reg = <0x41>; @@ -279,6 +355,23 @@ &sdmmc1 { status = "okay"; }; +&sdmmc2 { + pinctrl-names = "default", "opendrain", "sleep"; + pinctrl-0 = <&sdmmc2_b4_pins_b &sdmmc2_d47_pins_b>; + pinctrl-1 = <&sdmmc2_b4_od_pins_b &sdmmc2_d47_pins_b>; + pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_a>; + non-removable; + no-sd; + no-sdio; + st,neg-edge; + bus-width = <8>; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + vmmc-supply = <&scmi_vdd_emmc>; + vqmmc-supply = <&scmi_vddio2>; + status = "okay"; +}; + &usart2 { pinctrl-names = "default", "idle", "sleep"; pinctrl-0 = <&usart2_pins_a>;
diff --git a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts index b5db62a..782b4bb 100644 --- a/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts +++ b/arch/arm64/boot/dts/st/stm32mp257f-ev1.dts
@@ -8,6 +8,7 @@ #include <dt-bindings/gpio/gpio.h> #include <dt-bindings/leds/common.h> +#include <dt-bindings/media/video-interfaces.h> #include <dt-bindings/regulator/st,stm32mp25-regulator.h> #include "stm32mp257.dtsi" #include "stm32mp25xf.dtsi" @@ -72,30 +73,6 @@ ddr_channel: sdram-channel-0 { io-width = <32>; }; - imx335_2v9: regulator-2v9 { - compatible = "regulator-fixed"; - regulator-name = "imx335-avdd"; - regulator-min-microvolt = <2900000>; - regulator-max-microvolt = <2900000>; - regulator-always-on; - }; - - imx335_1v8: regulator-1v8 { - compatible = "regulator-fixed"; - regulator-name = "imx335-ovdd"; - regulator-min-microvolt = <1800000>; - regulator-max-microvolt = <1800000>; - regulator-always-on; - }; - - imx335_1v2: regulator-1v2 { - compatible = "regulator-fixed"; - regulator-name = "imx335-dvdd"; - regulator-min-microvolt = <1200000>; - regulator-max-microvolt = <1200000>; - regulator-always-on; - }; - memory@80000000 { device_type = "memory"; reg = <0x0 0x80000000 0x1 0x0>; @@ -185,7 +162,7 @@ port@0 { csi_sink: endpoint { remote-endpoint = <&imx335_ep>; data-lanes = <1 2>; - bus-type = <4>; + bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>; }; }; port@1 { @@ -202,7 +179,7 @@ &dcmipp { port { dcmipp_0: endpoint { remote-endpoint = <&csi_source>; - bus-type = <4>; + bus-type = <MEDIA_BUS_TYPE_CSI2_DPHY>; }; }; }; @@ -253,6 +230,16 @@ phy0_eth2: ethernet-phy@1 { }; }; +&gpioi { + /* Enable the IMX335 power line */ + imx335-en-hog { + gpio-hog; + gpios = <0 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "imx335_en"; + }; +}; + &i2c2 { pinctrl-names = "default", "sleep"; pinctrl-0 = <&i2c2_pins_a>; @@ -269,9 +256,9 @@ imx335: camera@1a { compatible = "sony,imx335"; reg = <0x1a>; clocks = <&clk_ext_camera>; - avdd-supply = <&imx335_2v9>; - ovdd-supply = <&imx335_1v8>; - dvdd-supply = <&imx335_1v2>; + avdd-supply = <&scmi_v3v3>; + ovdd-supply = <&scmi_v3v3>; + dvdd-supply = <&scmi_v3v3>; reset-gpios = <&gpioi 7 (GPIO_ACTIVE_LOW | GPIO_PUSH_PULL)>; port { @@ -307,34 +294,6 @@ &i2c8 { /delete-property/dma-names; }; -&ommanager { - memory-region = <&mm_ospi1>; - memory-region-names = "ospi1"; - pinctrl-0 = <&ospi_port1_clk_pins_a - &ospi_port1_io03_pins_a - &ospi_port1_cs0_pins_a>; - pinctrl-1 = <&ospi_port1_clk_sleep_pins_a - &ospi_port1_io03_sleep_pins_a - &ospi_port1_cs0_sleep_pins_a>; - pinctrl-names = "default", "sleep"; - status = "okay"; - - spi@0 { - #address-cells = <1>; - #size-cells = <0>; - memory-region = <&mm_ospi1>; - status = "okay"; - - flash0: flash@0 { - compatible = "jedec,spi-nor"; - reg = <0>; - spi-rx-bus-width = <4>; - spi-tx-bus-width = <4>; - spi-max-frequency = <50000000>; - }; - }; -}; - /* use LPTIMER with tick broadcast for suspend mode */ &lptimer3 { status = "okay"; @@ -374,6 +333,34 @@ lvds_out0: endpoint { }; }; +&ommanager { + memory-region = <&mm_ospi1>; + memory-region-names = "ospi1"; + pinctrl-0 = <&ospi_port1_clk_pins_a + &ospi_port1_io03_pins_a + &ospi_port1_cs0_pins_a>; + pinctrl-1 = <&ospi_port1_clk_sleep_pins_a + &ospi_port1_io03_sleep_pins_a + &ospi_port1_cs0_sleep_pins_a>; + pinctrl-names = "default", "sleep"; + status = "okay"; + + spi@0 { + #address-cells = <1>; + #size-cells = <0>; + memory-region = <&mm_ospi1>; + status = "okay"; + + flash0: flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + spi-max-frequency = <50000000>; + }; + }; +}; + &pcie_ep { pinctrl-names = "default", "init"; pinctrl-0 = <&pcie_pins_a>;
diff --git a/arch/arm64/boot/dts/st/stm32mp25xc.dtsi b/arch/arm64/boot/dts/st/stm32mp25xc.dtsi new file mode 100644 index 0000000..56872fb --- /dev/null +++ b/arch/arm64/boot/dts/st/stm32mp25xc.dtsi
@@ -0,0 +1,7 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause) +/* + * Copyright (C) 2026 Marek Vasut <marex@nabladev.com> + */ + +/ { +};
diff --git a/arch/arm64/boot/dts/st/stm32mp25xx-dhcos-bb.dts b/arch/arm64/boot/dts/st/stm32mp25xx-dhcos-bb.dts new file mode 100644 index 0000000..cf66e8e --- /dev/null +++ b/arch/arm64/boot/dts/st/stm32mp25xx-dhcos-bb.dts
@@ -0,0 +1,15 @@ +// SPDX-License-Identifier: (GPL-2.0-or-later OR BSD-3-Clause) +/* + * Copyright (C) 2025-2026 Marek Vasut <marex@nabladev.com> + */ + +/dts-v1/; + +#include "stm32mp255.dtsi" +#include "stm32mp25xc.dtsi" +#include "stm32mp25xx-dhcos-som.dtsi" + +/ { + model = "DH electronics STM32MP25xx DHCOS Breakout Board"; + compatible = "dh,stm32mp251a-dhcos-bb", "dh,stm32mp251a-dhcos-som", "st,stm32mp251"; +};
diff --git a/arch/arm64/boot/dts/st/stm32mp25xx-dhcos-som.dtsi b/arch/arm64/boot/dts/st/stm32mp25xx-dhcos-som.dtsi new file mode 100644 index 0000000..23c25ea --- /dev/null +++ b/arch/arm64/boot/dts/st/stm32mp25xx-dhcos-som.dtsi
@@ -0,0 +1,51 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +/* + * Copyright (C) 2025-2026 Marek Vasut <marex@nabladev.com> + */ + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/input/input.h> +#include <dt-bindings/leds/common.h> +#include "stm32mp25-pinctrl.dtsi" +#include "stm32mp25xxak-pinctrl.dtsi" +#include "stm32mp2xxx-dhcos-som.dtsi" + +/ { + model = "DH electronics STM32MP25xx DHCOS SoM"; + compatible = "dh,stm32mp251a-dhcos-som", "st,stm32mp251"; + + aliases { + serial1 = &uart8; + serial2 = &uart9; + }; +}; + +&rv3032 { + interrupts-extended = <&gpioi 10 IRQ_TYPE_EDGE_FALLING>; +}; + +/* Bluetooth */ +&uart8 { + pinctrl-names = "default", "sleep", "idle"; + pinctrl-0 = <&uart8_pins_a>; + pinctrl-1 = <&uart8_sleep_pins_a>; + pinctrl-2 = <&uart8_idle_pins_a>; + uart-has-rtscts; + status = "okay"; + + bluetooth { + compatible = "infineon,cyw55572-bt"; + brcm,requires-autobaud-mode; + max-speed = <3000000>; + shutdown-gpios = <&ioexp 2 GPIO_ACTIVE_HIGH>; + }; +}; + +&uart9 { + pinctrl-names = "default", "sleep", "idle"; + pinctrl-0 = <&uart9_pins_a>; + pinctrl-1 = <&uart9_sleep_pins_a>; + pinctrl-2 = <&uart9_idle_pins_a>; + uart-has-rtscts; + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/st/stm32mp2xxx-dhcos-som.dtsi b/arch/arm64/boot/dts/st/stm32mp2xxx-dhcos-som.dtsi new file mode 100644 index 0000000..bcf63e2 --- /dev/null +++ b/arch/arm64/boot/dts/st/stm32mp2xxx-dhcos-som.dtsi
@@ -0,0 +1,456 @@ +// SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) +/* + * Copyright (C) 2025-2026 Marek Vasut <marex@nabladev.com> + */ + +/ { + aliases { + mmc0 = &sdmmc2; + mmc1 = &sdmmc3; + serial0 = &usart6; + serial1 = &uart8; + eeprom0 = &eeprom0; + eeprom0wl = &eeprom0wl; + rtc0 = &rv3032; + rtc1 = &rtc; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + memory@80000000 { + device_type = "memory"; + reg = <0x0 0x80000000 0x1 0x0>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + /* Internal RAM reserved memory declaration */ + tfa_bl31: tfa-bl31@a000000 { + reg = <0x0 0xa000000 0x0 0x20000>; + no-map; + }; + + hpdma1_lli: hpdma1-lli@a020000 { + reg = <0x0 0xa020000 0x0 0xf0f0>; + no-map; + }; + + hpdma2_lli: hpdma2-lli@a02f0f0 { + reg = <0x0 0xa02f0f0 0x0 0xf0f0>; + no-map; + }; + + hpdma3_lli: hpdma3-lli@a03e1e0 { + reg = <0x0 0xa03e1e0 0x0 0x1e20>; + no-map; + }; + + bsec_mirror: bsec-mirror@a040000 { + reg = <0x0 0xa040000 0x0 0x1000>; + no-map; + }; + + scmi_cid2_s: scmi-cid2-s@a041000 { + reg = <0x0 0xa041000 0x0 0x1000>; + no-map; + }; + + scmi_cid2_ns: scmi-cid2-ns@a042000 { + reg = <0x0 0xa042000 0x0 0x1000>; + no-map; + }; + + cm33_sram1: cm33-sram1@a043000 { + reg = <0x0 0xa043000 0x0 0x1d000>; + no-map; + }; + + cm33_sram2: cm33-sram2@a060000 { + reg = <0x0 0xa060000 0x0 0x20000>; + no-map; + }; + + cm33_retram: cm33-retram@a080000 { + reg = <0x0 0xa080000 0x0 0x1f000>; + no-map; + }; + + ddr_param: ddr-param@a09f000 { + reg = <0x0 0xa09f000 0x0 0x1000>; + no-map; + }; + + cm0_cube_fw: cm0-cube-fw@200C0000 { + compatible = "shared-dma-pool"; + reg = <0x0 0x200C0000 0x0 0x4000>; + no-map; + }; + + cm0_cube_data: cm0-cube-data@200C4000 { + compatible = "shared-dma-pool"; + reg = <0x0 0x200C4000 0x0 0x2000>; + no-map; + }; + + ipc_shmem_2: ipc-shmem-2@200C6000{ + compatible = "shared-dma-pool"; + reg = <0x0 0x200C6000 0x0 0x2000>; + no-map; + }; + + /* Backup RAM reserved memory declaration */ + bl31_lowpower: bl31-lowpower@42000000 { + reg = <0x0 0x42000000 0x0 0x1000>; + no-map; + }; + + tfm_its: tfm-its@42001000 { + reg = <0x0 0x42001000 0x0 0x1000>; + no-map; + }; + + /* Octo Memory Manager reserved memory declaration */ + mm_ospi1: mm-ospi@60000000 { + reg = <0x0 0x60000000 0x0 0x10000000>; + no-map; + }; + + /* DDR reserved memory declaration */ + tfm_code: tfm-code@80000000 { + reg = <0x0 0x80000000 0x0 0x100000>; + no-map; + }; + + cm33_cube_fw: cm33-cube-fw@80100000 { + reg = <0x0 0x80100000 0x0 0x800000>; + no-map; + }; + + tfm_data: tfm-data@80900000 { + reg = <0x0 0x80900000 0x0 0x100000>; + no-map; + }; + + cm33_cube_data: cm33-cube-data@80a00000 { + reg = <0x0 0x80a00000 0x0 0x800000>; + no-map; + }; + + ipc_shmem_1: ipc-shmem-1@81200000 { + compatible = "shared-dma-pool"; + reg = <0x0 0x81200000 0x0 0xf8000>; + no-map; + }; + + vdev0vring0: vdev0vring0@812f8000 { + compatible = "shared-dma-pool"; + reg = <0x0 0x812f8000 0x0 0x1000>; + no-map; + }; + + vdev0vring1: vdev0vring1@812f9000 { + compatible = "shared-dma-pool"; + reg = <0x0 0x812f9000 0x0 0x1000>; + no-map; + }; + + vdev0buffer: vdev0buffer@812fa000 { + compatible = "shared-dma-pool"; + reg = <0x0 0x812fa000 0x0 0x6000>; + no-map; + }; + + spare1: spare1@81300000 { + reg = <0x0 0x81300000 0x0 0xcc0000>; + no-map; + }; + + bl31_context: bl31-context@81fc0000 { + reg = <0x0 0x81fc0000 0x0 0x40000>; + no-map; + }; + + op_tee: op-tee@82000000 { + reg = <0x0 0x82000000 0x0 0x2000000>; + no-map; + }; + + gpu_reserved: gpu-reserved@fa800000 { + reg = <0x0 0xfa800000 0x0 0x4000000>; + no-map; + }; + + ltdc_sec_layer: ltdc-sec-layer@fe800000 { + reg = <0x0 0xfe800000 0x0 0x800000>; + no-map; + }; + + ltdc_sec_rotation: ltdc-sec-rotation@ff000000 { + reg = <0x0 0xff000000 0x0 0x1000000>; + no-map; + }; + + /* global autoconfigured region for contiguous allocations */ + linux,cma { + compatible = "shared-dma-pool"; + reusable; + alloc-ranges = <0 0x80000000 0 0x80000000>; + size = <0x0 0x8000000>; + alignment = <0x0 0x2000>; + linux,cma-default; + }; + }; + + sdio_pwrseq: sdio-pwrseq { + compatible = "mmc-pwrseq-simple"; + post-power-on-delay-ms = <50>; + reset-gpios = <&ioexp 3 GPIO_ACTIVE_LOW>; + }; +}; + +&arm_wdt { + timeout-sec = <32>; + status = "okay"; +}; + +&gpioa { + gpio-line-names = "", "DHCOS-M", "DHCOS-K", "DHCOS-L", + "DHCOS-E", "DHCOS-J", "", "", + "DHCOS-D", "", "", "", + "", "", "", ""; +}; + +&gpiof { + gpio-line-names = "", "", "", "", + "", "", "", "", + "", "", "", "", + "", "", "", "DHCOS_RAM-CODE_2"; +}; + +&gpiog { + gpio-line-names = "", "", "", "", + "", "", "", "", + "", "DHCOS_RAM-CODE_0", "DHCOS_RAM-CODE_1", "", + "", "", "DHCOS-F", "DHCOS_HW-CODE_0"; +}; + +&gpioh { + gpio-line-names = "", "", "DHCOS-I", "DHCOS-N", + "", "", "DHCOS-O", "DHCOS-H", + "DHCOS-G", "", "", "", + "", "", "", ""; +}; + +&gpioi { + gpio-line-names = "DHCOS_HW-CODE_1", "DHCOS_HW-CODE_2", "", "", + "", "", "", "", + "", "DHCOS-C", "", "", + "", "", "", ""; +}; + +&gpioz { + gpio-line-names = "", "", "DHCOS-A", "DHCOS-B", + "", "", "", "", + "", "", "", "", + "", "", "", ""; +}; + +&i2c8 { + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&i2c8_pins_b>; + pinctrl-1 = <&i2c8_sleep_pins_b>; + i2c-scl-rising-time-ns = <57>; + i2c-scl-falling-time-ns = <7>; + clock-frequency = <400000>; + status = "okay"; + + ioexp: gpio@20 { + compatible = "kinetic,kts1622", "ti,tcal6416"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + interrupts-extended = <&gpiod 11 IRQ_TYPE_LEVEL_LOW>; + interrupt-controller; + #interrupt-cells = <2>; + wakeup-source; + + gpio-line-names = + "#ETH1_RST_P0_0", "#ETH0_RST_P0_1", + "BT_REG_ON_P0_2", "WL_REG_ON_P0_3", + "USB1_PWR_EN_P0_4", "USB1_PWR_STAT_P0_5", + "USB0_PWR_EN_P0_6", "USB0_PWR_STAT_P0_7", + "SDIO0_CD_P1_0", "USB0_SS_SEL_P1_1", + "#PCIe_RST_1_2", "#PCIe_Wake_P1_3", + "#QSPI_RST_P1_4", "#CSI0_PWDN_P1_5", + "#CSI0_RST_P1_6", "#ETH3_RST_P1_7"; + }; + + eeprom0: eeprom@50 { + compatible = "atmel,24c256"; /* ST M24256 */ + reg = <0x50>; + pagesize = <64>; + }; + + rv3032: rtc@51 { + compatible = "microcrystal,rv3032"; + reg = <0x51>; + wakeup-source; + }; + + eeprom0wl: eeprom@58 { + compatible = "st,24256e-wl"; /* ST M24256E WL page of 0x50 */ + pagesize = <64>; + reg = <0x58>; + }; +}; + +&ommanager { + memory-region = <&mm_ospi1>; + pinctrl-names = "default", "sleep"; + pinctrl-0 = <&ospi_port1_clk_pins_a + &ospi_port1_io03_pins_a + &ospi_port1_cs0_pins_a>; + pinctrl-1 = <&ospi_port1_clk_sleep_pins_a + &ospi_port1_io03_sleep_pins_a + &ospi_port1_cs0_sleep_pins_a>; + pinctrl-names = "default", "sleep"; + status = "okay"; +}; + +&ospi1 { + #address-cells = <1>; + #size-cells = <0>; + memory-region = <&mm_ospi1>; + status = "okay"; + + flash0: flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-rx-bus-width = <4>; + spi-tx-bus-width = <4>; + spi-max-frequency = <100000000>; + }; +}; + +&rtc { + status = "okay"; +}; + +&scmi_regu { + scmi_vddcore: regulator@b { + reg = <VOLTD_SCMI_STPMIC2_BUCK2>; + regulator-name = "vddcore"; + }; + + regulator@c { + reg = <VOLTD_SCMI_STPMIC2_BUCK3>; + regulator-name = "vddgpu"; + regulator-always-on; + }; + + scmi_v1v8: regulator@e { + reg = <VOLTD_SCMI_STPMIC2_BUCK5>; + regulator-name = "v1v8"; + regulator-always-on; + }; + + scmi_v3v3: regulator@10 { + reg = <VOLTD_SCMI_STPMIC2_BUCK7>; + regulator-name = "v3v3"; + regulator-always-on; + }; + + scmi_vdd_emmc: regulator@12 { + reg = <VOLTD_SCMI_STPMIC2_LDO2>; + regulator-name = "vdd_emmc"; + }; + + scmi_vdd3v3_usb: regulator@14 { + reg = <VOLTD_SCMI_STPMIC2_LDO4>; + regulator-name = "vdd3v3_usb"; + }; + + scmi_vdd_sdcard: regulator@17 { + reg = <VOLTD_SCMI_STPMIC2_LDO7>; + regulator-name = "vdd_sdcard"; + }; +}; + +&scmi_vddio3 { + regulator-always-on; +}; + +&scmi_vddio4 { + regulator-always-on; +}; + +&sdmmc2_b4_pins_a { + pins2 { + /delete-property/ bias-disable; + bias-pull-up; + }; +}; + +&sdmmc2_b4_od_pins_a { + pins2 { + /delete-property/ bias-disable; + bias-pull-up; + }; +}; + +&sdmmc2 { + pinctrl-names = "default", "opendrain", "sleep"; + pinctrl-0 = <&sdmmc2_b4_pins_a &sdmmc2_d47_pins_a>; + pinctrl-1 = <&sdmmc2_b4_od_pins_a &sdmmc2_d47_pins_a>; + pinctrl-2 = <&sdmmc2_b4_sleep_pins_a &sdmmc2_d47_sleep_pins_a>; + non-removable; + no-sd; + no-sdio; + st,neg-edge; + bus-width = <8>; + vmmc-supply = <&scmi_vdd_emmc>; + vqmmc-supply = <&scmi_vddio2>; + mmc-ddr-1_8v; + mmc-hs200-1_8v; + status = "okay"; +}; + +&sdmmc3 { + pinctrl-names = "default", "opendrain", "sleep"; + pinctrl-0 = <&sdmmc3_b4_pins_b>; + pinctrl-1 = <&sdmmc3_b4_od_pins_b>; + pinctrl-2 = <&sdmmc3_b4_sleep_pins_b>; + bus-width = <4>; + keep-power-in-suspend; + non-removable; + no-sd; + no-mmc; + st,neg-edge; + vmmc-supply = <&scmi_v3v3>; + vqmmc-supply = <&scmi_v1v8>; + mmc-pwrseq = <&sdio_pwrseq>; + status = "okay"; + + #address-cells = <1>; + #size-cells = <0>; + + brcmf: wifi@1 { /* muRata 2FY */ + reg = <1>; + compatible = "brcm,bcm4329-fmac"; + }; +}; + +&usart6 { + pinctrl-names = "default", "idle", "sleep"; + pinctrl-0 = <&usart6_pins_b>; + pinctrl-1 = <&usart6_idle_pins_b>; + pinctrl-2 = <&usart6_sleep_pins_b>; + /delete-property/dmas; + /delete-property/dma-names; + status = "okay"; +};
diff --git a/arch/arm64/boot/dts/tesla/fsd-evb.dts b/arch/arm64/boot/dts/tesla/fsd-evb.dts index 503abe5..a1f3d3f 100644 --- a/arch/arm64/boot/dts/tesla/fsd-evb.dts +++ b/arch/arm64/boot/dts/tesla/fsd-evb.dts
@@ -50,6 +50,11 @@ simple-audio-card,dai-link@0 { bitclock-master = <&tlv320aic3x>; frame-master = <&tlv320aic3x>; + codec { + sound-dai = <&tlv320aic3x>; + system-clock-frequency = <33000000>; + }; + cpu-0 { sound-dai = <&i2s_0 0>; }; @@ -57,11 +62,6 @@ cpu-0 { cpu-1 { sound-dai = <&i2s_0 1>; }; - - codec { - sound-dai = <&tlv320aic3x>; - system-clock-frequency = <33000000>; - }; }; }; };
diff --git a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi index 6f4658f..ab25433 100644 --- a/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi +++ b/arch/arm64/boot/dts/tesla/fsd-pinctrl.dtsi
@@ -27,14 +27,6 @@ gpf1: gpf1-gpio-bank { #interrupt-cells = <2>; }; - gpf6: gpf6-gpio-bank { - gpio-controller; - #gpio-cells = <2>; - - interrupt-controller; - #interrupt-cells = <2>; - }; - gpf4: gpf4-gpio-bank { gpio-controller; #gpio-cells = <2>; @@ -51,6 +43,14 @@ gpf5: gpf5-gpio-bank { #interrupt-cells = <2>; }; + gpf6: gpf6-gpio-bank { + gpio-controller; + #gpio-cells = <2>; + + interrupt-controller; + #interrupt-cells = <2>; + }; + ufs_rst_n: ufs-rst-n-pins { samsung,pins = "gpf5-0"; samsung,pin-function = <FSD_PIN_FUNC_2>;
diff --git a/arch/arm64/boot/dts/tesla/fsd.dtsi b/arch/arm64/boot/dts/tesla/fsd.dtsi index 6766c78..36925b2 100644 --- a/arch/arm64/boot/dts/tesla/fsd.dtsi +++ b/arch/arm64/boot/dts/tesla/fsd.dtsi
@@ -34,6 +34,12 @@ aliases { spi2 = &spi_2; }; + fin_pll: clock { + compatible = "fixed-clock"; + clock-output-names = "fin_pll"; + #clock-cells = <0>; + }; + cpus { #address-cells = <2>; #size-cells = <0>; @@ -96,196 +102,196 @@ core3 { /* Cluster 0 */ cpucl0_0: cpu@0 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x0 0x000>; - enable-method = "psci"; - clock-frequency = <2400000000>; - cpu-idle-states = <&cpu_sleep>; - i-cache-size = <0xc000>; - i-cache-line-size = <64>; - i-cache-sets = <256>; - d-cache-size = <0x8000>; - d-cache-line-size = <64>; - d-cache-sets = <256>; - next-level-cache = <&cpucl_l2>; + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <0x0 0x000>; + enable-method = "psci"; + clock-frequency = <2400000000>; + cpu-idle-states = <&cpu_sleep>; + i-cache-size = <0xc000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&cpucl_l2>; }; cpucl0_1: cpu@1 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x0 0x001>; - enable-method = "psci"; - clock-frequency = <2400000000>; - cpu-idle-states = <&cpu_sleep>; - i-cache-size = <0xc000>; - i-cache-line-size = <64>; - i-cache-sets = <256>; - d-cache-size = <0x8000>; - d-cache-line-size = <64>; - d-cache-sets = <256>; - next-level-cache = <&cpucl_l2>; + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <0x0 0x001>; + enable-method = "psci"; + clock-frequency = <2400000000>; + cpu-idle-states = <&cpu_sleep>; + i-cache-size = <0xc000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&cpucl_l2>; }; cpucl0_2: cpu@2 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x0 0x002>; - enable-method = "psci"; - clock-frequency = <2400000000>; - cpu-idle-states = <&cpu_sleep>; - i-cache-size = <0xc000>; - i-cache-line-size = <64>; - i-cache-sets = <256>; - d-cache-size = <0x8000>; - d-cache-line-size = <64>; - d-cache-sets = <256>; - next-level-cache = <&cpucl_l2>; + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <0x0 0x002>; + enable-method = "psci"; + clock-frequency = <2400000000>; + cpu-idle-states = <&cpu_sleep>; + i-cache-size = <0xc000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&cpucl_l2>; }; cpucl0_3: cpu@3 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x0 0x003>; - enable-method = "psci"; - cpu-idle-states = <&cpu_sleep>; - i-cache-size = <0xc000>; - i-cache-line-size = <64>; - i-cache-sets = <256>; - d-cache-size = <0x8000>; - d-cache-line-size = <64>; - d-cache-sets = <256>; - next-level-cache = <&cpucl_l2>; + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <0x0 0x003>; + enable-method = "psci"; + cpu-idle-states = <&cpu_sleep>; + i-cache-size = <0xc000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&cpucl_l2>; }; /* Cluster 1 */ cpucl1_0: cpu@100 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x0 0x100>; - enable-method = "psci"; - clock-frequency = <2400000000>; - cpu-idle-states = <&cpu_sleep>; - i-cache-size = <0xc000>; - i-cache-line-size = <64>; - i-cache-sets = <256>; - d-cache-size = <0x8000>; - d-cache-line-size = <64>; - d-cache-sets = <256>; - next-level-cache = <&cpucl_l2>; + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <0x0 0x100>; + enable-method = "psci"; + clock-frequency = <2400000000>; + cpu-idle-states = <&cpu_sleep>; + i-cache-size = <0xc000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&cpucl_l2>; }; cpucl1_1: cpu@101 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x0 0x101>; - enable-method = "psci"; - clock-frequency = <2400000000>; - cpu-idle-states = <&cpu_sleep>; - i-cache-size = <0xc000>; - i-cache-line-size = <64>; - i-cache-sets = <256>; - d-cache-size = <0x8000>; - d-cache-line-size = <64>; - d-cache-sets = <256>; - next-level-cache = <&cpucl_l2>; + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <0x0 0x101>; + enable-method = "psci"; + clock-frequency = <2400000000>; + cpu-idle-states = <&cpu_sleep>; + i-cache-size = <0xc000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&cpucl_l2>; }; cpucl1_2: cpu@102 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x0 0x102>; - enable-method = "psci"; - clock-frequency = <2400000000>; - cpu-idle-states = <&cpu_sleep>; - i-cache-size = <0xc000>; - i-cache-line-size = <64>; - i-cache-sets = <256>; - d-cache-size = <0x8000>; - d-cache-line-size = <64>; - d-cache-sets = <256>; - next-level-cache = <&cpucl_l2>; + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <0x0 0x102>; + enable-method = "psci"; + clock-frequency = <2400000000>; + cpu-idle-states = <&cpu_sleep>; + i-cache-size = <0xc000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&cpucl_l2>; }; cpucl1_3: cpu@103 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x0 0x103>; - enable-method = "psci"; - clock-frequency = <2400000000>; - cpu-idle-states = <&cpu_sleep>; - i-cache-size = <0xc000>; - i-cache-line-size = <64>; - i-cache-sets = <256>; - d-cache-size = <0x8000>; - d-cache-line-size = <64>; - d-cache-sets = <256>; - next-level-cache = <&cpucl_l2>; + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <0x0 0x103>; + enable-method = "psci"; + clock-frequency = <2400000000>; + cpu-idle-states = <&cpu_sleep>; + i-cache-size = <0xc000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&cpucl_l2>; }; /* Cluster 2 */ cpucl2_0: cpu@200 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x0 0x200>; - enable-method = "psci"; - clock-frequency = <2400000000>; - cpu-idle-states = <&cpu_sleep>; - i-cache-size = <0xc000>; - i-cache-line-size = <64>; - i-cache-sets = <256>; - d-cache-size = <0x8000>; - d-cache-line-size = <64>; - d-cache-sets = <256>; - next-level-cache = <&cpucl_l2>; + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <0x0 0x200>; + enable-method = "psci"; + clock-frequency = <2400000000>; + cpu-idle-states = <&cpu_sleep>; + i-cache-size = <0xc000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&cpucl_l2>; }; cpucl2_1: cpu@201 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x0 0x201>; - enable-method = "psci"; - clock-frequency = <2400000000>; - cpu-idle-states = <&cpu_sleep>; - i-cache-size = <0xc000>; - i-cache-line-size = <64>; - i-cache-sets = <256>; - d-cache-size = <0x8000>; - d-cache-line-size = <64>; - d-cache-sets = <256>; - next-level-cache = <&cpucl_l2>; + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <0x0 0x201>; + enable-method = "psci"; + clock-frequency = <2400000000>; + cpu-idle-states = <&cpu_sleep>; + i-cache-size = <0xc000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&cpucl_l2>; }; cpucl2_2: cpu@202 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x0 0x202>; - enable-method = "psci"; - clock-frequency = <2400000000>; - cpu-idle-states = <&cpu_sleep>; - i-cache-size = <0xc000>; - i-cache-line-size = <64>; - i-cache-sets = <256>; - d-cache-size = <0x8000>; - d-cache-line-size = <64>; - d-cache-sets = <256>; - next-level-cache = <&cpucl_l2>; + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <0x0 0x202>; + enable-method = "psci"; + clock-frequency = <2400000000>; + cpu-idle-states = <&cpu_sleep>; + i-cache-size = <0xc000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&cpucl_l2>; }; cpucl2_3: cpu@203 { - device_type = "cpu"; - compatible = "arm,cortex-a72"; - reg = <0x0 0x203>; - enable-method = "psci"; - clock-frequency = <2400000000>; - cpu-idle-states = <&cpu_sleep>; - i-cache-size = <0xc000>; - i-cache-line-size = <64>; - i-cache-sets = <256>; - d-cache-size = <0x8000>; - d-cache-line-size = <64>; - d-cache-sets = <256>; - next-level-cache = <&cpucl_l2>; + device_type = "cpu"; + compatible = "arm,cortex-a72"; + reg = <0x0 0x203>; + enable-method = "psci"; + clock-frequency = <2400000000>; + cpu-idle-states = <&cpu_sleep>; + i-cache-size = <0xc000>; + i-cache-line-size = <64>; + i-cache-sets = <256>; + d-cache-size = <0x8000>; + d-cache-line-size = <64>; + d-cache-sets = <256>; + next-level-cache = <&cpucl_l2>; }; cpucl_l2: l2-cache0 { @@ -296,23 +302,23 @@ cpucl_l2: l2-cache0 { cache-line-size = <64>; cache-sets = <4096>; }; + }; - idle-states { - entry-method = "psci"; + idle-states { + entry-method = "psci"; - cpu_sleep: cpu-sleep { - idle-state-name = "c2"; - compatible = "arm,idle-state"; - local-timer-stop; - arm,psci-suspend-param = <0x0010000>; - entry-latency-us = <30>; - exit-latency-us = <75>; - min-residency-us = <300>; - }; + cpu_sleep: cpu-sleep { + compatible = "arm,idle-state"; + idle-state-name = "c2"; + local-timer-stop; + entry-latency-us = <30>; + exit-latency-us = <75>; + min-residency-us = <300>; + arm,psci-suspend-param = <0x0010000>; }; }; - arm-pmu { + pmu { compatible = "arm,cortex-a72-pmu"; interrupts = <GIC_SPI 356 IRQ_TYPE_LEVEL_HIGH>, <GIC_SPI 357 IRQ_TYPE_LEVEL_HIGH>, @@ -337,47 +343,107 @@ psci { method = "smc"; }; - timer { - compatible = "arm,armv8-timer"; - interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, - <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, - <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, - <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; - }; - - fin_pll: clock { - compatible = "fixed-clock"; - clock-output-names = "fin_pll"; - #clock-cells = <0>; - }; - reserved-memory { + ranges; #address-cells = <2>; #size-cells = <2>; - ranges; mfc_left: region@84000000 { compatible = "shared-dma-pool"; - no-map; reg = <0 0x84000000 0 0x8000000>; + no-map; }; }; soc: soc@0 { compatible = "simple-bus"; - #address-cells = <2>; - #size-cells = <2>; ranges = <0x0 0x0 0x0 0x0 0x0 0x18000000>; dma-ranges = <0x0 0x0 0x0 0x0 0x10 0x0>; + #address-cells = <2>; + #size-cells = <2>; - gic: interrupt-controller@10400000 { - compatible = "arm,gic-v3"; - #address-cells = <0>; - #interrupt-cells = <3>; - interrupt-controller; - reg = <0x0 0x10400000 0x0 0x10000>, /* GICD */ - <0x0 0x10600000 0x0 0x200000>; /* GICR_RD+GICR_SGI */ - interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + clock_imem: clock-controller@10010000 { + compatible = "tesla,fsd-clock-imem"; + reg = <0x0 0x10010000 0x0 0x3000>; + #clock-cells = <1>; + clocks = <&fin_pll>, + <&clock_cmu DOUT_CMU_IMEM_TCUCLK>, + <&clock_cmu DOUT_CMU_IMEM_ACLK>, + <&clock_cmu DOUT_CMU_IMEM_DMACLK>; + clock-names = "fin_pll", + "dout_cmu_imem_tcuclk", + "dout_cmu_imem_aclk", + "dout_cmu_imem_dmaclk"; + }; + + timer@10040000 { + compatible = "tesla,fsd-mct", "samsung,exynos4210-mct"; + reg = <0x0 0x10040000 0x0 0x800>; + interrupts = <GIC_SPI 455 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&fin_pll>, <&clock_imem IMEM_MCT_PCLK>; + clock-names = "fin_pll", "mct"; + }; + + watchdog_0: watchdog@100a0000 { + compatible = "tesla,fsd-wdt", "samsung,exynos7-wdt"; + reg = <0x0 0x100a0000 0x0 0x100>; + interrupts = <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&fin_pll>; + clock-names = "watchdog"; + samsung,syscon-phandle = <&pmu_system_controller>; + }; + + watchdog_1: watchdog@100b0000 { + compatible = "tesla,fsd-wdt", "samsung,exynos7-wdt"; + reg = <0x0 0x100b0000 0x0 0x100>; + interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&fin_pll>; + clock-names = "watchdog"; + samsung,syscon-phandle = <&pmu_system_controller>; + }; + + watchdog_2: watchdog@100c0000 { + compatible = "tesla,fsd-wdt", "samsung,exynos7-wdt"; + reg = <0x0 0x100c0000 0x0 0x100>; + interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&fin_pll>; + clock-names = "watchdog"; + samsung,syscon-phandle = <&pmu_system_controller>; + }; + + mdma0: dma-controller@10100000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x0 0x10100000 0x0 0x1000>; + interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>; + #dma-cells = <1>; + clocks = <&clock_imem IMEM_DMA0_IPCLKPORT_ACLK>; + clock-names = "apb_pclk"; + iommus = <&smmu_imem 0x800 0x0>; + }; + + mdma1: dma-controller@10110000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x0 0x10110000 0x0 0x1000>; + interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>; + #dma-cells = <1>; + clocks = <&clock_imem IMEM_DMA1_IPCLKPORT_ACLK>; + clock-names = "apb_pclk"; + iommus = <&smmu_imem 0x801 0x0>; }; smmu_imem: iommu@10200000 { @@ -400,6 +466,34 @@ smmu_imem: iommu@10200000 { <GIC_SPI 449 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_3 */ }; + gic: interrupt-controller@10400000 { + compatible = "arm,gic-v3"; + reg = <0x0 0x10400000 0x0 0x10000>, /* GICD */ + <0x0 0x10600000 0x0 0x200000>; /* GICR_RD+GICR_SGI */ + #address-cells = <0>; + #interrupt-cells = <3>; + interrupt-controller; + interrupts = <GIC_PPI 9 IRQ_TYPE_LEVEL_HIGH>; + }; + + pmu_system_controller: system-controller@11400000 { + compatible = "tesla,fsd-pmu", "samsung,exynos7-pmu", "syscon"; + reg = <0x0 0x11400000 0x0 0x5000>; + }; + + pinctrl_pmu: pinctrl@114f0000 { + compatible = "tesla,fsd-pinctrl"; + reg = <0x0 0x114f0000 0x0 0x1000>; + }; + + clock_cmu: clock-controller@11c10000 { + compatible = "tesla,fsd-clock-cmu"; + reg = <0x0 0x11c10000 0x0 0x3000>; + #clock-cells = <1>; + clocks = <&fin_pll>; + clock-names = "fin_pll"; + }; + smmu_isp: iommu@12100000 { compatible = "arm,mmu-500"; reg = <0x0 0x12100000 0x0 0x10000>; @@ -428,60 +522,6 @@ smmu_isp: iommu@12100000 { <GIC_SPI 337 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_7 */ }; - smmu_peric: iommu@14900000 { - compatible = "arm,mmu-500"; - reg = <0x0 0x14900000 0x0 0x10000>; - #iommu-cells = <2>; - #global-interrupts = <5>; - interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */ - <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */ - <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */ - <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */ - /* Performance counter interrupts */ - <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>, /* for PERIC */ - /* Per context non-secure context interrupts, 0-1 interrupts */ - <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */ - <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */ - }; - - smmu_fsys0: iommu@15450000 { - compatible = "arm,mmu-500"; - reg = <0x0 0x15450000 0x0 0x10000>; - #iommu-cells = <2>; - #global-interrupts = <5>; - interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */ - <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */ - <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */ - <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */ - /* Performance counter interrupts */ - <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS0 */ - /* Per context non-secure context interrupts, 0-1 interrupts */ - <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */ - <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */ - }; - - clock_imem: clock-controller@10010000 { - compatible = "tesla,fsd-clock-imem"; - reg = <0x0 0x10010000 0x0 0x3000>; - #clock-cells = <1>; - clocks = <&fin_pll>, - <&clock_cmu DOUT_CMU_IMEM_TCUCLK>, - <&clock_cmu DOUT_CMU_IMEM_ACLK>, - <&clock_cmu DOUT_CMU_IMEM_DMACLK>; - clock-names = "fin_pll", - "dout_cmu_imem_tcuclk", - "dout_cmu_imem_aclk", - "dout_cmu_imem_dmaclk"; - }; - - clock_cmu: clock-controller@11c10000 { - compatible = "tesla,fsd-clock-cmu"; - reg = <0x0 0x11c10000 0x0 0x3000>; - #clock-cells = <1>; - clocks = <&fin_pll>; - clock-names = "fin_pll"; - }; - clock_csi: clock-controller@12610000 { compatible = "tesla,fsd-clock-cam_csi"; reg = <0x0 0x12610000 0x0 0x3000>; @@ -503,6 +543,15 @@ clock_mfc: clock-controller@12810000 { clock-names = "fin_pll"; }; + mfc: mfc@12880000 { + compatible = "tesla,fsd-mfc"; + reg = <0x0 0x12880000 0x0 0x10000>; + interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>; + clocks = <&clock_mfc MFC_MFC_IPCLKPORT_ACLK>; + clock-names = "mfc"; + memory-region = <&mfc_left>; + }; + clock_peric: clock-controller@14010000 { compatible = "tesla,fsd-clock-peric"; reg = <0x0 0x14010000 0x0 0x3000>; @@ -526,80 +575,191 @@ sysreg_peric: system-controller@14030000 { reg = <0x0 0x14030000 0x0 0x1000>; }; - clock_fsys0: clock-controller@15010000 { - compatible = "tesla,fsd-clock-fsys0"; - reg = <0x0 0x15010000 0x0 0x3000>; + m_can0: can@14088000 { + compatible = "bosch,m_can"; + reg = <0x0 0x14088000 0x0 0x0200>, + <0x0 0x14080000 0x0 0x8000>; + reg-names = "m_can", "message_ram"; + interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "int0", "int1"; + pinctrl-0 = <&m_can0_bus>; + pinctrl-names = "default"; + clocks = <&clock_peric PERIC_MCAN0_IPCLKPORT_PCLK>, + <&clock_peric PERIC_MCAN0_IPCLKPORT_CCLK>; + clock-names = "hclk", "cclk"; + bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; + + status = "disabled"; + }; + + m_can1: can@14098000 { + compatible = "bosch,m_can"; + reg = <0x0 0x14098000 0x0 0x0200>, + <0x0 0x14090000 0x0 0x8000>; + reg-names = "m_can", "message_ram"; + interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "int0", "int1"; + pinctrl-0 = <&m_can1_bus>; + pinctrl-names = "default"; + clocks = <&clock_peric PERIC_MCAN1_IPCLKPORT_PCLK>, + <&clock_peric PERIC_MCAN1_IPCLKPORT_CCLK>; + clock-names = "hclk", "cclk"; + bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; + + status = "disabled"; + }; + + m_can2: can@140a8000 { + compatible = "bosch,m_can"; + reg = <0x0 0x140a8000 0x0 0x0200>, + <0x0 0x140a0000 0x0 0x8000>; + reg-names = "m_can", "message_ram"; + interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "int0", "int1"; + pinctrl-0 = <&m_can2_bus>; + pinctrl-names = "default"; + clocks = <&clock_peric PERIC_MCAN2_IPCLKPORT_PCLK>, + <&clock_peric PERIC_MCAN2_IPCLKPORT_CCLK>; + clock-names = "hclk", "cclk"; + bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; + + status = "disabled"; + }; + + m_can3: can@140b8000 { + compatible = "bosch,m_can"; + reg = <0x0 0x140b8000 0x0 0x0200>, + <0x0 0x140b0000 0x0 0x8000>; + reg-names = "m_can", "message_ram"; + interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, + <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "int0", "int1"; + pinctrl-0 = <&m_can3_bus>; + pinctrl-names = "default"; + clocks = <&clock_peric PERIC_MCAN3_IPCLKPORT_PCLK>, + <&clock_peric PERIC_MCAN3_IPCLKPORT_CCLK>; + clock-names = "hclk", "cclk"; + bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; + + status = "disabled"; + }; + + i2s_0: i2s@140e0000 { + compatible = "tesla,fsd-i2s"; + reg = <0x0 0x140e0000 0x0 0x100>; + interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&pdma1 14>, <&pdma1 13>, <&pdma1 12>; + dma-names = "tx", "rx", "tx-sec"; #clock-cells = <1>; - clocks = <&fin_pll>, - <&clock_cmu DOUT_CMU_PLL_SHARED0_DIV6>, - <&clock_cmu DOUT_CMU_FSYS0_SHARED1DIV4>, - <&clock_cmu DOUT_CMU_FSYS0_SHARED0DIV4>; - clock-names = "fin_pll", - "dout_cmu_pll_shared0_div6", - "dout_cmu_fsys0_shared1div4", - "dout_cmu_fsys0_shared0div4"; + clocks = <&clock_peric PERIC_PCLK_TDM0>, + <&clock_peric PERIC_HCLK_TDM0>, + <&clock_peric PERIC_HCLK_TDM0>; + clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; + pinctrl-0 = <&i2s0_bus>; + pinctrl-names = "default"; + #sound-dai-cells = <1>; + + status = "disabled"; }; - sysreg_fsys0: system-controller@15030000 { - compatible = "tesla,fsd-fsys0-sysreg", "syscon"; - reg = <0x0 0x15030000 0x0 0x1000>; - }; - - clock_fsys1: clock-controller@16810000 { - compatible = "tesla,fsd-clock-fsys1"; - reg = <0x0 0x16810000 0x0 0x3000>; + i2s_1: i2s@140f0000 { + compatible = "tesla,fsd-i2s"; + reg = <0x0 0x140f0000 0x0 0x100>; + interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&pdma1 17>, <&pdma1 16>, <&pdma1 15>; + dma-names = "tx", "rx", "tx-sec"; #clock-cells = <1>; - clocks = <&fin_pll>, - <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>, - <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>; - clock-names = "fin_pll", - "dout_cmu_fsys1_shared0div8", - "dout_cmu_fsys1_shared0div4"; + clocks = <&clock_peric PERIC_PCLK_TDM1>, + <&clock_peric PERIC_HCLK_TDM1>, + <&clock_peric PERIC_HCLK_TDM1>; + clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; + pinctrl-0 = <&i2s1_bus>; + pinctrl-names = "default"; + #sound-dai-cells = <1>; + + status = "disabled"; }; - sysreg_fsys1: system-controller@16830000 { - compatible = "tesla,fsd-fsys1-sysreg", "syscon"; - reg = <0x0 0x16830000 0x0 0x1000>; + pwm_0: pwm@14100000 { + compatible = "tesla,fsd-pwm", "samsung,exynos4210-pwm"; + reg = <0x0 0x14100000 0x0 0x100>; + #pwm-cells = <3>; + clocks = <&clock_peric PERIC_PWM0_IPCLKPORT_I_PCLK_S0>; + clock-names = "timers"; + samsung,pwm-outputs = <0>, <1>, <2>, <3>; + + status = "disabled"; }; - mdma0: dma-controller@10100000 { - compatible = "arm,pl330", "arm,primecell"; - reg = <0x0 0x10100000 0x0 0x1000>; - interrupts = <GIC_SPI 424 IRQ_TYPE_LEVEL_HIGH>; - #dma-cells = <1>; - clocks = <&clock_imem IMEM_DMA0_IPCLKPORT_ACLK>; - clock-names = "apb_pclk"; - iommus = <&smmu_imem 0x800 0x0>; + pwm_1: pwm@14110000 { + compatible = "tesla,fsd-pwm", "samsung,exynos4210-pwm"; + reg = <0x0 0x14110000 0x0 0x100>; + #pwm-cells = <3>; + clocks = <&clock_peric PERIC_PWM1_IPCLKPORT_I_PCLK_S0>; + clock-names = "timers"; + samsung,pwm-outputs = <0>, <1>, <2>, <3>; + + status = "disabled"; }; - mdma1: dma-controller@10110000 { - compatible = "arm,pl330", "arm,primecell"; - reg = <0x0 0x10110000 0x0 0x1000>; - interrupts = <GIC_SPI 425 IRQ_TYPE_LEVEL_HIGH>; - #dma-cells = <1>; - clocks = <&clock_imem IMEM_DMA1_IPCLKPORT_ACLK>; - clock-names = "apb_pclk"; - iommus = <&smmu_imem 0x801 0x0>; + spi_0: spi@14140000 { + compatible = "tesla,fsd-spi"; + reg = <0x0 0x14140000 0x0 0x100>; + interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&pdma1 4>, <&pdma1 5>; + dma-names = "tx", "rx"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clock_peric PERIC_PCLK_SPI0>, + <&clock_peric PERIC_SCLK_SPI0>; + clock-names = "spi", "spi_busclk0"; + pinctrl-0 = <&spi0_bus>; + pinctrl-names = "default"; + num-cs = <1>; + samsung,spi-src-clk = <0>; + + status = "disabled"; }; - pdma0: dma-controller@14280000 { - compatible = "arm,pl330", "arm,primecell"; - reg = <0x0 0x14280000 0x0 0x1000>; - interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>; - #dma-cells = <1>; - clocks = <&clock_peric PERIC_DMA0_IPCLKPORT_ACLK>; - clock-names = "apb_pclk"; - iommus = <&smmu_peric 0x2 0x0>; + spi_1: spi@14150000 { + compatible = "tesla,fsd-spi"; + reg = <0x0 0x14150000 0x0 0x100>; + interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&pdma1 6>, <&pdma1 7>; + dma-names = "tx", "rx"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clock_peric PERIC_PCLK_SPI1>, + <&clock_peric PERIC_SCLK_SPI1>; + clock-names = "spi", "spi_busclk0"; + pinctrl-0 = <&spi1_bus>; + pinctrl-names = "default"; + num-cs = <1>; + samsung,spi-src-clk = <0>; + + status = "disabled"; }; - pdma1: dma-controller@14290000 { - compatible = "arm,pl330", "arm,primecell"; - reg = <0x0 0x14290000 0x0 0x1000>; - interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>; - #dma-cells = <1>; - clocks = <&clock_peric PERIC_DMA1_IPCLKPORT_ACLK>; - clock-names = "apb_pclk"; - iommus = <&smmu_peric 0x1 0x0>; + spi_2: spi@14160000 { + compatible = "tesla,fsd-spi"; + reg = <0x0 0x14160000 0x0 0x100>; + interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>; + dmas = <&pdma1 8>, <&pdma1 9>; + dma-names = "tx", "rx"; + #address-cells = <1>; + #size-cells = <0>; + clocks = <&clock_peric PERIC_PCLK_SPI2>, + <&clock_peric PERIC_SCLK_SPI2>; + clock-names = "spi", "spi_busclk0"; + pinctrl-0 = <&spi2_bus>; + pinctrl-names = "default"; + num-cs = <1>; + samsung,spi-src-clk = <0>; + + status = "disabled"; }; serial_0: serial@14180000 { @@ -630,58 +790,10 @@ serial_1: serial@14190000 { status = "disabled"; }; - pmu_system_controller: system-controller@11400000 { - compatible = "tesla,fsd-pmu", "samsung,exynos7-pmu", "syscon"; - reg = <0x0 0x11400000 0x0 0x5000>; - }; - - watchdog_0: watchdog@100a0000 { - compatible = "tesla,fsd-wdt", "samsung,exynos7-wdt"; - reg = <0x0 0x100a0000 0x0 0x100>; - interrupts = <GIC_SPI 471 IRQ_TYPE_LEVEL_HIGH>; - samsung,syscon-phandle = <&pmu_system_controller>; - clocks = <&fin_pll>; - clock-names = "watchdog"; - }; - - watchdog_1: watchdog@100b0000 { - compatible = "tesla,fsd-wdt", "samsung,exynos7-wdt"; - reg = <0x0 0x100b0000 0x0 0x100>; - interrupts = <GIC_SPI 472 IRQ_TYPE_LEVEL_HIGH>; - samsung,syscon-phandle = <&pmu_system_controller>; - clocks = <&fin_pll>; - clock-names = "watchdog"; - }; - - watchdog_2: watchdog@100c0000 { - compatible = "tesla,fsd-wdt", "samsung,exynos7-wdt"; - reg = <0x0 0x100c0000 0x0 0x100>; - interrupts = <GIC_SPI 473 IRQ_TYPE_LEVEL_HIGH>; - samsung,syscon-phandle = <&pmu_system_controller>; - clocks = <&fin_pll>; - clock-names = "watchdog"; - }; - - pwm_0: pwm@14100000 { - compatible = "tesla,fsd-pwm", "samsung,exynos4210-pwm"; - reg = <0x0 0x14100000 0x0 0x100>; - samsung,pwm-outputs = <0>, <1>, <2>, <3>; - #pwm-cells = <3>; - clocks = <&clock_peric PERIC_PWM0_IPCLKPORT_I_PCLK_S0>; - clock-names = "timers"; - - status = "disabled"; - }; - - pwm_1: pwm@14110000 { - compatible = "tesla,fsd-pwm", "samsung,exynos4210-pwm"; - reg = <0x0 0x14110000 0x0 0x100>; - samsung,pwm-outputs = <0>, <1>, <2>, <3>; - #pwm-cells = <3>; - clocks = <&clock_peric PERIC_PWM1_IPCLKPORT_I_PCLK_S0>; - clock-names = "timers"; - - status = "disabled"; + pinctrl_peric: pinctrl@141f0000 { + compatible = "tesla,fsd-pinctrl"; + reg = <0x0 0x141f0000 0x0 0x1000>; + interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>; }; hsi2c_0: i2c@14200000 { @@ -690,8 +802,8 @@ hsi2c_0: i2c@14200000 { interrupts = <GIC_SPI 148 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c0_bus>; + pinctrl-names = "default"; clocks = <&clock_peric PERIC_PCLK_HSI2C0>; clock-names = "hsi2c"; @@ -704,8 +816,8 @@ hsi2c_1: i2c@14210000 { interrupts = <GIC_SPI 149 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c1_bus>; + pinctrl-names = "default"; clocks = <&clock_peric PERIC_PCLK_HSI2C1>; clock-names = "hsi2c"; @@ -718,8 +830,8 @@ hsi2c_2: i2c@14220000 { interrupts = <GIC_SPI 150 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c2_bus>; + pinctrl-names = "default"; clocks = <&clock_peric PERIC_PCLK_HSI2C2>; clock-names = "hsi2c"; @@ -732,8 +844,8 @@ hsi2c_3: i2c@14230000 { interrupts = <GIC_SPI 151 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c3_bus>; + pinctrl-names = "default"; clocks = <&clock_peric PERIC_PCLK_HSI2C3>; clock-names = "hsi2c"; @@ -746,8 +858,8 @@ hsi2c_4: i2c@14240000 { interrupts = <GIC_SPI 152 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c4_bus>; + pinctrl-names = "default"; clocks = <&clock_peric PERIC_PCLK_HSI2C4>; clock-names = "hsi2c"; @@ -760,8 +872,8 @@ hsi2c_5: i2c@14250000 { interrupts = <GIC_SPI 153 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c5_bus>; + pinctrl-names = "default"; clocks = <&clock_peric PERIC_PCLK_HSI2C5>; clock-names = "hsi2c"; @@ -774,8 +886,8 @@ hsi2c_6: i2c@14260000 { interrupts = <GIC_SPI 154 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c6_bus>; + pinctrl-names = "default"; clocks = <&clock_peric PERIC_PCLK_HSI2C6>; clock-names = "hsi2c"; @@ -788,226 +900,32 @@ hsi2c_7: i2c@14270000 { interrupts = <GIC_SPI 155 IRQ_TYPE_LEVEL_HIGH>; #address-cells = <1>; #size-cells = <0>; - pinctrl-names = "default"; pinctrl-0 = <&hs_i2c7_bus>; + pinctrl-names = "default"; clocks = <&clock_peric PERIC_PCLK_HSI2C7>; clock-names = "hsi2c"; status = "disabled"; }; - i2s_0: i2s@140e0000 { - compatible = "tesla,fsd-i2s"; - reg = <0x0 0x140e0000 0x0 0x100>; - interrupts = <GIC_SPI 206 IRQ_TYPE_LEVEL_HIGH>; - dmas = <&pdma1 14>, <&pdma1 13>, <&pdma1 12>; - dma-names = "tx", "rx", "tx-sec"; - #clock-cells = <1>; - clocks = <&clock_peric PERIC_PCLK_TDM0>, - <&clock_peric PERIC_HCLK_TDM0>, - <&clock_peric PERIC_HCLK_TDM0>; - clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; - pinctrl-names = "default"; - pinctrl-0 = <&i2s0_bus>; - #sound-dai-cells = <1>; - - status = "disabled"; + pdma0: dma-controller@14280000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x0 0x14280000 0x0 0x1000>; + interrupts = <GIC_SPI 190 IRQ_TYPE_LEVEL_HIGH>; + #dma-cells = <1>; + clocks = <&clock_peric PERIC_DMA0_IPCLKPORT_ACLK>; + clock-names = "apb_pclk"; + iommus = <&smmu_peric 0x2 0x0>; }; - i2s_1: i2s@140f0000 { - compatible = "tesla,fsd-i2s"; - reg = <0x0 0x140f0000 0x0 0x100>; - interrupts = <GIC_SPI 207 IRQ_TYPE_LEVEL_HIGH>; - dmas = <&pdma1 17>, <&pdma1 16>, <&pdma1 15>; - dma-names = "tx", "rx", "tx-sec"; - #clock-cells = <1>; - clocks = <&clock_peric PERIC_PCLK_TDM1>, - <&clock_peric PERIC_HCLK_TDM1>, - <&clock_peric PERIC_HCLK_TDM1>; - clock-names = "iis", "i2s_opclk0", "i2s_opclk1"; - pinctrl-names = "default"; - pinctrl-0 = <&i2s1_bus>; - #sound-dai-cells = <1>; - - status = "disabled"; - }; - - pinctrl_pmu: pinctrl@114f0000 { - compatible = "tesla,fsd-pinctrl"; - reg = <0x0 0x114f0000 0x0 0x1000>; - }; - - pinctrl_peric: pinctrl@141f0000 { - compatible = "tesla,fsd-pinctrl"; - reg = <0x0 0x141f0000 0x0 0x1000>; - interrupts = <GIC_SPI 189 IRQ_TYPE_LEVEL_HIGH>; - }; - - pinctrl_fsys0: pinctrl@15020000 { - compatible = "tesla,fsd-pinctrl"; - reg = <0x0 0x15020000 0x0 0x1000>; - interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; - }; - - m_can0: can@14088000 { - compatible = "bosch,m_can"; - reg = <0x0 0x14088000 0x0 0x0200>, - <0x0 0x14080000 0x0 0x8000>; - reg-names = "m_can", "message_ram"; - interrupts = <GIC_SPI 159 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 160 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "int0", "int1"; - pinctrl-names = "default"; - pinctrl-0 = <&m_can0_bus>; - clocks = <&clock_peric PERIC_MCAN0_IPCLKPORT_PCLK>, - <&clock_peric PERIC_MCAN0_IPCLKPORT_CCLK>; - clock-names = "hclk", "cclk"; - bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; - - status = "disabled"; - }; - - m_can1: can@14098000 { - compatible = "bosch,m_can"; - reg = <0x0 0x14098000 0x0 0x0200>, - <0x0 0x14090000 0x0 0x8000>; - reg-names = "m_can", "message_ram"; - interrupts = <GIC_SPI 162 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 163 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "int0", "int1"; - pinctrl-names = "default"; - pinctrl-0 = <&m_can1_bus>; - clocks = <&clock_peric PERIC_MCAN1_IPCLKPORT_PCLK>, - <&clock_peric PERIC_MCAN1_IPCLKPORT_CCLK>; - clock-names = "hclk", "cclk"; - bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; - - status = "disabled"; - }; - - m_can2: can@140a8000 { - compatible = "bosch,m_can"; - reg = <0x0 0x140a8000 0x0 0x0200>, - <0x0 0x140a0000 0x0 0x8000>; - reg-names = "m_can", "message_ram"; - interrupts = <GIC_SPI 165 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 166 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "int0", "int1"; - pinctrl-names = "default"; - pinctrl-0 = <&m_can2_bus>; - clocks = <&clock_peric PERIC_MCAN2_IPCLKPORT_PCLK>, - <&clock_peric PERIC_MCAN2_IPCLKPORT_CCLK>; - clock-names = "hclk", "cclk"; - bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; - - status = "disabled"; - }; - - m_can3: can@140b8000 { - compatible = "bosch,m_can"; - reg = <0x0 0x140b8000 0x0 0x0200>, - <0x0 0x140b0000 0x0 0x8000>; - reg-names = "m_can", "message_ram"; - interrupts = <GIC_SPI 168 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>; - interrupt-names = "int0", "int1"; - pinctrl-names = "default"; - pinctrl-0 = <&m_can3_bus>; - clocks = <&clock_peric PERIC_MCAN3_IPCLKPORT_PCLK>, - <&clock_peric PERIC_MCAN3_IPCLKPORT_CCLK>; - clock-names = "hclk", "cclk"; - bosch,mram-cfg = <0x0 128 64 64 64 64 32 32>; - - status = "disabled"; - }; - - spi_0: spi@14140000 { - compatible = "tesla,fsd-spi"; - reg = <0x0 0x14140000 0x0 0x100>; - interrupts = <GIC_SPI 156 IRQ_TYPE_LEVEL_HIGH>; - dmas = <&pdma1 4>, <&pdma1 5>; - dma-names = "tx", "rx"; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clock_peric PERIC_PCLK_SPI0>, - <&clock_peric PERIC_SCLK_SPI0>; - clock-names = "spi", "spi_busclk0"; - samsung,spi-src-clk = <0>; - pinctrl-names = "default"; - pinctrl-0 = <&spi0_bus>; - num-cs = <1>; - - status = "disabled"; - }; - - spi_1: spi@14150000 { - compatible = "tesla,fsd-spi"; - reg = <0x0 0x14150000 0x0 0x100>; - interrupts = <GIC_SPI 157 IRQ_TYPE_LEVEL_HIGH>; - dmas = <&pdma1 6>, <&pdma1 7>; - dma-names = "tx", "rx"; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clock_peric PERIC_PCLK_SPI1>, - <&clock_peric PERIC_SCLK_SPI1>; - clock-names = "spi", "spi_busclk0"; - samsung,spi-src-clk = <0>; - pinctrl-names = "default"; - pinctrl-0 = <&spi1_bus>; - num-cs = <1>; - - status = "disabled"; - }; - - spi_2: spi@14160000 { - compatible = "tesla,fsd-spi"; - reg = <0x0 0x14160000 0x0 0x100>; - interrupts = <GIC_SPI 158 IRQ_TYPE_LEVEL_HIGH>; - dmas = <&pdma1 8>, <&pdma1 9>; - dma-names = "tx", "rx"; - #address-cells = <1>; - #size-cells = <0>; - clocks = <&clock_peric PERIC_PCLK_SPI2>, - <&clock_peric PERIC_SCLK_SPI2>; - clock-names = "spi", "spi_busclk0"; - samsung,spi-src-clk = <0>; - pinctrl-names = "default"; - pinctrl-0 = <&spi2_bus>; - num-cs = <1>; - - status = "disabled"; - }; - - timer@10040000 { - compatible = "tesla,fsd-mct", "samsung,exynos4210-mct"; - reg = <0x0 0x10040000 0x0 0x800>; - interrupts = <GIC_SPI 455 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 456 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 457 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 458 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 459 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 460 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 461 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 462 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 463 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 464 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 465 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 466 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 467 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 468 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 469 IRQ_TYPE_LEVEL_HIGH>, - <GIC_SPI 470 IRQ_TYPE_LEVEL_HIGH>; - clocks = <&fin_pll>, <&clock_imem IMEM_MCT_PCLK>; - clock-names = "fin_pll", "mct"; - }; - - mfc: mfc@12880000 { - compatible = "tesla,fsd-mfc"; - reg = <0x0 0x12880000 0x0 0x10000>; - interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>; - clock-names = "mfc"; - clocks = <&clock_mfc MFC_MFC_IPCLKPORT_ACLK>; - memory-region = <&mfc_left>; + pdma1: dma-controller@14290000 { + compatible = "arm,pl330", "arm,primecell"; + reg = <0x0 0x14290000 0x0 0x1000>; + interrupts = <GIC_SPI 191 IRQ_TYPE_LEVEL_HIGH>; + #dma-cells = <1>; + clocks = <&clock_peric PERIC_DMA1_IPCLKPORT_ACLK>; + clock-names = "apb_pclk"; + iommus = <&smmu_peric 0x1 0x0>; }; ethernet1: ethernet@14300000 { @@ -1031,16 +949,57 @@ ethernet1: ethernet@14300000 { assigned-clocks = <&clock_peric PERIC_EQOS_PHYRXCLK_MUX>, <&clock_peric PERIC_EQOS_PHYRXCLK>; assigned-clock-parents = <&clock_peric PERIC_EQOS_PHYRXCLK>; - pinctrl-names = "default"; pinctrl-0 = <ð1_tx_clk>, <ð1_tx_data>, <ð1_tx_ctrl>, <ð1_phy_intr>, <ð1_rx_clk>, <ð1_rx_data>, <ð1_rx_ctrl>, <ð1_mdio>; + pinctrl-names = "default"; local-mac-address = [00 00 00 00 00 00]; iommus = <&smmu_peric 0x0 0x1>; status = "disabled"; }; + smmu_peric: iommu@14900000 { + compatible = "arm,mmu-500"; + reg = <0x0 0x14900000 0x0 0x10000>; + #iommu-cells = <2>; + #global-interrupts = <5>; + interrupts = <GIC_SPI 197 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */ + <GIC_SPI 196 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */ + <GIC_SPI 193 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */ + <GIC_SPI 192 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */ + /* Performance counter interrupts */ + <GIC_SPI 198 IRQ_TYPE_LEVEL_HIGH>, /* for PERIC */ + /* Per context non-secure context interrupts, 0-1 interrupts */ + <GIC_SPI 194 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */ + <GIC_SPI 195 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */ + }; + + clock_fsys0: clock-controller@15010000 { + compatible = "tesla,fsd-clock-fsys0"; + reg = <0x0 0x15010000 0x0 0x3000>; + #clock-cells = <1>; + clocks = <&fin_pll>, + <&clock_cmu DOUT_CMU_PLL_SHARED0_DIV6>, + <&clock_cmu DOUT_CMU_FSYS0_SHARED1DIV4>, + <&clock_cmu DOUT_CMU_FSYS0_SHARED0DIV4>; + clock-names = "fin_pll", + "dout_cmu_pll_shared0_div6", + "dout_cmu_fsys0_shared1div4", + "dout_cmu_fsys0_shared0div4"; + }; + + pinctrl_fsys0: pinctrl@15020000 { + compatible = "tesla,fsd-pinctrl"; + reg = <0x0 0x15020000 0x0 0x1000>; + interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>; + }; + + sysreg_fsys0: system-controller@15030000 { + compatible = "tesla,fsd-fsys0-sysreg", "syscon"; + reg = <0x0 0x15030000 0x0 0x1000>; + }; + ufs: ufs@15120000 { compatible = "tesla,fsd-ufs"; reg = <0x0 0x15120000 0x0 0x200>, /* 0: HCI standard */ @@ -1053,8 +1012,8 @@ ufs: ufs@15120000 { <&clock_fsys0 UFS0_TOP0_CLK_UNIPRO>; clock-names = "core_clk", "sclk_unipro_main"; freq-table-hz = <0 0>, <0 0>; - pinctrl-names = "default"; pinctrl-0 = <&ufs_rst_n &ufs_refclk_out>; + pinctrl-names = "default"; phys = <&ufs_phy>; phy-names = "ufs-phy"; @@ -1065,10 +1024,10 @@ ufs_phy: ufs-phy@15124000 { compatible = "tesla,fsd-ufs-phy"; reg = <0x0 0x15124000 0x0 0x800>; reg-names = "phy-pma"; - samsung,pmu-syscon = <&pmu_system_controller>; #phy-cells = <0>; clocks = <&clock_fsys0 UFS0_MPHY_REFCLK_IXTAL26>; clock-names = "ref_clk"; + samsung,pmu-syscon = <&pmu_system_controller>; }; ethernet0: ethernet@15300000 { @@ -1082,15 +1041,56 @@ ethernet0: ethernet@15300000 { <&clock_fsys0 FSYS0_EQOS_TOP0_IPCLKPORT_RGMII_CLK_I>, <&clock_fsys0 FSYS0_EQOS_TOP0_IPCLKPORT_CLK_RX_I>; clock-names = "ptp_ref", "master_bus", "slave_bus", "tx", "rx"; - pinctrl-names = "default"; pinctrl-0 = <ð0_tx_clk>, <ð0_tx_data>, <ð0_tx_ctrl>, <ð0_phy_intr>, <ð0_rx_clk>, <ð0_rx_data>, <ð0_rx_ctrl>, <ð0_mdio>; + pinctrl-names = "default"; local-mac-address = [00 00 00 00 00 00]; iommus = <&smmu_fsys0 0x0 0x1>; status = "disabled"; }; + + smmu_fsys0: iommu@15450000 { + compatible = "arm,mmu-500"; + reg = <0x0 0x15450000 0x0 0x10000>; + #iommu-cells = <2>; + #global-interrupts = <5>; + interrupts = <GIC_SPI 100 IRQ_TYPE_LEVEL_HIGH>, /* Global secure fault */ + <GIC_SPI 99 IRQ_TYPE_LEVEL_HIGH>, /* Global non-secure fault */ + <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>, /* Combined secure interrupt */ + <GIC_SPI 95 IRQ_TYPE_LEVEL_HIGH>, /* Combined non-secure interrupt */ + /* Performance counter interrupts */ + <GIC_SPI 101 IRQ_TYPE_LEVEL_HIGH>, /* for FSYS0 */ + /* Per context non-secure context interrupts, 0-1 interrupts */ + <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>, /* for CONTEXT_0 */ + <GIC_SPI 98 IRQ_TYPE_LEVEL_HIGH>; /* for CONTEXT_1 */ + }; + + clock_fsys1: clock-controller@16810000 { + compatible = "tesla,fsd-clock-fsys1"; + reg = <0x0 0x16810000 0x0 0x3000>; + #clock-cells = <1>; + clocks = <&fin_pll>, + <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV8>, + <&clock_cmu DOUT_CMU_FSYS1_SHARED0DIV4>; + clock-names = "fin_pll", + "dout_cmu_fsys1_shared0div8", + "dout_cmu_fsys1_shared0div4"; + }; + + sysreg_fsys1: system-controller@16830000 { + compatible = "tesla,fsd-fsys1-sysreg", "syscon"; + reg = <0x0 0x16830000 0x0 0x1000>; + }; + }; + + timer { + compatible = "arm,armv8-timer"; + interrupts = <GIC_PPI 13 IRQ_TYPE_LEVEL_LOW>, + <GIC_PPI 14 IRQ_TYPE_LEVEL_LOW>, + <GIC_PPI 11 IRQ_TYPE_LEVEL_LOW>, + <GIC_PPI 10 IRQ_TYPE_LEVEL_LOW>; }; };
diff --git a/arch/arm64/boot/dts/ti/Makefile b/arch/arm64/boot/dts/ti/Makefile index 795978e..da65415 100644 --- a/arch/arm64/boot/dts/ti/Makefile +++ b/arch/arm64/boot/dts/ti/Makefile
@@ -91,6 +91,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62p5-verdin-nonwifi-ivy.dtb dtb-$(CONFIG_ARCH_K3) += k3-am62p5-verdin-nonwifi-mallow.dtb dtb-$(CONFIG_ARCH_K3) += k3-am62p5-verdin-nonwifi-yavia.dtb +dtb-$(CONFIG_ARCH_K3) += k3-am62p5-verdin-nonwifi-zinnia.dtb dtb-$(CONFIG_ARCH_K3) += k3-am62p5-verdin-ov5640-24mhz.dtbo dtb-$(CONFIG_ARCH_K3) += k3-am62p5-verdin-ov5640.dtbo dtb-$(CONFIG_ARCH_K3) += k3-am62p5-verdin-wifi-dahlia.dtb @@ -98,6 +99,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am62p5-verdin-wifi-ivy.dtb dtb-$(CONFIG_ARCH_K3) += k3-am62p5-verdin-wifi-mallow.dtb dtb-$(CONFIG_ARCH_K3) += k3-am62p5-verdin-wifi-yavia.dtb +dtb-$(CONFIG_ARCH_K3) += k3-am62p5-verdin-wifi-zinnia.dtb # Common overlays for SK-AM62* family of boards dtb-$(CONFIG_ARCH_K3) += k3-am62x-sk-csi2-ov5640.dtbo @@ -196,10 +198,12 @@ dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-gesi-exp-board.dtbo k3-j721s2-evm-dtbs := k3-j721s2-common-proc-board.dtb k3-j721s2-evm-gesi-exp-board.dtbo dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm.dtb +dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-audio.dtbo dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-pcie1-ep.dtbo dtb-$(CONFIG_ARCH_K3) += k3-j721s2-evm-usb0-type-a.dtbo # Boards with J722s SoC +dtb-$(CONFIG_ARCH_K3) += k3-am6754-phyboard-rigel.dtb dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai.dtb dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-csi0-imx219.dtbo dtb-$(CONFIG_ARCH_K3) += k3-am67a-beagley-ai-csi1-imx219.dtbo @@ -225,6 +229,7 @@ dtb-$(CONFIG_ARCH_K3) += k3-am69-aquila-dev-dsi-to-hdmi.dtb dtb-$(CONFIG_ARCH_K3) += k3-am69-aquila-dsi-to-hdmi.dtbo dtb-$(CONFIG_ARCH_K3) += k3-am69-aquila-dsi-to-lvds-panel-cap-touch-10inch.dtbo +dtb-$(CONFIG_ARCH_K3) += k3-am69-aquila-dsi-to-lvds-v2-panel-cap-touch-10inch.dtbo dtb-$(CONFIG_ARCH_K3) += k3-am69-aquila-panel-cap-touch-10inch-dsi.dtbo dtb-$(CONFIG_ARCH_K3) += k3-am69-aquila-panel-cap-touch-7inch-dsi.dtbo dtb-$(CONFIG_ARCH_K3) += k3-am69-sk.dtb @@ -389,6 +394,9 @@ k3-am69-aquila-dev-dsi-to-lvds-panel-cap-touch-10inch-dtbs := \ k3-am69-aquila-dev.dtb \ k3-am69-aquila-dsi-to-lvds-panel-cap-touch-10inch.dtbo +k3-am69-aquila-dev-dsi-to-lvds-v2-panel-cap-touch-10inch-dtbs := \ + k3-am69-aquila-dev.dtb \ + k3-am69-aquila-dsi-to-lvds-v2-panel-cap-touch-10inch.dtbo k3-am69-sk-csi2-dual-imx219-dtbs := k3-am69-sk.dtb \ k3-j721e-sk-csi2-dual-imx219.dtbo k3-am69-sk-pcie0-ep-dtbs := k3-am69-sk.dtb \ @@ -403,6 +411,8 @@ k3-j721e-evm-pcie1-ep.dtbo k3-j721e-sk-csi2-dual-imx219-dtbs := k3-j721e-sk.dtb \ k3-j721e-sk-csi2-dual-imx219.dtbo +k3-j721s2-evm-audio-dtbs := k3-j721s2-common-proc-board.dtb \ + k3-j721s2-evm-audio.dtbo k3-j721s2-evm-pcie1-ep-dtbs := k3-j721s2-common-proc-board.dtb \ k3-j721s2-evm-pcie1-ep.dtbo k3-j721s2-evm-usb0-type-a-dtbs := k3-j721s2-common-proc-board.dtb \ @@ -491,6 +501,7 @@ k3-am69-aquila-dev-csi-ov5640-24mhz.dtb \ k3-am69-aquila-dev-csi-ov5640.dtb \ k3-am69-aquila-dev-dsi-to-lvds-panel-cap-touch-10inch.dtb \ + k3-am69-aquila-dev-dsi-to-lvds-v2-panel-cap-touch-10inch.dtb \ k3-am69-sk-csi2-dual-imx219.dtb \ k3-am69-sk-pcie0-ep.dtb \ k3-j7200-evm-pcie1-ep.dtb \ @@ -498,6 +509,7 @@ k3-j721e-evm-pcie0-ep.dtb \ k3-j721e-evm-pcie1-ep.dtb \ k3-j721e-sk-csi2-dual-imx219.dtb \ + k3-j721s2-evm-audio.dtb \ k3-j721s2-evm-pcie1-ep.dtb \ k3-j721s2-evm-usb0-type-a.dtb \ k3-j722s-evm-csi2-quad-rpi-cam-imx219.dtb \
diff --git a/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts b/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts index dfd65c0..7fd508f 100644 --- a/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts +++ b/arch/arm64/boot/dts/ti/k3-am62-lp-sk.dts
@@ -86,7 +86,7 @@ main_mmc0_pins_default: main-mmc0-default-pins { bootph-all; pinctrl-single,pins = < AM62X_IOPAD(0x220, PIN_INPUT, 0) /* (V3) MMC0_CMD */ - AM62X_IOPAD(0x218, PIN_INPUT, 0) /* (Y1) MMC0_CLK */ + AM62X_IOPAD(0x218, PIN_OUTPUT, 0) /* (Y1) MMC0_CLK */ AM62X_IOPAD(0x214, PIN_INPUT, 0) /* (V2) MMC0_DAT0 */ AM62X_IOPAD(0x210, PIN_INPUT_PULLUP, 0) /* (V1) MMC0_DAT1 */ AM62X_IOPAD(0x20c, PIN_INPUT_PULLUP, 0) /* (W2) MMC0_DAT2 */
diff --git a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi index 3baa653..ce3e516 100644 --- a/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62-phycore-som.dtsi
@@ -153,7 +153,7 @@ AM62X_IOPAD(0x15c, PIN_INPUT, 0) /* (AB22) MDIO0_MDIO */ main_mmc0_pins_default: main-mmc0-default-pins { pinctrl-single,pins = < AM62X_IOPAD(0x220, PIN_INPUT_PULLUP, 0) /* (Y3) MMC0_CMD */ - AM62X_IOPAD(0x218, PIN_INPUT_PULLDOWN, 0) /* (AB1) MMC0_CLK */ + AM62X_IOPAD(0x218, PIN_OUTPUT_PULLDOWN, 0) /* (AB1) MMC0_CLK */ AM62X_IOPAD(0x214, PIN_INPUT_PULLUP, 0) /* (AA2) MMC0_DAT0 */ AM62X_IOPAD(0x210, PIN_INPUT_PULLUP, 0) /* (AA1) MMC0_DAT1 */ AM62X_IOPAD(0x20c, PIN_INPUT_PULLUP, 0) /* (AA3) MMC0_DAT2 */
diff --git a/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2.dts b/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2.dts index 7a4cffc..1c69162 100644 --- a/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2.dts +++ b/arch/arm64/boot/dts/ti/k3-am62-pocketbeagle2.dts
@@ -235,7 +235,7 @@ AM62X_IOPAD(0x0020, PIN_OUTPUT, 3) /* (J25) OSPI0_D5.UART6_TXD */ main_mmc1_pins_default: main-mmc1-default-pins { pinctrl-single,pins = < AM62X_IOPAD(0x23c, PIN_INPUT, 0) /* (A21/C18) MMC1_CMD */ - AM62X_IOPAD(0x234, PIN_INPUT, 0) /* (B22/A20) MMC1_CLK */ + AM62X_IOPAD(0x234, PIN_OUTPUT, 0) /* (B22/A20) MMC1_CLK */ AM62X_IOPAD(0x230, PIN_INPUT, 0) /* (A22/A19) MMC1_DAT0 */ AM62X_IOPAD(0x22c, PIN_INPUT, 0) /* (B21/B19) MMC1_DAT1 */ AM62X_IOPAD(0x228, PIN_INPUT, 0) /* (C21/B20) MMC1_DAT2 */
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-ivy.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-ivy.dtsi index 844f59f..c990761 100644 --- a/arch/arm64/boot/dts/ti/k3-am62-verdin-ivy.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-ivy.dtsi
@@ -367,6 +367,11 @@ &main_gpio0 { "", "", "", + "", + "", + "", + "", + "", /* 90 */ ""; }; @@ -425,42 +430,6 @@ &main_gpio1 { "", "", "", /* 50 */ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", /* 60 */ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", /* 70 */ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", /* 80 */ - "", - "", - "", - "", - "", - "", ""; };
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin-zinnia.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin-zinnia.dtsi index 0ce8357..f399764 100644 --- a/arch/arm64/boot/dts/ti/k3-am62-verdin-zinnia.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin-zinnia.dtsi
@@ -274,6 +274,11 @@ &main_gpio0 { "", "", "", + "", + "", + "", + "", + "", /* 90 */ ""; }; @@ -330,42 +335,6 @@ &main_gpio1 { "", "", "", /* 50 */ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", /* 60 */ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", /* 70 */ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", /* 80 */ - "", - "", - "", - "", - "", - "", ""; };
diff --git a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi index e97b2b0..77e6885 100644 --- a/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62-verdin.dtsi
@@ -573,7 +573,7 @@ AM62X_IOPAD(0x15c, PIN_INPUT, 0) /* (AB22) MDIO0_MDIO */ /* ETH_1_MDIO, SODIMM pinctrl_sdhci0: main-mmc0-default-pins { pinctrl-single,pins = < AM62X_IOPAD(0x220, PIN_INPUT, 0) /* (Y3) MMC0_CMD */ - AM62X_IOPAD(0x218, PIN_INPUT, 0) /* (AB1) MMC0_CLK */ + AM62X_IOPAD(0x218, PIN_OUTPUT, 0) /* (AB1) MMC0_CLK */ AM62X_IOPAD(0x214, PIN_INPUT, 0) /* (AA2) MMC0_DAT0 */ AM62X_IOPAD(0x210, PIN_INPUT_PULLUP, 0) /* (AA1) MMC0_DAT1 */ AM62X_IOPAD(0x20c, PIN_INPUT_PULLUP, 0) /* (AA3) MMC0_DAT2 */ @@ -589,7 +589,7 @@ AM62X_IOPAD(0x1f8, PIN_INPUT_PULLUP, 0) /* (AC2) MMC0_DAT7 */ pinctrl_sdhci1: main-mmc1-default-pins { pinctrl-single,pins = < AM62X_IOPAD(0x23c, PIN_INPUT, 0) /* (A21) MMC1_CMD */ /* SODIMM 74 */ - AM62X_IOPAD(0x234, PIN_INPUT, 0) /* (B22) MMC1_CLK */ /* SODIMM 78 */ + AM62X_IOPAD(0x234, PIN_OUTPUT, 0) /* (B22) MMC1_CLK */ /* SODIMM 78 */ AM62X_IOPAD(0x230, PIN_INPUT, 0) /* (A22) MMC1_DAT0 */ /* SODIMM 80 */ AM62X_IOPAD(0x22c, PIN_INPUT, 0) /* (B21) MMC1_DAT1 */ /* SODIMM 82 */ AM62X_IOPAD(0x228, PIN_INPUT, 0) /* (C21) MMC1_DAT2 */ /* SODIMM 70 */ @@ -601,7 +601,7 @@ AM62X_IOPAD(0x224, PIN_INPUT, 0) /* (D22) MMC1_DAT3 */ /* SODIMM 72 */ pinctrl_sdhci2: main-mmc2-default-pins { pinctrl-single,pins = < AM62X_IOPAD(0x120, PIN_INPUT, 0) /* (C24) MMC2_CMD */ /* WiFi_SDIO_CMD */ - AM62X_IOPAD(0x118, PIN_INPUT, 0) /* (D25) MMC2_CLK */ /* WiFi_SDIO_CLK */ + AM62X_IOPAD(0x118, PIN_OUTPUT,0) /* (D25) MMC2_CLK */ /* WiFi_SDIO_CLK */ AM62X_IOPAD(0x114, PIN_INPUT, 0) /* (B24) MMC2_DAT0 */ /* WiFi_SDIO_DATA0 */ AM62X_IOPAD(0x110, PIN_INPUT, 0) /* (C25) MMC2_DAT1 */ /* WiFi_SDIO_DATA1 */ AM62X_IOPAD(0x10c, PIN_INPUT, 0) /* (E23) MMC2_DAT2 */ /* WiFi_SDIO_DATA2 */ @@ -1012,6 +1012,11 @@ &main_gpio0 { "", "", "", + "", + "", + "", + "", + "", /* 90 */ ""; }; @@ -1065,45 +1070,9 @@ &main_gpio1 { "", "", "", - "", + "SODIMM_84", "SODIMM_17", "SODIMM_155", /* 50 */ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", /* 60 */ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", /* 70 */ - "", - "", - "", - "", - "", - "", - "", - "", - "", - "", /* 80 */ - "", - "", - "", - "", - "", - "", ""; };
diff --git a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts index c468b9c..898e4ca 100644 --- a/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts +++ b/arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts
@@ -323,7 +323,7 @@ emmc_pins_default: emmc-default-pins { bootph-all; pinctrl-single,pins = < AM62X_IOPAD(0x0220, PIN_INPUT, 0) /* (Y3) MMC0_CMD */ - AM62X_IOPAD(0x0218, PIN_INPUT, 0) /* (AB1) MMC0_CLK */ + AM62X_IOPAD(0x0218, PIN_OUTPUT, 0) /* (AB1) MMC0_CLK */ AM62X_IOPAD(0x0214, PIN_INPUT, 0) /* (AA2) MMC0_DAT0 */ AM62X_IOPAD(0x0210, PIN_INPUT, 0) /* (AA1) MMC0_DAT1 */ AM62X_IOPAD(0x020c, PIN_INPUT, 0) /* (AA3) MMC0_DAT2 */ @@ -346,7 +346,7 @@ sd_pins_default: sd-default-pins { bootph-all; pinctrl-single,pins = < AM62X_IOPAD(0x023c, PIN_INPUT, 0) /* (A21) MMC1_CMD */ - AM62X_IOPAD(0x0234, PIN_INPUT, 0) /* (B22) MMC1_CLK */ + AM62X_IOPAD(0x0234, PIN_OUTPUT, 0) /* (B22) MMC1_CLK */ AM62X_IOPAD(0x0230, PIN_INPUT, 0) /* (A22) MMC1_DAT0 */ AM62X_IOPAD(0x022c, PIN_INPUT, 0) /* (B21) MMC1_DAT1 */ AM62X_IOPAD(0x0228, PIN_INPUT, 0) /* (C21) MMC1_DAT2 */ @@ -358,7 +358,7 @@ AM62X_IOPAD(0x0240, PIN_INPUT, 7) /* (D17) MMC1_SDCD.GPIO1_48 */ wifi_pins_default: wifi-default-pins { pinctrl-single,pins = < AM62X_IOPAD(0x0120, PIN_INPUT, 0) /* (C24) MMC2_CMD */ - AM62X_IOPAD(0x0118, PIN_INPUT, 0) /* (D25) MMC2_CLK */ + AM62X_IOPAD(0x0118, PIN_OUTPUT, 0) /* (D25) MMC2_CLK */ AM62X_IOPAD(0x0114, PIN_INPUT, 0) /* (B24) MMC2_DAT0 */ AM62X_IOPAD(0x0110, PIN_INPUT, 0) /* (C25) MMC2_DAT1 */ AM62X_IOPAD(0x010c, PIN_INPUT, 0) /* (E23) MMC2_DAT2 */
diff --git a/arch/arm64/boot/dts/ti/k3-am625-sk-common.dtsi b/arch/arm64/boot/dts/ti/k3-am625-sk-common.dtsi index 9c83626..8e07d2c 100644 --- a/arch/arm64/boot/dts/ti/k3-am625-sk-common.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am625-sk-common.dtsi
@@ -98,7 +98,7 @@ main_mmc0_pins_default: main-mmc0-default-pins { bootph-all; pinctrl-single,pins = < AM62X_IOPAD(0x220, PIN_INPUT, 0) /* (Y3) MMC0_CMD */ - AM62X_IOPAD(0x218, PIN_INPUT, 0) /* (AB1) MMC0_CLK */ + AM62X_IOPAD(0x218, PIN_OUTPUT, 0) /* (AB1) MMC0_CLK */ AM62X_IOPAD(0x214, PIN_INPUT, 0) /* (AA2) MMC0_DAT0 */ AM62X_IOPAD(0x210, PIN_INPUT_PULLUP, 0) /* (AA1) MMC0_DAT1 */ AM62X_IOPAD(0x20c, PIN_INPUT_PULLUP, 0) /* (AA3) MMC0_DAT2 */ @@ -198,6 +198,7 @@ exp1: gpio@22 { &sdhci0 { bootph-all; + non-removable; status = "okay"; pinctrl-names = "default"; pinctrl-0 = <&main_mmc0_pins_default>;
diff --git a/arch/arm64/boot/dts/ti/k3-am625-tqma62xx-mba62xx.dts b/arch/arm64/boot/dts/ti/k3-am625-tqma62xx-mba62xx.dts index efc00d2..3859512 100644 --- a/arch/arm64/boot/dts/ti/k3-am625-tqma62xx-mba62xx.dts +++ b/arch/arm64/boot/dts/ti/k3-am625-tqma62xx-mba62xx.dts
@@ -735,7 +735,7 @@ main_mmc1_pins: main-mmc1-pins { /* (A21) MMC1_CMD */ AM62X_IOPAD(0x23c, PIN_INPUT, 0) /* (B22) MMC1_CLK */ - AM62X_IOPAD(0x234, PIN_INPUT, 0) + AM62X_IOPAD(0x234, PIN_OUTPUT, 0) /* (A22) MMC1_DAT0 */ AM62X_IOPAD(0x230, PIN_INPUT, 0) /* (B21) MMC1_DAT1 */ @@ -755,7 +755,7 @@ main_mmc2_pins: main-mmc2-pins { /* (C24) MMC2_CMD */ AM62X_IOPAD(0x120, PIN_INPUT, 0) /* (D25) MMC2_CLK */ - AM62X_IOPAD(0x118, PIN_INPUT, 0) + AM62X_IOPAD(0x118, PIN_OUTPUT, 0) /* (B24) MMC2_DAT0 */ AM62X_IOPAD(0x114, PIN_INPUT, 0) /* (C25) MMC2_DAT1 */
diff --git a/arch/arm64/boot/dts/ti/k3-am625-tqma62xx.dtsi b/arch/arm64/boot/dts/ti/k3-am625-tqma62xx.dtsi index 7228867..a200a2a 100644 --- a/arch/arm64/boot/dts/ti/k3-am625-tqma62xx.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am625-tqma62xx.dtsi
@@ -299,7 +299,7 @@ main_mmc0_pins: main-mmc0-pins { /* (Y3) MMC0_CMD */ AM62X_IOPAD(0x220, PIN_INPUT, 0) /* (AB1) MMC0_CLK */ - AM62X_IOPAD(0x218, PIN_INPUT, 0) + AM62X_IOPAD(0x218, PIN_OUTPUT, 0) /* (AA2) MMC0_DAT0 */ AM62X_IOPAD(0x214, PIN_INPUT, 0) /* (AA1) MMC0_DAT1 */
diff --git a/arch/arm64/boot/dts/ti/k3-am625-var-som-symphony.dts b/arch/arm64/boot/dts/ti/k3-am625-var-som-symphony.dts index 7951d7e..082bf81 100644 --- a/arch/arm64/boot/dts/ti/k3-am625-var-som-symphony.dts +++ b/arch/arm64/boot/dts/ti/k3-am625-var-som-symphony.dts
@@ -391,7 +391,7 @@ pinctrl_mmc1: main-mmc1-default-pins { bootph-all; pinctrl-single,pins = < AM62X_IOPAD(0x23c, PIN_INPUT, 0) /* (A21) MMC1_CMD */ - AM62X_IOPAD(0x234, PIN_INPUT, 0) /* (B22) MMC1_CLK */ + AM62X_IOPAD(0x234, PIN_OUTPUT, 0) /* (B22) MMC1_CLK */ AM62X_IOPAD(0x230, PIN_INPUT, 0) /* (A22) MMC1_DAT0 */ AM62X_IOPAD(0x22c, PIN_INPUT, 0) /* (B21) MMC1_DAT1 */ AM62X_IOPAD(0x228, PIN_INPUT, 0) /* (C21) MMC1_DAT2 */
diff --git a/arch/arm64/boot/dts/ti/k3-am625-var-som.dtsi b/arch/arm64/boot/dts/ti/k3-am625-var-som.dtsi index c2daa56..c23b6a9 100644 --- a/arch/arm64/boot/dts/ti/k3-am625-var-som.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am625-var-som.dtsi
@@ -277,7 +277,7 @@ pinctrl_mmc0: main-mmc0-default-pins { bootph-all; pinctrl-single,pins = < AM62X_IOPAD(0x220, PIN_INPUT, 0) /* (Y3) MMC0_CMD */ - AM62X_IOPAD(0x218, PIN_INPUT, 0) /* (AB1) MMC0_CLK */ + AM62X_IOPAD(0x218, PIN_OUTPUT, 0) /* (AB1) MMC0_CLK */ AM62X_IOPAD(0x214, PIN_INPUT, 0) /* (AA2) MMC0_DAT0 */ AM62X_IOPAD(0x210, PIN_INPUT, 0) /* (AA1) MMC0_DAT1 */ AM62X_IOPAD(0x20c, PIN_INPUT, 0) /* (AA3) MMC0_DAT2 */ @@ -292,7 +292,7 @@ AM62X_IOPAD(0x1f8, PIN_INPUT, 0) /* (AC2) MMC0_DAT7 */ pinctrl_mmc2: main-mmc2-default-pins { pinctrl-single,pins = < AM62X_IOPAD(0x120, PIN_INPUT_PULLUP, 0) /* (C24) MMC2_CMD */ - AM62X_IOPAD(0x118, PIN_INPUT_PULLDOWN, 0) /* (D25) MMC2_CLK */ + AM62X_IOPAD(0x118, PIN_OUTPUT_PULLDOWN, 0) /* (D25) MMC2_CLK */ AM62X_IOPAD(0x114, PIN_INPUT_PULLUP, 0) /* (B24) MMC2_DAT0 */ AM62X_IOPAD(0x110, PIN_INPUT_PULLUP, 0) /* (C25) MMC2_DAT1 */ AM62X_IOPAD(0x10c, PIN_INPUT_PULLUP, 0) /* (E23) MMC2_DAT2 */
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi index 9e5b75a..92dd1b9 100644 --- a/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62a-main.dtsi
@@ -1149,6 +1149,7 @@ vpu: video-codec@30210000 { reg = <0x00 0x30210000 0x00 0x10000>; clocks = <&k3_clks 204 2>; power-domains = <&k3_pds 204 TI_SCI_PD_EXCLUSIVE>; + sram = <&oc_sram>; }; c7x_0: dsp@7e000000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi index d22caa7..5b90320 100644 --- a/arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62a-mcu.dtsi
@@ -147,7 +147,7 @@ mcu_rti0: watchdog@4880000 { power-domains = <&k3_pds 131 TI_SCI_PD_EXCLUSIVE>; assigned-clocks = <&k3_clks 131 0>; assigned-clock-parents = <&k3_clks 131 2>; - /* Tightly coupled to M4F */ + /* Tightly coupled to R5F */ status = "reserved"; };
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-phycore-som.dtsi index de4048a3..d7f30a9 100644 --- a/arch/arm64/boot/dts/ti/k3-am62a-phycore-som.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62a-phycore-som.dtsi
@@ -65,9 +65,34 @@ wkup_r5fss0_core0_dma_memory_region: memory@9c800000 { no-map; }; - wkup_r5fss0_core0_memory_region: memory@9c900000 { + wkup_r5fss0_core0_ipc_region: memory@9c900000 { compatible = "shared-dma-pool"; - reg = <0x00 0x9c900000 0x00 0xf00000>; + reg = <0x00 0x9c900000 0x00 0x100000>; + no-map; + }; + + wkup_r5fss0_core0_lpm_fs_stub_region: memory@9ca00000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca00000 0x00 0x8000>; + no-map; + }; + + wkup_r5fss0_core0_lpm_metadata_region: memory@9ca08000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca08000 0x00 0x1000>; + bootph-pre-ram; + no-map; + }; + + wkup_r5fss0_core0_lpm_rest_region: memory@9ca09000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca09000 0x00 0x97000>; + no-map; + }; + + wkup_r5fss0_core0_dm_region: memory@9caa0000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9caa0000 0x00 0x1c60000>; no-map; }; @@ -120,7 +145,7 @@ AM62AX_IOPAD(0x15c, PIN_INPUT, 0) /* (V13) MDIO0_MDIO */ main_mmc0_pins_default: main-mmc0-default-pins { pinctrl-single,pins = < AM62AX_IOPAD(0x220, PIN_INPUT_PULLUP, 0) /* (Y6) MMC0_CMD */ - AM62AX_IOPAD(0x218, PIN_INPUT_PULLDOWN, 0) /* (AB7) MMC0_CLK */ + AM62AX_IOPAD(0x218, PIN_OUTPUT_PULLDOWN, 0) /* (AB7) MMC0_CLK */ AM62AX_IOPAD(0x214, PIN_INPUT_PULLUP, 0) /* (AA6) MMC0_DAT0 */ AM62AX_IOPAD(0x210, PIN_INPUT_PULLUP, 0) /* (AB6) MMC0_DAT1 */ AM62AX_IOPAD(0x20c, PIN_INPUT_PULLUP, 0) /* (Y7) MMC0_DAT2 */
diff --git a/arch/arm64/boot/dts/ti/k3-am62a-ti-ipc-firmware.dtsi b/arch/arm64/boot/dts/ti/k3-am62a-ti-ipc-firmware.dtsi index 06d4e81..7beca54 100644 --- a/arch/arm64/boot/dts/ti/k3-am62a-ti-ipc-firmware.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62a-ti-ipc-firmware.dtsi
@@ -63,10 +63,17 @@ &wkup_r5fss0 { }; &wkup_r5fss0_core0 { + bootph-pre-ram; mboxes = <&mailbox0_cluster0>, <&mbox_r5_0>; memory-region = <&wkup_r5fss0_core0_dma_memory_region>, - <&wkup_r5fss0_core0_memory_region>; - memory-region-names = "dma", "firmware"; + <&wkup_r5fss0_core0_ipc_region>, + <&wkup_r5fss0_core0_lpm_fs_stub_region>, + <&wkup_r5fss0_core0_lpm_metadata_region>, + <&wkup_r5fss0_core0_lpm_rest_region>, + <&wkup_r5fss0_core0_dm_region>; + memory-region-names = "dma", "ipc", "lpm-stub", + "lpm-metadata", "lpm-context", + "dm-firmware"; status = "okay"; };
diff --git a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts index d3b3675..af54384 100644 --- a/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts +++ b/arch/arm64/boot/dts/ti/k3-am62a7-sk.dts
@@ -25,6 +25,7 @@ aliases { mmc1 = &sdhci1; rtc0 = &wkup_rtc0; rtc1 = &tps659312; + ethernet0 = &cpsw_port1; }; chosen { @@ -59,9 +60,34 @@ wkup_r5fss0_core0_dma_memory_region: memory@9c800000 { no-map; }; - wkup_r5fss0_core0_memory_region: memory@9c900000 { + wkup_r5fss0_core0_ipc_region: memory@9c900000 { compatible = "shared-dma-pool"; - reg = <0x00 0x9c900000 0x00 0xf00000>; + reg = <0x00 0x9c900000 0x00 0x100000>; + no-map; + }; + + wkup_r5fss0_core0_lpm_fs_stub_region: memory@9ca00000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca00000 0x00 0x8000>; + no-map; + }; + + wkup_r5fss0_core0_lpm_metadata_region: memory@9ca08000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca08000 0x00 0x1000>; + bootph-pre-ram; + no-map; + }; + + wkup_r5fss0_core0_lpm_rest_region: memory@9ca09000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca09000 0x00 0x97000>; + no-map; + }; + + wkup_r5fss0_core0_dm_region: memory@9caa0000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9caa0000 0x00 0x1c60000>; no-map; }; @@ -328,8 +354,7 @@ AM62AX_IOPAD(0x0b4, PIN_INPUT_PULLUP, 1) /* (K24) GPMC0_CSn3.I2C2_SDA */ main_mmc0_pins_default: main-mmc0-default-pins { pinctrl-single,pins = < AM62AX_IOPAD(0x220, PIN_INPUT, 0) /* (Y3) MMC0_CMD */ - AM62AX_IOPAD(0x218, PIN_INPUT, 0) /* (AB1) MMC0_CLKLB */ - AM62AX_IOPAD(0x21c, PIN_INPUT, 0) /* (AB1) MMC0_CLK */ + AM62AX_IOPAD(0x218, PIN_OUTPUT, 0) /* (AB1) MMC0_CLK */ AM62AX_IOPAD(0x214, PIN_INPUT, 0) /* (AA2) MMC0_DAT0 */ AM62AX_IOPAD(0x210, PIN_INPUT_PULLUP, 0) /* (AA1) MMC0_DAT1 */ AM62AX_IOPAD(0x20c, PIN_INPUT_PULLUP, 0) /* (AA3) MMC0_DAT2 */ @@ -345,7 +370,7 @@ AM62AX_IOPAD(0x1f8, PIN_INPUT_PULLUP, 0) /* (AC2) MMC0_DAT7 */ main_mmc1_pins_default: main-mmc1-default-pins { pinctrl-single,pins = < AM62AX_IOPAD(0x23c, PIN_INPUT, 0) /* (A21) MMC1_CMD */ - AM62AX_IOPAD(0x234, PIN_INPUT, 0) /* (B22) MMC1_CLK */ + AM62AX_IOPAD(0x234, PIN_OUTPUT, 0) /* (B22) MMC1_CLK */ AM62AX_IOPAD(0x230, PIN_INPUT, 0) /* (A22) MMC1_DAT0 */ AM62AX_IOPAD(0x22c, PIN_INPUT, 0) /* (B21) MMC1_DAT1 */ AM62AX_IOPAD(0x228, PIN_INPUT, 0) /* (C21) MMC1_DAT2 */
diff --git a/arch/arm64/boot/dts/ti/k3-am62d2-evm.dts b/arch/arm64/boot/dts/ti/k3-am62d2-evm.dts index f5ceb6a..f87d6d51 100644 --- a/arch/arm64/boot/dts/ti/k3-am62d2-evm.dts +++ b/arch/arm64/boot/dts/ti/k3-am62d2-evm.dts
@@ -65,13 +65,37 @@ wkup_r5fss0_core0_dma_memory_region: memory@9c800000 { no-map; }; - wkup_r5fss0_core0_memory_region: memory@9c900000 { + wkup_r5fss0_core0_ipc_region: memory@9c900000 { compatible = "shared-dma-pool"; - reg = <0x00 0x9c900000 0x00 0xf00000>; + reg = <0x00 0x9c900000 0x00 0x100000>; + no-map; + }; + + wkup_r5fss0_core0_lpm_fs_stub_region: memory@9ca00000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca00000 0x00 0x8000>; + no-map; + }; + + wkup_r5fss0_core0_lpm_metadata_region: memory@9ca08000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca08000 0x00 0x1000>; no-map; bootph-pre-ram; }; + wkup_r5fss0_core0_lpm_rest_region: memory@9ca09000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca09000 0x00 0x97000>; + no-map; + }; + + wkup_r5fss0_core0_dm_region: memory@9caa0000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9caa0000 0x00 0x1c60000>; + no-map; + }; + secure_ddr: optee@9e800000 { reg = <0x00 0x9e800000 0x00 0x01800000>; /* for OP-TEE */ no-map; @@ -776,10 +800,6 @@ partition@3fc0000 { }; }; -&wkup_r5fss0_core0 { - bootph-pre-ram; -}; - &mcu_r5fss0_core0 { firmware-name = "am62d-mcu-r5f0_0-fw"; };
diff --git a/arch/arm64/boot/dts/ti/k3-am62l3-evm.dts b/arch/arm64/boot/dts/ti/k3-am62l3-evm.dts index 84a0cfa..964387e 100644 --- a/arch/arm64/boot/dts/ti/k3-am62l3-evm.dts +++ b/arch/arm64/boot/dts/ti/k3-am62l3-evm.dts
@@ -253,9 +253,9 @@ AM62LX_IOPAD(0x01e0, PIN_INPUT_PULLUP, 0) /* (D8) I2C2_SDA */ mmc0_pins_default: mmc0-default-pins { pinctrl-single,pins = < - AM62LX_IOPAD(0x0214, PIN_INPUT_PULLUP, 0) /* (D2) MMC0_CMD */ + AM62LX_IOPAD(0x0214, PIN_INPUT, 0) /* (D2) MMC0_CMD */ AM62LX_IOPAD(0x020c, PIN_OUTPUT, 0) /* (B2) MMC0_CLK */ - AM62LX_IOPAD(0x0208, PIN_INPUT_PULLUP, 0) /* (D3) MMC0_DAT0 */ + AM62LX_IOPAD(0x0208, PIN_INPUT, 0) /* (D3) MMC0_DAT0 */ AM62LX_IOPAD(0x0204, PIN_INPUT_PULLUP, 0) /* (D4) MMC0_DAT1 */ AM62LX_IOPAD(0x0200, PIN_INPUT_PULLUP, 0) /* (C1) MMC0_DAT2 */ AM62LX_IOPAD(0x01fc, PIN_INPUT_PULLUP, 0) /* (C2) MMC0_DAT3 */
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi index f130c7c..e93f4dd 100644 --- a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-main.dtsi
@@ -1111,12 +1111,24 @@ dphy0: phy@30110000 { status = "disabled"; }; + gpu: gpu@fd80000 { + compatible = "ti,am62p-gpu", "img,img-bxs-4-64", "img,img-rogue"; + reg = <0x00 0x0fd80000 0x00 0x80000>; + clocks = <&k3_clks 237 3>; + clock-names = "core"; + interrupts = <GIC_SPI 241 IRQ_TYPE_LEVEL_HIGH>; + power-domains = <&k3_pds 237 TI_SCI_PD_EXCLUSIVE>, + <&k3_pds 242 TI_SCI_PD_EXCLUSIVE>; + power-domain-names = "a", "b"; + }; + vpu: video-codec@30210000 { compatible = "ti,j721s2-wave521c", "cnm,wave521c"; reg = <0x00 0x30210000 0x00 0x10000>; interrupts = <GIC_SPI 225 IRQ_TYPE_LEVEL_HIGH>; clocks = <&k3_clks 204 2>; power-domains = <&k3_pds 204 TI_SCI_PD_EXCLUSIVE>; + sram = <&oc_sram>; }; hsm: remoteproc@43c00000 {
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi index 5288c95..2394a4f 100644 --- a/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62p-j722s-common-mcu.dtsi
@@ -149,7 +149,7 @@ mcu_rti0: watchdog@4880000 { power-domains = <&k3_pds 131 TI_SCI_PD_EXCLUSIVE>; assigned-clocks = <&k3_clks 131 0>; assigned-clock-parents = <&k3_clks 131 2>; - /* Tightly coupled to M4F */ + /* Tightly coupled to R5F */ status = "reserved"; };
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-ti-ipc-firmware.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-ti-ipc-firmware.dtsi index 5d7f701..277d7e2 100644 --- a/arch/arm64/boot/dts/ti/k3-am62p-ti-ipc-firmware.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62p-ti-ipc-firmware.dtsi
@@ -42,10 +42,17 @@ &wkup_r5fss0 { }; &wkup_r5fss0_core0 { + bootph-pre-ram; mboxes = <&mailbox0_cluster0 &mbox_r5_0>; memory-region = <&wkup_r5fss0_core0_dma_memory_region>, - <&wkup_r5fss0_core0_memory_region>; - memory-region-names = "dma", "firmware"; + <&wkup_r5fss0_core0_ipc_region>, + <&wkup_r5fss0_core0_lpm_fs_stub_region>, + <&wkup_r5fss0_core0_lpm_metadata_region>, + <&wkup_r5fss0_core0_lpm_rest_region>, + <&wkup_r5fss0_core0_dm_region>; + memory-region-names = "dma", "ipc", "lpm-stub", + "lpm-metadata", "lpm-context", + "dm-firmware"; status = "okay"; };
diff --git a/arch/arm64/boot/dts/ti/k3-am62p-verdin.dtsi b/arch/arm64/boot/dts/ti/k3-am62p-verdin.dtsi index 7ee894d..62a518d 100644 --- a/arch/arm64/boot/dts/ti/k3-am62p-verdin.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62p-verdin.dtsi
@@ -168,9 +168,34 @@ wkup_r5fss0_core0_dma_memory_region: memory@9c800000 { no-map; }; - wkup_r5fss0_core0_memory_region: memory@9c900000 { + wkup_r5fss0_core0_ipc_region: memory@9c900000 { compatible = "shared-dma-pool"; - reg = <0x00 0x9c900000 0x00 0x01e00000>; + reg = <0x00 0x9c900000 0x00 0x100000>; + no-map; + }; + + wkup_r5fss0_core0_lpm_fs_stub_region: memory@9ca00000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca00000 0x00 0x8000>; + no-map; + }; + + wkup_r5fss0_core0_lpm_metadata_region: memory@9ca08000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca08000 0x00 0x1000>; + bootph-pre-ram; + no-map; + }; + + wkup_r5fss0_core0_lpm_rest_region: memory@9ca09000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca09000 0x00 0x97000>; + no-map; + }; + + wkup_r5fss0_core0_dm_region: memory@9caa0000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9caa0000 0x00 0x1b68000>; no-map; }; };
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts index b770ed8..39af098 100644 --- a/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts +++ b/arch/arm64/boot/dts/ti/k3-am62p5-sk.dts
@@ -55,9 +55,34 @@ wkup_r5fss0_core0_dma_memory_region: memory@9c800000 { no-map; }; - wkup_r5fss0_core0_memory_region: memory@9c900000 { + wkup_r5fss0_core0_ipc_region: memory@9c900000 { compatible = "shared-dma-pool"; - reg = <0x00 0x9c900000 0x00 0xf00000>; + reg = <0x00 0x9c900000 0x00 0x100000>; + no-map; + }; + + wkup_r5fss0_core0_lpm_fs_stub_region: memory@9ca00000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca00000 0x00 0x8000>; + no-map; + }; + + wkup_r5fss0_core0_lpm_metadata_region: memory@9ca08000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca08000 0x00 0x1000>; + bootph-pre-ram; + no-map; + }; + + wkup_r5fss0_core0_lpm_rest_region: memory@9ca09000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca09000 0x00 0x97000>; + no-map; + }; + + wkup_r5fss0_core0_dm_region: memory@9caa0000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9caa0000 0x00 0x1b68000>; no-map; };
diff --git a/arch/arm64/boot/dts/ti/k3-am62p5-var-som.dtsi b/arch/arm64/boot/dts/ti/k3-am62p5-var-som.dtsi index 8a8dec8..2eefbd8 100644 --- a/arch/arm64/boot/dts/ti/k3-am62p5-var-som.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62p5-var-som.dtsi
@@ -69,9 +69,34 @@ wkup_r5fss0_core0_dma_memory_region: r5f-dma-memory@9c800000 { no-map; }; - wkup_r5fss0_core0_memory_region: r5f-memory@9c900000 { + wkup_r5fss0_core0_ipc_region: r5f-memory@9c900000 { compatible = "shared-dma-pool"; - reg = <0x00 0x9c900000 0x00 0x01e00000>; + reg = <0x00 0x9c900000 0x00 0x100000>; + no-map; + }; + + wkup_r5fss0_core0_lpm_fs_stub_region: r5f-memory@9ca00000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca00000 0x00 0x8000>; + no-map; + }; + + wkup_r5fss0_core0_lpm_metadata_region: r5f-memory@9ca08000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca08000 0x00 0x1000>; + bootph-pre-ram; + no-map; + }; + + wkup_r5fss0_core0_lpm_rest_region: r5f-memory@9ca09000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9ca09000 0x00 0x97000>; + no-map; + }; + + wkup_r5fss0_core0_dm_region: r5f-memory@9caa0000 { + compatible = "shared-dma-pool"; + reg = <0x00 0x9caa0000 0x00 0x1b68000>; no-map; };
diff --git a/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra.dtsi b/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra.dtsi index d6e70ee..c9b3e05 100644 --- a/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62x-phyboard-lyra.dtsi
@@ -227,7 +227,7 @@ AM62X_IOPAD(0x068, PIN_INPUT, 3) /* (R21) GPMC0_AD11.MCASP2_AXR3 */ main_mmc1_pins_default: main-mmc1-default-pins { pinctrl-single,pins = < AM62X_IOPAD(0x23c, PIN_INPUT_PULLUP, 0) /* (A21) MMC1_CMD */ - AM62X_IOPAD(0x234, PIN_INPUT_PULLDOWN, 0) /* (B22) MMC1_CLK */ + AM62X_IOPAD(0x234, PIN_OUTPUT_PULLDOWN, 0) /* (B22) MMC1_CLK */ AM62X_IOPAD(0x230, PIN_INPUT_PULLUP, 0) /* (A22) MMC1_DAT0 */ AM62X_IOPAD(0x22c, PIN_INPUT_PULLUP, 0) /* (B21) MMC1_DAT1 */ AM62X_IOPAD(0x228, PIN_INPUT_PULLUP, 0) /* (C21) MMC1_DAT2 */
diff --git a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi index ab9e58c..d2f41e2 100644 --- a/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am62x-sk-common.dtsi
@@ -194,7 +194,7 @@ main_mmc1_pins_default: main-mmc1-default-pins { bootph-all; pinctrl-single,pins = < AM62X_IOPAD(0x23c, PIN_INPUT, 0) /* (A21/C18) MMC1_CMD */ - AM62X_IOPAD(0x234, PIN_INPUT, 0) /* (B22/A20) MMC1_CLK */ + AM62X_IOPAD(0x234, PIN_OUTPUT, 0) /* (B22/A20) MMC1_CLK */ AM62X_IOPAD(0x230, PIN_INPUT, 0) /* (A22/A19) MMC1_DAT0 */ AM62X_IOPAD(0x22c, PIN_INPUT, 0) /* (B21/B19) MMC1_DAT1 */ AM62X_IOPAD(0x228, PIN_INPUT, 0) /* (C21/B20) MMC1_DAT2 */
diff --git a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts index ca1300e..edcf039 100644 --- a/arch/arm64/boot/dts/ti/k3-am654-base-board.dts +++ b/arch/arm64/boot/dts/ti/k3-am654-base-board.dts
@@ -460,6 +460,7 @@ &sdhci0 { &sdhci1 { status = "okay"; vmmc-supply = <&vdd_mmc1_sd>; + power-off-delay-us = <650000>; pinctrl-names = "default"; pinctrl-0 = <&main_mmc1_pins_default>; ti,driver-strength-ohm = <50>;
diff --git a/arch/arm64/boot/dts/ti/k3-am67-phycore-som.dtsi b/arch/arm64/boot/dts/ti/k3-am67-phycore-som.dtsi new file mode 100644 index 0000000..bc74c4e --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am67-phycore-som.dtsi
@@ -0,0 +1,324 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (C) 2026 PHYTEC America LLC + * Author: Nathan Morrisson <nmorrisson@phytec.com> + */ + +#include <dt-bindings/net/ti-dp83867.h> +#include <dt-bindings/leds/common.h> +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> + +/ { + compatible = "phytec,am67-phycore-som", "ti,j722s"; + model = "PHYTEC phyCORE-AM67"; + + aliases { + ethernet0 = &cpsw_port1; + gpio0 = &main_gpio0; + mmc0 = &sdhci0; + rtc0 = &i2c_som_rtc; + rtc1 = &wkup_rtc0; + spi0 = &ospi0; + }; + + memory@80000000 { + /* 4G RAM */ + reg = <0x00000000 0x80000000 0x00000000 0x80000000>, + <0x00000008 0x80000000 0x00000000 0x80000000>; + device_type = "memory"; + bootph-all; + }; + + reserved_memory: reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + secure_tfa_ddr: tfa@9e780000 { + reg = <0x00 0x9e780000 0x00 0x80000>; + no-map; + }; + + secure_ddr: optee@9e800000 { + reg = <0x00 0x9e800000 0x00 0x01800000>; + no-map; + }; + + wkup_r5fss0_core0_dma_memory_region: memory@a0000000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa0000000 0x00 0x100000>; + no-map; + }; + + wkup_r5fss0_core0_memory_region: memory@a0100000 { + compatible = "shared-dma-pool"; + reg = <0x00 0xa0100000 0x00 0xf00000>; + no-map; + }; + }; + + vcc_5v0_som: regulator-vcc-5v0-som { + compatible = "regulator-fixed"; + regulator-name = "VCC_5V0_SOM"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + regulator-boot-on; + }; + + leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + pinctrl-0 = <&leds_pins_default>; + + led-0 { + color = <LED_COLOR_ID_GREEN>; + gpios = <&main_gpio0 13 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "heartbeat"; + function = LED_FUNCTION_HEARTBEAT; + }; + }; +}; + +&main_pmx0 { + leds_pins_default: leds-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x034, PIN_OUTPUT, 7) /* (K22) OSPI0_CSN2.GPIO0_13 */ + >; + }; + + mdio_pins_default: mdio-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x0160, PIN_OUTPUT, 0) /* (AC24) MDIO0_MDC */ + J722S_IOPAD(0x015c, PIN_INPUT, 0) /* (AD25) MDIO0_MDIO */ + >; + bootph-all; + }; + + ospi0_pins_default: ospi0-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x000, PIN_OUTPUT, 0) /* (L24) OSPI0_CLK */ + J722S_IOPAD(0x02c, PIN_OUTPUT, 0) /* (K26) OSPI0_CSn0 */ + J722S_IOPAD(0x00c, PIN_INPUT, 0) /* (K27) OSPI0_D0 */ + J722S_IOPAD(0x010, PIN_INPUT, 0) /* (L27) OSPI0_D1 */ + J722S_IOPAD(0x014, PIN_INPUT, 0) /* (L26) OSPI0_D2 */ + J722S_IOPAD(0x018, PIN_INPUT, 0) /* (L25) OSPI0_D3 */ + J722S_IOPAD(0x01c, PIN_INPUT, 0) /* (L21) OSPI0_D4 */ + J722S_IOPAD(0x020, PIN_INPUT, 0) /* (M26) OSPI0_D5 */ + J722S_IOPAD(0x024, PIN_INPUT, 0) /* (N27) OSPI0_D6 */ + J722S_IOPAD(0x028, PIN_INPUT, 0) /* (M27) OSPI0_D7 */ + J722S_IOPAD(0x008, PIN_INPUT, 0) /* (L22) OSPI0_DQS */ + J722S_IOPAD(0x038, PIN_INPUT, 7) /* (J22) OSPI0_CSn3.GPIO0_14 */ + >; + bootph-all; + }; + + pmic_irq_pins_default: pmic-irq-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x030, PIN_INPUT, 7) /* (K23) OSPI0_CSN1.GPIO0_12 */ + >; + }; + + rgmii1_pins_default: rgmii1-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x014c, PIN_INPUT, 0) /* (AC25) RGMII1_RD0 */ + J722S_IOPAD(0x0150, PIN_INPUT, 0) /* (AD27) RGMII1_RD1 */ + J722S_IOPAD(0x0154, PIN_INPUT, 0) /* (AE24) RGMII1_RD2 */ + J722S_IOPAD(0x0158, PIN_INPUT, 0) /* (AE26) RGMII1_RD3 */ + J722S_IOPAD(0x0148, PIN_INPUT, 0) /* (AE27) RGMII1_RXC */ + J722S_IOPAD(0x0144, PIN_INPUT, 0) /* (AD23) RGMII1_RX_CTL */ + J722S_IOPAD(0x0134, PIN_OUTPUT, 0) /* (AF27) RGMII1_TD0 */ + J722S_IOPAD(0x0138, PIN_OUTPUT, 0) /* (AE23) RGMII1_TD1 */ + J722S_IOPAD(0x013c, PIN_OUTPUT, 0) /* (AG25) RGMII1_TD2 */ + J722S_IOPAD(0x0140, PIN_OUTPUT, 0) /* (AF24) RGMII1_TD3 */ + J722S_IOPAD(0x0130, PIN_OUTPUT, 0) /* (AG26) RGMII1_TXC */ + J722S_IOPAD(0x012c, PIN_OUTPUT, 0) /* (AF25) RGMII1_TX_CTL */ + >; + bootph-all; + }; +}; + +&mcu_pmx0 { + wkup_i2c0_pins_default: wkup-i2c0-default-pins { + pinctrl-single,pins = < + J722S_MCU_IOPAD(0x04c, PIN_INPUT_PULLUP, 0) /* (B9) WKUP_I2C0_SCL */ + J722S_MCU_IOPAD(0x050, PIN_INPUT_PULLUP, 0) /* (D11) WKUP_I2C0_SDA */ + >; + bootph-all; + }; +}; + +&cpsw3g { + pinctrl-names = "default"; + pinctrl-0 = <&rgmii1_pins_default>; + bootph-all; + status = "okay"; +}; + +&cpsw3g_mdio { + pinctrl-names = "default"; + pinctrl-0 = <&mdio_pins_default>; + status = "okay"; + + cpsw3g_phy1: ethernet-phy@1 { + compatible = "ethernet-phy-ieee802.3-c22"; + reg = <1>; + ti,rx-internal-delay = <DP83867_RGMIIDCTL_2_00_NS>; + tx-fifo-depth = <DP83867_PHYCR_FIFO_DEPTH_4_B_NIB>; + ti,min-output-impedance; + }; +}; + +&cpsw_port1 { + phy-mode = "rgmii-id"; + phy-handle = <&cpsw3g_phy1>; + status = "okay"; +}; + +&ospi0 { + pinctrl-names = "default"; + pinctrl-0 = <&ospi0_pins_default>; + bootph-all; + status = "okay"; + + serial_flash: flash@0 { + compatible = "jedec,spi-nor"; + reg = <0x0>; + spi-tx-bus-width = <8>; + spi-rx-bus-width = <8>; + spi-max-frequency = <25000000>; + vcc-supply = <&vdd_1v8>; + cdns,tshsl-ns = <60>; + cdns,tsd2d-ns = <60>; + cdns,tchsh-ns = <60>; + cdns,tslch-ns = <60>; + cdns,read-delay = <0>; + }; +}; + +&sdhci0 { + non-removable; + bootph-all; + ti,driver-strength-ohm = <50>; + status = "okay"; +}; + +&wkup_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&wkup_i2c0_pins_default>; + clock-frequency = <400000>; + bootph-all; + status = "okay"; + + pmic@30 { + compatible = "ti,tps65219"; + reg = <0x30>; + buck1-supply = <&vcc_5v0_som>; + buck2-supply = <&vcc_5v0_som>; + buck3-supply = <&vcc_5v0_som>; + ldo1-supply = <&vdd_3v3>; + ldo2-supply = <&vdd_1v8>; + ldo3-supply = <&vdd_3v3>; + ldo4-supply = <&vdd_3v3>; + + pinctrl-names = "default"; + pinctrl-0 = <&pmic_irq_pins_default>; + interrupt-parent = <&main_gpio0>; + interrupts = <12 IRQ_TYPE_EDGE_FALLING>; + interrupt-controller; + #interrupt-cells = <1>; + + system-power-controller; + ti,power-button; + + regulators { + vdd_3v3: buck1 { + regulator-name = "VDD_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + vdd_1v8: buck2 { + regulator-name = "VDD_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + vdd_lpddr4: buck3 { + regulator-name = "VDD_LPDDR4"; + regulator-min-microvolt = <1100000>; + regulator-max-microvolt = <1100000>; + regulator-boot-on; + regulator-always-on; + }; + + vddshv_sdio: ldo1 { + regulator-name = "VDDSHV_SDIO"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <3300000>; + regulator-allow-bypass; + regulator-boot-on; + regulator-always-on; + }; + + vdd_1v2: ldo2 { + regulator-name = "VDD_1V2"; + regulator-min-microvolt = <1200000>; + regulator-max-microvolt = <1200000>; + regulator-boot-on; + regulator-always-on; + }; + + vdda_1v8_phy: ldo3 { + regulator-name = "VDDA_1V8_PHY"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + vdd_1v8_pll: ldo4 { + regulator-name = "VDD_1V8_PLL"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + }; + }; + + vdd_core: regulator-vdd-core@44 { + compatible = "ti,tps62873"; + reg = <0x44>; + bootph-pre-ram; + regulator-name = "VDD_CORE"; + regulator-min-microvolt = <850000>; + regulator-max-microvolt = <850000>; + regulator-boot-on; + regulator-always-on; + }; + + eeprom@50 { + compatible = "atmel,24c32"; + reg = <0x50>; + pagesize = <32>; + }; + + som_eeprom_opt: eeprom@51 { + compatible = "atmel,24c32"; + reg = <0x51>; + pagesize = <32>; + }; + + i2c_som_rtc: rtc@52 { + compatible = "microcrystal,rv3028"; + reg = <0x52>; + }; +}; + +#include "k3-j722s-ti-ipc-firmware.dtsi"
diff --git a/arch/arm64/boot/dts/ti/k3-am6754-phyboard-rigel.dts b/arch/arm64/boot/dts/ti/k3-am6754-phyboard-rigel.dts new file mode 100644 index 0000000..5fd4a8c --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am6754-phyboard-rigel.dts
@@ -0,0 +1,431 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Copyright (C) 2026 PHYTEC America LLC + * Author: Nathan Morrisson <nmorrisson@phytec.com> + */ + +/dts-v1/; + +#include <dt-bindings/input/input.h> +#include <dt-bindings/phy/phy.h> +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> +#include "k3-serdes.h" +#include "k3-j722s.dtsi" +#include "k3-am67-phycore-som.dtsi" + +/ { + compatible = "phytec,am6754-phyboard-rigel", + "phytec,am67-phycore-som", "ti,j722s"; + model = "PHYTEC phyBOARD-Rigel AM67"; + + aliases { + gpio1 = &main_gpio1; + mmc1 = &sdhci1; + serial2 = &main_uart0; + usb0 = &usb0; + usb1 = &usb1; + }; + + can_tc0: can-phy0 { + compatible = "ti,tcan1042"; + #phy-cells = <0>; + max-bitrate = <8000000>; + standby-gpios = <&gpio_exp1 1 GPIO_ACTIVE_HIGH>; + }; + + usb0_connector: connector { + compatible = "gpio-usb-b-connector", "usb-b-connector"; + label = "USB-C"; + data-role = "dual"; + + pinctrl-names = "default"; + pinctrl-0 = <&main_usbc_power_pins_default>; + + id-gpios = <&main_gpio1 15 GPIO_ACTIVE_HIGH>; + + port { + usb0_con: endpoint { + remote-endpoint = <&usb0_ep>; + }; + }; + }; + + keys { + compatible = "gpio-keys"; + autorepeat; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_keys_pins_default>; + + key-home { + label = "home"; + linux,code = <KEY_HOME>; + gpios = <&main_gpio1 23 GPIO_ACTIVE_HIGH>; + }; + + key-menu { + label = "menu"; + linux,code = <KEY_MENU>; + gpios = <&gpio_exp1 4 GPIO_ACTIVE_HIGH>; + }; + }; + + vcc_1v8: regulator-vcc-1v8 { + compatible = "regulator-fixed"; + regulator-name = "VCC_1V8"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + regulator-boot-on; + }; + + vcc_3v3_aud: regulator-vcc-3v3-aud { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3_AUD"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + vcc_3v3_mmc: regulator-vcc-3v3-mmc { + /* TPS22963C OUTPUT */ + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3_MMC"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + vcc_3v3_sw: regulator-vcc-3v3-sw { + compatible = "regulator-fixed"; + regulator-name = "VCC_3V3_SW"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + regulator-boot-on; + }; + + vcc_speaker: regulator-vcc-speaker { + compatible = "regulator-fixed"; + regulator-name = "VCC_SPEAKER"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-always-on; + regulator-boot-on; + }; + + sound { + compatible = "simple-audio-card"; + simple-audio-card,widgets = + "Microphone", "Mic Jack", + "Headphone", "Headphone Jack", + "Line", "Stereo Jack", + "Speaker", "L SPKR", + "Speaker", "R SPKR"; + simple-audio-card,routing = + "MIC1RP", "Mic Jack", + "Mic Jack", "MICBIAS", + "Headphone Jack", "HPL", + "Headphone Jack", "HPR", + "MIC1LM", "Stereo Jack", + "MIC1LP", "Stereo Jack", + "L SPKR", "SPL", + "R SPKR", "SPR"; + simple-audio-card,name = "phyBOARD-Rigel"; + simple-audio-card,format = "dsp_b"; + simple-audio-card,bitclock-master = <&sound_master>; + simple-audio-card,frame-master = <&sound_master>; + simple-audio-card,bitclock-inversion; + + simple-audio-card,cpu { + sound-dai = <&mcasp0>; + }; + + sound_master: simple-audio-card,codec { + sound-dai = <&audio_codec>; + clocks = <&audio_refclk1>; + }; + }; +}; + +&main_pmx0 { + audio_ext_refclk1_pins_default: audio-ext-refclk1-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x0a0, PIN_OUTPUT, 1) /* (N24) GPMC0_WPn.AUDIO_EXT_REFCLK1 */ + >; + }; + + gpio_exp0_int_pins_default: gpio-exp0-int-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x0054, PIN_INPUT, 7) /* (T21) GPMC0_AD6.GPIO0_21 */ + >; + }; + + gpio_exp1_int_pins_default: gpio-exp1-int-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x0244, PIN_INPUT, 7) /* (A24) MMC1_SDWP.GPIO1_49 */ + >; + }; + + gpio_exp2_int_pins_default: gpio-exp2-int-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x0050, PIN_INPUT, 7) /* (T24) GPMC0_AD5.GPIO0_20 */ + >; + }; + + gpio_keys_pins_default: gpio-keys-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x01d4, PIN_INPUT, 7) /* (B21) UART0_RTSn.GPIO1_23 */ + >; + }; + + main_i2c0_pins_default: main-i2c0-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x01e0, PIN_INPUT_PULLUP, 0) /* (D23) I2C0_SCL */ + J722S_IOPAD(0x01e4, PIN_INPUT_PULLUP, 0) /* (B22) I2C0_SDA */ + >; + bootph-all; + }; + + main_i2c1_pins_default: main-i2c1-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x01e8, PIN_INPUT_PULLUP, 0) /* (C24) I2C1_SCL */ + J722S_IOPAD(0x01ec, PIN_INPUT_PULLUP, 0) /* (A22) I2C1_SDA */ + >; + bootph-all; + }; + + main_mcan0_pins_default: main-mcan0-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x1dc, PIN_INPUT, 0) /* (C22) MCAN0_RX */ + J722S_IOPAD(0x1d8, PIN_OUTPUT, 0) /* (D22) MCAN0_TX */ + >; + }; + + main_mcasp0_pins_default: main-mcasp0-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x1a8, PIN_INPUT, 0) /* (C26) MCASP0_AFSX */ + J722S_IOPAD(0x1a4, PIN_INPUT, 0) /* (D25) MCASP0_ACLKX */ + J722S_IOPAD(0x198, PIN_OUTPUT, 0) /* (A26) MCASP0_AXR2 */ + J722S_IOPAD(0x194, PIN_INPUT, 0) /* (A25) MCASP0_AXR3 */ + >; + }; + + main_mmc1_pins_default: main-mmc1-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x023c, PIN_INPUT, 0) /* (H22) MMC1_CMD */ + J722S_IOPAD(0x0234, PIN_INPUT, 0) /* (H24) MMC1_CLK */ + J722S_IOPAD(0x0230, PIN_INPUT, 0) /* (H23) MMC1_DAT0 */ + J722S_IOPAD(0x022c, PIN_INPUT, 0) /* (H20) MMC1_DAT1 */ + J722S_IOPAD(0x0228, PIN_INPUT, 0) /* (J23) MMC1_DAT2 */ + J722S_IOPAD(0x0224, PIN_INPUT, 0) /* (H25) MMC1_DAT3 */ + J722S_IOPAD(0x0240, PIN_INPUT, 0) /* (B24) MMC1_SDCD */ + >; + bootph-all; + }; + + main_uart0_pins_default: main-uart0-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x01c8, PIN_INPUT, 0) /* (F19) UART0_RXD */ + J722S_IOPAD(0x01cc, PIN_OUTPUT, 0) /* (F20) UART0_TXD */ + >; + bootph-all; + }; + + main_usbc_power_pins_default: main-usbc-power-default-pins { + pinctrl-single,pins = < + J722S_IOPAD(0x1b4, PIN_INPUT, 7) /* (B20) SPI0_CS0.GPIO1_15 */ + >; + }; +}; + +&audio_refclk1 { + assigned-clock-rates = <25000000>; +}; + +&main_i2c0 { + pinctrl-names = "default"; + pinctrl-0 = <&main_i2c0_pins_default>; + clock-frequency = <400000>; + status = "okay"; + + veml6030: light-sensor@10 { + compatible = "vishay,veml6030"; + reg = <0x10>; + vdd-supply = <&vcc_3v3_sw>; + }; +}; + +&main_i2c1 { + pinctrl-names = "default"; + pinctrl-0 = <&main_i2c1_pins_default>; + clock-frequency = <100000>; + status = "okay"; + + audio_codec: audio-codec@18 { + compatible = "ti,tlv320aic3110"; + reg = <0x18>; + pinctrl-names = "default"; + pinctrl-0 = <&audio_ext_refclk1_pins_default>; + #sound-dai-cells = <0>; + ai31xx-micbias-vg = <2>; + reset-gpios = <&gpio_exp1 7 GPIO_ACTIVE_LOW>; + + HPVDD-supply = <&vcc_3v3_aud>; + SPRVDD-supply = <&vcc_speaker>; + SPLVDD-supply = <&vcc_speaker>; + AVDD-supply = <&vcc_3v3_aud>; + IOVDD-supply = <&vcc_3v3_aud>; + DVDD-supply = <&vcc_1v8>; + }; + + gpio_exp0: gpio@20 { + compatible = "nxp,pcf8574"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_exp0_int_pins_default>; + interrupt-parent = <&main_gpio0>; + interrupts = <21 IRQ_TYPE_EDGE_FALLING>; + gpio-line-names = "CSI3_STROBE", "CSI3_TRIGGER", + "CSI3_SHUTTER", "CSI3_OE", + "CSI2_STROBE", "CSI2_TRIGGER", + "CSI2_SHUTTER", "CSI2_OE"; + }; + + gpio_exp1: gpio@21 { + compatible = "nxp,pcf8574"; + reg = <0x21>; + gpio-controller; + #gpio-cells = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_exp1_int_pins_default>; + interrupt-parent = <&main_gpio1>; + interrupts = <49 IRQ_TYPE_EDGE_FALLING>; + gpio-line-names = "GPIO0_HDMI_RST", "GPIO1_CAN_nEN", + "GPIO2_LED", "GPIO3_MCU_CAN0_nEN", + "GPIO4_BUT2", "GPIO5_MCU_CAN1_nEN", + "GPIO6_AUDIO_GPIO", "GPIO7_AUDIO_USER_RESET"; + }; + + gpio_exp2: gpio@23 { + compatible = "nxp,pcf8574"; + reg = <0x23>; + gpio-controller; + #gpio-cells = <2>; + pinctrl-names = "default"; + pinctrl-0 = <&gpio_exp2_int_pins_default>; + interrupt-parent = <&main_gpio0>; + interrupts = <20 IRQ_TYPE_EDGE_FALLING>; + gpio-line-names = "CSI1_STROBE", "CSI1_TRIGGER", + "CSI1_SHUTTER", "CSI1_OE", + "CSI0_STROBE", "CSI0_TRIGGER", + "CSI0_SHUTTER", "CSI0_OE"; + }; + + current-sensor@40 { + compatible = "ti,ina233"; + reg = <0x40>; + shunt-resistor = <18000>; + }; + + eeprom@51 { + compatible = "atmel,24c02"; + reg = <0x51>; + pagesize = <16>; + }; +}; + +&main_mcan0 { + pinctrl-names = "default"; + pinctrl-0 = <&main_mcan0_pins_default>; + phys = <&can_tc0>; + status = "okay"; +}; + +&main_uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&main_uart0_pins_default>; + bootph-all; + status = "okay"; +}; + +&mcasp0 { + #sound-dai-cells = <0>; + op-mode = <0>; /* MCASP_IIS_MODE */ + pinctrl-names = "default"; + pinctrl-0 = <&main_mcasp0_pins_default>; + tdm-slots = <2>; + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 0 0 1 2 + 0 0 0 0 + 0 0 0 0 + 0 0 0 0 + >; + status = "okay"; +}; + +&sdhci1 { + /* SD/MMC */ + vmmc-supply = <&vcc_3v3_mmc>; + vqmmc-supply = <&vddshv_sdio>; + pinctrl-names = "default"; + pinctrl-0 = <&main_mmc1_pins_default>; + disable-wp; + no-1-8-v; + bootph-all; + status = "okay"; +}; + +&serdes_ln_ctrl { + idle-states = <J722S_SERDES0_LANE0_USB>, + <J722S_SERDES1_LANE0_PCIE0_LANE0>; +}; + +&serdes0 { + status = "okay"; + + serdes0_usb_link: phy@0 { + reg = <0>; + cdns,num-lanes = <1>; + #phy-cells = <0>; + cdns,phy-type = <PHY_TYPE_USB3>; + resets = <&serdes_wiz0 1>; + }; +}; + +&serdes_wiz0 { + status = "okay"; +}; + +&usbss0 { + ti,vbus-divider; + status = "okay"; +}; + +&usb0 { + dr_mode = "otg"; + usb-role-switch; + maximum-speed = "high-speed"; + + port { + usb0_ep: endpoint { + remote-endpoint = <&usb0_con>; + }; + }; +}; + +&usbss1 { + ti,vbus-divider; + status = "okay"; +}; + +&usb1 { + dr_mode = "host"; + phys = <&serdes0_usb_link>; + phy-names = "cdns3,usb3-phy"; + maximum-speed = "super-speed"; +};
diff --git a/arch/arm64/boot/dts/ti/k3-am69-aquila-dsi-to-lvds-v2-panel-cap-touch-10inch.dtso b/arch/arm64/boot/dts/ti/k3-am69-aquila-dsi-to-lvds-v2-panel-cap-touch-10inch.dtso new file mode 100644 index 0000000..92e2706 --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-am69-aquila-dsi-to-lvds-v2-panel-cap-touch-10inch.dtso
@@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-2.0-or-later OR MIT +/* + * Copyright (c) Toradex + * + * Toradex DSI to LVDS Adapter on Aquila DSI_1 with Capacitive Touch Display + * 10.1" V2 Used on Development Board (J44). DSI_1 is exposed via a Samtec + * LSS-130 connector. + * + * https://developer.toradex.com/hardware/accessories/displays/capacitive-touch-display-101inch-lvds + * https://www.toradex.com/accessories/capacitive-touch-display-10.1-inch-lvds + * https://developer.toradex.com/hardware/accessories/add-ons/dsi-lvds-adapter + * https://www.toradex.com/accessories/verdin-dsi-to-lvds-adapter + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/interrupt-controller/irq.h> + +&{/} { + backlight_pwm3: backlight-pwm3 { + compatible = "pwm-backlight"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_19_dsi_1>; + brightness-levels = <0 45 63 88 119 158 203 255>; + default-brightness-level = <4>; + /* Aquila GPIO_19_DSI_1 (AQUILA B44) - DSI_1_BKL_EN_LVDS */ + enable-gpios = <&main_gpio0 13 GPIO_ACTIVE_HIGH>; + /* Aquila PWM_3_DSI (AQUILA B46) - PWM_3_DSI_LVDS */ + pwms = <&main_ehrpwm5 0 6666667 0>; + }; + + panel-lvds-bridge { + compatible = "optologic,scx1001511ggc49", "panel-lvds"; + backlight = <&backlight_pwm3>; + data-mapping = "vesa-24"; + height-mm = <136>; + width-mm = <217>; + + /* + * The timings here are different from the nominal ones for the + * SCX1001511GGC49 display. The clock-frequency, along with the + * other timings, are adjusted from experimentation to work + * consistently with the DSI to LVDS bridge (TI SN65DSI84) + * across Toradex modules that use it. + */ + panel-timing { + clock-frequency = <70000000>; + hactive = <1280>; + hback-porch = <55>; + hfront-porch = <55>; + hsync-len = <45>; + vactive = <800>; + vback-porch = <5>; + vfront-porch = <5>; + vsync-len = <3>; + de-active = <1>; + hsync-active = <0>; + vsync-active = <0>; + pixelclk-active = <0>; + }; + + port { + panel_lvds_bridge_in: endpoint { + remote-endpoint = <&dsi_lvds_bridge_out>; + }; + }; + }; +}; + +&dphy_tx0 { + status = "okay"; +}; + +&dsi0 { + status = "okay"; +}; + +&dsi0_ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dsi0_out: endpoint { + remote-endpoint = <&dsi_lvds_bridge_in>; + }; + }; + + port@1 { + reg = <1>; + + dsi0_in: endpoint { + remote-endpoint = <&dpi2_out>; + }; + }; +}; + +&dss_ports { + #address-cells = <1>; + #size-cells = <0>; + + port@2 { + reg = <2>; + + dpi2_out: endpoint { + remote-endpoint = <&dsi0_in>; + }; + }; +}; + +&i2c_dsi_0 { + #address-cells = <1>; + #size-cells = <0>; + + bridge@2c { + compatible = "ti,sn65dsi84"; + reg = <0x2c>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_20_dsi_1>; + /* Aquila GPIO_20_DSI_1 (AQUILA B45) - LVDS_EN */ + enable-gpios = <&main_gpio0 18 GPIO_ACTIVE_HIGH>; + + ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + dsi_lvds_bridge_in: endpoint { + remote-endpoint = <&dsi0_out>; + data-lanes = <1 2 3 4>; + }; + }; + + port@2 { + reg = <2>; + + dsi_lvds_bridge_out: endpoint { + remote-endpoint = <&panel_lvds_bridge_in>; + }; + }; + }; + }; + + touchscreen@41 { + compatible = "ilitek,ili251x"; + reg = <0x41>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gpio_17_dsi_1>, <&pinctrl_gpio_18_dsi_1>; + /* Aquila GPIO_17_DSI_1 (AQUILA B42) - TOUCH_INT# */ + /* Rising edge avoids spurious interrupts from the noisy falling edge. */ + interrupt-parent = <&main_gpio0>; + interrupts = <12 IRQ_TYPE_EDGE_RISING>; + /* Aquila GPIO_18_DSI_1 (AQUILA B43) - TOUCH_RESET# */ + reset-gpios = <&main_gpio0 31 GPIO_ACTIVE_LOW>; + }; +};
diff --git a/arch/arm64/boot/dts/ti/k3-am69-aquila.dtsi b/arch/arm64/boot/dts/ti/k3-am69-aquila.dtsi index 5119baf..b6854ac 100644 --- a/arch/arm64/boot/dts/ti/k3-am69-aquila.dtsi +++ b/arch/arm64/boot/dts/ti/k3-am69-aquila.dtsi
@@ -1573,7 +1573,7 @@ &wkup_gpio0 { "AQUILA_B70", "AQUILA_B71", "AQUILA_B72", - "AQUILC_B73", + "AQUILA_B73", "AQUILA_B66", "AQUILA_B62", "AQUILA_C21",
diff --git a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts index 54dea36..ac1c1ff 100644 --- a/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts +++ b/arch/arm64/boot/dts/ti/k3-j7200-common-proc-board.dts
@@ -24,6 +24,7 @@ aliases { serial5 = &main_uart3; mmc0 = &main_sdhci0; mmc1 = &main_sdhci1; + ethernet0 = &cpsw_port1; }; chosen {
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts index 19c5157..a4a180b 100644 --- a/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts +++ b/arch/arm64/boot/dts/ti/k3-j721s2-common-proc-board.dts
@@ -32,6 +32,7 @@ aliases { can2 = &mcu_mcan1; can3 = &main_mcan3; can4 = &main_mcan5; + ethernet0 = &cpsw_port1; }; evm_12v0: fixedregulator-evm12v0 {
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-evm-audio.dtso b/arch/arm64/boot/dts/ti/k3-j721s2-evm-audio.dtso new file mode 100644 index 0000000..ac5a827 --- /dev/null +++ b/arch/arm64/boot/dts/ti/k3-j721s2-evm-audio.dtso
@@ -0,0 +1,157 @@ +// SPDX-License-Identifier: GPL-2.0-only OR MIT +/* + * Device Tree Overlay for J721S2 Audio Support + * + * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/ + */ + +/dts-v1/; +/plugin/; + +#include <dt-bindings/gpio/gpio.h> + +#include "k3-pinctrl.h" + +&{/} { + codec_audio: sound { + compatible = "ti,j7200-cpb-audio"; + model = "j721s2-cpb"; + + ti,cpb-mcasp = <&mcasp4>; + ti,cpb-codec = <&pcm3168a_1>; + + clocks = <&k3_clks 213 0>, <&k3_clks 213 1>, + <&k3_clks 157 299>, <&k3_clks 157 328>; + clock-names = "cpb-mcasp-auxclk", "cpb-mcasp-auxclk-48000", + "cpb-codec-scki", "cpb-codec-scki-48000"; + }; + + i2c_mux: mux-controller-2 { + compatible = "gpio-mux"; + #mux-state-cells = <1>; + mux-gpios = <&wkup_gpio0 54 GPIO_ACTIVE_HIGH>; + idle-state = <1>; + pinctrl-names = "default"; + pinctrl-0 = <&main_i2c3_mux_pins_default>; + }; +}; + +&main_pmx0 { + mcasp4_pins_default: mcasp4-default-pins { + pinctrl-single,pins = < + J721S2_IOPAD(0x0c8, PIN_OUTPUT_PULLDOWN, 1) /* (AD28) MCASP4_ACLKX */ + J721S2_IOPAD(0x06c, PIN_OUTPUT_PULLDOWN, 1) /* (V26) MCASP4_AFSX */ + J721S2_IOPAD(0x068, PIN_INPUT_PULLDOWN, 1) /* (U28) MCASP4_AXR1 */ + J721S2_IOPAD(0x0c4, PIN_OUTPUT_PULLDOWN, 1) /* (AB26) MCASP4_AXR2 */ + J721S2_IOPAD(0x070, PIN_OUTPUT_PULLDOWN, 1) /* (R27) MCASP4_AXR3 */ + >; + }; + + audio_ext_refclk1_pins_default: audio-ext-refclk1-default-pins { + pinctrl-single,pins = < + J721S2_IOPAD(0x078, PIN_OUTPUT, 1) /* (Y25) MCAN2_RX.AUDIO_EXT_REFCLK1 */ + >; + }; +}; + +&wkup_pmx2 { + main_i2c3_mux_pins_default: main-i2c3-mux-default-pins { + pinctrl-single,pins = < + J721S2_WKUP_IOPAD(0x038, PIN_OUTPUT, 7) /* (B27) WKUP_GPIO0_54 */ + >; + }; +}; + +&exp2 { + p09-hog { + /* P09 - MCASP/TRACE_MUX_S0 */ + gpio-hog; + gpios = <9 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "MCASP/TRACE_MUX_S0"; + }; + + p10-hog { + /* P10 - MCASP/TRACE_MUX_S1 */ + gpio-hog; + gpios = <10 GPIO_ACTIVE_HIGH>; + output-high; + line-name = "MCASP/TRACE_MUX_S1"; + }; +}; + +&mux0 { + idle-state = <0>; +}; + +&mux1 { + idle-state = <0>; +}; + +&main_mcan3 { + /* Conflicts with McASP4 signal routing via mux0 */ + status = "disabled"; +}; + +&main_mcan5 { + /* Conflicts with McASP4 signal routing via mux1 */ + status = "disabled"; +}; + +&k3_clks { + /* Configure AUDIO_EXT_REFCLK1 pin as output */ + pinctrl-names = "default"; + pinctrl-0 = <&audio_ext_refclk1_pins_default>; +}; + +&main_i2c3 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&main_i2c3_pins_default>; + clock-frequency = <400000>; + mux-states = <&i2c_mux 1>; + #address-cells = <1>; + #size-cells = <0>; + + exp3: gpio@20 { + compatible = "ti,tca6408"; + reg = <0x20>; + gpio-controller; + #gpio-cells = <2>; + gpio-line-names = "CODEC_RSTZ", "CODEC_SPARE1", + "UB926_RESETN", "UB926_LOCK", + "UB926_PWR_SW_CNTRL", "UB926_TUNER_RESET", + "UB926_GPIO_SPARE"; + }; + + pcm3168a_1: audio-codec@44 { + compatible = "ti,pcm3168a"; + reg = <0x44>; + #sound-dai-cells = <1>; + reset-gpios = <&exp3 0 GPIO_ACTIVE_LOW>; + clocks = <&audio_refclk1>; + clock-names = "scki"; + VDD1-supply = <&vsys_3v3>; + VDD2-supply = <&vsys_3v3>; + VCCAD1-supply = <&vsys_5v0>; + VCCAD2-supply = <&vsys_5v0>; + VCCDA1-supply = <&vsys_5v0>; + VCCDA2-supply = <&vsys_5v0>; + }; +}; + +&mcasp4 { + status = "okay"; + #sound-dai-cells = <0>; + pinctrl-names = "default"; + pinctrl-0 = <&mcasp4_pins_default>; + op-mode = <0>; /* MCASP_IIS_MODE */ + tdm-slots = <2>; + auxclk-fs-ratio = <256>; + serial-dir = < /* 0: INACTIVE, 1: TX, 2: RX */ + 0 2 1 1 + 0 0 0 0 + 0 0 0 0 + 0 0 0 0 + >; +};
diff --git a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi index 1228ac5..1bb25fb3 100644 --- a/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j721s2-main.dtsi
@@ -74,6 +74,15 @@ ehrpwm_tbclk: clock-controller@140 { reg = <0x140 0x18>; #clock-cells = <1>; }; + + audio_refclk1: clock-controller@42e4 { + compatible = "ti,j721s2-audio-refclk", "ti,am62-audio-refclk"; + reg = <0x42e4 0x4>; + clocks = <&k3_clks 157 299>; + assigned-clocks = <&k3_clks 157 299>; + assigned-clock-parents = <&k3_clks 157 328>; + #clock-cells = <0>; + }; }; main_ehrpwm0: pwm@3000000 { @@ -716,6 +725,7 @@ vpu: video-codec@4210000 { interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>; clocks = <&k3_clks 179 2>; power-domains = <&k3_pds 179 TI_SCI_PD_EXCLUSIVE>; + sram = <&main_navss_sram>; }; main_sdhci0: mmc@4f80000 { @@ -784,6 +794,14 @@ main_navss: bus@30000000 { dma-coherent; dma-ranges; + main_navss_sram: sram@30000000 { + compatible = "mmio-sram"; + reg = <0x00 0x30000000 0x00 0x10000>; + #address-cells = <1>; + #size-cells = <1>; + ranges = <0x0 0x00 0x30000000 0x10000>; + }; + main_navss_intr: interrupt-controller@310e0000 { compatible = "ti,sci-intr"; reg = <0x00 0x310e0000 0x00 0x4000>;
diff --git a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts index e66330c7..c6486cf 100644 --- a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts +++ b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts
@@ -23,6 +23,7 @@ aliases { serial3 = &main_uart5; mmc0 = &sdhci0; mmc1 = &sdhci1; + ethernet0 = &cpsw_port1; }; chosen { @@ -162,6 +163,12 @@ vsys_io_1v2: regulator-vsys-io-1v2 { regulator-boot-on; }; + tlv320_mclk: clock-12288000 { + compatible = "fixed-clock"; + clock-frequency = <12288000>; + #clock-cells = <0>; + }; + codec_audio: sound { compatible = "simple-audio-card"; simple-audio-card,name = "J722S-EVM"; @@ -187,7 +194,7 @@ simple-audio-card,cpu { sound_master: simple-audio-card,codec { sound-dai = <&tlv320aic3106>; - clocks = <&audio_refclk1>; + clocks = <&tlv320_mclk>; }; }; @@ -228,11 +235,6 @@ csi23_mux: mux-controller-1 { }; }; -&audio_refclk1 { - assigned-clocks = <&k3_clks 157 0>; - assigned-clock-parents = <&k3_clks 157 15>; -}; - &cpsw_mac_syscon { bootph-all; }; @@ -358,12 +360,6 @@ J722S_IOPAD(0x0084, PIN_INPUT, 2) /* (N21) GPMC0_ADVn_ALE.MCASP1_AXR2 */ >; }; - audio_ext_refclk1_pins_default: audio-ext-refclk1-default-pins { - pinctrl-single,pins = < - J722S_IOPAD(0x00a0, PIN_OUTPUT, 1) /* (N24) GPMC0_WPn.AUDIO_EXT_REFCLK1 */ - >; - }; - pmic_irq_pins_default: pmic-irq-default-pins { pinctrl-single,pins = < J722S_IOPAD(0x030, PIN_INPUT, 7) /* (K23) GPIO0_12 */ @@ -562,12 +558,6 @@ ldo3: ldo3 { }; }; -&k3_clks { - /* Configure AUDIO_EXT_REFCLK1 pin as output */ - pinctrl-names = "default"; - pinctrl-0 = <&audio_ext_refclk1_pins_default>; -}; - &main_i2c0 { pinctrl-names = "default"; pinctrl-0 = <&main_i2c0_pins_default>;
diff --git a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi index ff3a85c..7c08566 100644 --- a/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi +++ b/arch/arm64/boot/dts/ti/k3-j784s4-j742s2-evm-common.dtsi
@@ -1206,6 +1206,8 @@ &pcie1_rc { status = "okay"; clocks = <&k3_clks 333 0>, <&serdes0 CDNS_TORRENT_REFCLK_DRIVER>; clock-names = "fck", "pcie_refclk"; + assigned-clocks = <&k3_clks 415 0>; + assigned-clock-parents = <&k3_clks 415 2>; num-lanes = <2>; reset-gpios = <&exp1 2 GPIO_ACTIVE_HIGH>; phys = <&serdes0_pcie1_link>;
diff --git a/arch/arm64/boot/dts/ti/k3-pinctrl.h b/arch/arm64/boot/dts/ti/k3-pinctrl.h index 4491898d..e8ca69a 100644 --- a/arch/arm64/boot/dts/ti/k3-pinctrl.h +++ b/arch/arm64/boot/dts/ti/k3-pinctrl.h
@@ -8,6 +8,7 @@ #ifndef DTS_ARM64_TI_K3_PINCTRL_H #define DTS_ARM64_TI_K3_PINCTRL_H +#define VGPIO_SEL_SHIFT (4) #define WKUP_LVL_EN_SHIFT (7) #define WKUP_LVL_POL_SHIFT (8) #define DEBOUNCE_SHIFT (11) @@ -111,6 +112,15 @@ #define PIN_WKUP_EN_LEVEL_HIGH (WKUP_ENABLE | WKUP_ON_LEVEL | WKUP_LEVEL_HIGH) #define PIN_WKUP_EN (WKUP_ENABLE | WKUP_ON_EDGE) +/* + * SoC-specific field - Refer to the SoC Technical Reference Manual to + * determine which GPIO controller each value selects. + */ +#define PIN_VGPIO_SEL0 (0 << VGPIO_SEL_SHIFT) +#define PIN_VGPIO_SEL1 (1 << VGPIO_SEL_SHIFT) +#define PIN_VGPIO_SEL2 (2 << VGPIO_SEL_SHIFT) +#define PIN_VGPIO_SEL3 (3 << VGPIO_SEL_SHIFT) + /* Default mux configuration for gpio-ranges to use with pinctrl */ #define PIN_GPIO_RANGE_IOPAD (PIN_INPUT | 7)
diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 978e008..317337c 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig
@@ -51,6 +51,7 @@ CONFIG_ARCH_BST=y CONFIG_ARCH_CIX=y CONFIG_ARCH_EXYNOS=y +CONFIG_ARCH_GOOGLE=y CONFIG_ARCH_K3=y CONFIG_ARCH_LG1K=y CONFIG_ARCH_HISI=y @@ -267,9 +268,10 @@ CONFIG_INTEL_STRATIX10_SERVICE=y CONFIG_INTEL_STRATIX10_RSU=m CONFIG_MTK_ADSP_IPC=m -CONFIG_GOOGLE_FIRMWARE=y -CONFIG_GOOGLE_CBMEM=m -CONFIG_GOOGLE_COREBOOT_TABLE=m +CONFIG_TI_SCI_PROTOCOL=m +CONFIG_COREBOOT_FIRMWARE=y +CONFIG_COREBOOT_CBMEM=m +CONFIG_COREBOOT_TABLE=m CONFIG_EFI_CAPSULE_LOADER=y CONFIG_IMX_SCU=y CONFIG_QCOM_TZMEM_MODE_SHMBRIDGE=y @@ -636,11 +638,14 @@ CONFIG_I2C_RZV2M=m CONFIG_I2C_S3C2410=y CONFIG_I2C_SH_MOBILE=y +CONFIG_I2C_STM32F7=m CONFIG_I2C_TEGRA=y CONFIG_I2C_UNIPHIER_F=y CONFIG_I2C_XILINX=m CONFIG_I2C_RCAR=y CONFIG_I2C_CROS_EC_TUNNEL=y +CONFIG_I3C=m +CONFIG_DW_I3C_MASTER=m CONFIG_SPI=y CONFIG_SPI_APPLE=m CONFIG_SPI_ARMADA_3700=y @@ -673,6 +678,7 @@ CONFIG_SPI_QCOM_GENI=m CONFIG_SPI_S3C64XX=y CONFIG_SPI_SH_MSIOF=m +CONFIG_SPI_STM32=m CONFIG_SPI_STM32_OSPI=m CONFIG_SPI_SUN6I=y CONFIG_SPI_TEGRA210_QUAD=m @@ -763,15 +769,18 @@ CONFIG_SENSORS_GPIO_FAN=m CONFIG_SENSORS_JC42=m CONFIG_SENSORS_MACSMC_HWMON=m +CONFIG_SENSORS_MR75203=m CONFIG_SENSORS_LM75=m CONFIG_SENSORS_LM90=m CONFIG_SENSORS_PWM_FAN=m CONFIG_SENSORS_RASPBERRYPI_HWMON=m CONFIG_SENSORS_SL28CPLD=m CONFIG_SENSORS_SHT4x=m +CONFIG_SENSORS_EMC2305=m CONFIG_SENSORS_AMC6821=m CONFIG_SENSORS_INA2XX=m CONFIG_SENSORS_INA3221=m +CONFIG_SENSORS_SPD5118=m CONFIG_SENSORS_TMP102=m CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y CONFIG_CPU_THERMAL=y @@ -800,6 +809,7 @@ CONFIG_GENERIC_ADC_THERMAL=m CONFIG_QCOM_TSENS=y CONFIG_QCOM_SPMI_ADC_TM5=m +CONFIG_QCOM_SPMI_ADC_TM5_GEN3=m CONFIG_QCOM_SPMI_TEMP_ALARM=m CONFIG_QCOM_LMH=m CONFIG_UNIPHIER_THERMAL=y @@ -895,6 +905,7 @@ CONFIG_REGULATOR_RAA215300=y CONFIG_REGULATOR_RK808=y CONFIG_REGULATOR_S2MPS11=y +CONFIG_REGULATOR_SGM3804=y CONFIG_REGULATOR_TPS65132=m CONFIG_REGULATOR_TPS65219=y CONFIG_REGULATOR_VCTRL=m @@ -1018,6 +1029,7 @@ CONFIG_DRM_PANEL_HIMAX_HX8279=m CONFIG_DRM_PANEL_HIMAX_HX83112A=m CONFIG_DRM_PANEL_HIMAX_HX83112B=m +CONFIG_DRM_PANEL_ILITEK_ILI9806E_SPI=m CONFIG_DRM_PANEL_ILITEK_ILI9882T=m CONFIG_DRM_PANEL_KHADAS_TS050=m CONFIG_DRM_PANEL_MANTIX_MLAF057WE51=m @@ -1026,6 +1038,7 @@ CONFIG_DRM_PANEL_NOVATEK_NT37801=m CONFIG_DRM_PANEL_RAYDIUM_RM67191=m CONFIG_DRM_PANEL_RAYDIUM_RM692E5=m +CONFIG_DRM_PANEL_RENESAS_R63419=m CONFIG_DRM_PANEL_SAMSUNG_ATNA33XC20=m CONFIG_DRM_PANEL_SITRONIX_ST7703=m CONFIG_DRM_PANEL_STARTEK_KD070FHFID015=m @@ -1062,6 +1075,7 @@ CONFIG_FB=y CONFIG_FB_EFI=y CONFIG_FB_MODE_HELPERS=y +CONFIG_BACKLIGHT_SY7758=m CONFIG_BACKLIGHT_PWM=m CONFIG_BACKLIGHT_APPLE_DWI=m CONFIG_BACKLIGHT_QCOM_WLED=m @@ -1120,6 +1134,7 @@ CONFIG_SND_SOC_ROCKCHIP_RT5645=m CONFIG_SND_SOC_RK3399_GRU_SOUND=m CONFIG_SND_SOC_SAMSUNG=m +CONFIG_SND_SOC_STM32_SAI=m CONFIG_SND_SUN8I_CODEC=m CONFIG_SND_SUN8I_CODEC_ANALOG=m CONFIG_SND_SUN50I_CODEC_ANALOG=m @@ -1323,6 +1338,7 @@ CONFIG_LEDS_LM3692X=m CONFIG_LEDS_PCA9532=m CONFIG_LEDS_GPIO=y +CONFIG_LEDS_PCA963X=m CONFIG_LEDS_PWM=y CONFIG_LEDS_SYSCON=y CONFIG_LEDS_QCOM_FLASH=m @@ -1403,8 +1419,8 @@ CONFIG_RCAR_DMAC=y CONFIG_RENESAS_USB_DMAC=m CONFIG_RZ_DMAC=y -CONFIG_TI_K3_UDMA=y -CONFIG_TI_K3_UDMA_GLUE_LAYER=y +CONFIG_TI_K3_UDMA=m +CONFIG_TI_K3_UDMA_GLUE_LAYER=m CONFIG_STM32_DMA3=m CONFIG_DMABUF_HEAPS=y CONFIG_DMABUF_HEAPS_SYSTEM=m @@ -1456,7 +1472,7 @@ CONFIG_CLK_IMX8ULP=y CONFIG_CLK_IMX93=y CONFIG_CLK_IMX95_BLK_CTL=y -CONFIG_TI_SCI_CLK=y +CONFIG_TI_SCI_CLK=m CONFIG_COMMON_CLK_MT8192_AUDSYS=y CONFIG_COMMON_CLK_MT8192_CAMSYS=y CONFIG_COMMON_CLK_MT8192_IMGSYS=y @@ -1470,126 +1486,7 @@ CONFIG_COMMON_CLK_MT8192_VDECSYS=y CONFIG_COMMON_CLK_MT8192_VENCSYS=y CONFIG_COMMON_CLK_QCOM=y -CONFIG_CLK_ELIZA_DISPCC=m -CONFIG_CLK_ELIZA_GCC=y -CONFIG_CLK_ELIZA_TCSRCC=m -CONFIG_CLK_GLYMUR_DISPCC=m -CONFIG_CLK_GLYMUR_GCC=y -CONFIG_CLK_GLYMUR_TCSRCC=m -CONFIG_CLK_KAANAPALI_CAMCC=m -CONFIG_CLK_KAANAPALI_DISPCC=m -CONFIG_CLK_KAANAPALI_GCC=y -CONFIG_CLK_KAANAPALI_GPUCC=m -CONFIG_CLK_KAANAPALI_TCSRCC=m -CONFIG_CLK_KAANAPALI_VIDEOCC=m -CONFIG_CLK_X1E80100_CAMCC=m -CONFIG_CLK_X1E80100_DISPCC=m -CONFIG_CLK_X1E80100_GCC=y -CONFIG_CLK_X1E80100_GPUCC=m -CONFIG_CLK_X1E80100_TCSRCC=y -CONFIG_CLK_X1P42100_GPUCC=m -CONFIG_CLK_QCM2290_GPUCC=m -CONFIG_QCOM_A53PLL=y -CONFIG_QCOM_CLK_APCS_MSM8916=y -CONFIG_QCOM_CLK_APCC_MSM8996=y -CONFIG_QCOM_CLK_SMD_RPM=y -CONFIG_QCOM_CLK_RPMH=y -CONFIG_IPQ_APSS_6018=y -CONFIG_IPQ_CMN_PLL=m -CONFIG_IPQ_GCC_5018=y -CONFIG_IPQ_GCC_5210=y -CONFIG_IPQ_GCC_5332=y -CONFIG_IPQ_GCC_5424=y -CONFIG_IPQ_GCC_6018=y -CONFIG_IPQ_GCC_8074=y -CONFIG_IPQ_GCC_9574=y -CONFIG_IPQ_NSSCC_5424=m -CONFIG_IPQ_NSSCC_9574=m -CONFIG_MSM_GCC_8916=y -CONFIG_MSM_GCC_8953=y -CONFIG_MSM_MMCC_8994=m -CONFIG_MSM_GCC_8994=y -CONFIG_MSM_GCC_8996=y -CONFIG_MSM_MMCC_8996=m -CONFIG_MSM_GCC_8998=y -CONFIG_MSM_MMCC_8998=m -CONFIG_QCM_GCC_2290=y -CONFIG_QCM_DISPCC_2290=m -CONFIG_QCS_DISPCC_615=m -CONFIG_QCS_CAMCC_615=m -CONFIG_QCS_GCC_404=y -CONFIG_SA_CAMCC_8775P=m -CONFIG_QCS_GCC_8300=y -CONFIG_QCS_GCC_615=y -CONFIG_QCS_GPUCC_615=m -CONFIG_QCS_VIDEOCC_615=m -CONFIG_SC_CAMCC_7280=m -CONFIG_SC_CAMCC_8280XP=m -CONFIG_SA_DISPCC_8775P=m -CONFIG_SC_DISPCC_7280=m -CONFIG_SC_DISPCC_8280XP=m -CONFIG_SA_GCC_8775P=y -CONFIG_SA_GPUCC_8775P=m -CONFIG_SC_GCC_7180=y -CONFIG_SC_GCC_7280=y -CONFIG_SC_GCC_8180X=y -CONFIG_SC_GCC_8280XP=y -CONFIG_SC_GPUCC_7280=m -CONFIG_SC_GPUCC_8280XP=m -CONFIG_SC_LPASSCC_8280XP=m -CONFIG_SC_LPASS_CORECC_7280=m -CONFIG_SC_VIDEOCC_7280=m -CONFIG_SDM_CAMCC_845=m -CONFIG_QDU_GCC_1000=y -CONFIG_SDM_GPUCC_845=y -CONFIG_SDM_VIDEOCC_845=y -CONFIG_SDM_DISPCC_845=y -CONFIG_SDM_LPASSCC_845=m -CONFIG_SDX_GCC_75=y -CONFIG_SM_CAMCC_6350=m -CONFIG_SM_CAMCC_MILOS=m -CONFIG_SM_CAMCC_8250=m -CONFIG_SM_CAMCC_8550=m -CONFIG_SM_CAMCC_8650=m -CONFIG_SM_CAMCC_8750=m -CONFIG_SM_DISPCC_6115=m -CONFIG_SM_DISPCC_8250=y -CONFIG_SM_DISPCC_6350=m -CONFIG_SM_DISPCC_MILOS=m -CONFIG_SM_DISPCC_8450=m -CONFIG_SM_DISPCC_8550=m -CONFIG_SM_DISPCC_8750=m -CONFIG_SM_GCC_4450=y -CONFIG_SM_GCC_6115=y -CONFIG_SM_GCC_6350=y -CONFIG_SM_GCC_MILOS=y -CONFIG_SM_GCC_8350=y -CONFIG_SM_GCC_8450=y -CONFIG_SM_GCC_8550=y -CONFIG_SM_GCC_8650=y -CONFIG_SM_GCC_8750=y -CONFIG_SM_GPUCC_6115=m -CONFIG_SM_GPUCC_6350=m -CONFIG_SM_GPUCC_MILOS=m -CONFIG_SM_GPUCC_8150=y -CONFIG_SM_GPUCC_8250=y -CONFIG_SM_GPUCC_8350=m -CONFIG_SM_GPUCC_8450=m -CONFIG_SM_GPUCC_8550=m -CONFIG_SM_GPUCC_8650=m -CONFIG_SM_GPUCC_8750=m -CONFIG_SM_TCSRCC_8550=y -CONFIG_SM_TCSRCC_8650=y -CONFIG_SM_TCSRCC_8750=m -CONFIG_SA_VIDEOCC_8775P=m -CONFIG_SM_VIDEOCC_6350=m -CONFIG_SM_VIDEOCC_MILOS=m -CONFIG_SM_VIDEOCC_8250=y -CONFIG_SM_VIDEOCC_8550=m -CONFIG_SM_VIDEOCC_8750=m CONFIG_QCOM_HFPLL=y -CONFIG_CLK_GFM_LPASS_SM8250=m -CONFIG_SM_VIDEOCC_8450=m CONFIG_CLK_RCAR_USB2_CLOCK_SEL=y CONFIG_CLK_RENESAS_VBATTB=m CONFIG_EXYNOS_ACPM_CLK=m @@ -1678,7 +1575,7 @@ CONFIG_QCOM_RPMHPD=y CONFIG_QCOM_RPMPD=y CONFIG_ROCKCHIP_PM_DOMAINS=y -CONFIG_TI_SCI_PM_DOMAINS=y +CONFIG_TI_SCI_PM_DOMAINS=m CONFIG_ARM_IMX_BUS_DEVFREQ=y CONFIG_ARM_IMX8M_DDRC_DEVFREQ=m CONFIG_ARM_MEDIATEK_CCI_DEVFREQ=m @@ -1699,6 +1596,7 @@ CONFIG_MEDIATEK_MT6577_AUXADC=m CONFIG_QCOM_SPMI_VADC=m CONFIG_QCOM_SPMI_ADC5=m +CONFIG_QCOM_SPMI_ADC5_GEN3=m CONFIG_ROCKCHIP_SARADC=m CONFIG_RZG2L_ADC=m CONFIG_RZT2H_ADC=m @@ -1743,15 +1641,15 @@ CONFIG_PWM_XILINX=m CONFIG_SL28CPLD_INTC=y CONFIG_XILINX_INTC=y -CONFIG_TI_SCI_INTR_IRQCHIP=y -CONFIG_TI_SCI_INTA_IRQCHIP=y +CONFIG_TI_SCI_INTR_IRQCHIP=m +CONFIG_TI_SCI_INTA_IRQCHIP=m CONFIG_RESET_GPIO=m CONFIG_RESET_IMX7=y CONFIG_RESET_QCOM_AOSS=y CONFIG_RESET_QCOM_PDC=m CONFIG_RESET_RZG2L_USBPHY_CTRL=y CONFIG_RESET_RZV2H_USB2PHY=m -CONFIG_RESET_TI_SCI=y +CONFIG_RESET_TI_SCI=m CONFIG_PHY_CAN_TRANSCEIVER=m CONFIG_PHY_NXP_PTN3222=m CONFIG_PHY_SNPS_EUSB2=m @@ -1776,6 +1674,7 @@ CONFIG_PHY_QCOM_EDP=m CONFIG_PHY_QCOM_PCIE2=m CONFIG_PHY_QCOM_QMP=m +CONFIG_PHY_QCOM_QMP_PCIE_MULTIPHY=m CONFIG_PHY_QCOM_QUSB2=m CONFIG_PHY_QCOM_EUSB2_REPEATER=m CONFIG_PHY_QCOM_M31_USB=m
diff --git a/arch/arm64/crypto/aes-neonbs-glue.c b/arch/arm64/crypto/aes-neonbs-glue.c index 7cb1aed..20b2b23 100644 --- a/arch/arm64/crypto/aes-neonbs-glue.c +++ b/arch/arm64/crypto/aes-neonbs-glue.c
@@ -247,7 +247,7 @@ static int aesbs_xts_setkey(struct crypto_skcipher *tfm, const u8 *in_key, unsigned int key_len) { struct aesbs_xts_ctx *ctx = crypto_skcipher_ctx(tfm); - struct crypto_aes_ctx rk; + struct crypto_aes_ctx rk __cleanup(aes_zeroize_ctx); int err; err = xts_verify_key(tfm, in_key, key_len);
diff --git a/arch/powerpc/boot/dts/ac14xx.dts b/arch/powerpc/boot/dts/ac14xx.dts index 5d8877e..05fcf08 100644 --- a/arch/powerpc/boot/dts/ac14xx.dts +++ b/arch/powerpc/boot/dts/ac14xx.dts
@@ -148,19 +148,6 @@ clock@f00 { compatible = "fsl,mpc5121rev2-clock", "fsl,mpc5121-clock"; }; - /* - * GPIO PIC: - * interrupts cell = <pin nr, sense> - * sense == 8: Level, low assertion - * sense == 2: Edge, high-to-low change - */ - gpio_pic: gpio@1100 { - gpio-controller; - #gpio-cells = <2>; - interrupt-controller; - #interrupt-cells = <2>; - }; - sdhc@1500 { cd-gpios = <&gpio_pic 23 0>; /* card detect */ wp-gpios = <&gpio_pic 24 0>; /* write protect */
diff --git a/arch/powerpc/boot/dts/mpc5121.dtsi b/arch/powerpc/boot/dts/mpc5121.dtsi index a278fb7..9c5dacb 100644 --- a/arch/powerpc/boot/dts/mpc5121.dtsi +++ b/arch/powerpc/boot/dts/mpc5121.dtsi
@@ -146,10 +146,14 @@ pmc@1000 { interrupts = <83 0x8>; }; - gpio@1100 { + gpio_pic: gpio@1100 { compatible = "fsl,mpc5121-gpio"; reg = <0x1100 0x100>; interrupts = <78 0x8>; + gpio-controller; + #gpio-cells = <2>; + interrupt-controller; + #interrupt-cells = <2>; }; can@1300 {
diff --git a/arch/powerpc/boot/dts/pdm360ng.dts b/arch/powerpc/boot/dts/pdm360ng.dts index 67c3b9d..05e93ca 100644 --- a/arch/powerpc/boot/dts/pdm360ng.dts +++ b/arch/powerpc/boot/dts/pdm360ng.dts
@@ -9,6 +9,7 @@ * Copyright 2008 Freescale Semiconductor Inc. */ +#include <dt-bindings/gpio/gpio.h> #include "mpc5121.dtsi" / { @@ -176,11 +177,12 @@ psc@11900 { /* ADS7845 touch screen controller */ ts@0 { - compatible = "ti,ads7846"; + compatible = "ti,ads7845"; reg = <0x0>; spi-max-frequency = <3000000>; - /* pen irq is GPIO25 */ - interrupts = <78 0x8>; + interrupt-parent = <&gpio_pic>; + interrupts = <25 0x8>; + pendown-gpio = <&gpio_pic 25 GPIO_ACTIVE_LOW>; }; };
diff --git a/arch/powerpc/crypto/vmx.c b/arch/powerpc/crypto/vmx.c index 08da531..8abc4db 100644 --- a/arch/powerpc/crypto/vmx.c +++ b/arch/powerpc/crypto/vmx.c
@@ -8,12 +8,7 @@ */ #include <linux/module.h> -#include <linux/moduleparam.h> -#include <linux/types.h> -#include <linux/err.h> #include <linux/cpufeature.h> -#include <linux/crypto.h> -#include <asm/cputable.h> #include <crypto/internal/skcipher.h> #include "aesp8-ppc.h" @@ -24,7 +19,7 @@ static int __init p8_init(void) ret = crypto_register_skcipher(&p8_aes_cbc_alg); if (ret) - goto err; + return ret; ret = crypto_register_skcipher(&p8_aes_ctr_alg); if (ret) @@ -40,7 +35,6 @@ static int __init p8_init(void) crypto_unregister_skcipher(&p8_aes_ctr_alg); err_unregister_aes_cbc: crypto_unregister_skcipher(&p8_aes_cbc_alg); -err: return ret; } @@ -54,8 +48,6 @@ static void __exit p8_exit(void) module_cpu_feature_match(PPC_MODULE_FEATURE_VEC_CRYPTO, p8_init); module_exit(p8_exit); -MODULE_AUTHOR("Marcelo Cerri<mhcerri@br.ibm.com>"); -MODULE_DESCRIPTION("IBM VMX cryptographic acceleration instructions " - "support on Power 8"); +MODULE_AUTHOR("Marcelo Cerri <mhcerri@br.ibm.com>"); +MODULE_DESCRIPTION("IBM VMX cryptographic acceleration instructions support on Power 8"); MODULE_LICENSE("GPL"); -MODULE_VERSION("1.0.0");
diff --git a/arch/powerpc/include/asm/hardirq.h b/arch/powerpc/include/asm/hardirq.h index f133b59..be6cd5a 100644 --- a/arch/powerpc/include/asm/hardirq.h +++ b/arch/powerpc/include/asm/hardirq.h
@@ -5,24 +5,33 @@ #include <linux/threads.h> #include <linux/irq.h> -typedef struct { - unsigned int __softirq_pending; - unsigned int timer_irqs_event; - unsigned int broadcast_irqs_event; - unsigned int timer_irqs_others; - unsigned int pmu_irqs; - unsigned int mce_exceptions; - unsigned int spurious_irqs; - unsigned int sreset_irqs; +enum irq_stat_counts { + IRQ_COUNT_LOC_TIMER, + IRQ_COUNT_BCT_TIMER, + IRQ_COUNT_OTHER_TIMER, + IRQ_COUNT_SPURIOUS, + IRQ_COUNT_PMI, + IRQ_COUNT_MCE, + IRQ_COUNT_NMI_SRESET, #ifdef CONFIG_PPC_WATCHDOG - unsigned int soft_nmi_irqs; + IRQ_COUNT_WATCHDOG, #endif #ifdef CONFIG_PPC_DOORBELL - unsigned int doorbell_irqs; + IRQ_COUNT_DOORBELL, #endif + IRQ_COUNT_MAX, +}; + +typedef struct { + unsigned int counts[IRQ_COUNT_MAX]; } ____cacheline_aligned irq_cpustat_t; DECLARE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); +DECLARE_PER_CPU(unsigned int, __softirq_pending); +#define local_softirq_pending_ref __softirq_pending + +#define inc_irq_stat(index) __this_cpu_inc(irq_stat.counts[IRQ_COUNT_##index]) +void inc_irq_stat_and_enable(enum irq_stat_counts which); #define __ARCH_IRQ_STAT #define __ARCH_IRQ_EXIT_IRQS_DISABLED
diff --git a/arch/powerpc/include/asm/interrupt.h b/arch/powerpc/include/asm/interrupt.h index 1b45a49..c7d0e71 100644 --- a/arch/powerpc/include/asm/interrupt.h +++ b/arch/powerpc/include/asm/interrupt.h
@@ -70,6 +70,7 @@ #include <linux/irq-entry-common.h> #include <asm/kprobes.h> +#include <asm/mmu.h> #include <asm/runlatch.h> #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG @@ -290,7 +291,7 @@ interrupt_handler long func(struct pt_regs *regs) \ state = irqentry_nmi_enter(regs); \ } else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && \ firmware_has_feature(FW_FEATURE_LPAR) && \ - !radix_enabled()) { \ + !early_radix_enabled()) { \ /* no nmi_entry for a pseries hash guest \ * taking a real mode exception */ \ } else if (IS_ENABLED(CONFIG_KASAN)) { \ @@ -301,13 +302,12 @@ interrupt_handler long func(struct pt_regs *regs) \ state = irqentry_nmi_enter(regs); \ } \ ret = ____##func (regs); \ - arch_interrupt_nmi_exit_prepare(regs, &nmi_state); \ if (mfmsr() & MSR_DR) { \ /* nmi_exit if relocations are on */ \ irqentry_nmi_exit(regs, state); \ } else if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && \ firmware_has_feature(FW_FEATURE_LPAR) && \ - !radix_enabled()) { \ + !early_radix_enabled()) { \ /* no nmi_exit for a pseries hash guest \ * taking a real mode exception */ \ } else if (IS_ENABLED(CONFIG_KASAN)) { \ @@ -317,6 +317,7 @@ interrupt_handler long func(struct pt_regs *regs) \ } else { \ irqentry_nmi_exit(regs, state); \ } \ + arch_interrupt_nmi_exit_prepare(regs, &nmi_state); \ \ return ret; \ } \
diff --git a/arch/powerpc/include/asm/kasan.h b/arch/powerpc/include/asm/kasan.h index a690e7d..599a9e0 100644 --- a/arch/powerpc/include/asm/kasan.h +++ b/arch/powerpc/include/asm/kasan.h
@@ -2,21 +2,6 @@ #ifndef __ASM_KASAN_H #define __ASM_KASAN_H -#if defined(CONFIG_KASAN) && !defined(CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX) -#define _GLOBAL_KASAN(fn) \ - _GLOBAL(fn); \ - _GLOBAL(__##fn) -#define _GLOBAL_TOC_KASAN(fn) \ - _GLOBAL_TOC(fn); \ - _GLOBAL_TOC(__##fn) -#define EXPORT_SYMBOL_KASAN(fn) \ - EXPORT_SYMBOL(__##fn) -#else /* CONFIG_KASAN && !CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */ -#define _GLOBAL_KASAN(fn) _GLOBAL(fn) -#define _GLOBAL_TOC_KASAN(fn) _GLOBAL_TOC(fn) -#define EXPORT_SYMBOL_KASAN(fn) -#endif /* CONFIG_KASAN && !CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */ - #ifndef __ASSEMBLER__ #include <asm/page.h>
diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h index 1981bd4..161b949 100644 --- a/arch/powerpc/include/asm/string.h +++ b/arch/powerpc/include/asm/string.h
@@ -29,29 +29,10 @@ extern void * memchr(const void *,int,__kernel_size_t); void memcpy_flushcache(void *dest, const void *src, size_t size); #ifdef CONFIG_KASAN -/* __mem variants are used by KASAN to implement instrumented meminstrinsics. */ -#ifdef CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX +/* Used by mm/kasan as raw backends to bypass KASAN checking. */ #define __memset memset #define __memcpy memcpy #define __memmove memmove -#else /* CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */ -void *__memset(void *s, int c, __kernel_size_t count); -void *__memcpy(void *to, const void *from, __kernel_size_t n); -void *__memmove(void *to, const void *from, __kernel_size_t n); -#ifndef __SANITIZE_ADDRESS__ -/* - * For files that are not instrumented (e.g. mm/slub.c) we - * should use not instrumented version of mem* functions. - */ -#define memcpy(dst, src, len) __memcpy(dst, src, len) -#define memmove(dst, src, len) __memmove(dst, src, len) -#define memset(s, c, n) __memset(s, c, n) - -#ifndef __NO_FORTIFY -#define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */ -#endif -#endif /* !__SANITIZE_ADDRESS__ */ -#endif /* CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX */ #endif /* CONFIG_KASAN */ #ifdef CONFIG_PPC64
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index 44ec416..02c3c9a 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h
@@ -71,6 +71,7 @@ extern void map_cpu_to_node(int cpu, int node); extern void unmap_cpu_from_node(unsigned long cpu); #endif /* CONFIG_HOTPLUG_CPU */ +int cpu_to_coregroup_id(int cpu); #else static inline int early_cpu_to_node(int cpu) { return 0; } @@ -107,14 +108,6 @@ static inline void map_cpu_to_node(int cpu, int node) {} static inline void unmap_cpu_from_node(unsigned long cpu) {} #endif /* CONFIG_HOTPLUG_CPU */ #endif /* CONFIG_SMP */ - -#endif /* CONFIG_NUMA */ - -#if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR) -void find_and_update_cpu_nid(int cpu); -extern int cpu_to_coregroup_id(int cpu); -#else -static inline void find_and_update_cpu_nid(int cpu) {} static inline int cpu_to_coregroup_id(int cpu) { #ifdef CONFIG_SMP @@ -124,6 +117,12 @@ static inline int cpu_to_coregroup_id(int cpu) #endif } +#endif /* CONFIG_NUMA */ + +#if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR) +void find_and_update_cpu_nid(int cpu); +#else +static inline void find_and_update_cpu_nid(int cpu) {} #endif /* CONFIG_NUMA && CONFIG_PPC_SPLPAR */ #include <asm-generic/topology.h>
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c index 6f6801d..4731e27 100644 --- a/arch/powerpc/kernel/cputable.c +++ b/arch/powerpc/kernel/cputable.c
@@ -35,12 +35,7 @@ void __init set_cur_cpu_spec(struct cpu_spec *s) struct cpu_spec *t = &the_cpu_spec; t = PTRRELOC(t); - /* - * use memcpy() instead of *t = *s so that GCC replaces it - * by __memcpy() when KASAN is active - */ - memcpy(t, s, sizeof(*t)); - + *t = *s; *PTRRELOC(&cur_cpu_spec) = &the_cpu_spec; } @@ -53,11 +48,8 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset, t = PTRRELOC(t); old = *t; - /* - * Copy everything, then do fixups. Use memcpy() instead of *t = *s - * so that GCC replaces it by __memcpy() when KASAN is active - */ - memcpy(t, s, sizeof(*t)); + /* Copy everything, then do fixups. */ + *t = *s; /* * If we are overriding a previous value derived from the real
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c index 5712dd8..f5e298a 100644 --- a/arch/powerpc/kernel/dbell.c +++ b/arch/powerpc/kernel/dbell.c
@@ -31,7 +31,7 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(doorbell_exception) do_hard_irq_enable(); kvmppc_clear_host_ipi(smp_processor_id()); - __this_cpu_inc(irq_stat.doorbell_irqs); + inc_irq_stat(DOORBELL); smp_ipi_demux_relaxed(); /* already performed the barrier */
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index 15a3c3f..bce5469 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c
@@ -73,6 +73,7 @@ DEFINE_PER_CPU_SHARED_ALIGNED(irq_cpustat_t, irq_stat); EXPORT_PER_CPU_SYMBOL(irq_stat); +DEFINE_PER_CPU(unsigned int, __softirq_pending); #ifdef CONFIG_PPC32 atomic_t ppc_n_lost_interrupts; @@ -83,105 +84,105 @@ u32 tau_interrupts(unsigned long cpu); #endif #endif /* CONFIG_PPC32 */ +struct irq_stat_info { + const char *symbol; + const char *text; + int optional; +}; + +/* ISE - IRQ STAT ENABLED, ISC - IRQ STAT CONDITIONAL */ +#define ISE(idx, sym, txt)[IRQ_COUNT_##idx] = { .symbol = sym, .text = txt, .optional = 0} +#define ISC(idx, sym, txt)[IRQ_COUNT_##idx] = { .symbol = sym, .text = txt, .optional = 1} + + +static struct irq_stat_info irq_stat_info[IRQ_COUNT_MAX] __ro_after_init = { + ISE(LOC_TIMER, "LOC", " Local timer interrupts for timer event device\n"), + ISE(BCT_TIMER, "BCT", " Broadcast timer interrupts for timer event device\n"), + ISE(OTHER_TIMER, "LOC", " Local timer interrupts for others\n"), + ISE(SPURIOUS, "SPU", " Spurious interrupts\n"), + ISE(PMI, "PMI", " Performance monitoring interrupts\n"), + ISC(MCE, "MCE", " Machine check exceptions\n"), + ISC(NMI_SRESET, "NMI", " System Reset interrupts\n"), +#ifdef CONFIG_PPC_WATCHDOG + ISE(WATCHDOG, "WDG", " Watchdog soft-NMI interrupts\n"), +#endif +#ifdef CONFIG_PPC_DOORBELL + ISE(DOORBELL, "DBL", " Doorbell interrupts\n"), +#endif +}; + +/* + * Used for default disabled counters to increment the stats and to enable the + * entry for /proc/interrupts output. + */ +static DECLARE_BITMAP(irq_stat_count_show, IRQ_COUNT_MAX) __read_mostly; +void inc_irq_stat_and_enable(enum irq_stat_counts which) +{ + __this_cpu_inc(irq_stat.counts[which]); + set_bit(which, irq_stat_count_show); +} + int arch_show_interrupts(struct seq_file *p, int prec) { - int j; + const struct irq_stat_info *info = irq_stat_info; + + for (unsigned int i = 0; i < ARRAY_SIZE(irq_stat_info); i++, info++) { + if (info->optional && !test_bit(i, irq_stat_count_show)) + continue; + + seq_printf(p, "%*s:", prec, info->symbol); + irq_proc_emit_counts(p, &irq_stat.counts[i]); + seq_puts(p, info->text); + } #if defined(CONFIG_PPC32) && defined(CONFIG_TAU_INT) if (tau_initialized) { + int j; seq_printf(p, "%*s:", prec, "TAU"); for_each_online_cpu(j) seq_put_decimal_ull_width(p, " ", tau_interrupts(j), 10); seq_puts(p, " PowerPC Thermal Assist (cpu temp)\n"); } #endif /* CONFIG_PPC32 && CONFIG_TAU_INT */ - - seq_printf(p, "%*s:", prec, "LOC"); - for_each_online_cpu(j) - seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).timer_irqs_event, 10); - seq_printf(p, " Local timer interrupts for timer event device\n"); - - seq_printf(p, "%*s:", prec, "BCT"); - for_each_online_cpu(j) - seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).broadcast_irqs_event, 10); - seq_printf(p, " Broadcast timer interrupts for timer event device\n"); - - seq_printf(p, "%*s:", prec, "LOC"); - for_each_online_cpu(j) - seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).timer_irqs_others, 10); - seq_printf(p, " Local timer interrupts for others\n"); - - seq_printf(p, "%*s:", prec, "SPU"); - for_each_online_cpu(j) - seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).spurious_irqs, 10); - seq_printf(p, " Spurious interrupts\n"); - - seq_printf(p, "%*s:", prec, "PMI"); - for_each_online_cpu(j) - seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).pmu_irqs, 10); - seq_printf(p, " Performance monitoring interrupts\n"); - - seq_printf(p, "%*s:", prec, "MCE"); - for_each_online_cpu(j) - seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).mce_exceptions, 10); - seq_printf(p, " Machine check exceptions\n"); - #ifdef CONFIG_PPC_BOOK3S_64 if (cpu_has_feature(CPU_FTR_HVMODE)) { + int j; seq_printf(p, "%*s:", prec, "HMI"); for_each_online_cpu(j) seq_put_decimal_ull_width(p, " ", paca_ptrs[j]->hmi_irqs, 10); seq_printf(p, " Hypervisor Maintenance Interrupts\n"); } #endif + return 0; +} - seq_printf(p, "%*s:", prec, "NMI"); - for_each_online_cpu(j) - seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).sreset_irqs, 10); - seq_printf(p, " System Reset interrupts\n"); +static int __init irq_init_stats(void) +{ + struct irq_stat_info *info = irq_stat_info; -#ifdef CONFIG_PPC_WATCHDOG - seq_printf(p, "%*s:", prec, "WDG"); - for_each_online_cpu(j) - seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).soft_nmi_irqs, 10); - seq_printf(p, " Watchdog soft-NMI interrupts\n"); -#endif - -#ifdef CONFIG_PPC_DOORBELL - if (cpu_has_feature(CPU_FTR_DBELL)) { - seq_printf(p, "%*s:", prec, "DBL"); - for_each_online_cpu(j) - seq_put_decimal_ull_width(p, " ", per_cpu(irq_stat, j).doorbell_irqs, 10); - seq_printf(p, " Doorbell interrupts\n"); + for (unsigned int i = 0; i < ARRAY_SIZE(irq_stat_info); i++, info++) { + if (info->optional == 0) + set_bit(i, irq_stat_count_show); } -#endif return 0; } +late_initcall(irq_init_stats); /* * /proc/stat helpers */ u64 arch_irq_stat_cpu(unsigned int cpu) { - u64 sum = per_cpu(irq_stat, cpu).timer_irqs_event; + irq_cpustat_t *p = per_cpu_ptr(&irq_stat, cpu); + u64 sum = 0; - sum += per_cpu(irq_stat, cpu).broadcast_irqs_event; - sum += per_cpu(irq_stat, cpu).pmu_irqs; - sum += per_cpu(irq_stat, cpu).mce_exceptions; - sum += per_cpu(irq_stat, cpu).spurious_irqs; - sum += per_cpu(irq_stat, cpu).timer_irqs_others; + for (unsigned int i = 0; i < ARRAY_SIZE(irq_stat_info); i++) + sum += p->counts[i]; + #ifdef CONFIG_PPC_BOOK3S_64 sum += paca_ptrs[cpu]->hmi_irqs; #endif - sum += per_cpu(irq_stat, cpu).sreset_irqs; -#ifdef CONFIG_PPC_WATCHDOG - sum += per_cpu(irq_stat, cpu).soft_nmi_irqs; -#endif -#ifdef CONFIG_PPC_DOORBELL - sum += per_cpu(irq_stat, cpu).doorbell_irqs; -#endif - return sum; } @@ -251,7 +252,7 @@ static void __do_irq(struct pt_regs *regs, unsigned long oldsp) /* And finally process it */ if (unlikely(!irq)) - __this_cpu_inc(irq_stat.spurious_irqs); + inc_irq_stat(SPURIOUS); else generic_handle_irq(irq);
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index eb9f556..e8e0710 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c
@@ -1362,14 +1362,8 @@ static void __init prom_check_platform_support(void) int prop_len = prom_getproplen(prom.chosen, "ibm,arch-vec-5-platform-support"); - /* - * First copy the architecture vec template - * - * use memcpy() instead of *vec = *vec_template so that GCC replaces it - * by __memcpy() when KASAN is active - */ - memcpy(&ibm_architecture_vec, &ibm_architecture_vec_template, - sizeof(ibm_architecture_vec)); + /* First copy the architecture vec template */ + ibm_architecture_vec = ibm_architecture_vec_template; prom_strscpy_pad(ibm_architecture_vec.vec7.os_id, linux_banner, 256);
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh index 3090b97..3155cc7 100644 --- a/arch/powerpc/kernel/prom_init_check.sh +++ b/arch/powerpc/kernel/prom_init_check.sh
@@ -13,21 +13,8 @@ # If you really need to reference something from prom_init.o add # it to the list below: -has_renamed_memintrinsics() -{ - grep -q "^CONFIG_KASAN=y$" "${KCONFIG_CONFIG}" && \ - ! grep -q "^CONFIG_CC_HAS_KASAN_MEMINTRINSIC_PREFIX=y" "${KCONFIG_CONFIG}" -} - -if has_renamed_memintrinsics -then - MEM_FUNCS="__memcpy __memset" -else - MEM_FUNCS="memcpy memset" -fi - WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush -_end enter_prom $MEM_FUNCS reloc_offset __secondary_hold +_end enter_prom memcpy memset reloc_offset __secondary_hold __secondary_hold_acknowledge __secondary_hold_spinloop __start logo_linux_clut224 btext_prepare_BAT reloc_got2 kernstart_addr memstart_addr linux_banner _stext
diff --git a/arch/powerpc/kernel/syscall.c b/arch/powerpc/kernel/syscall.c index fbefe19..8529827 100644 --- a/arch/powerpc/kernel/syscall.c +++ b/arch/powerpc/kernel/syscall.c
@@ -18,14 +18,12 @@ notrace long system_call_exception(struct pt_regs *regs, unsigned long r0) long ret; syscall_fn f; - if (unlikely(!syscall_enter_from_user_mode_randomize_stack(regs, &r0))) { + if (unlikely(!syscall_enter_from_user_mode_randomize_stack(regs, &r0) || + test_thread_flag(TIF_SYSCALL_RET))) { clear_thread_flag(TIF_SYSCALL_RET); return syscall_get_error(current, regs); } - if (unlikely(test_and_clear_thread_flag(TIF_SYSCALL_RET))) - return syscall_get_error(current, regs); - if (unlikely(r0 >= NR_syscalls)) { if (unlikely(trap_is_unsupported_scv(regs))) { /* Unsupported scv vector */
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c index 329c169..2100c5e 100644 --- a/arch/powerpc/kernel/sysfs.c +++ b/arch/powerpc/kernel/sysfs.c
@@ -338,7 +338,7 @@ static ssize_t show_pw20_wait_time(struct device *dev, time = pw20_wt; } - return sysfs_emit(buf, "%llu\n", time > 0 ? time : 0); + return sysfs_emit(buf, "%llu\n", time); } static void set_pw20_wait_entry_bit(void *val) @@ -460,7 +460,7 @@ static ssize_t show_altivec_idle_wait_time(struct device *dev, time = altivec_idle_wt; } - return sysfs_emit(buf, "%llu\n", time > 0 ? time : 0); + return sysfs_emit(buf, "%llu\n", time); } static void set_altivec_idle_wait_entry_bit(void *val)
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c index 11145c4..e00dcda 100644 --- a/arch/powerpc/kernel/time.c +++ b/arch/powerpc/kernel/time.c
@@ -615,13 +615,13 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(timer_interrupt) now = get_tb(); if (now >= *next_tb) { evt->event_handler(evt); - __this_cpu_inc(irq_stat.timer_irqs_event); + inc_irq_stat(LOC_TIMER); } else { now = *next_tb - now; if (now > decrementer_max) now = decrementer_max; set_dec_or_work(now); - __this_cpu_inc(irq_stat.timer_irqs_others); + inc_irq_stat(OTHER_TIMER); } trace_timer_interrupt_exit(regs); @@ -634,7 +634,7 @@ EXPORT_SYMBOL(timer_interrupt); void timer_broadcast_interrupt(void) { tick_receive_broadcast(); - __this_cpu_inc(irq_stat.broadcast_irqs_event); + inc_irq_stat(BCT_TIMER); } #endif
diff --git a/arch/powerpc/kernel/trace/ftrace_entry.S b/arch/powerpc/kernel/trace/ftrace_entry.S index 6599fe3..5eb8eee 100644 --- a/arch/powerpc/kernel/trace/ftrace_entry.S +++ b/arch/powerpc/kernel/trace/ftrace_entry.S
@@ -220,7 +220,13 @@ /* Restore gprs */ .if \allregs == 1 +#ifdef CONFIG_PPC64 + REST_GPRS(2, 12, r1) + /* Do not restore a stale PACA pointer if the task migrated */ + REST_GPRS(14, 31, r1) +#else REST_GPRS(2, 31, r1) +#endif .else REST_GPRS(3, 10, r1) #if defined(CONFIG_LIVEPATCH_64) || defined(CONFIG_PPC_FTRACE_OUT_OF_LINE)
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 629f2a2..3a8f541 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c
@@ -459,8 +459,7 @@ DEFINE_INTERRUPT_HANDLER_NMI(system_reset_exception) } hv_nmi_check_nonrecoverable(regs); - - __this_cpu_inc(irq_stat.sreset_irqs); + inc_irq_stat_and_enable(IRQ_COUNT_NMI_SRESET); /* See if any machine dependent calls */ if (ppc_md.system_reset_exception) { @@ -817,7 +816,7 @@ static void __machine_check_exception(struct pt_regs *regs) { int recover = 0; - __this_cpu_inc(irq_stat.mce_exceptions); + inc_irq_stat_and_enable(IRQ_COUNT_MCE); add_taint(TAINT_MACHINE_CHECK, LOCKDEP_NOW_UNRELIABLE); @@ -1932,8 +1931,7 @@ DEFINE_INTERRUPT_HANDLER(vsx_unavailable_tm) DECLARE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi); DEFINE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi) { - __this_cpu_inc(irq_stat.pmu_irqs); - + inc_irq_stat(PMI); perf_irq(regs); return 0; @@ -1943,8 +1941,7 @@ DEFINE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi) DECLARE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async); DEFINE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async) { - __this_cpu_inc(irq_stat.pmu_irqs); - + inc_irq_stat(PMI); perf_irq(regs); }
diff --git a/arch/powerpc/kernel/watchdog.c b/arch/powerpc/kernel/watchdog.c index c40c693..582ee3f 100644 --- a/arch/powerpc/kernel/watchdog.c +++ b/arch/powerpc/kernel/watchdog.c
@@ -381,7 +381,7 @@ DEFINE_INTERRUPT_HANDLER_NMI(soft_nmi_interrupt) if (!cpumask_test_cpu(cpu, &wd_cpus_enabled)) return 0; - __this_cpu_inc(irq_stat.soft_nmi_irqs); + inc_irq_stat(WATCHDOG); tb = get_tb(); if (tb - per_cpu(wd_timer_tb, cpu) >= wd_panic_timeout_tb) {
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index de05d72..140eadb 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c
@@ -1159,6 +1159,38 @@ static long kvmppc_h_rpt_invalidate(struct kvm_vcpu *vcpu, return H_SUCCESS; } +static long kvmppc_pseries_do_hpt_hcall(struct kvm_vcpu *vcpu, unsigned long req) +{ + switch (req) { + case H_REMOVE: + return kvmppc_h_remove(vcpu, kvmppc_get_gpr(vcpu, 4), + kvmppc_get_gpr(vcpu, 5), + kvmppc_get_gpr(vcpu, 6)); + case H_ENTER: + return kvmppc_h_enter(vcpu, kvmppc_get_gpr(vcpu, 4), + kvmppc_get_gpr(vcpu, 5), + kvmppc_get_gpr(vcpu, 6), + kvmppc_get_gpr(vcpu, 7)); + case H_READ: + return kvmppc_h_read(vcpu, kvmppc_get_gpr(vcpu, 4), + kvmppc_get_gpr(vcpu, 5)); + case H_CLEAR_MOD: + return kvmppc_h_clear_mod(vcpu, kvmppc_get_gpr(vcpu, 4), + kvmppc_get_gpr(vcpu, 5)); + case H_CLEAR_REF: + return kvmppc_h_clear_ref(vcpu, kvmppc_get_gpr(vcpu, 4), + kvmppc_get_gpr(vcpu, 5)); + case H_PROTECT: + return kvmppc_h_protect(vcpu, kvmppc_get_gpr(vcpu, 4), + kvmppc_get_gpr(vcpu, 5), + kvmppc_get_gpr(vcpu, 6)); + case H_BULK_REMOVE: + return kvmppc_h_bulk_remove(vcpu); + } + + return H_FUNCTION; +} + int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) { struct kvm *kvm = vcpu->kvm; @@ -1174,47 +1206,17 @@ int kvmppc_pseries_do_hcall(struct kvm_vcpu *vcpu) switch (req) { case H_REMOVE: - ret = kvmppc_h_remove(vcpu, kvmppc_get_gpr(vcpu, 4), - kvmppc_get_gpr(vcpu, 5), - kvmppc_get_gpr(vcpu, 6)); - if (ret == H_TOO_HARD) - return RESUME_HOST; - break; case H_ENTER: - ret = kvmppc_h_enter(vcpu, kvmppc_get_gpr(vcpu, 4), - kvmppc_get_gpr(vcpu, 5), - kvmppc_get_gpr(vcpu, 6), - kvmppc_get_gpr(vcpu, 7)); - if (ret == H_TOO_HARD) - return RESUME_HOST; - break; case H_READ: - ret = kvmppc_h_read(vcpu, kvmppc_get_gpr(vcpu, 4), - kvmppc_get_gpr(vcpu, 5)); - if (ret == H_TOO_HARD) - return RESUME_HOST; - break; case H_CLEAR_MOD: - ret = kvmppc_h_clear_mod(vcpu, kvmppc_get_gpr(vcpu, 4), - kvmppc_get_gpr(vcpu, 5)); - if (ret == H_TOO_HARD) - return RESUME_HOST; - break; case H_CLEAR_REF: - ret = kvmppc_h_clear_ref(vcpu, kvmppc_get_gpr(vcpu, 4), - kvmppc_get_gpr(vcpu, 5)); - if (ret == H_TOO_HARD) - return RESUME_HOST; - break; case H_PROTECT: - ret = kvmppc_h_protect(vcpu, kvmppc_get_gpr(vcpu, 4), - kvmppc_get_gpr(vcpu, 5), - kvmppc_get_gpr(vcpu, 6)); - if (ret == H_TOO_HARD) - return RESUME_HOST; - break; case H_BULK_REMOVE: - ret = kvmppc_h_bulk_remove(vcpu); + preempt_disable(); + idx = srcu_read_lock(&kvm->srcu); + ret = kvmppc_pseries_do_hpt_hcall(vcpu, req); + srcu_read_unlock(&kvm->srcu, idx); + preempt_enable(); if (ret == H_TOO_HARD) return RESUME_HOST; break; @@ -1834,8 +1836,10 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, else vsid = vcpu->arch.fault_gpa; + preempt_disable(); err = kvmppc_hpte_hv_fault(vcpu, vcpu->arch.fault_dar, vsid, vcpu->arch.fault_dsisr, true); + preempt_enable(); if (err == 0) { r = RESUME_GUEST; } else if (err == -1 || err == -2) { @@ -1881,8 +1885,10 @@ static int kvmppc_handle_exit_hv(struct kvm_vcpu *vcpu, else vsid = vcpu->arch.fault_gpa; + preempt_disable(); err = kvmppc_hpte_hv_fault(vcpu, vcpu->arch.fault_dar, vsid, vcpu->arch.fault_dsisr, false); + preempt_enable(); if (err == 0) { r = RESUME_GUEST; } else if (err == -1) {
diff --git a/arch/powerpc/kvm/book3s_paired_singles.c b/arch/powerpc/kvm/book3s_paired_singles.c index bc39c76..532f962 100644 --- a/arch/powerpc/kvm/book3s_paired_singles.c +++ b/arch/powerpc/kvm/book3s_paired_singles.c
@@ -479,12 +479,7 @@ static bool kvmppc_inst_is_paired_single(struct kvm_vcpu *vcpu, u32 inst) static int get_d_signext(u32 inst) { - int d = inst & 0x8ff; - - if (d & 0x800) - return -(d & 0x7ff); - - return (d & 0x7ff); + return sign_extend32(inst & 0xfff, 11); } static int kvmppc_ps_three_in(struct kvm_vcpu *vcpu, bool rc,
diff --git a/arch/powerpc/kvm/book3s_xive.c b/arch/powerpc/kvm/book3s_xive.c index 1d67237..d348365 100644 --- a/arch/powerpc/kvm/book3s_xive.c +++ b/arch/powerpc/kvm/book3s_xive.c
@@ -961,9 +961,11 @@ static int xive_provision_queue(struct kvm_vcpu *vcpu, u8 prio) */ rc = xive_native_configure_queue(xc->vp_id, q, prio, qpage, xive->q_order, true); - if (rc) + if (rc) { pr_err("Failed to configure queue %d for VCPU %d\n", prio, xc->server_num); + free_pages((unsigned long)qpage, xive->q_page_order); + } return rc; }
diff --git a/arch/powerpc/kvm/guest-state-buffer.c b/arch/powerpc/kvm/guest-state-buffer.c index 42843ec..aeb586b 100644 --- a/arch/powerpc/kvm/guest-state-buffer.c +++ b/arch/powerpc/kvm/guest-state-buffer.c
@@ -598,7 +598,7 @@ EXPORT_SYMBOL_GPL(kvmppc_gsm_fill_info); int kvmppc_gsm_refresh_info(struct kvmppc_gs_msg *gsm, struct kvmppc_gs_buff *gsb) { - if (!gsm->ops->fill_info) + if (!gsm->ops->refresh_info) return -EINVAL; return gsm->ops->refresh_info(gsm, gsb);
diff --git a/arch/powerpc/kvm/trace_book3s.h b/arch/powerpc/kvm/trace_book3s.h index 9260ddb..4ee35c6 100644 --- a/arch/powerpc/kvm/trace_book3s.h +++ b/arch/powerpc/kvm/trace_book3s.h
@@ -7,6 +7,7 @@ */ #define kvm_trace_symbol_exit \ + {0x0, "RETURN_TO_HOST"}, \ {0x100, "SYSTEM_RESET"}, \ {0x200, "MACHINE_CHECK"}, \ {0x300, "DATA_STORAGE"}, \ @@ -28,6 +29,7 @@ {0xea0, "H_VIRT"}, \ {0xf00, "PERFMON"}, \ {0xf20, "ALTIVEC"}, \ - {0xf40, "VSX"} + {0xf40, "VSX"}, \ + {0xf80, "H_FAC_UNAVAIL"} #endif
diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S index 933b685..97eb9ca 100644 --- a/arch/powerpc/lib/copy_32.S +++ b/arch/powerpc/lib/copy_32.S
@@ -10,7 +10,6 @@ #include <asm/errno.h> #include <asm/ppc_asm.h> #include <asm/code-patching-asm.h> -#include <asm/kasan.h> #define COPY_16_BYTES \ lwz r7,4(r4); \ @@ -87,7 +86,7 @@ * We therefore skip the optimised bloc that uses dcbz. This jump is * replaced by a nop once cache is active. This is done in machine_init() */ -_GLOBAL_KASAN(memset) +_GLOBAL(memset) cmplwi 0,r5,4 blt 7f @@ -147,7 +146,6 @@ bdnz 9b blr EXPORT_SYMBOL(memset) -EXPORT_SYMBOL_KASAN(memset) /* * This version uses dcbz on the complete cache lines in the @@ -160,12 +158,12 @@ * We therefore jump to generic_memcpy which doesn't use dcbz. This jump is * replaced by a nop once cache is active. This is done in machine_init() */ -_GLOBAL_KASAN(memmove) +_GLOBAL(memmove) cmplw 0,r3,r4 bgt backwards_memcpy /* fall through */ -_GLOBAL_KASAN(memcpy) +_GLOBAL(memcpy) 1: b generic_memcpy patch_site 1b, patch__memcpy_nocache @@ -241,8 +239,6 @@ 65: blr EXPORT_SYMBOL(memcpy) EXPORT_SYMBOL(memmove) -EXPORT_SYMBOL_KASAN(memcpy) -EXPORT_SYMBOL_KASAN(memmove) generic_memcpy: srwi. r7,r5,3
diff --git a/arch/powerpc/lib/mem_64.S b/arch/powerpc/lib/mem_64.S index 6fd06cd..40eaedd 100644 --- a/arch/powerpc/lib/mem_64.S +++ b/arch/powerpc/lib/mem_64.S
@@ -8,7 +8,6 @@ #include <asm/processor.h> #include <asm/errno.h> #include <asm/ppc_asm.h> -#include <asm/kasan.h> #ifndef CONFIG_KASAN _GLOBAL(__memset16) @@ -29,7 +28,7 @@ EXPORT_SYMBOL(__memset64) #endif -_GLOBAL_KASAN(memset) +_GLOBAL(memset) neg r0,r3 rlwimi r4,r4,8,16,23 andi. r0,r0,7 /* # bytes to be 8-byte aligned */ @@ -95,9 +94,8 @@ stb r4,0(r6) blr EXPORT_SYMBOL(memset) -EXPORT_SYMBOL_KASAN(memset) -_GLOBAL_TOC_KASAN(memmove) +_GLOBAL_TOC(memmove) cmplw 0,r3,r4 bgt backwards_memcpy b memcpy @@ -139,4 +137,3 @@ mtctr r7 b 1b EXPORT_SYMBOL(memmove) -EXPORT_SYMBOL_KASAN(memmove)
diff --git a/arch/powerpc/lib/memcpy_64.S b/arch/powerpc/lib/memcpy_64.S index b5a67e2..0cedd45 100644 --- a/arch/powerpc/lib/memcpy_64.S +++ b/arch/powerpc/lib/memcpy_64.S
@@ -7,7 +7,6 @@ #include <asm/ppc_asm.h> #include <asm/asm-compat.h> #include <asm/feature-fixups.h> -#include <asm/kasan.h> #ifndef SELFTEST_CASE /* For big-endian, 0 == most CPUs, 1 == POWER6, 2 == Cell */ @@ -15,7 +14,7 @@ #endif .align 7 -_GLOBAL_TOC_KASAN(memcpy) +_GLOBAL_TOC(memcpy) BEGIN_FTR_SECTION #ifdef __LITTLE_ENDIAN__ cmpdi cr7,r5,0 @@ -227,4 +226,3 @@ blr #endif EXPORT_SYMBOL(memcpy) -EXPORT_SYMBOL_KASAN(memcpy)
diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index f0d6aa6..d49b2ef 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c
@@ -47,7 +47,7 @@ extern void conv_sp_to_dp(const float *sp, double *dp); extern void conv_dp_to_sp(const double *dp, float *sp); #endif -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 /* * Functions in quad.S */ @@ -134,7 +134,7 @@ static nokprobe_inline unsigned long dform_ea(unsigned int instr, return ea; } -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 /* * Calculate effective address for a DS-form instruction */ @@ -168,7 +168,7 @@ static nokprobe_inline unsigned long dqform_ea(unsigned int instr, return ea; } -#endif /* __powerpc64 */ +#endif /* CONFIG_PPC64 */ /* * Calculate effective address for an X-form instruction @@ -250,7 +250,7 @@ static nokprobe_inline unsigned long byterev_4(unsigned long x) ((x & 0xff00) << 8) | ((x & 0xff) << 24); } -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 static nokprobe_inline unsigned long byterev_8(unsigned long x) { return (byterev_4(x) << 32) | byterev_4(x >> 32); @@ -266,7 +266,7 @@ static nokprobe_inline void do_byte_reverse(void *ptr, int nb) case 4: *(u32 *)ptr = byterev_4(*(u32 *)ptr); break; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 8: *(unsigned long *)ptr = byterev_8(*(unsigned long *)ptr); break; @@ -312,7 +312,7 @@ __read_mem_aligned(unsigned long *dest, unsigned long ea, int nb, struct pt_regs case 4: unsafe_get_user(x, (unsigned int __user *)ea, Efault); break; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 8: unsafe_get_user(x, (unsigned long __user *)ea, Efault); break; @@ -364,7 +364,7 @@ static __always_inline int __copy_mem_in(u8 *dest, unsigned long ea, int nb, str case 4: unsafe_get_user(*(u32 *)dest, (u32 __user *)ea, Efault); break; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 8: unsafe_get_user(*(u64 *)dest, (u64 __user *)ea, Efault); break; @@ -443,7 +443,7 @@ __write_mem_aligned(unsigned long val, unsigned long ea, int nb, struct pt_regs case 4: unsafe_put_user(val, (unsigned int __user *)ea, Efault); break; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 8: unsafe_put_user(val, (unsigned long __user *)ea, Efault); break; @@ -494,7 +494,7 @@ static __always_inline int __copy_mem_out(u8 *dest, unsigned long ea, int nb, st case 4: unsafe_put_user(*(u32 *)dest, (u32 __user *)ea, Efault); break; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 8: unsafe_put_user(*(u64 *)dest, (u64 __user *)ea, Efault); break; @@ -722,7 +722,7 @@ static nokprobe_inline int do_vec_store(int rn, unsigned long ea, } #endif /* CONFIG_ALTIVEC */ -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 static nokprobe_inline int emulate_lq(struct pt_regs *regs, unsigned long ea, int reg, bool cross_endian) { @@ -765,7 +765,7 @@ static nokprobe_inline int emulate_stq(struct pt_regs *regs, unsigned long ea, err = write_mem(vals[IS_BE], ea + 8, 8, regs); return err; } -#endif /* __powerpc64 */ +#endif /* CONFIG_PPC64 */ #ifdef CONFIG_VSX static nokprobe_inline void emulate_vsx_load(struct instruction_op *op, union vsx_reg *reg, @@ -1316,7 +1316,7 @@ static nokprobe_inline int trap_compare(long v1, long v2) */ #define MASK32(mb, me) ((0xffffffffUL >> (mb)) + \ ((signed long)-0x80000000L >> (me)) + ((me) >= (mb))) -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 #define MASK64_L(mb) (~0UL >> (mb)) #define MASK64_R(me) ((signed long)-0x8000000000000000L >> (me)) #define MASK64(mb, me) (MASK64_L(mb) + MASK64_R(me) + ((me) >= (mb))) @@ -1342,16 +1342,19 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, { #ifdef CONFIG_PPC64 unsigned int suffixopcode, prefixtype, prefix_r; + unsigned int rc, suffix; #endif - unsigned int opcode, ra, rb, rc, rd, spr, u; + unsigned int opcode, ra, rb, rd, spr, u; unsigned long int imm; unsigned long int val, val2; unsigned int mb, me, sh; - unsigned int word, suffix; + unsigned int word; long ival; word = ppc_inst_val(instr); +#ifdef CONFIG_PPC64 suffix = ppc_inst_suffix(instr); +#endif op->type = COMPUTE; @@ -1447,7 +1450,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, switch ((word >> 1) & 0x3ff) { case 598: /* sync */ op->type = BARRIER + BARRIER_SYNC; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 switch ((word >> 21) & 3) { case 1: /* lwsync */ op->type = BARRIER + BARRIER_LWSYNC; @@ -1469,10 +1472,12 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, rd = (word >> 21) & 0x1f; ra = (word >> 16) & 0x1f; rb = (word >> 11) & 0x1f; +#ifdef CONFIG_PPC64 rc = (word >> 6) & 0x1f; +#endif switch (opcode) { -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 1: if (!cpu_has_feature(CPU_FTR_ARCH_31)) goto unknown_opcode; @@ -1506,7 +1511,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, goto trap; return 1; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 4: /* * There are very many instructions with this primary opcode @@ -1555,7 +1560,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 10: /* cmpli */ imm = (unsigned short) word; val = regs->gpr[ra]; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 if ((rd & 1) == 0) val = (unsigned int) val; #endif @@ -1565,7 +1570,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 11: /* cmpi */ imm = (short) word; val = regs->gpr[ra]; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 if ((rd & 1) == 0) val = (int) val; #endif @@ -1662,7 +1667,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, set_cr0(regs, op); goto logical_done_nocc; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 30: /* rld* */ mb = ((word >> 6) & 0x1f) | (word & 0x20); val = regs->gpr[rd]; @@ -1720,7 +1725,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, (int)regs->gpr[rb]))) goto trap; return 1; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 68: /* td */ if (rd & trap_compare(regs->gpr[ra], regs->gpr[rb])) goto trap; @@ -1826,7 +1831,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 0: /* cmp */ val = regs->gpr[ra]; val2 = regs->gpr[rb]; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 if ((rd & 1) == 0) { /* word (32-bit) compare */ val = (int) val; @@ -1839,7 +1844,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 32: /* cmpl */ val = regs->gpr[ra]; val2 = regs->gpr[rb]; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 if ((rd & 1) == 0) { /* word (32-bit) compare */ val = (unsigned int) val; @@ -1860,7 +1865,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, add_with_carry(regs, op, rd, ~regs->gpr[ra], regs->gpr[rb], 1); goto arith_done; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 9: /* mulhdu */ asm("mulhdu %0,%1,%2" : "=r" (op->val) : "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); @@ -1879,7 +1884,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 40: /* subf */ op->val = regs->gpr[rb] - regs->gpr[ra]; goto arith_done; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 73: /* mulhd */ asm("mulhd %0,%1,%2" : "=r" (op->val) : "r" (regs->gpr[ra]), "r" (regs->gpr[rb])); @@ -1918,7 +1923,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, add_with_carry(regs, op, rd, ~regs->gpr[ra], -1L, regs->xer & XER_CA); goto arith_done; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 233: /* mulld */ op->val = regs->gpr[ra] * regs->gpr[rb]; goto arith_done; @@ -1933,7 +1938,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, (int) regs->gpr[rb]; goto arith_done; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 265: /* modud */ if (!cpu_has_feature(CPU_FTR_ARCH_300)) goto unknown_opcode; @@ -1950,7 +1955,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, op->val = (unsigned int) regs->gpr[ra] % (unsigned int) regs->gpr[rb]; goto compute_done; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 457: /* divdu */ op->val = regs->gpr[ra] / regs->gpr[rb]; goto arith_done; @@ -1959,7 +1964,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, op->val = (unsigned int) regs->gpr[ra] / (unsigned int) regs->gpr[rb]; goto arith_done; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 489: /* divd */ op->val = (long int) regs->gpr[ra] / (long int) regs->gpr[rb]; @@ -1969,7 +1974,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, op->val = (int) regs->gpr[ra] / (int) regs->gpr[rb]; goto arith_done; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 425: /* divde[.] */ asm volatile(PPC_DIVDE(%0, %1, %2) : "=r" (op->val) : "r" (regs->gpr[ra]), @@ -2002,7 +2007,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, } goto unknown_opcode; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 777: /* modsd */ if (!cpu_has_feature(CPU_FTR_ARCH_300)) goto unknown_opcode; @@ -2025,7 +2030,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, val = (unsigned int) regs->gpr[rd]; op->val = ( val ? __builtin_clz(val) : 32 ); goto logical_done; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 58: /* cntlzd */ val = regs->gpr[rd]; op->val = ( val ? __builtin_clzl(val) : 64 ); @@ -2093,7 +2098,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, val = (unsigned int) regs->gpr[rd]; op->val = (val ? __builtin_ctz(val) : 32); goto logical_done; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 570: /* cnttzd */ if (!cpu_has_feature(CPU_FTR_ARCH_300)) goto unknown_opcode; @@ -2108,7 +2113,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 954: /* extsb */ op->val = (signed char) regs->gpr[rd]; goto logical_done; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 986: /* extsw */ op->val = (signed int) regs->gpr[rd]; goto logical_done; @@ -2159,7 +2164,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, set_ca32(op, op->xerval & XER_CA); goto logical_done; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 27: /* sld */ sh = regs->gpr[rb] & 0x7f; if (sh < 64) @@ -2216,7 +2221,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, op->val = val; goto logical_done; -#endif /* __powerpc64__ */ +#endif /* CONFIG_PPC64 */ /* * Cache instructions @@ -2296,7 +2301,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, op->type = MKOP(STCX, 0, 2); break; #endif -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 84: /* ldarx */ op->type = MKOP(LARX, 0, 8); break; @@ -2373,7 +2378,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; #endif /* CONFIG_ALTIVEC */ -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 21: /* ldx */ case 53: /* ldux */ op->type = MKOP(LOAD, u, 8); @@ -2400,7 +2405,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, op->type = MKOP(LOAD, u, 2); break; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 341: /* lwax */ case 373: /* lwaux */ op->type = MKOP(LOAD, SIGNEXT | u, 4); @@ -2417,7 +2422,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, op->type = MKOP(STORE, u, 2); break; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 532: /* ldbrx */ op->type = MKOP(LOAD, BYTEREV, 8); break; @@ -2459,7 +2464,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, op->type = MKOP(STORE_FP, u, 8); break; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 791: /* lfdpx */ op->type = MKOP(LOAD_FP, 0, 16); break; @@ -2479,10 +2484,10 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 983: /* stfiwx */ op->type = MKOP(STORE_FP, 0, 4); break; -#endif /* __powerpc64 */ +#endif /* CONFIG_PPC64 */ #endif /* CONFIG_PPC_FPU */ -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 660: /* stdbrx */ op->type = MKOP(STORE, BYTEREV, 8); op->val = byterev_8(regs->gpr[rd]); @@ -2820,7 +2825,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; #endif -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 56: /* lq */ if (!((rd & 1) || (rd == ra))) op->type = MKOP(LOAD, 0, 16); @@ -2857,7 +2862,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; #endif /* CONFIG_VSX */ -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 58: /* ld[u], lwa */ op->ea = dsform_ea(word, regs); switch (word & 3) { @@ -2946,7 +2951,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; #endif /* CONFIG_VSX */ -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 62: /* std[u] */ op->ea = dsform_ea(word, regs); switch (word & 3) { @@ -3099,7 +3104,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 3: /* Type 11 Modified Register-to-Register */ break; } -#endif /* __powerpc64__ */ +#endif /* CONFIG_PPC64 */ } @@ -3200,7 +3205,7 @@ static nokprobe_inline void do_byterev(unsigned long *valp, int size) case 4: *valp = byterev_4(*valp); break; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 8: *valp = byterev_8(*valp); break; @@ -3341,7 +3346,7 @@ int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op) case 4: __get_user_asmx(val, ea, err, "lwarx"); break; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 8: __get_user_asmx(val, ea, err, "ldarx"); break; @@ -3367,7 +3372,7 @@ int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op) return -EFAULT; err = 0; switch (size) { -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 1: __put_user_asmx(op->val, ea, err, "stbcx.", cr); break; @@ -3378,7 +3383,7 @@ int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op) case 4: __put_user_asmx(op->val, ea, err, "stwcx.", cr); break; -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 case 8: __put_user_asmx(op->val, ea, err, "stdcx.", cr); break; @@ -3399,7 +3404,7 @@ int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op) break; case LOAD: -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 if (size == 16) { err = emulate_lq(regs, ea, op->reg, cross_endian); break; @@ -3473,7 +3478,7 @@ int emulate_loadstore(struct pt_regs *regs, struct instruction_op *op) break; case STORE: -#ifdef __powerpc64__ +#ifdef CONFIG_PPC64 if (size == 16) { err = emulate_stq(regs, ea, op->reg, cross_endian); break;
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index f4cf3ae..e97b624 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c
@@ -432,7 +432,7 @@ static void __init initialize_form2_numa_distance_lookup_table(void) static int __init find_primary_domain_index(void) { - int index; + int index = -1; struct device_node *root; /* @@ -502,12 +502,9 @@ static int __init find_primary_domain_index(void) distance_ref_points_depth = MAX_DISTANCE_REF_POINTS; } - of_node_put(root); - return index; - err: of_node_put(root); - return -1; + return index; } static void __init get_n_mem_cells(int *n_addr_cells, int *n_size_cells) @@ -892,12 +889,32 @@ static int __init numa_setup_drmem_lmb(struct drmem_lmb *lmb, return 0; } +/* + * If hierarchy extends beyond primary_domain_index + 1, then next + * level corresponds to coregroup. + */ +static int detect_and_enable_coregroup(const __be32 *associativity, int index) +{ + if (!associativity || index == -1) + goto out; + + index = of_read_number(associativity, 1); + + if (index > primary_domain_index + 1) { + coregroup_enabled = 1; + return index; + } +out: + coregroup_enabled = 0; + return -1; +} + static int __init parse_numa_properties(void) { struct device_node *memory, *pci; - int default_nid = 0; - unsigned long i; + int default_nid = 0, index = 0; const __be32 *associativity; + unsigned long i; if (numa_enabled == 0) { pr_warn("disabled by user\n"); @@ -930,7 +947,6 @@ static int __init parse_numa_properties(void) */ for_each_present_cpu(i) { __be32 vphn_assoc[VPHN_ASSOC_BUFSIZE]; - struct device_node *cpu; int nid = NUMA_NO_NODE; memset(vphn_assoc, 0, VPHN_ASSOC_BUFSIZE * sizeof(__be32)); @@ -938,7 +954,9 @@ static int __init parse_numa_properties(void) if (__vphn_get_associativity(i, vphn_assoc) == 0) { nid = associativity_to_nid(vphn_assoc); initialize_form1_numa_distance(vphn_assoc); + index = detect_and_enable_coregroup(vphn_assoc, index); } else { + struct device_node *cpu; /* * Don't fall back to default_nid yet -- we will plug @@ -951,6 +969,7 @@ static int __init parse_numa_properties(void) associativity = of_get_associativity(cpu); if (associativity) { nid = associativity_to_nid(associativity); + index = detect_and_enable_coregroup(associativity, index); initialize_form1_numa_distance(associativity); } of_node_put(cpu); @@ -1431,9 +1450,26 @@ void find_and_update_cpu_nid(int cpu) pr_debug("%s:%d cpu %d nid %d\n", __func__, __LINE__, cpu, new_nid); } +static int topology_update_init(void) +{ + topology_inited = 1; + return 0; +} +device_initcall(topology_update_init); + +#else +static long vphn_get_associativity(unsigned long cpu, + __be32 *associativity) +{ + return -1; +} +#endif /* CONFIG_PPC_SPLPAR */ + int cpu_to_coregroup_id(int cpu) { - __be32 associativity[VPHN_ASSOC_BUFSIZE] = {0}; + int coregroup_id = cpu_to_core_id(cpu); + struct device_node *cpunode = NULL; + const __be32 *associativity; int index; if (cpu < 0 || cpu > nr_cpu_ids) @@ -1442,24 +1478,31 @@ int cpu_to_coregroup_id(int cpu) if (!coregroup_enabled) goto out; - if (!firmware_has_feature(FW_FEATURE_VPHN)) - goto out; + if (firmware_has_feature(FW_FEATURE_VPHN)) { + __be32 tmp[VPHN_ASSOC_BUFSIZE] = {0}; - if (vphn_get_associativity(cpu, associativity)) + if (vphn_get_associativity(cpu, tmp)) + goto out; + + associativity = tmp; + + } else { + cpunode = of_get_cpu_node(cpu, NULL); + if (!cpunode) + goto out; + + associativity = of_get_associativity(cpunode); + } + if (!associativity) goto out; index = of_read_number(associativity, 1); if (index > primary_domain_index + 1) - return of_read_number(&associativity[index - 1], 1); + coregroup_id = of_read_number(&associativity[index - 1], 1); out: - return cpu_to_core_id(cpu); -} + if (cpunode) + of_node_put(cpunode); -static int topology_update_init(void) -{ - topology_inited = 1; - return 0; + return coregroup_id; } -device_initcall(topology_update_init); -#endif /* CONFIG_PPC_SPLPAR */
diff --git a/arch/powerpc/net/bpf_jit.h b/arch/powerpc/net/bpf_jit.h index f32de87..4da8bde 100644 --- a/arch/powerpc/net/bpf_jit.h +++ b/arch/powerpc/net/bpf_jit.h
@@ -14,6 +14,13 @@ #include <asm/ppc-opcode.h> #include <linux/build_bug.h> +/* + * We need at least 2 passes for proper code generation, and may need + * additional passes if code size changes between passes. + */ +#define CODEGEN_MIN_PASSES 2 +#define CODEGEN_MAX_PASSES 3 + #ifdef CONFIG_PPC64_ELF_ABI_V1 #define FUNCTION_DESCR_SIZE 24 #else @@ -188,6 +195,12 @@ struct codegen_context { #define bpf_to_ppc(r) (ctx->b2p[r]) +#ifdef CONFIG_PPC64 +#define PPC_RAW_CMPLLI(a, i) PPC_RAW_CMPLDI(a, i) +#else +#define PPC_RAW_CMPLLI(a, i) PPC_RAW_CMPLWI(a, i) +#endif + #ifdef CONFIG_PPC32 #define BPF_FIXUP_LEN 3 /* Three instructions => 12 bytes */ #else @@ -214,10 +227,11 @@ int bpf_jit_emit_func_call_rel(u32 *image, u32 *fimage, struct codegen_context * int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct codegen_context *ctx, u32 *addrs, int pass, bool extra_pass); void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx); -void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx); -void bpf_jit_build_fentry_stubs(u32 *image, struct codegen_context *ctx); +void bpf_jit_build_epilogue(u32 *image, u32 *fimage, struct codegen_context *ctx); +void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context *ctx); void bpf_jit_realloc_regs(struct codegen_context *ctx); -int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg, long exit_addr); +int bpf_jit_emit_exit_insn(u32 *image, u32 *fimage, struct codegen_context *ctx, int tmp_reg, + long exit_addr); void prepare_for_fsession_fentry(u32 *image, struct codegen_context *ctx, int cookie_cnt, int cookie_off, int retval_off); void store_func_meta(u32 *image, struct codegen_context *ctx, u64 func_meta, int func_meta_off);
diff --git a/arch/powerpc/net/bpf_jit_comp.c b/arch/powerpc/net/bpf_jit_comp.c index 7a61268..cfe01c3 100644 --- a/arch/powerpc/net/bpf_jit_comp.c +++ b/arch/powerpc/net/bpf_jit_comp.c
@@ -49,11 +49,35 @@ asm ( " .popsection ;" ); -void bpf_jit_build_fentry_stubs(u32 *image, struct codegen_context *ctx) +void bpf_jit_build_fentry_stubs(u32 *image, u32 *fimage, struct codegen_context *ctx) { int ool_stub_idx, long_branch_stub_idx; + int stub_sz; /* + * The dummy_tramp_addr field is placed at bottom of Long branch stub. + * Align the mis-aligned dummy_tramp_addr field in the fimage. + * The alignment NOP must appear before OOL stub, to make + * ool_stub_idx & long_branch_stub_idx constant from end. + * + * The fimage can be non 8-byte aligned, so final alignment depends + * on start of fimage and the stub's instruction count. The + * stubs block has 11 instructions (with CONFIG_PPC_FTRACE_OUT_OF_LINE) + * or 10 instructions (without) before dummy_tramp_addr field. Emit a + * NOP if the address of dummy_tramp_addr is non aligned. + * + * In pass=0 when image==NULL, conservatively account for space + * required to accommodate alignment NOP. In case final pass skips + * emitting alignment NOP, the image buffer have 4 spare bytes and + * jited_len signifies correct program size. + */ + + stub_sz = IS_ENABLED(CONFIG_PPC_FTRACE_OUT_OF_LINE) ? 44 : 40; + if (!image || !IS_ALIGNED((unsigned long)fimage + ctx->idx*4 + stub_sz, SZL)) + EMIT(PPC_RAW_NOP()); + + /* + * nop // optional, for alignment of dummy_tramp_addr * Out-of-line stub: * mflr r0 * [b|bl] tramp @@ -70,44 +94,46 @@ void bpf_jit_build_fentry_stubs(u32 *image, struct codegen_context *ctx) /* * Long branch stub: - * .long <dummy_tramp_addr> * mflr r11 * bcl 20,31,$+4 - * mflr r12 - * ld r12, -8-SZL(r12) + * mflr r12 // lr/r12 stores pc of current(this) inst. + * ld r12, 20(r12) // offset(dummy_tramp_addr) from prev inst. is 20 * mtctr r12 - * mtlr r11 // needed to retain ftrace ABI + * mtlr r11 // needed to retain ftrace ABI * bctr + * .long <dummy_tramp_addr> // SZL bytes aligned */ - if (image) - *((unsigned long *)&image[ctx->idx]) = (unsigned long)dummy_tramp; - ctx->idx += SZL / 4; long_branch_stub_idx = ctx->idx; EMIT(PPC_RAW_MFLR(_R11)); EMIT(PPC_RAW_BCL4()); EMIT(PPC_RAW_MFLR(_R12)); - EMIT(PPC_RAW_LL(_R12, _R12, -8-SZL)); + EMIT(PPC_RAW_LL(_R12, _R12, 20)); EMIT(PPC_RAW_MTCTR(_R12)); EMIT(PPC_RAW_MTLR(_R11)); EMIT(PPC_RAW_BCTR()); + if (image) + *((unsigned long *)&image[ctx->idx]) = (unsigned long)dummy_tramp; + + ctx->idx += SZL / 4; + if (!bpf_jit_ool_stub) { bpf_jit_ool_stub = (ctx->idx - ool_stub_idx) * 4; bpf_jit_long_branch_stub = (ctx->idx - long_branch_stub_idx) * 4; } } -int bpf_jit_emit_exit_insn(u32 *image, struct codegen_context *ctx, int tmp_reg, long exit_addr) +int bpf_jit_emit_exit_insn(u32 *image, u32 *fimage, struct codegen_context *ctx, + int tmp_reg, long exit_addr) { - if (!exit_addr || is_offset_in_branch_range(exit_addr - (ctx->idx * 4))) { + if (exit_addr && is_offset_in_branch_range(exit_addr - (long)(ctx->idx * 4))) { PPC_JMP(exit_addr); - } else if (ctx->alt_exit_addr) { - if (WARN_ON(!is_offset_in_branch_range((long)ctx->alt_exit_addr - (ctx->idx * 4)))) - return -1; + } else if (ctx->alt_exit_addr && is_offset_in_branch_range( + (long)(ctx->alt_exit_addr) - (long)(ctx->idx * 4))) { PPC_JMP(ctx->alt_exit_addr); } else { ctx->alt_exit_addr = ctx->idx * 4; - bpf_jit_build_epilogue(image, ctx); + bpf_jit_build_epilogue(image, fimage, ctx); } return 0; @@ -274,6 +300,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr */ if (cgctx.seen & SEEN_TAILCALL || !is_offset_in_branch_range((long)cgctx.idx * 4)) { cgctx.idx = 0; + cgctx.alt_exit_addr = 0; if (bpf_jit_build_body(fp, NULL, NULL, &cgctx, addrs, 0, false)) goto out_err; } @@ -286,7 +313,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr */ bpf_jit_build_prologue(NULL, &cgctx); addrs[fp->len] = cgctx.idx * 4; - bpf_jit_build_epilogue(NULL, &cgctx); + bpf_jit_build_epilogue(NULL, NULL, &cgctx); fixup_len = fp->aux->num_exentries * BPF_FIXUP_LEN * 4; extable_len = fp->aux->num_exentries * sizeof(struct exception_table_entry); @@ -306,10 +333,13 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr code_base = (u32 *)(image + FUNCTION_DESCR_SIZE); fcode_base = (u32 *)(fimage + FUNCTION_DESCR_SIZE); - /* Code generation passes 1-2 */ - for (pass = 1; pass < 3; pass++) { + /* Code generation passes 1-2+, loop until program size converges. */ + for (pass = 1; pass <= CODEGEN_MAX_PASSES; pass++) { + u32 prev_proglen = proglen; + /* Now build the prologue, body code & epilogue for real. */ cgctx.idx = 0; + cgctx.exentry_idx = 0; cgctx.alt_exit_addr = 0; bpf_jit_build_prologue(code_base, &cgctx); if (bpf_jit_build_body(fp, code_base, fcode_base, &cgctx, addrs, pass, @@ -318,11 +348,26 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr bpf_jit_binary_pack_free(fhdr, hdr); goto out_err; } - bpf_jit_build_epilogue(code_base, &cgctx); + addrs[fp->len] = cgctx.idx * 4; + bpf_jit_build_epilogue(code_base, fcode_base, &cgctx); + + proglen = cgctx.idx * 4; if (bpf_jit_enable > 1) pr_info("Pass %d: shrink = %d, seen = 0x%x\n", pass, - proglen - (cgctx.idx * 4), cgctx.seen); + prev_proglen - proglen, cgctx.seen); + + /* Check if program size has converged, but ensure minimum passes */ + if (pass >= CODEGEN_MIN_PASSES && proglen == prev_proglen) + break; + + if (pass == CODEGEN_MAX_PASSES && proglen != prev_proglen) { + pr_err("BPF JIT: Program did not converge after %d passes\n", + CODEGEN_MAX_PASSES); + bpf_arch_text_copy(&fhdr->size, &hdr->size, sizeof(hdr->size)); + bpf_jit_binary_pack_free(fhdr, hdr); + goto out_err; + } } if (bpf_jit_enable > 1) @@ -357,7 +402,7 @@ struct bpf_prog *bpf_int_jit_compile(struct bpf_verifier_env *env, struct bpf_pr (void *)fimage + FUNCTION_DESCR_SIZE); out_addrs: - if (!image && priv_stack_ptr) { + if (!fp->jited && priv_stack_ptr) { fp->aux->priv_stack_ptr = NULL; free_percpu(priv_stack_ptr); } @@ -399,7 +444,7 @@ int bpf_add_extable_entry(struct bpf_prog *fp, u32 *image, u32 *fimage, int pass u32 *fixup; /* Populate extable entries only in the last pass */ - if (pass != 2) + if (pass < CODEGEN_MIN_PASSES) return 0; if (!fp->aux->extable || @@ -747,7 +792,7 @@ static void bpf_trampoline_setup_tail_call_info(u32 *image, struct codegen_conte * Setting the tail_call_info in trampoline's frame * depending on if previous frame had value or reference. */ - EMIT(PPC_RAW_CMPLWI(_R3, MAX_TAIL_CALL_CNT)); + EMIT(PPC_RAW_CMPLLI(_R3, MAX_TAIL_CALL_CNT)); PPC_BCC_CONST_SHORT(COND_GT, 8); EMIT(PPC_RAW_ADDI(_R3, _R4, -BPF_PPC_TAILCALL)); @@ -1266,6 +1311,7 @@ static void do_isync(void *info __maybe_unused) * bpf_func: * [nop|b] ool_stub * 2. Out-of-line stub: + * nop // optional nop for alignment * ool_stub: * mflr r0 * [b|bl] <bpf_prog>/<long_branch_stub> @@ -1273,14 +1319,14 @@ static void do_isync(void *info __maybe_unused) * b bpf_func + 4 * 3. Long branch stub: * long_branch_stub: - * .long <branch_addr>/<dummy_tramp> * mflr r11 * bcl 20,31,$+4 * mflr r12 - * ld r12, -16(r12) + * ld r12, 20(r12) * mtctr r12 * mtlr r11 // needed to retain ftrace ABI * bctr + * .long <branch_addr>/<dummy_tramp> * * dummy_tramp is used to reduce synchronization requirements. * @@ -1382,10 +1428,12 @@ int bpf_arch_text_poke(void *ip, enum bpf_text_poke_type old_t, * 1. Update the address in the long branch stub: * If new_addr is out of range, we will have to use the long branch stub, so patch new_addr * here. Otherwise, revert to dummy_tramp, but only if we had patched old_addr here. + * + * dummy_tramp_addr moved to bottom of long branch stub. */ if ((new_addr && !is_offset_in_branch_range(new_addr - ip)) || (old_addr && !is_offset_in_branch_range(old_addr - ip))) - ret = patch_ulong((void *)(bpf_func_end - bpf_jit_long_branch_stub - SZL), + ret = patch_ulong((void *)(bpf_func_end - SZL), /* SZL: dummy_tramp_addr offset */ (new_addr && !is_offset_in_branch_range(new_addr - ip)) ? (unsigned long)new_addr : (unsigned long)dummy_tramp); if (ret)
diff --git a/arch/powerpc/net/bpf_jit_comp32.c b/arch/powerpc/net/bpf_jit_comp32.c index bfdc507..f5b9441 100644 --- a/arch/powerpc/net/bpf_jit_comp32.c +++ b/arch/powerpc/net/bpf_jit_comp32.c
@@ -229,7 +229,7 @@ static void bpf_jit_emit_common_epilogue(u32 *image, struct codegen_context *ctx } -void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) +void bpf_jit_build_epilogue(u32 *image, u32 *fimage, struct codegen_context *ctx) { EMIT(PPC_RAW_MR(_R3, bpf_to_ppc(BPF_REG_0))); @@ -237,7 +237,7 @@ void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) EMIT(PPC_RAW_BLR()); - bpf_jit_build_fentry_stubs(image, ctx); + bpf_jit_build_fentry_stubs(image, fimage, ctx); } /* Relative offset needs to be calculated based on final image location */ @@ -1149,7 +1149,8 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code * we'll just fall through to the epilogue. */ if (i != flen - 1) { - ret = bpf_jit_emit_exit_insn(image, ctx, _R0, exit_addr); + ret = bpf_jit_emit_exit_insn(image, fimage, + ctx, _R0, exit_addr); if (ret) return ret; }
diff --git a/arch/powerpc/net/bpf_jit_comp64.c b/arch/powerpc/net/bpf_jit_comp64.c index fc9db69..c1e86fe0b 100644 --- a/arch/powerpc/net/bpf_jit_comp64.c +++ b/arch/powerpc/net/bpf_jit_comp64.c
@@ -276,7 +276,7 @@ void bpf_jit_build_prologue(u32 *image, struct codegen_context *ctx) */ EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_2), _R1, 0)); EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_1), bpf_to_ppc(TMP_REG_2), -(BPF_PPC_TAILCALL))); - EMIT(PPC_RAW_CMPLWI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT)); + EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT)); PPC_BCC_CONST_SHORT(COND_GT, 8); EMIT(PPC_RAW_ADDI(bpf_to_ppc(TMP_REG_1), bpf_to_ppc(TMP_REG_2), -(BPF_PPC_TAILCALL))); @@ -398,7 +398,7 @@ static void bpf_jit_emit_common_epilogue(u32 *image, struct codegen_context *ctx } } -void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) +void bpf_jit_build_epilogue(u32 *image, u32 *fimage, struct codegen_context *ctx) { bpf_jit_emit_common_epilogue(image, ctx); @@ -407,7 +407,7 @@ void bpf_jit_build_epilogue(u32 *image, struct codegen_context *ctx) EMIT(PPC_RAW_BLR()); - bpf_jit_build_fentry_stubs(image, ctx); + bpf_jit_build_fentry_stubs(image, fimage, ctx); } /* @@ -662,7 +662,7 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o PPC_BCC_SHORT(COND_GE, out); EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_1), _R1, bpf_jit_stack_tailcallinfo_offset(ctx))); - EMIT(PPC_RAW_CMPLWI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT)); + EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT)); PPC_BCC_CONST_SHORT(COND_LE, 8); /* dereference TMP_REG_1 */ @@ -672,7 +672,7 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o * if (tail_call_info == MAX_TAIL_CALL_CNT) * goto out; */ - EMIT(PPC_RAW_CMPLWI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT)); + EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_1), MAX_TAIL_CALL_CNT)); PPC_BCC_SHORT(COND_EQ, out); /* @@ -707,7 +707,7 @@ static int bpf_jit_emit_tail_call(u32 *image, struct codegen_context *ctx, u32 o * tail_call_info. */ EMIT(PPC_RAW_LD(bpf_to_ppc(TMP_REG_2), _R1, bpf_jit_stack_tailcallinfo_offset(ctx))); - EMIT(PPC_RAW_CMPLWI(bpf_to_ppc(TMP_REG_2), MAX_TAIL_CALL_CNT)); + EMIT(PPC_RAW_CMPLDI(bpf_to_ppc(TMP_REG_2), MAX_TAIL_CALL_CNT)); PPC_BCC_CONST_SHORT(COND_GT, 8); /* First get address of tail_call_info */ @@ -1737,7 +1737,8 @@ int bpf_jit_build_body(struct bpf_prog *fp, u32 *image, u32 *fimage, struct code * we'll just fall through to the epilogue. */ if (i != flen - 1) { - ret = bpf_jit_emit_exit_insn(image, ctx, tmp1_reg, exit_addr); + ret = bpf_jit_emit_exit_insn(image, fimage, ctx, + tmp1_reg, exit_addr); if (ret) return ret; }
diff --git a/arch/powerpc/platforms/512x/Kconfig b/arch/powerpc/platforms/512x/Kconfig index deecede..9d46d79 100644 --- a/arch/powerpc/platforms/512x/Kconfig +++ b/arch/powerpc/platforms/512x/Kconfig
@@ -32,11 +32,12 @@ which do not need custom platform specific setup. Compatible boards include: Protonic LVT base boards (ZANMCU - and VICVT2), Freescale MPC5125 Tower system. + and VICVT2), Freescale MPC5125 Tower system, IFM PDM360NG. config PDM360NG bool "ifm PDM360NG board" depends on PPC_MPC512x + select MPC512x_GENERIC select DEFAULT_UIMAGE help This option enables support for the PDM360NG board.
diff --git a/arch/powerpc/platforms/512x/Makefile b/arch/powerpc/platforms/512x/Makefile index 2daf22e..4da6f69 100644 --- a/arch/powerpc/platforms/512x/Makefile +++ b/arch/powerpc/platforms/512x/Makefile
@@ -7,4 +7,3 @@ obj-$(CONFIG_MPC5121_ADS) += mpc5121_ads.o mpc5121_ads_cpld.o obj-$(CONFIG_MPC512x_GENERIC) += mpc512x_generic.o obj-$(CONFIG_MPC512x_LPBFIFO) += mpc512x_lpbfifo.o -obj-$(CONFIG_PDM360NG) += pdm360ng.o
diff --git a/arch/powerpc/platforms/512x/mpc512x_generic.c b/arch/powerpc/platforms/512x/mpc512x_generic.c index d4fa6c3..d330d3d 100644 --- a/arch/powerpc/platforms/512x/mpc512x_generic.c +++ b/arch/powerpc/platforms/512x/mpc512x_generic.c
@@ -24,6 +24,7 @@ static const char * const board[] __initconst = { "prt,prtlvt", "fsl,mpc5125ads", "ifm,ac14xx", + "ifm,pdm360ng", NULL };
diff --git a/arch/powerpc/platforms/512x/pdm360ng.c b/arch/powerpc/platforms/512x/pdm360ng.c deleted file mode 100644 index 8bbbf78..0000000 --- a/arch/powerpc/platforms/512x/pdm360ng.c +++ /dev/null
@@ -1,126 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2010 DENX Software Engineering - * - * Anatolij Gustschin, <agust@denx.de> - * - * PDM360NG board setup - */ - -#include <linux/device.h> -#include <linux/kernel.h> -#include <linux/io.h> -#include <linux/of.h> -#include <linux/of_address.h> -#include <linux/of_fdt.h> - -#include <asm/machdep.h> -#include <asm/ipic.h> - -#include "mpc512x.h" - -#if defined(CONFIG_TOUCHSCREEN_ADS7846) || \ - defined(CONFIG_TOUCHSCREEN_ADS7846_MODULE) -#include <linux/interrupt.h> -#include <linux/spi/ads7846.h> -#include <linux/spi/spi.h> -#include <linux/notifier.h> - -static void *pdm360ng_gpio_base; - -static int pdm360ng_get_pendown_state(void) -{ - u32 reg; - - reg = in_be32(pdm360ng_gpio_base + 0xc); - if (reg & 0x40) - setbits32(pdm360ng_gpio_base + 0xc, 0x40); - - reg = in_be32(pdm360ng_gpio_base + 0x8); - - /* return 1 if pen is down */ - return (reg & 0x40) == 0; -} - -static struct ads7846_platform_data pdm360ng_ads7846_pdata = { - .model = 7845, - .get_pendown_state = pdm360ng_get_pendown_state, - .irq_flags = IRQF_TRIGGER_LOW, -}; - -static int __init pdm360ng_penirq_init(void) -{ - struct device_node *np; - - np = of_find_compatible_node(NULL, NULL, "fsl,mpc5121-gpio"); - if (!np) { - pr_err("%s: Can't find 'mpc5121-gpio' node\n", __func__); - return -ENODEV; - } - - pdm360ng_gpio_base = of_iomap(np, 0); - of_node_put(np); - if (!pdm360ng_gpio_base) { - pr_err("%s: Can't map gpio regs.\n", __func__); - return -ENODEV; - } - out_be32(pdm360ng_gpio_base + 0xc, 0xffffffff); - setbits32(pdm360ng_gpio_base + 0x18, 0x2000); - setbits32(pdm360ng_gpio_base + 0x10, 0x40); - - return 0; -} - -static int pdm360ng_touchscreen_notifier_call(struct notifier_block *nb, - unsigned long event, void *__dev) -{ - struct device *dev = __dev; - - if ((event == BUS_NOTIFY_ADD_DEVICE) && - of_device_is_compatible(dev->of_node, "ti,ads7846")) { - dev->platform_data = &pdm360ng_ads7846_pdata; - return NOTIFY_OK; - } - return NOTIFY_DONE; -} - -static struct notifier_block pdm360ng_touchscreen_nb = { - .notifier_call = pdm360ng_touchscreen_notifier_call, -}; - -static void __init pdm360ng_touchscreen_init(void) -{ - if (pdm360ng_penirq_init()) - return; - - bus_register_notifier(&spi_bus_type, &pdm360ng_touchscreen_nb); -} -#else -static inline void __init pdm360ng_touchscreen_init(void) -{ -} -#endif /* CONFIG_TOUCHSCREEN_ADS7846 */ - -static void __init pdm360ng_init(void) -{ - mpc512x_init(); - pdm360ng_touchscreen_init(); -} - -static int __init pdm360ng_probe(void) -{ - mpc512x_init_early(); - - return 1; -} - -define_machine(pdm360ng) { - .name = "PDM360NG", - .compatible = "ifm,pdm360ng", - .probe = pdm360ng_probe, - .setup_arch = mpc512x_setup_arch, - .init = pdm360ng_init, - .init_IRQ = mpc512x_init_IRQ, - .get_irq = ipic_get_irq, - .restart = mpc512x_restart, -};
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c index a4ad4b4..3586116 100644 --- a/arch/powerpc/platforms/ps3/interrupt.c +++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -184,8 +184,7 @@ static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, if (!*virq) { FAIL("%s:%d: irq_create_mapping failed: outlet %lu\n", __func__, __LINE__, outlet); - result = -ENOMEM; - goto fail_create; + return -ENOMEM; } DBG("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__, @@ -196,17 +195,13 @@ static int ps3_virq_setup(enum ps3_cpu_binding cpu, unsigned long outlet, if (result) { FAIL("%s:%d: irq_set_chip_data failed\n", __func__, __LINE__); - goto fail_set; + irq_dispose_mapping(*virq); + return result; } ps3_chip_mask(irq_get_irq_data(*virq)); return result; - -fail_set: - irq_dispose_mapping(*virq); -fail_create: - return result; } /** @@ -250,7 +245,7 @@ int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, if (result) { FAIL("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__); - goto fail_setup; + return result; } pd = irq_get_chip_data(*virq); @@ -263,16 +258,11 @@ int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet, if (result) { FAIL("%s:%d: lv1_connect_irq_plug_ext failed: %s\n", __func__, __LINE__, ps3_result(result)); - result = -EPERM; - goto fail_connect; + ps3_virq_destroy(*virq); + return -EPERM; } return result; - -fail_connect: - ps3_virq_destroy(*virq); -fail_setup: - return result; } EXPORT_SYMBOL_GPL(ps3_irq_plug_setup);
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 272e9aa..32d414c 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -69,6 +69,8 @@ static struct iommu_table *iommu_pseries_alloc_table(int node) return tbl; } +static phys_addr_t pseries_ddw_max_ram __ro_after_init; + #ifdef CONFIG_IOMMU_API static struct iommu_table_group_ops spapr_tce_table_group_ops; #endif @@ -1284,15 +1286,19 @@ struct failed_ddw_pdn { static LIST_HEAD(failed_ddw_pdn_list); -static phys_addr_t ddw_memory_hotplug_max(void) +static phys_addr_t __init ddw_memory_hotplug_max(void) { - resource_size_t max_addr; + resource_size_t max_addr = memory_hotplug_max(); + struct device_node *memory; -#if defined(CONFIG_NUMA) && defined(CONFIG_MEMORY_HOTPLUG) - max_addr = hot_add_drconf_memory_max(); -#else - max_addr = memblock_end_of_DRAM(); -#endif + for_each_node_by_type(memory, "memory") { + struct resource res; + + if (of_address_to_resource(memory, 0, &res)) + continue; + + max_addr = max_t(resource_size_t, max_addr, res.end + 1); + } return max_addr; } @@ -1447,7 +1453,7 @@ static struct property *ddw_property_create(const char *propname, u32 liobn, u64 static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn, u64 dma_mask) { int len = 0, ret; - int max_ram_len = order_base_2(ddw_memory_hotplug_max()); + int max_ram_len = order_base_2(pseries_ddw_max_ram); struct ddw_query_response query; struct ddw_create_response create; int page_shift; @@ -1617,12 +1623,12 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn, u64 dma_mas if (default_win_removed && pmem_present && !direct_mapping) { /* DDW is big enough to be split */ if ((1ULL << ddw_sz) >= - MIN_DDW_VPMEM_DMA_WINDOW + (1ULL << max_ram_len)) { + MIN_DDW_VPMEM_DMA_WINDOW + pseries_ddw_max_ram) { direct_mapping = true; /* offset of the Dynamic part of DDW */ - dynamic_offset = 1ULL << max_ram_len; + dynamic_offset = pseries_ddw_max_ram; } /* DDW will at least have dynamic allocation */ @@ -1669,7 +1675,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn, u64 dma_mas if (direct_mapping) { /* DDW maps the whole partition, so enable direct DMA mapping */ - ret = walk_system_ram_range(0, ddw_memory_hotplug_max() >> PAGE_SHIFT, + ret = walk_system_ram_range(0, pseries_ddw_max_ram >> PAGE_SHIFT, win64->value, tce_setrange_multi_pSeriesLP_walk); if (ret) { dev_info(&dev->dev, "failed to map DMA window for %pOF: %d\n", @@ -1772,8 +1778,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn, u64 dma_mas /* For pre-mapped memory, set bus_dma_limit to the max RAM */ if (direct_mapping) - dev->dev.bus_dma_limit = dev->dev.archdata.dma_offset + - (1ULL << max_ram_len); + dev->dev.bus_dma_limit = dev->dev.archdata.dma_offset + pseries_ddw_max_ram; dev_info(&dev->dev, "lsa_required: %x, lsa_enabled: %x, direct mapping: %x\n", limited_addr_req, limited_addr_enabled, direct_mapping); @@ -2420,23 +2425,35 @@ static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action, { struct dma_win *window; struct memory_notify *arg = data; + unsigned long limit = arg->nr_pages; + unsigned long max_ram_pages = pseries_ddw_max_ram >> PAGE_SHIFT; int ret = 0; /* This notifier can get called when onlining persistent memory as well. * TCEs are not pre-mapped for persistent memory. Persistent memory will - * always be above ddw_memory_hotplug_max() + * always be above pseries_ddw_max_ram */ + if (arg->start_pfn >= max_ram_pages) + return NOTIFY_OK; + + /* RAM is being DLPAR'ed. The range should never exceed max ram. + * Just in case, clamp the range and throw a warning. + */ + if (arg->start_pfn + limit > max_ram_pages) { + limit = max_ram_pages - arg->start_pfn; + WARN_ONCE(1, "Limiting Page Range %lx - %lx to Max Mem Pages: %lx\n", + arg->start_pfn, arg->start_pfn + arg->nr_pages, + max_ram_pages); + } switch (action) { case MEM_GOING_ONLINE: spin_lock(&dma_win_list_lock); list_for_each_entry(window, &dma_win_list, list) { - if (window->direct && (arg->start_pfn << PAGE_SHIFT) < - ddw_memory_hotplug_max()) { + if (window->direct) { ret |= tce_setrange_multi_pSeriesLP(arg->start_pfn, - arg->nr_pages, window->prop); + limit, window->prop); } - /* XXX log error */ } spin_unlock(&dma_win_list_lock); break; @@ -2444,12 +2461,10 @@ static int iommu_mem_notifier(struct notifier_block *nb, unsigned long action, case MEM_OFFLINE: spin_lock(&dma_win_list_lock); list_for_each_entry(window, &dma_win_list, list) { - if (window->direct && (arg->start_pfn << PAGE_SHIFT) < - ddw_memory_hotplug_max()) { + if (window->direct) { ret |= tce_clearrange_multi_pSeriesLP(arg->start_pfn, - arg->nr_pages, window->prop); + limit, window->prop); } - /* XXX log error */ } spin_unlock(&dma_win_list_lock); break; @@ -2533,6 +2548,14 @@ void __init iommu_init_early_pSeries(void) register_memory_notifier(&iommu_mem_nb); set_pci_dma_ops(&dma_iommu_ops); + + /* During init determine the max memory an LPAR can have and set it. This + * will be used for pre-mapping RAM in DDW. memblock_end_of_DRAM() can + * change during the running of LPAR - daxctl can add pmemory as + * "system-ram". This memory range should not be pre-mapped in DDW since + * the address of pmemory can be much higher than the DDW size. + */ + pseries_ddw_max_ram = ddw_memory_hotplug_max(); } static int __init disable_multitce(char *str)
diff --git a/arch/powerpc/platforms/pseries/plpks-sysfs.c b/arch/powerpc/platforms/pseries/plpks-sysfs.c index c2ebcbb..f243622 100644 --- a/arch/powerpc/platforms/pseries/plpks-sysfs.c +++ b/arch/powerpc/platforms/pseries/plpks-sysfs.c
@@ -45,6 +45,16 @@ static const struct attribute *config_attrs[] = { static struct kobject *plpks_kobj, *plpks_config_kobj; +static umode_t plpks_config_attr_is_visible(struct kobject *kobj, + struct attribute *attr, int n) +{ + if (attr == &attr_wrapping_features.attr && + !plpks_wrapping_is_supported()) + return 0; + + return attr->mode; +} + int plpks_config_create_softlink(struct kobject *from) { if (!plpks_config_kobj) @@ -52,13 +62,13 @@ int plpks_config_create_softlink(struct kobject *from) return sysfs_create_link(from, plpks_config_kobj, "config"); } +static const struct attribute_group config_group = { + .attrs = (struct attribute **)config_attrs, + .is_visible = plpks_config_attr_is_visible, +}; + static __init int plpks_sysfs_config(struct kobject *kobj) { - struct attribute_group config_group = { - .name = NULL, - .attrs = (struct attribute **)config_attrs, - }; - return sysfs_create_group(kobj, &config_group); }
diff --git a/arch/powerpc/platforms/pseries/plpks.c b/arch/powerpc/platforms/pseries/plpks.c index 23e4e2a..240cd56 100644 --- a/arch/powerpc/platforms/pseries/plpks.c +++ b/arch/powerpc/platforms/pseries/plpks.c
@@ -10,7 +10,7 @@ #define pr_fmt(fmt) "plpks: " fmt #define PLPKS_WRAPKEY_COMPONENT "PLPKSWR" -#define PLPKS_WRAPKEY_NAME "default-wrapping-key" +#define PLPKS_DEFAULT_WRAPKEY_LABEL "default-wrapping-key" /* * To 4K align the {input, output} buffers to the {UN}WRAP H_CALLs @@ -576,7 +576,7 @@ static int plpks_confirm_object_flushed(struct label *label, virt_to_phys(auth), virt_to_phys(label), label->size); - status = retbuf[0]; + status = (u8)retbuf[0]; if (rc) { timed_out = false; if (rc == H_NOT_FOUND && status == 1) @@ -637,6 +637,9 @@ int plpks_signed_update_var(struct plpks_var *var, u64 flags) u64 continuetoken = 0; u64 timeout = 0; + if (!var) + return -EINVAL; + if (!var->data || var->datalen <= 0 || var->namelen > PLPKS_MAX_NAME_SIZE) return -EINVAL; @@ -682,7 +685,7 @@ int plpks_signed_update_var(struct plpks_var *var, u64 flags) kfree(label); out: - kfree(auth); + kfree_sensitive(auth); return rc; } @@ -751,7 +754,7 @@ int plpks_write_var(struct plpks_var var) rc = pseries_status_to_err(rc); kfree(label); out: - kfree(auth); + kfree_sensitive(auth); return rc; } @@ -809,7 +812,7 @@ int plpks_remove_var(char *component, u8 varos, struct plpks_var_name vname) rc = pseries_status_to_err(rc); kfree(label); out: - kfree(auth); + kfree_sensitive(auth); return rc; } @@ -822,11 +825,14 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var) u8 *output; int rc; + if (!var) + return -EINVAL; + if (var->namelen > PLPKS_MAX_NAME_SIZE) return -EINVAL; if (var->policy & PLPKS_WRAPPINGKEY) - return -EINVAL; + return -EPERM; auth = construct_auth(consumer); if (IS_ERR(auth)) @@ -856,28 +862,27 @@ static int plpks_read_var(u8 consumer, struct plpks_var *var) virt_to_phys(var->name), var->namelen, virt_to_phys(output), maxobjsize); - if (rc != H_SUCCESS) { rc = pseries_status_to_err(rc); - goto out_free_output; + if (rc != -EPERM || !retbuf[1]) + goto out_free_output; + goto out_copy_policy; } if (!var->data || var->datalen > retbuf[0]) - var->datalen = retbuf[0]; - - var->policy = retbuf[1]; + var->datalen = (u16)retbuf[0]; if (var->data) memcpy(var->data, output, var->datalen); - rc = 0; - +out_copy_policy: + var->policy = (u32)retbuf[1]; out_free_output: - kfree(output); + kfree_sensitive(output); out_free_label: kfree(label); out_free_auth: - kfree(auth); + kfree_sensitive(auth); return rc; } @@ -933,8 +938,8 @@ int plpks_gen_wrapping_key(void) struct label *label; int rc = 0, pseries_status = 0; struct plpks_var var = { - .name = PLPKS_WRAPKEY_NAME, - .namelen = strlen(var.name), + .name = PLPKS_DEFAULT_WRAPKEY_LABEL, + .namelen = sizeof(PLPKS_DEFAULT_WRAPKEY_LABEL) - 1, .policy = PLPKS_WRAPPINGKEY, .os = PLPKS_VAR_LINUX, .component = PLPKS_WRAPKEY_COMPONENT @@ -970,7 +975,7 @@ int plpks_gen_wrapping_key(void) kfree(label); out: - kfree(auth); + kfree_sensitive(auth); return rc; } EXPORT_SYMBOL_GPL(plpks_gen_wrapping_key); @@ -1028,8 +1033,8 @@ int plpks_wrap_object(u8 **input_buf, u32 input_len, u16 wrap_flags, bool sb_audit_or_enforce_bit = wrap_flags & BIT(0); bool sb_enforce_bit = wrap_flags & BIT(1); struct plpks_var var = { - .name = PLPKS_WRAPKEY_NAME, - .namelen = strlen(var.name), + .name = PLPKS_DEFAULT_WRAPKEY_LABEL, + .namelen = sizeof(PLPKS_DEFAULT_WRAPKEY_LABEL) - 1, .os = PLPKS_VAR_LINUX, .component = PLPKS_WRAPKEY_COMPONENT }; @@ -1095,7 +1100,7 @@ int plpks_wrap_object(u8 **input_buf, u32 input_len, u16 wrap_flags, out_free_label: kfree(label); out: - kfree(auth); + kfree_sensitive(auth); return rc; } EXPORT_SYMBOL_GPL(plpks_wrap_object); @@ -1172,14 +1177,14 @@ int plpks_unwrap_object(u8 **input_buf, u32 input_len, u8 **output_buf, if (rc) { pr_err("H_PKS_UNWRAP_OBJECT failed. pseries_status=%d, rc=%d", pseries_status, rc); - kfree(*output_buf); + kfree_sensitive(*output_buf); *output_buf = NULL; } else { *output_len = retbuf[1]; } out: - kfree(auth); + kfree_sensitive(auth); return rc; } EXPORT_SYMBOL_GPL(plpks_unwrap_object);
diff --git a/arch/powerpc/platforms/pseries/plpks_sed_ops.c b/arch/powerpc/platforms/pseries/plpks_sed_ops.c index 7c873c9..ac3ec2ca 100644 --- a/arch/powerpc/platforms/pseries/plpks_sed_ops.c +++ b/arch/powerpc/platforms/pseries/plpks_sed_ops.c
@@ -84,14 +84,16 @@ int sed_read_key(char *keyname, char *key, u_int *keylen) ret = plpks_read_os_var(&var); if (ret != 0) - return ret; + goto out; len = min_t(u16, be32_to_cpu(data.key_len), var.datalen); memcpy(key, data.key, len); key[len] = '\0'; *keylen = len; - return 0; +out: + memzero_explicit(&data, sizeof(data)); + return ret; } /* @@ -102,6 +104,7 @@ int sed_write_key(char *keyname, char *key, u_int keylen) struct plpks_var var; struct plpks_sed_object_data data; struct plpks_var_name vname; + int ret; plpks_init_var(&var, keyname); @@ -127,5 +130,8 @@ int sed_write_key(char *keyname, char *key, u_int keylen) vname.name = var.name; plpks_remove_var(var.component, var.os, vname); - return plpks_write_var(var); + ret = plpks_write_var(var); + memzero_explicit(&data, sizeof(data)); + + return ret; }
diff --git a/arch/powerpc/platforms/pseries/rtas-fadump.c b/arch/powerpc/platforms/pseries/rtas-fadump.c index 3bb4ac2..9b9e09f 100644 --- a/arch/powerpc/platforms/pseries/rtas-fadump.c +++ b/arch/powerpc/platforms/pseries/rtas-fadump.c
@@ -459,6 +459,8 @@ static int __init rtas_fadump_process(struct fw_dump *fadump_conf) /* Check if the dump data is valid. */ for (int i = 0; i < be16_to_cpu(fdm_active->header.dump_num_sections); i++) { int type = be16_to_cpu(fdm_active->rgn[i].source_data_type); + uint64_t bytes_dumped = be64_to_cpu(fdm_active->rgn[i].bytes_dumped); + uint64_t source_len = be64_to_cpu(fdm_active->rgn[i].source_len); int rc = 0; switch (type) { @@ -469,10 +471,20 @@ static int __init rtas_fadump_process(struct fw_dump *fadump_conf) pr_err("Dump taken by platform is not valid (%d)\n", i); rc = -EINVAL; } - if (fdm_active->rgn[i].bytes_dumped != fdm_active->rgn[i].source_len) { - pr_err("Dump taken by platform is incomplete (%d)\n", i); + + /* + * Make sure that dump is collected for entire region. + * CPU_STATE_DATA region is allowed to dump less than allocated space. + */ + if (!(bytes_dumped == source_len || + (type == RTAS_FADUMP_CPU_STATE_DATA && bytes_dumped <= source_len))) { + pr_err("Dump taken by platform is %s (%d)\n", + (bytes_dumped < source_len ? "incomplete" : "corrupted"), i); + pr_debug("type -> %d, bytes_dumped -> %llx, source_len -> %llx\n", + type, bytes_dumped, source_len); rc = -EINVAL; } + if (rc) { pr_warn("Region type: %u src addr: 0x%llx dest addr: 0x%llx\n", be16_to_cpu(fdm_active->rgn[i].source_data_type), @@ -482,7 +494,7 @@ static int __init rtas_fadump_process(struct fw_dump *fadump_conf) } break; case RTAS_FADUMP_PARAM_AREA: - if (fdm_active->rgn[i].bytes_dumped != fdm_active->rgn[i].source_len || + if (bytes_dumped != source_len || fdm_active->rgn[i].error_flags != 0) { pr_warn("Failed to process additional parameters! Proceeding anyway..\n"); fadump_conf->param_area = 0;
diff --git a/arch/riscv/boot/dts/sophgo/Makefile b/arch/riscv/boot/dts/sophgo/Makefile index d5c80d4..49639cb 100644 --- a/arch/riscv/boot/dts/sophgo/Makefile +++ b/arch/riscv/boot/dts/sophgo/Makefile
@@ -4,6 +4,9 @@ dtb-$(CONFIG_ARCH_SOPHGO) += sg2000-milkv-duo-s.dtb dtb-$(CONFIG_ARCH_SOPHGO) += sg2002-licheerv-nano-b.dtb dtb-$(CONFIG_ARCH_SOPHGO) += sg2002-milkv-duo256m.dtb +sg2002-milkv-duo256m-eth-dtbs := sg2002-milkv-duo256m.dtb sg2002-milkv-duo256m-eth.dtbo +dtb-$(CONFIG_ARCH_SOPHGO) += sg2002-milkv-duo256m-eth.dtb +dtb-$(CONFIG_ARCH_SOPHGO) += sg2002-milkv-duo256m-eth.dtbo dtb-$(CONFIG_ARCH_SOPHGO) += sg2042-milkv-pioneer.dtb dtb-$(CONFIG_ARCH_SOPHGO) += sg2042-evb-v1.dtb dtb-$(CONFIG_ARCH_SOPHGO) += sg2042-evb-v2.dtb
diff --git a/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts b/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts index 0e6d79e6..02848ba 100644 --- a/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts +++ b/arch/riscv/boot/dts/sophgo/cv1800b-milkv-duo.dts
@@ -22,17 +22,6 @@ aliases { chosen { stdout-path = "serial0:115200n8"; }; - - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - coprocessor_rtos: region@83f40000 { - reg = <0x83f40000 0xc0000>; - no-map; - }; - }; }; &osc {
diff --git a/arch/riscv/boot/dts/sophgo/cv180x.dtsi b/arch/riscv/boot/dts/sophgo/cv180x.dtsi index ec3bf305..d2ec70f 100644 --- a/arch/riscv/boot/dts/sophgo/cv180x.dtsi +++ b/arch/riscv/boot/dts/sophgo/cv180x.dtsi
@@ -71,7 +71,7 @@ internal_mdio: mdio@0 { #size-cells = <0>; reg = <0>; - internal_ephy: phy@0 { + internal_ephy: ethernet-phy@1 { compatible = "ethernet-phy-ieee802.3-c22"; reg = <1>; };
diff --git a/arch/riscv/boot/dts/sophgo/sg2002-milkv-duo256m-eth.dtso b/arch/riscv/boot/dts/sophgo/sg2002-milkv-duo256m-eth.dtso new file mode 100644 index 0000000..cc93746 --- /dev/null +++ b/arch/riscv/boot/dts/sophgo/sg2002-milkv-duo256m-eth.dtso
@@ -0,0 +1,17 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Enable ethernet on Milk-V Duo 256M with the USB & Ethernet IO board. + * + * Copyright (c) 2026, Chen-Yu Yeh <chenyou910331@gmail.com> + */ + +/dts-v1/; +/plugin/; + +&gmac0 { + status = "okay"; +}; + +&mdio { + status = "okay"; +};
diff --git a/arch/riscv/boot/dts/sophgo/sg2002-milkv-duo256m.dts b/arch/riscv/boot/dts/sophgo/sg2002-milkv-duo256m.dts index a2797c0..d4e86c1 100644 --- a/arch/riscv/boot/dts/sophgo/sg2002-milkv-duo256m.dts +++ b/arch/riscv/boot/dts/sophgo/sg2002-milkv-duo256m.dts
@@ -36,17 +36,6 @@ led-0 { linux,default-trigger = "heartbeat"; }; }; - - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - coprocessor_rtos: region@8fe00000 { - reg = <0x8fe00000 0x200000>; - no-map; - }; - }; }; &osc {
diff --git a/arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts b/arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts index b116dfa..9f403e5 100644 --- a/arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts +++ b/arch/riscv/boot/dts/sophgo/sg2042-evb-v1.dts
@@ -256,7 +256,7 @@ &spifmc0 { flash@0 { compatible = "jedec,spi-nor"; reg = <0>; - spi-max-frequency = <50000000>; + spi-max-frequency = <12500000>; spi-tx-bus-width = <1>; spi-rx-bus-width = <1>; }; @@ -268,7 +268,7 @@ &spifmc1 { flash@0 { compatible = "jedec,spi-nor"; reg = <0>; - spi-max-frequency = <50000000>; + spi-max-frequency = <12500000>; spi-tx-bus-width = <1>; spi-rx-bus-width = <1>; };
diff --git a/arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts b/arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts index b2ceae2..d8c5814f 100644 --- a/arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts +++ b/arch/riscv/boot/dts/sophgo/sg2042-evb-v2.dts
@@ -244,7 +244,7 @@ &spifmc1 { flash@0 { compatible = "jedec,spi-nor"; reg = <0>; - spi-max-frequency = <50000000>; + spi-max-frequency = <12500000>; spi-tx-bus-width = <1>; spi-rx-bus-width = <1>; };
diff --git a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts index ecf8c1e..4f39eb5 100644 --- a/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts +++ b/arch/riscv/boot/dts/sophgo/sg2042-milkv-pioneer.dts
@@ -177,7 +177,7 @@ &spifmc0 { flash@0 { compatible = "jedec,spi-nor"; reg = <0>; - spi-max-frequency = <50000000>; + spi-max-frequency = <12500000>; spi-tx-bus-width = <1>; spi-rx-bus-width = <1>; }; @@ -189,7 +189,7 @@ &spifmc1 { flash@0 { compatible = "jedec,spi-nor"; reg = <0>; - spi-max-frequency = <50000000>; + spi-max-frequency = <12500000>; spi-tx-bus-width = <1>; spi-rx-bus-width = <1>; };
diff --git a/arch/riscv/boot/dts/sophgo/sg2044-sophgo-srd3-10.dts b/arch/riscv/boot/dts/sophgo/sg2044-sophgo-srd3-10.dts index fed3d9a..88ddc8e 100644 --- a/arch/riscv/boot/dts/sophgo/sg2044-sophgo-srd3-10.dts +++ b/arch/riscv/boot/dts/sophgo/sg2044-sophgo-srd3-10.dts
@@ -109,6 +109,30 @@ &sd { status = "okay"; }; +&spifmc0 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <12500000>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <1>; + }; +}; + +&spifmc1 { + status = "okay"; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-max-frequency = <12500000>; + spi-tx-bus-width = <1>; + spi-rx-bus-width = <1>; + }; +}; + &uart0 { /* for firmware */ status = "reserved";
diff --git a/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts index 246f8f2a..23f32a8 100644 --- a/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts +++ b/arch/riscv/boot/dts/spacemit/k1-musepi-pro.dts
@@ -8,6 +8,7 @@ /dts-v1/; #include "k1.dtsi" +#include "k1-opp.dtsi" #include "k1-pinctrl.dtsi" / { @@ -99,6 +100,38 @@ &combo_phy { status = "okay"; }; +&cpu_0 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_1 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_2 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_3 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_4 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_5 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_6 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_7 { + cpu-supply = <&buck1_0v9>; +}; + ð0 { phy-handle = <&rgmii0>; phy-mode = "rgmii-id"; @@ -178,7 +211,7 @@ pmic@41 { dldoin2-supply = <&buck5>; regulators { - buck1 { + buck1_0v9: buck1 { regulator-min-microvolt = <500000>; regulator-max-microvolt = <1050000>; regulator-ramp-delay = <5000>;
diff --git a/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts b/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts index 2d1ba34..eb77aae 100644 --- a/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts +++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-r2s.dts
@@ -6,6 +6,7 @@ /dts-v1/; #include "k1.dtsi" +#include "k1-opp.dtsi" #include "k1-pinctrl.dtsi" / { @@ -13,6 +14,7 @@ / { compatible = "xunlong,orangepi-r2s", "spacemit,k1"; aliases { + i2c2 = &i2c2; i2c8 = &i2c8; serial0 = &uart0; ethernet0 = ð0; @@ -50,6 +52,38 @@ vcc5v0_usb: regulator-vcc5v0-usb { }; }; +&cpu_0 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_1 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_2 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_3 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_4 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_5 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_6 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_7 { + cpu-supply = <&buck1_0v9>; +}; + &combo_phy { status = "okay"; }; @@ -65,6 +99,8 @@ &emmc { }; ð0 { + nvmem-cells = <&mac_address 0>; + nvmem-cell-names = "mac-address"; phy-handle = <&rgmii0>; phy-mode = "rgmii-id"; pinctrl-names = "default"; @@ -89,6 +125,8 @@ rgmii0: phy@1 { }; ð1 { + nvmem-cells = <&mac_address 1>; + nvmem-cell-names = "mac-address"; phy-handle = <&rgmii1>; phy-mode = "rgmii-id"; pinctrl-names = "default"; @@ -112,6 +150,35 @@ rgmii1: phy@1 { }; }; +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_0_cfg>; + status = "okay"; + + eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + size = <256>; + read-only; + vcc-supply = <&buck3_1v8>; + + nvmem-layout { + compatible = "onie,tlv-layout"; + + mac_address: mac-address { + #nvmem-cell-cells = <1>; + }; + + num-macs { + }; + + product-name { + }; + }; + }; +}; + &i2c8 { pinctrl-names = "default"; pinctrl-0 = <&i2c8_cfg>; @@ -132,7 +199,7 @@ pmic@41 { dldoin2-supply = <&buck5>; regulators { - buck1 { + buck1_0v9: buck1 { regulator-min-microvolt = <500000>; regulator-max-microvolt = <1050000>; regulator-ramp-delay = <5000>;
diff --git a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts index b907a13..790234f 100644 --- a/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts +++ b/arch/riscv/boot/dts/spacemit/k1-orangepi-rv2.dts
@@ -7,6 +7,7 @@ /dts-v1/; #include "k1.dtsi" +#include "k1-opp.dtsi" #include "k1-pinctrl.dtsi" / { @@ -17,12 +18,25 @@ aliases { serial0 = &uart0; ethernet0 = ð0; ethernet1 = ð1; + i2c2 = &i2c2; + i2c8 = &i2c8; mmc0 = &emmc; mmc1 = &sdhci0; }; chosen { - stdout-path = "serial0"; + stdout-path = "serial0:115200n8"; + }; + + leds { + compatible = "gpio-leds"; + + led-1 { + label = "sys-led"; + gpios = <&gpio K1_GPIO(96) GPIO_ACTIVE_LOW>; + linux,default-trigger = "heartbeat"; + default-state = "on"; + }; }; pcie_vcc3v3: regulator-pcie-vcc3v3 { @@ -63,23 +77,44 @@ vcc5v0_usb30: regulator-vcc5v0-usb30 { regulator-max-microvolt = <5000000>; vin-supply = <&vcc_5v0>; }; - - leds { - compatible = "gpio-leds"; - - led1 { - label = "sys-led"; - gpios = <&gpio K1_GPIO(96) GPIO_ACTIVE_LOW>; - linux,default-trigger = "heartbeat"; - default-state = "on"; - }; - }; }; &combo_phy { status = "okay"; }; +&cpu_0 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_1 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_2 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_3 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_4 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_5 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_6 { + cpu-supply = <&buck1_0v9>; +}; + +&cpu_7 { + cpu-supply = <&buck1_0v9>; +}; + &emmc { bus-width = <8>; mmc-hs400-1_8v; @@ -91,6 +126,8 @@ &emmc { }; ð0 { + nvmem-cells = <&mac_address 0>; + nvmem-cell-names = "mac-address"; phy-handle = <&rgmii0>; phy-mode = "rgmii-id"; pinctrl-names = "default"; @@ -115,6 +152,8 @@ rgmii0: phy@1 { }; ð1 { + nvmem-cells = <&mac_address 1>; + nvmem-cell-names = "mac-address"; phy-handle = <&rgmii1>; phy-mode = "rgmii-id"; pinctrl-names = "default"; @@ -138,8 +177,33 @@ rgmii1: phy@1 { }; }; -&pdma { +&i2c2 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_0_cfg>; status = "okay"; + + eeprom@50 { + compatible = "atmel,24c02"; + reg = <0x50>; + pagesize = <16>; + size = <256>; + read-only; + vcc-supply = <&buck3_1v8>; + + nvmem-layout { + compatible = "onie,tlv-layout"; + + mac_address: mac-address { + #nvmem-cell-cells = <1>; + }; + + num-macs { + }; + + product-name { + }; + }; + }; }; &i2c8 { @@ -162,7 +226,7 @@ pmic@41 { dldoin2-supply = <&buck5>; regulators { - buck1 { + buck1_0v9: buck1 { regulator-min-microvolt = <500000>; regulator-max-microvolt = <1050000>; regulator-ramp-delay = <5000>; @@ -290,6 +354,10 @@ &pcie2 { status = "okay"; }; +&pdma { + status = "okay"; +}; + &qspi { pinctrl-names = "default"; pinctrl-0 = <&qspi_cfg>; @@ -335,6 +403,24 @@ uboot@a0000 { }; }; +&sdhci0 { + bus-width = <4>; + cap-sd-highspeed; + cd-gpios = <&gpio K1_GPIO(80) GPIO_ACTIVE_LOW>; + disable-wp; + no-mmc; + no-sdio; + pinctrl-names = "default", "uhs"; + pinctrl-0 = <&mmc1_cfg>; + pinctrl-1 = <&mmc1_uhs_cfg>; + sd-uhs-sdr25; + sd-uhs-sdr50; + sd-uhs-sdr104; + vmmc-supply = <&buck4_3v3>; + vqmmc-supply = <&aldo1>; + status = "okay"; +}; + &uart0 { pinctrl-names = "default"; pinctrl-0 = <&uart0_2_cfg>; @@ -366,21 +452,3 @@ hub_3_0: hub@2 { vdd-supply = <&vcc_5v0>; }; }; - -&sdhci0 { - pinctrl-names = "default", "uhs"; - pinctrl-0 = <&mmc1_cfg>; - pinctrl-1 = <&mmc1_uhs_cfg>; - bus-width = <4>; - cd-gpios = <&gpio K1_GPIO(80) GPIO_ACTIVE_LOW>; - no-mmc; - no-sdio; - disable-wp; - cap-sd-highspeed; - vmmc-supply = <&buck4_3v3>; - vqmmc-supply = <&aldo1>; - sd-uhs-sdr25; - sd-uhs-sdr50; - sd-uhs-sdr104; - status = "okay"; -};
diff --git a/arch/riscv/boot/dts/spacemit/k3-com260-ifx.dts b/arch/riscv/boot/dts/spacemit/k3-com260-ifx.dts index a5c08a7..fadcf28 100644 --- a/arch/riscv/boot/dts/spacemit/k3-com260-ifx.dts +++ b/arch/riscv/boot/dts/spacemit/k3-com260-ifx.dts
@@ -3,6 +3,7 @@ * Copyright (c) 2026 SpacemiT (Hangzhou) Technology Co. Ltd * Copyright (c) 2026 Yixun Lan <dlan@kernel.org> */ +#include <dt-bindings/phy/phy.h> #include "k3-com260.dtsi" @@ -18,6 +19,45 @@ aliases { chosen { stdout-path = "serial0:115200n8"; }; + + reg_hub_5v: regulator-usb3-hub-5v { + compatible = "regulator-fixed"; + regulator-name = "USB30_HUB"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + regulator-always-on; + vin-supply = <®_5v_sys>; + }; + + reg_vbus_5v: regulator-usb3-vbus-5v { + compatible = "regulator-fixed"; + regulator-name = "USB30_VBUS"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + vin-supply = <®_5v_sys>; + gpio = <&gpio K3_GPIO(67) GPIO_ACTIVE_HIGH>; + enable-active-high; + }; + + rfkill-pcie-wlan { + compatible = "rfkill-gpio"; + label = "rfkill-pcie-wlan"; + radio-type = "wlan"; + shutdown-gpios = <&gpio K3_GPIO(73) GPIO_ACTIVE_LOW>; + }; + + rfkill-usb-bt { + compatible = "rfkill-gpio"; + label = "rfkill-usb-bt"; + radio-type = "bluetooth"; + shutdown-gpios = <&gpio K3_GPIO(57) GPIO_ACTIVE_LOW>; + }; +}; + +&combophy { + spacemit,apmu = <&syscon_apmu 0x14>; + status = "okay"; }; &i2c1 { @@ -35,6 +75,43 @@ eeprom@50 { }; }; +&usb2_host { + status = "okay"; +}; + +&usb2_phy { + status = "okay"; +}; + +&usb3b { + phys = <&usb3b_u2phy>, <&combophy 2 PHY_TYPE_USB3>; + phy-names = "usb2-phy", "usb3-phy"; + status = "okay"; + vbus-supply = <®_vbus_5v>; + #address-cells = <1>; + #size-cells = <0>; + + hub_2_0: hub@1 { + compatible = "usb2109,2817"; + reg = <1>; + vdd-supply = <®_hub_5v>; + peer-hub = <&hub_3_0>; + reset-gpios = <&gpio K3_GPIO(53) GPIO_ACTIVE_LOW>; + }; + + hub_3_0: hub@2 { + compatible = "usb2109,817"; + reg = <2>; + vdd-supply = <®_hub_5v>; + peer-hub = <&hub_2_0>; + reset-gpios = <&gpio K3_GPIO(53) GPIO_ACTIVE_LOW>; + }; +}; + +&usb3b_u2phy { + status = "okay"; +}; + &sdhci0 { pinctrl-names = "default","uhs"; pinctrl-0 = <&mmc1_cfg>;
diff --git a/arch/riscv/boot/dts/spacemit/k3-com260.dtsi b/arch/riscv/boot/dts/spacemit/k3-com260.dtsi index 3762796..054bfff 100644 --- a/arch/riscv/boot/dts/spacemit/k3-com260.dtsi +++ b/arch/riscv/boot/dts/spacemit/k3-com260.dtsi
@@ -58,6 +58,23 @@ serial-number { }; }; +&i2c6_1_cfg { + i2c6-1-pins { + power-source = <3300>; + }; +}; + +&i2c6 { + pinctrl-names = "default"; + pinctrl-0 = <&i2c6_1_cfg>; + status = "okay"; + + temperature-sensor@4c { + compatible = "sensylink,ctf2301"; + reg = <0x4c>; + }; +}; + &i2c8 { pinctrl-names = "default"; pinctrl-0 = <&i2c8_cfg>; @@ -170,6 +187,7 @@ dldo3: dldo3 { dldo4: dldo4 { regulator-min-microvolt = <1800000>; regulator-max-microvolt = <1800000>; + regulator-always-on; regulator-boot-on; };
diff --git a/arch/riscv/boot/dts/spacemit/k3-pico-itx.dts b/arch/riscv/boot/dts/spacemit/k3-pico-itx.dts index b084a35a..dda4209 100644 --- a/arch/riscv/boot/dts/spacemit/k3-pico-itx.dts +++ b/arch/riscv/boot/dts/spacemit/k3-pico-itx.dts
@@ -43,6 +43,20 @@ reg_aux_vcc5v: regulator-aux-vcc5v { regulator-max-microvolt = <5000000>; regulator-always-on; }; + + rfkill-pcie-wlan { + compatible = "rfkill-gpio"; + label = "rfkill-pcie-wlan"; + radio-type = "wlan"; + shutdown-gpios = <&gpio 1 3 GPIO_ACTIVE_HIGH>; + }; + + rfkill-usb-bt { + compatible = "rfkill-gpio"; + label = "rfkill-usb-bt"; + radio-type = "bluetooth"; + shutdown-gpios = <&gpio 0 30 GPIO_ACTIVE_HIGH>; + }; }; &i2c2 { @@ -323,10 +337,34 @@ &usb2_phy { status = "okay"; }; +&usb3b { + phys = <&usb3b_u2phy>; + phy-names = "usb2-phy"; + maximum-speed = "high-speed"; + status = "okay"; +}; + +&usb3b_u2phy { + status = "okay"; +}; + +&usb3c { + phys = <&usb3c_u2phy>; + phy-names = "usb2-phy"; + maximum-speed = "high-speed"; + status = "okay"; +}; + +&usb3c_u2phy { + status = "okay"; +}; + &usb3d_u2phy { status = "okay"; }; &usb3d { + phys = <&usb3d_u2phy>, <&combophy 4 PHY_TYPE_USB3>; + phy-names = "usb2-phy", "usb3-phy"; status = "okay"; };
diff --git a/arch/riscv/boot/dts/spacemit/k3-pinctrl.dtsi b/arch/riscv/boot/dts/spacemit/k3-pinctrl.dtsi index 6482d24..cb4f4f4 100644 --- a/arch/riscv/boot/dts/spacemit/k3-pinctrl.dtsi +++ b/arch/riscv/boot/dts/spacemit/k3-pinctrl.dtsi
@@ -102,6 +102,17 @@ i2c2-1-pins { }; /omit-if-no-ref/ + i2c6_1_cfg: i2c6-1-cfg { + i2c6-1-pins { + pinmux = <K3_PADCONF(7, 6)>, /* i2c6 scl */ + <K3_PADCONF(8, 6)>; /* i2c6 sda */ + + bias-pull-up = <0>; + drive-strength = <25>; + }; + }; + + /omit-if-no-ref/ i2c8_cfg: i2c8-cfg { i2c8-pins { pinmux = <K3_PADCONF(128, 0)>, /* i2c8 scl */
diff --git a/arch/riscv/boot/dts/spacemit/k3.dtsi b/arch/riscv/boot/dts/spacemit/k3.dtsi index c3f2dce..a5fb72e 100644 --- a/arch/riscv/boot/dts/spacemit/k3.dtsi +++ b/arch/riscv/boot/dts/spacemit/k3.dtsi
@@ -441,6 +441,66 @@ soc: soc { dma-noncoherent; ranges; + usb3b: usb@81400000 { + compatible = "spacemit,k3-dwc3"; + reg = <0x0 0x81400000 0x0 0x10000>; + interrupts = <125 IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <&saplic>; + clocks = <&syscon_apmu CLK_APMU_USB3_PORTB_BUS>; + clock-names = "usbdrd30"; + resets = <&syscon_apmu RESET_APMU_USB3_B_AHB>, + <&syscon_apmu RESET_APMU_USB3_B_VCC>, + <&syscon_apmu RESET_APMU_USB3_B_PHY>; + reset-names = "ahb", "vcc", "phy"; + phy_type = "utmi"; + snps,dis_enblslpm_quirk; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,dis-del-phy-power-chg-quirk; + snps,dis-tx-ipgap-linecheck-quirk; + snps,parkmode-disable-ss-quirk; + dr_mode = "host"; + status = "disabled"; + }; + + usb3b_u2phy: phy@81500000 { + compatible = "spacemit,k3-usb2-phy"; + reg = <0x0 0x81500000 0x0 0x200>; + clocks = <&syscon_apmu CLK_APMU_USB3_PORTB_BUS>; + #phy-cells = <0>; + status = "disabled"; + }; + + usb3c: usb@81700000 { + compatible = "spacemit,k3-dwc3"; + reg = <0x0 0x81700000 0x0 0x10000>; + interrupts = <148 IRQ_TYPE_LEVEL_HIGH>; + interrupt-parent = <&saplic>; + clocks = <&syscon_apmu CLK_APMU_USB3_PORTC_BUS>; + clock-names = "usbdrd30"; + resets = <&syscon_apmu RESET_APMU_USB3_C_AHB>, + <&syscon_apmu RESET_APMU_USB3_C_VCC>, + <&syscon_apmu RESET_APMU_USB3_C_PHY>; + reset-names = "ahb", "vcc", "phy"; + phy_type = "utmi"; + snps,dis_enblslpm_quirk; + snps,dis_u2_susphy_quirk; + snps,dis_u3_susphy_quirk; + snps,dis-del-phy-power-chg-quirk; + snps,dis-tx-ipgap-linecheck-quirk; + snps,parkmode-disable-ss-quirk; + dr_mode = "host"; + status = "disabled"; + }; + + usb3c_u2phy: phy@81800000 { + compatible = "spacemit,k3-usb2-phy"; + reg = <0x0 0x81800000 0x0 0x200>; + clocks = <&syscon_apmu CLK_APMU_USB3_PORTC_BUS>; + #phy-cells = <0>; + status = "disabled"; + }; + usb3d: usb@81a00000 { compatible = "spacemit,k3-dwc3"; reg = <0x0 0x81a00000 0x0 0x10000>; @@ -452,9 +512,6 @@ usb3d: usb@81a00000 { <&syscon_apmu RESET_APMU_USB3_D_VCC>, <&syscon_apmu RESET_APMU_USB3_D_PHY>; reset-names = "ahb", "vcc", "phy"; - phys = <&usb3d_u2phy>, - <&combophy 4 PHY_TYPE_USB3>; - phy-names = "usb2-phy", "usb3-phy"; phy_type = "utmi"; snps,dis_enblslpm_quirk; snps,dis_u2_susphy_quirk; @@ -1140,6 +1197,85 @@ uart10: serial@d401f000 { status = "disabled"; }; + i2s0: i2s@d4026000 { + compatible = "spacemit,k3-i2s"; + reg = <0x0 0xd4026000 0x0 0x30>; + clocks = <&syscon_mpmu CLK_MPMU_I2S0_SYSCLK>, + <&syscon_apbc CLK_APBC_I2S0_BCLK>, + <&syscon_apbc CLK_APBC_I2S0_BUS>, + <&syscon_apbc CLK_APBC_I2S0>, + <&syscon_mpmu CLK_MPMU_I2S0_SYSCLK_DIV>, + <&syscon_mpmu CLK_MPMU_I2S_SYSCLK>, + <&syscon_mpmu CLK_MPMU_I2S_BCLK>; + clock-names = "sysclk", "bclk", "bus", "func", + "sysclk_div", "c_sysclk", "c_bclk"; + dmas = <&pdma K3_PDMA_SSPA0_TX>, <&pdma K3_PDMA_SSPA0_RX>; + dma-names = "tx", "rx"; + resets = <&syscon_apbc RESET_APBC_I2S0>; + #sound-dai-cells = <0>; + + status = "disabled"; + }; + + i2s1: i2s@d4026800 { + compatible = "spacemit,k3-i2s"; + reg = <0x0 0xd4026800 0x0 0x30>; + clocks = <&syscon_mpmu CLK_MPMU_I2S1_SYSCLK>, + <&syscon_apbc CLK_APBC_I2S1_BCLK>, + <&syscon_apbc CLK_APBC_I2S1_BUS>, + <&syscon_apbc CLK_APBC_I2S1>, + <&syscon_mpmu CLK_MPMU_I2S_SYSCLK>, + <&syscon_mpmu CLK_MPMU_I2S_BCLK>; + clock-names = "sysclk", "bclk", "bus", "func", + "c_sysclk", "c_bclk"; + dmas = <&pdma K3_PDMA_SSPA1_TX>, <&pdma K3_PDMA_SSPA1_RX>; + dma-names = "tx", "rx"; + resets = <&syscon_apbc RESET_APBC_I2S1>; + #sound-dai-cells = <0>; + + status = "disabled"; + }; + + i2s2: i2s@d4027000 { + compatible = "spacemit,k3-i2s"; + reg = <0x0 0xd4027000 0x0 0x30>; + clocks = <&syscon_mpmu CLK_MPMU_I2S2_SYSCLK>, + <&syscon_apbc CLK_APBC_I2S2_BCLK>, + <&syscon_apbc CLK_APBC_I2S2_BUS>, + <&syscon_apbc CLK_APBC_I2S2>, + <&syscon_mpmu CLK_MPMU_I2S2_SYSCLK_DIV>, + <&syscon_mpmu CLK_MPMU_I2S_SYSCLK>, + <&syscon_mpmu CLK_MPMU_I2S_BCLK>; + clock-names = "sysclk", "bclk", "bus", "func", + "sysclk_div", "c_sysclk", "c_bclk"; + dmas = <&pdma K3_PDMA_SSPA2_TX>, <&pdma K3_PDMA_SSPA2_RX>; + dma-names = "tx", "rx"; + resets = <&syscon_apbc RESET_APBC_I2S2>; + #sound-dai-cells = <0>; + + status = "disabled"; + }; + + i2s3: i2s@d4027800 { + compatible = "spacemit,k3-i2s"; + reg = <0x0 0xd4027800 0x0 0x30>; + clocks = <&syscon_mpmu CLK_MPMU_I2S3_SYSCLK>, + <&syscon_apbc CLK_APBC_I2S3_BCLK>, + <&syscon_apbc CLK_APBC_I2S3_BUS>, + <&syscon_apbc CLK_APBC_I2S3>, + <&syscon_mpmu CLK_MPMU_I2S3_SYSCLK_DIV>, + <&syscon_mpmu CLK_MPMU_I2S_SYSCLK>, + <&syscon_mpmu CLK_MPMU_I2S_BCLK>; + clock-names = "sysclk", "bclk", "bus", "func", + "sysclk_div", "c_sysclk", "c_bclk"; + dmas = <&pdma K3_PDMA_SSPA3_TX>, <&pdma K3_PDMA_SSPA3_RX>; + dma-names = "tx", "rx"; + resets = <&syscon_apbc RESET_APBC_I2S3>; + #sound-dai-cells = <0>; + + status = "disabled"; + }; + spi0: spi@d4040000 { compatible = "spacemit,k3-spi", "spacemit,k1-spi"; reg = <0x0 0xd4040000 0x0 0x30>; @@ -1170,6 +1306,46 @@ spi1: spi@d4040800 { status = "disabled"; }; + i2s4: i2s@d4041000 { + compatible = "spacemit,k3-i2s"; + reg = <0x0 0xd4041000 0x0 0x30>; + clocks = <&syscon_mpmu CLK_MPMU_I2S4_SYSCLK>, + <&syscon_apbc CLK_APBC_I2S4_BCLK>, + <&syscon_apbc CLK_APBC_I2S4_BUS>, + <&syscon_apbc CLK_APBC_I2S4>, + <&syscon_mpmu CLK_MPMU_I2S4_SYSCLK_DIV>, + <&syscon_mpmu CLK_MPMU_I2S_SYSCLK>, + <&syscon_mpmu CLK_MPMU_I2S_BCLK>; + clock-names = "sysclk", "bclk", "bus", "func", + "sysclk_div", "c_sysclk", "c_bclk"; + dmas = <&pdma K3_PDMA_SSPA4_TX>, <&pdma K3_PDMA_SSPA4_RX>; + dma-names = "tx", "rx"; + resets = <&syscon_apbc RESET_APBC_I2S4>; + #sound-dai-cells = <0>; + + status = "disabled"; + }; + + i2s5: i2s@d4041800 { + compatible = "spacemit,k3-i2s"; + reg = <0x0 0xd4041800 0x0 0x30>; + clocks = <&syscon_mpmu CLK_MPMU_I2S5_SYSCLK>, + <&syscon_apbc CLK_APBC_I2S5_BCLK>, + <&syscon_apbc CLK_APBC_I2S5_BUS>, + <&syscon_apbc CLK_APBC_I2S5>, + <&syscon_mpmu CLK_MPMU_I2S5_SYSCLK_DIV>, + <&syscon_mpmu CLK_MPMU_I2S_SYSCLK>, + <&syscon_mpmu CLK_MPMU_I2S_BCLK>; + clock-names = "sysclk", "bclk", "bus", "func", + "sysclk_div", "c_sysclk", "c_bclk"; + dmas = <&pdma K3_PDMA_SSPA5_TX>, <&pdma K3_PDMA_SSPA5_RX>; + dma-names = "tx", "rx"; + resets = <&syscon_apbc RESET_APBC_I2S5>; + #sound-dai-cells = <0>; + + status = "disabled"; + }; + syscon_mpmu: system-controller@d4050000 { compatible = "spacemit,k3-syscon-mpmu"; reg = <0x0 0xd4050000 0x0 0x10000>; @@ -1248,7 +1424,7 @@ simsic: interrupt-controller@e0400000 { msi-controller; riscv,guest-index-bits = <6>; riscv,hart-index-bits = <4>; - riscv,num-guest-ids = <511>; + riscv,num-guest-ids = <63>; riscv,num-ids = <511>; }; @@ -1261,19 +1437,6 @@ saplic: interrupt-controller@e0804000 { riscv,num-sources = <512>; }; - clint: timer@e081c000 { - compatible = "spacemit,k3-clint", "sifive,clint0"; - reg = <0x0 0xe081c000 0x0 0x4000>; - interrupts-extended = <&cpu0_intc 3>, <&cpu0_intc 7>, - <&cpu1_intc 3>, <&cpu1_intc 7>, - <&cpu2_intc 3>, <&cpu2_intc 7>, - <&cpu3_intc 3>, <&cpu3_intc 7>, - <&cpu4_intc 3>, <&cpu4_intc 7>, - <&cpu5_intc 3>, <&cpu5_intc 7>, - <&cpu6_intc 3>, <&cpu6_intc 7>, - <&cpu7_intc 3>, <&cpu7_intc 7>; - }; - /* sec_i2c3: 0xf0614000, not available from Linux */ mimsic: interrupt-controller@f1000000 { @@ -1287,9 +1450,7 @@ mimsic: interrupt-controller@f1000000 { <&cpu4_intc 11>, <&cpu5_intc 11>, <&cpu6_intc 11>, <&cpu7_intc 11>; msi-controller; - riscv,guest-index-bits = <6>; riscv,hart-index-bits = <4>; - riscv,num-guest-ids = <511>; riscv,num-ids = <511>; status = "reserved"; }; @@ -1305,5 +1466,35 @@ maplic: interrupt-controller@f1800000 { riscv,num-sources = <512>; status = "reserved"; }; + + aclint_mswi: interrupt-controller@f1810000 { + compatible = "spacemit,k3-aclint-mswi"; + reg = <0x0 0xf1810000 0x0 0x4000>; + interrupts-extended = <&cpu0_intc 3>, <&cpu1_intc 3>, + <&cpu2_intc 3>, <&cpu3_intc 3>, + <&cpu4_intc 3>, <&cpu5_intc 3>, + <&cpu6_intc 3>, <&cpu7_intc 3>; + }; + + aclint_mtimer: timer@f1814000 { + compatible = "spacemit,k3-aclint-mtimer"; + reg = <0x0 0xf1814000 0x0 0x8000>; + reg-names = "mtimecmp"; + interrupts-extended = <&cpu0_intc 7>, <&cpu1_intc 7>, + <&cpu2_intc 7>, <&cpu3_intc 7>, + <&cpu4_intc 7>, <&cpu5_intc 7>, + <&cpu6_intc 7>, <&cpu7_intc 7>; + }; + + aclint_sswi: interrupt-controller@f181c000 { + compatible = "spacemit,k3-aclint-sswi"; + reg = <0x0 0xf181c000 0x0 0x4000>; + #interrupt-cells = <0>; + interrupt-controller; + interrupts-extended = <&cpu0_intc 1>, <&cpu1_intc 1>, + <&cpu2_intc 1>, <&cpu3_intc 1>, + <&cpu4_intc 1>, <&cpu5_intc 1>, + <&cpu6_intc 1>, <&cpu7_intc 1>; + }; }; };
diff --git a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi index ae1a6ae..8510654 100644 --- a/arch/riscv/boot/dts/starfive/jh7100-common.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7100-common.dtsi
@@ -199,13 +199,23 @@ GPO_I2C2_PAD_SDA_OEN, }; }; - pwm_pins: pwm-0 { - pwm-pins { + pwm0_pins: pwm0-0 { + pwm0-pins { pinmux = <GPIOMUX(7, GPO_PWM_PAD_OUT_BIT0, GPO_PWM_PAD_OE_N_BIT0, - GPI_NONE)>, - <GPIOMUX(5, + GPI_NONE)>; + bias-disable; + drive-strength = <35>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pwm1_pins: pwm1-0 { + pwm1-pins { + pinmux = <GPIOMUX(5, GPO_PWM_PAD_OUT_BIT1, GPO_PWM_PAD_OE_N_BIT1, GPI_NONE)>; @@ -359,9 +369,15 @@ &osc_aud { clock-frequency = <27000000>; }; -&pwm { +&pwm0 { pinctrl-names = "default"; - pinctrl-0 = <&pwm_pins>; + pinctrl-0 = <&pwm0_pins>; + status = "okay"; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pwm1_pins>; status = "okay"; };
diff --git a/arch/riscv/boot/dts/starfive/jh7100.dtsi b/arch/riscv/boot/dts/starfive/jh7100.dtsi index 7de0732..90438df 100644 --- a/arch/riscv/boot/dts/starfive/jh7100.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7100.dtsi
@@ -360,9 +360,72 @@ watchdog@12480000 { <&rstgen JH7100_RSTN_WDT>; }; - pwm: pwm@12490000 { + pwm0: pwm@12490000 { compatible = "starfive,jh7100-pwm", "opencores,pwm-v1"; - reg = <0x0 0x12490000 0x0 0x10000>; + reg = <0x0 0x12490000 0x0 0x10>; + clocks = <&clkgen JH7100_CLK_PWM_APB>; + resets = <&rstgen JH7100_RSTN_PWM_APB>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm1: pwm@12490010 { + compatible = "starfive,jh7100-pwm", "opencores,pwm-v1"; + reg = <0x0 0x12490010 0x0 0x10>; + clocks = <&clkgen JH7100_CLK_PWM_APB>; + resets = <&rstgen JH7100_RSTN_PWM_APB>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm2: pwm@12490020 { + compatible = "starfive,jh7100-pwm", "opencores,pwm-v1"; + reg = <0x0 0x12490020 0x0 0x10>; + clocks = <&clkgen JH7100_CLK_PWM_APB>; + resets = <&rstgen JH7100_RSTN_PWM_APB>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm@12490030 { + compatible = "starfive,jh7100-pwm", "opencores,pwm-v1"; + reg = <0x0 0x12490030 0x0 0x10>; + clocks = <&clkgen JH7100_CLK_PWM_APB>; + resets = <&rstgen JH7100_RSTN_PWM_APB>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm4: pwm@12498000 { + compatible = "starfive,jh7100-pwm", "opencores,pwm-v1"; + reg = <0x0 0x12498000 0x0 0x10>; + clocks = <&clkgen JH7100_CLK_PWM_APB>; + resets = <&rstgen JH7100_RSTN_PWM_APB>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm5: pwm@12498010 { + compatible = "starfive,jh7100-pwm", "opencores,pwm-v1"; + reg = <0x0 0x12498010 0x0 0x10>; + clocks = <&clkgen JH7100_CLK_PWM_APB>; + resets = <&rstgen JH7100_RSTN_PWM_APB>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm6: pwm@12498020 { + compatible = "starfive,jh7100-pwm", "opencores,pwm-v1"; + reg = <0x0 0x12498020 0x0 0x10>; + clocks = <&clkgen JH7100_CLK_PWM_APB>; + resets = <&rstgen JH7100_RSTN_PWM_APB>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm7: pwm@12498030 { + compatible = "starfive,jh7100-pwm", "opencores,pwm-v1"; + reg = <0x0 0x12498030 0x0 0x10>; clocks = <&clkgen JH7100_CLK_PWM_APB>; resets = <&rstgen JH7100_RSTN_PWM_APB>; #pwm-cells = <3>;
diff --git a/arch/riscv/boot/dts/starfive/jh7110-common.dtsi b/arch/riscv/boot/dts/starfive/jh7110-common.dtsi index a7a1c09..64de468 100644 --- a/arch/riscv/boot/dts/starfive/jh7110-common.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110-common.dtsi
@@ -326,9 +326,14 @@ uboot@100000 { }; }; -&pwm { +&pwm0 { pinctrl-names = "default"; - pinctrl-0 = <&pwm_pins>; + pinctrl-0 = <&pwm0_pins>; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pwm1_pins>; }; &spi0 { @@ -528,12 +533,22 @@ GPOEN_ENABLE, }; }; - pwm_pins: pwm-0 { - pwm-pins { + pwm0_pins: pwm0-0 { + pwm0-pins { pinmux = <GPIOMUX(46, GPOUT_SYS_PWM_CHANNEL0, GPOEN_SYS_PWM0_CHANNEL0, - GPI_NONE)>, - <GPIOMUX(59, GPOUT_SYS_PWM_CHANNEL1, + GPI_NONE)>; + bias-disable; + drive-strength = <12>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + pwm1_pins: pwm1-0 { + pwm1-pins { + pinmux = <GPIOMUX(59, GPOUT_SYS_PWM_CHANNEL1, GPOEN_SYS_PWM0_CHANNEL1, GPI_NONE)>; bias-disable;
diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts index 2187361..54013c7 100644 --- a/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts +++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-mars.dts
@@ -68,7 +68,11 @@ &phy0 { motorcomm,tx-clk-adj-enabled; }; -&pwm { +&pwm0 { + status = "okay"; +}; + +&pwm1 { status = "okay"; };
diff --git a/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi b/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi index 0254710..31afac2 100644 --- a/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110-milkv-marscm.dtsi
@@ -87,7 +87,11 @@ &phy0 { motorcomm,tx-clk-adj-enabled; }; -&pwm { +&pwm0 { + status = "okay"; +}; + +&pwm1 { status = "okay"; };
diff --git a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts index aec7ae3..a9e82f2 100644 --- a/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts +++ b/arch/riscv/boot/dts/starfive/jh7110-pine64-star64.dts
@@ -95,7 +95,11 @@ &phy1 { motorcomm,tx-clk-100-inverted; }; -&pwm { +&pwm0 { + status = "okay"; +}; + +&pwm1 { status = "okay"; };
diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dtsi index f8797a6..85b56a7 100644 --- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2-lite.dtsi
@@ -74,7 +74,11 @@ &phy0 { tx-internal-delay-ps = <1500>; }; -&pwm { +&pwm0 { + status = "okay"; +}; + +&pwm1 { status = "okay"; };
diff --git a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi index edc8f45..35208f9 100644 --- a/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110-starfive-visionfive-2.dtsi
@@ -73,7 +73,11 @@ &pcie1 { status = "okay"; }; -&pwm { +&pwm0 { + status = "okay"; +}; + +&pwm1 { status = "okay"; };
diff --git a/arch/riscv/boot/dts/starfive/jh7110.dtsi b/arch/riscv/boot/dts/starfive/jh7110.dtsi index 9c3e459..82ea63f 100644 --- a/arch/riscv/boot/dts/starfive/jh7110.dtsi +++ b/arch/riscv/boot/dts/starfive/jh7110.dtsi
@@ -846,9 +846,72 @@ i2stx1: i2s@120c0000 { status = "disabled"; }; - pwm: pwm@120d0000 { + pwm0: pwm@120d0000 { compatible = "starfive,jh7110-pwm", "opencores,pwm-v1"; - reg = <0x0 0x120d0000 0x0 0x10000>; + reg = <0x0 0x120d0000 0x0 0x10>; + clocks = <&syscrg JH7110_SYSCLK_PWM_APB>; + resets = <&syscrg JH7110_SYSRST_PWM_APB>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm1: pwm@120d0010 { + compatible = "starfive,jh7110-pwm", "opencores,pwm-v1"; + reg = <0x0 0x120d0010 0x0 0x10>; + clocks = <&syscrg JH7110_SYSCLK_PWM_APB>; + resets = <&syscrg JH7110_SYSRST_PWM_APB>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm2: pwm@120d0020 { + compatible = "starfive,jh7110-pwm", "opencores,pwm-v1"; + reg = <0x0 0x120d0020 0x0 0x10>; + clocks = <&syscrg JH7110_SYSCLK_PWM_APB>; + resets = <&syscrg JH7110_SYSRST_PWM_APB>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm3: pwm@120d0030 { + compatible = "starfive,jh7110-pwm", "opencores,pwm-v1"; + reg = <0x0 0x120d0030 0x0 0x10>; + clocks = <&syscrg JH7110_SYSCLK_PWM_APB>; + resets = <&syscrg JH7110_SYSRST_PWM_APB>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm4: pwm@120d8000 { + compatible = "starfive,jh7110-pwm", "opencores,pwm-v1"; + reg = <0x0 0x120d8000 0x0 0x10>; + clocks = <&syscrg JH7110_SYSCLK_PWM_APB>; + resets = <&syscrg JH7110_SYSRST_PWM_APB>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm5: pwm@120d8010 { + compatible = "starfive,jh7110-pwm", "opencores,pwm-v1"; + reg = <0x0 0x120d8010 0x0 0x10>; + clocks = <&syscrg JH7110_SYSCLK_PWM_APB>; + resets = <&syscrg JH7110_SYSRST_PWM_APB>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm6: pwm@120d8020 { + compatible = "starfive,jh7110-pwm", "opencores,pwm-v1"; + reg = <0x0 0x120d8020 0x0 0x10>; + clocks = <&syscrg JH7110_SYSCLK_PWM_APB>; + resets = <&syscrg JH7110_SYSRST_PWM_APB>; + #pwm-cells = <3>; + status = "disabled"; + }; + + pwm7: pwm@120d8030 { + compatible = "starfive,jh7110-pwm", "opencores,pwm-v1"; + reg = <0x0 0x120d8030 0x0 0x10>; clocks = <&syscrg JH7110_SYSCLK_PWM_APB>; resets = <&syscrg JH7110_SYSRST_PWM_APB>; #pwm-cells = <3>;
diff --git a/arch/riscv/boot/dts/thead/Makefile b/arch/riscv/boot/dts/thead/Makefile index b55a171..25f7fe0 100644 --- a/arch/riscv/boot/dts/thead/Makefile +++ b/arch/riscv/boot/dts/thead/Makefile
@@ -1,2 +1,3 @@ # SPDX-License-Identifier: GPL-2.0 dtb-$(CONFIG_ARCH_THEAD) += th1520-lichee-pi-4a.dtb th1520-beaglev-ahead.dtb +dtb-$(CONFIG_ARCH_THEAD) += th1520-milkv-meles.dtb
diff --git a/arch/riscv/boot/dts/thead/th1520-milkv-meles.dts b/arch/riscv/boot/dts/thead/th1520-milkv-meles.dts new file mode 100644 index 0000000..1c9de6b --- /dev/null +++ b/arch/riscv/boot/dts/thead/th1520-milkv-meles.dts
@@ -0,0 +1,346 @@ +// SPDX-License-Identifier: (GPL-2.0 OR MIT) +/* + * Copyright (C) 2021-2022 Alibaba Group Holding Limited. + * Copyright (C) 2026 Han Gao <gaohan@iscas.ac.cn> + */ + +/dts-v1/; + +#include "th1520.dtsi" +#include <dt-bindings/gpio/gpio.h> + +/ { + model = "Milk-V Meles"; + compatible = "milkv,meles", "thead,th1520"; + + aliases { + ethernet0 = &gmac0; + gpio0 = &gpio0; + gpio1 = &gpio1; + gpio2 = &gpio2; + gpio3 = &gpio3; + gpio4 = &gpio4; + gpio5 = &aogpio; + mmc0 = &emmc; + mmc1 = &sdio0; + mmc2 = &sdio1; + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; + + wifi_32k: clock-wifi-32k { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <32768>; + /* The module LPO input is supplied by PMIC_32K_OUT. */ + }; + + hdmi-connector { + compatible = "hdmi-connector"; + type = "a"; + + port { + hdmi_con_in: endpoint { + remote-endpoint = <&hdmi_out_con>; + }; + }; + }; + + memory@0 { + device_type = "memory"; + reg = <0x0 0x0 0x2 0x0>; + }; + + fan: pwm-fan { + compatible = "pwm-fan"; + pinctrl-names = "default"; + pinctrl-0 = <&fan_pins>; + pwms = <&pwm 2 10000000 0>; + cooling-levels = <0 64 192 255>; + #cooling-cells = <2>; + }; + + wifi_vbat: regulator-wifi-vbat { + compatible = "regulator-fixed"; + regulator-name = "WIFI_3V3"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-always-on; + }; + + wifi_vddio: regulator-wifi-vddio { + compatible = "regulator-fixed"; + regulator-name = "WIFI_VDDIO"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-always-on; + }; + + wifi_pwrseq: wifi-pwrseq { + compatible = "mmc-pwrseq-simple"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_enable_pins>; + reset-gpios = <&gpio0 20 GPIO_ACTIVE_LOW>; + post-power-on-delay-ms = <50>; + }; +}; + +/* Names follow the 40-pin header signal labels. */ +&aogpio { + gpio-line-names = "", "", "", "", "", "", "", "AOGPIO_7", + "AOGPIO_8", "", "AOGPIO_10", "AOGPIO_11"; +}; + +&dpu { + status = "okay"; +}; + +&emmc { + bus-width = <8>; + max-frequency = <52000000>; + cap-mmc-highspeed; + mmc-ddr-1_8v; + non-removable; + no-sdio; + no-sd; + + status = "okay"; +}; + +&gmac0 { + pinctrl-names = "default"; + pinctrl-0 = <&gmac0_pins>, <&mdio0_pins>; + phy-handle = <&phy0>; + phy-mode = "rgmii-id"; + + status = "okay"; +}; + +&gpio0 { + gpio-line-names = "", "", "", "", "", "", "", "", "GPIO0_8", + "GPIO0_9", "GPIO0_10", "GPIO0_11", "", "", "", + "", "GPIO0_16", "GPIO0_17"; +}; + +&gpio1 { + /* GPIO1_24 low selects the external antenna through U39. */ + wifi-antenna-select-hog { + gpio-hog; + gpios = <24 GPIO_ACTIVE_HIGH>; + output-low; + line-name = "wifi-external-antenna"; + }; +}; + +&gpio2 { + gpio-line-names = "GPIO2_0", "GPIO2_1", "", "", "", "", "", "", + "", "", "", "GPIO2_11", "GPIO2_12", "", + "GPIO2_14", "GPIO2_15", "GPIO2_16", "GPIO2_17", + "", "", "", "", "GPIO2_22", "GPIO2_23", + "GPIO2_24", "GPIO2_25", "", "", "", "", "", + "GPIO2_31"; +}; + +&gpio3 { + gpio-line-names = "GPIO3_0", "GPIO3_1", "GPIO3_2", "GPIO3_3"; +}; + +&hdmi { + status = "okay"; +}; + +&hdmi_out_port { + hdmi_out_con: endpoint { + remote-endpoint = <&hdmi_con_in>; + }; +}; + +&mdio0 { + phy0: ethernet-phy@1 { + reg = <1>; + }; +}; + +&osc { + clock-frequency = <24000000>; +}; + +&osc_32k { + clock-frequency = <32768>; +}; + +&padctrl0_apsys { + fan_pins: fan-0 { + pwm2-pins { + pins = "QSPI0_CSN1"; + function = "pwm"; + bias-disable; + drive-strength = <25>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + gmac0_pins: gmac0-0 { + tx-pins { + pins = "GMAC0_TX_CLK", + "GMAC0_TXEN", + "GMAC0_TXD0", + "GMAC0_TXD1", + "GMAC0_TXD2", + "GMAC0_TXD3"; + function = "gmac0"; + bias-disable; + drive-strength = <25>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + + rx-pins { + pins = "GMAC0_RX_CLK", + "GMAC0_RXDV", + "GMAC0_RXD0", + "GMAC0_RXD1", + "GMAC0_RXD2", + "GMAC0_RXD3"; + function = "gmac0"; + bias-disable; + drive-strength = <1>; + input-enable; + input-schmitt-disable; + slew-rate = <0>; + }; + }; + + mdio0_pins: mdio0-0 { + mdc-pins { + pins = "GMAC0_MDC"; + function = "gmac0"; + bias-disable; + drive-strength = <13>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + + mdio-pins { + pins = "GMAC0_MDIO"; + function = "gmac0"; + bias-disable; + drive-strength = <13>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + }; + + sdio0_pins: sdio0-0 { + detn-pins { + pins = "SDIO0_DETN"; + function = "sdio"; + bias-disable; /* external pull-up */ + drive-strength = <1>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + }; + + uart0_pins: uart0-0 { + tx-pins { + pins = "UART0_TXD"; + function = "uart"; + bias-disable; + drive-strength = <3>; + input-disable; + input-schmitt-disable; + slew-rate = <0>; + }; + + rx-pins { + pins = "UART0_RXD"; + function = "uart"; + bias-disable; + drive-strength = <1>; + input-enable; + input-schmitt-enable; + slew-rate = <0>; + }; + }; +}; + +&padctrl1_apsys { + wifi_enable_pins: wifi-enable-0 { + gpio-pins { + pins = "GPIO0_20"; + bias-disable; + drive-strength = <7>; + input-disable; + }; + }; + + wifi_host_wake_pins: wifi-host-wake-0 { + gpio-pins { + pins = "GPIO0_21"; + function = "gpio"; + bias-disable; + input-enable; + input-schmitt-enable; + }; + }; +}; + +&sdio0 { + pinctrl-names = "default"; + pinctrl-0 = <&sdio0_pins>; + bus-width = <4>; + max-frequency = <50000000>; + cap-sd-highspeed; + no-1-8-v; + disable-wp; + no-sdio; + + status = "okay"; +}; + +&sdio1 { + bus-width = <4>; + max-frequency = <198000000>; + cap-sd-highspeed; + cap-sdio-irq; + non-removable; + no-sd; + no-mmc; + keep-power-in-suspend; + vmmc-supply = <&wifi_vbat>; + vqmmc-supply = <&wifi_vddio>; + mmc-pwrseq = <&wifi_pwrseq>; + #address-cells = <1>; + #size-cells = <0>; + + status = "okay"; + + wifi@1 { + compatible = "brcm,bcm43456-fmac", "brcm,bcm4329-fmac"; + reg = <1>; + clocks = <&wifi_32k>; + clock-names = "lpo"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_host_wake_pins>; + interrupt-parent = <&gpio0>; + interrupts = <21 IRQ_TYPE_LEVEL_HIGH>; + interrupt-names = "host-wake"; + }; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins>; + + status = "okay"; +};
diff --git a/arch/um/Kconfig b/arch/um/Kconfig index d9541d1..59d62c7 100644 --- a/arch/um/Kconfig +++ b/arch/um/Kconfig
@@ -17,9 +17,9 @@ select ARCH_HAS_KCOV select ARCH_HAS_STRNCPY_FROM_USER select ARCH_HAS_STRNLEN_USER - select ARCH_HAS_STRICT_KERNEL_RWX + select ARCH_HAS_STRICT_KERNEL_RWX if MMU select HAVE_ARCH_AUDITSYSCALL - select HAVE_ARCH_KASAN if X86_64 + select HAVE_ARCH_KASAN if X86_64 && MMU select HAVE_ARCH_KASAN_VMALLOC if HAVE_ARCH_KASAN select HAVE_ARCH_SECCOMP_FILTER select HAVE_ASM_MODVERSIONS @@ -27,6 +27,7 @@ select HAVE_DEBUG_KMEMLEAK select HAVE_DEBUG_BUGVERBOSE select HAVE_PAGE_SIZE_4KB + select HAVE_PERF_EVENTS select NO_DMA if !UML_DMA_EMULATION select OF_EARLY_FLATTREE if OF select GENERIC_IRQ_SHOW @@ -37,18 +38,23 @@ select ARCH_SUPPORTS_LTO_CLANG_THIN select TRACE_IRQFLAGS_SUPPORT select TTY # Needed for line.c - select HAVE_ARCH_VMAP_STACK + select HAVE_ARCH_VMAP_STACK if MMU select HAVE_RUST select ARCH_HAS_UBSAN select HAVE_ARCH_TRACEHOOK select HAVE_SYSCALL_TRACEPOINTS select THREAD_INFO_IN_TASK select SPARSE_IRQ - select MMU_GATHER_RCU_TABLE_FREE + select MMU_GATHER_RCU_TABLE_FREE if MMU + select UACCESS_MEMCPY if !MMU + select GENERIC_STRNLEN_USER if !MMU + select GENERIC_STRNCPY_FROM_USER if !MMU config MMU - bool + bool "MMU support" default y + help + Turning this off allows a nommu build, say Y. config UML_DMA_EMULATION bool @@ -210,27 +216,15 @@ It is safe to say 'Y' here. -config MAGIC_SYSRQ - bool "Magic SysRq key" - depends on MCONSOLE - help - If you say Y here, you will have some control over the system even - if the system crashes for example during kernel debugging (e.g., you - will be able to flush the buffer cache to disk, reboot the system - immediately or dump some status information). A key for each of the - possible requests is provided. - - This is the feature normally accomplished by pressing a key - while holding SysRq (Alt+PrintScreen). - - On UML, this is accomplished by sending a "sysrq" command with - mconsole, followed by the letter for the requested command. - - The keys are documented in <file:Documentation/admin-guide/sysrq.rst>. Don't say Y - unless you really know what this hack does. +config ARCH_FORCE_MAX_ORDER + int "Order of maximal physically contiguous allocations" if EXPERT + default "10" if MMU + default "16" if !MMU config KERNEL_STACK_ORDER int "Kernel stack size order" + default 3 if !MMU + range 3 10 if !MMU default 2 if 64BIT range 2 10 if 64BIT default 1 if !64BIT
diff --git a/arch/um/Makefile b/arch/um/Makefile index 937639e..d930c5f 100644 --- a/arch/um/Makefile +++ b/arch/um/Makefile
@@ -134,9 +134,10 @@ # Avoid binutils 2.39+ warnings by marking the stack non-executable and # ignorning warnings for the kallsyms sections. LDFLAGS_EXECSTACK = -z noexecstack -ifeq ($(CONFIG_LD_IS_BFD),y) -LDFLAGS_EXECSTACK += $(call ld-option,--no-warn-rwx-segments) -endif +# check --no-warn-rwx-segments with CC-as-linker since that gets used +# for vmlinux and is where we need the option, in particular with LLVM=1 +# it might be different links (ld.bfd vs. ld.lld) +LDFLAGS_EXECSTACK += $(call try-run,$(CC) -Wl$(comma)--no-warn-rwx-segments -shared -x c /dev/null -o "$$TMP",--no-warn-rwx-segments) LD_FLAGS_CMDLINE = $(foreach opt,$(KBUILD_LDFLAGS) $(LDFLAGS_EXECSTACK),-Wl,$(opt))
diff --git a/arch/um/drivers/Kconfig b/arch/um/drivers/Kconfig index 6a0354c..655e5a2 100644 --- a/arch/um/drivers/Kconfig +++ b/arch/um/drivers/Kconfig
@@ -159,6 +159,7 @@ config UML_PCI bool + depends on MMU select FORCE_PCI select IRQ_MSI_LIB select UML_IOMEM_EMULATION @@ -169,6 +170,7 @@ config UML_PCI_OVER_VIRTIO bool "Enable PCI over VIRTIO device simulation" # in theory, just VIRTIO is enough, but that causes recursion + depends on MMU depends on VIRTIO_UML select UML_PCI @@ -183,6 +185,7 @@ config UML_PCI_OVER_VFIO bool "Enable VFIO-based PCI passthrough" + depends on MMU select UML_PCI help This driver provides support for VFIO-based PCI passthrough.
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c index dc1d1bc..bb9f05a 100644 --- a/arch/um/drivers/cow_user.c +++ b/arch/um/drivers/cow_user.c
@@ -279,7 +279,7 @@ int file_reader(__u64 offset, char *buf, int len, void *arg) return pread(fd, buf, len, offset); } -/* XXX Need to sanity-check the values read from the header */ +/* Sanity checks are performed after reading each header version below. */ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, __u32 *version_out, char **backing_file_out, @@ -325,6 +325,12 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, *sectorsize_out = header->v1.sectorsize; *bitmap_offset_out = sizeof(header->v1); *align_out = *sectorsize_out; + if (!memchr(header->v1.backing_file, '\0', + sizeof(header->v1.backing_file))) { + cow_printf("%s - V1 backing_file not terminated\n", + __func__); + goto out; + } file = header->v1.backing_file; } else if (version == 2) { @@ -338,6 +344,12 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, *sectorsize_out = be32toh(header->v2.sectorsize); *bitmap_offset_out = sizeof(header->v2); *align_out = *sectorsize_out; + if (!memchr(header->v2.backing_file, '\0', + sizeof(header->v2.backing_file))) { + cow_printf("%s - V2 backing_file not terminated\n", + __func__); + goto out; + } file = header->v2.backing_file; } /* This is very subtle - see above at union cow_header definition */ @@ -354,8 +366,15 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, if (*align_out == 0) { cow_printf("read_cow_header - invalid COW header, " "align == 0\n"); + goto out; } *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out); + if (!memchr(header->v3.backing_file, '\0', + sizeof(header->v3.backing_file))) { + cow_printf("%s - V3 backing_file not terminated\n", + __func__); + goto out; + } file = header->v3.backing_file; } else if (version == 3) { @@ -385,14 +404,27 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg, if (*align_out == 0) { cow_printf("read_cow_header - invalid COW header, " "align == 0\n"); + goto out; } *bitmap_offset_out = ROUND_UP(sizeof(header->v3_b), *align_out); + if (!memchr(header->v3_b.backing_file, '\0', + sizeof(header->v3_b.backing_file))) { + cow_printf("%s - V3 backing_file not terminated\n", + __func__); + goto out; + } file = header->v3_b.backing_file; } else { cow_printf("read_cow_header - invalid COW version\n"); goto out; } + + if (*sectorsize_out <= 0) { + cow_printf("%s - invalid sectorsize %d\n", __func__, + *sectorsize_out); + goto out; + } err = -ENOMEM; *backing_file_out = cow_strdup(file); if (*backing_file_out == NULL) {
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c index e2a9e88..f01b7d8 100644 --- a/arch/um/drivers/mconsole_kern.c +++ b/arch/um/drivers/mconsole_kern.c
@@ -106,9 +106,9 @@ void mconsole_version(struct mc_request *req) { char version[256]; - sprintf(version, "%s %s %s %s %s", utsname()->sysname, - utsname()->nodename, utsname()->release, utsname()->version, - utsname()->machine); + snprintf(version, sizeof(version), "%s %s %s %s %s", + utsname()->sysname, utsname()->nodename, utsname()->release, + utsname()->version, utsname()->machine); mconsole_reply(req, version, 0, 0); } @@ -117,10 +117,12 @@ void mconsole_log(struct mc_request *req) int len; char *ptr = req->request.data; - ptr += strlen("log "); + ptr += strlen(req->cmd->command); + ptr = skip_spaces(ptr); - len = req->len - (ptr - req->request.data); - printk(KERN_WARNING "%.*s", len, ptr); + len = req->request.len - (ptr - req->request.data); + if (len > 0) + printk(KERN_WARNING "%.*s", len, ptr); mconsole_reply(req, "", 0, 0); }
diff --git a/arch/um/drivers/vector_kern.c b/arch/um/drivers/vector_kern.c index 8a70b3a..e902e78 100644 --- a/arch/um/drivers/vector_kern.c +++ b/arch/um/drivers/vector_kern.c
@@ -111,19 +111,26 @@ static void vector_reset_stats(struct vector_private *vp) * in vector_poll. */ - spin_lock(&vp->rx_queue->head_lock); + if (vp->rx_queue) + spin_lock(&vp->rx_queue->head_lock); + vp->estats.rx_queue_max = 0; vp->estats.rx_queue_running_average = 0; vp->estats.rx_encaps_errors = 0; vp->estats.sg_ok = 0; vp->estats.sg_linearized = 0; - spin_unlock(&vp->rx_queue->head_lock); + + if (vp->rx_queue) + spin_unlock(&vp->rx_queue->head_lock); + /* TX stats are modified with TX head_lock held * in vector_send. */ - spin_lock(&vp->tx_queue->head_lock); + if (vp->tx_queue) + spin_lock(&vp->tx_queue->head_lock); + vp->estats.tx_timeout_count = 0; vp->estats.tx_restart_queue = 0; vp->estats.tx_kicks = 0; @@ -131,7 +138,10 @@ static void vector_reset_stats(struct vector_private *vp) vp->estats.tx_flow_control_xoff = 0; vp->estats.tx_queue_max = 0; vp->estats.tx_queue_running_average = 0; - spin_unlock(&vp->tx_queue->head_lock); + + if (vp->tx_queue) + spin_unlock(&vp->tx_queue->head_lock); + } static int get_mtu(struct arglist *def) @@ -471,8 +481,6 @@ static void destroy_queue(struct vector_queue *qi) struct vector_private *vp = netdev_priv(qi->dev); struct mmsghdr *mmsg_vector; - if (qi == NULL) - return; /* deallocate any skbuffs - we rely on any unused to be * set to NULL. */ @@ -1166,15 +1174,15 @@ static int vector_poll(struct napi_struct *napi, int budget) if ((vp->options & VECTOR_TX) != 0) tx_enqueued = (vector_send(vp->tx_queue) > 0); - spin_lock(&vp->rx_queue->head_lock); - if ((vp->options & VECTOR_RX) > 0) + if ((vp->options & VECTOR_RX) > 0) { + spin_lock(&vp->rx_queue->head_lock); err = vector_mmsg_rx(vp, budget); - else { + spin_unlock(&vp->rx_queue->head_lock); + } else { err = vector_legacy_rx(vp); if (err > 0) err = 1; } - spin_unlock(&vp->rx_queue->head_lock); if (err > 0) work_done += err; @@ -1560,13 +1568,16 @@ static void vector_setup_etheraddr(struct net_device *dev, char *str) "Attempt to assign an invalid ethernet address to a device disallowed\n"); goto random; } + + eth_hw_addr_set(dev, addr); + if (!is_local_ether_addr(addr)) { + addr[0] |= 0x02; netdev_warn(dev, "Warning: Assigning a globally valid ethernet address to a device\n"); netdev_warn(dev, "You should set the 2nd rightmost bit in the first byte of the MAC,\n"); - netdev_warn(dev, "i.e. %02x:%02x:%02x:%02x:%02x:%02x\n", - addr[0] | 0x02, addr[1], addr[2], addr[3], addr[4], addr[5]); + netdev_warn(dev, "i.e. %pM\n", addr); } - eth_hw_addr_set(dev, addr); + return; random:
diff --git a/arch/um/drivers/vector_user.c b/arch/um/drivers/vector_user.c index 2ea67e6..3bee634 100644 --- a/arch/um/drivers/vector_user.c +++ b/arch/um/drivers/vector_user.c
@@ -93,6 +93,9 @@ struct arglist *uml_parse_vector_ifspec(char *arg) len = strlen(arg); for (pos = 0; pos < len; pos++) { if (next_starts) { + if (result->numargs >= MAXVARGS) + goto cleanup; + if (parsing_token) { result->tokens[result->numargs] = arg + pos; } else {
diff --git a/arch/um/drivers/virtio_pcidev.c b/arch/um/drivers/virtio_pcidev.c index 2bf5a64..53cffd3 100644 --- a/arch/um/drivers/virtio_pcidev.c +++ b/arch/um/drivers/virtio_pcidev.c
@@ -490,13 +490,24 @@ static int virtio_pcidev_init_vqs(struct virtio_pcidev_device *dev) return 0; } +static void virtio_pcidev_del_vqs(struct virtio_device *vdev, + struct virtio_pcidev_device *dev) +{ + void *msg; + + while ((msg = virtqueue_detach_unused_buf(dev->irq_vq))) + kfree(msg); + + vdev->config->del_vqs(vdev); +} + static void __virtio_pcidev_virtio_platform_remove(struct virtio_device *vdev, struct virtio_pcidev_device *dev) { um_pci_platform_device_unregister(&dev->pdev); virtio_reset_device(vdev); - vdev->config->del_vqs(vdev); + virtio_pcidev_del_vqs(vdev, dev); kfree(dev); } @@ -526,7 +537,7 @@ static int virtio_pcidev_virtio_platform_probe(struct virtio_device *vdev, um_pci_platform_device_unregister(&dev->pdev); err_reset: virtio_reset_device(vdev); - vdev->config->del_vqs(vdev); + virtio_pcidev_del_vqs(vdev, dev); err_free: kfree(dev); return err; @@ -569,7 +580,7 @@ static int virtio_pcidev_virtio_probe(struct virtio_device *vdev) err_reset: virtio_reset_device(vdev); - vdev->config->del_vqs(vdev); + virtio_pcidev_del_vqs(vdev, dev); err_free: kfree(dev); return err; @@ -591,9 +602,9 @@ static void virtio_pcidev_virtio_remove(struct virtio_device *vdev) /* Stop all virtqueues */ virtio_reset_device(vdev); + virtio_pcidev_del_vqs(vdev, dev); dev->cmd_vq = NULL; dev->irq_vq = NULL; - vdev->config->del_vqs(vdev); kfree(dev); }
diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c index 7425a85..30899dd 100644 --- a/arch/um/drivers/virtio_uml.c +++ b/arch/um/drivers/virtio_uml.c
@@ -568,7 +568,7 @@ static void vhost_user_get_config(struct virtio_uml_device *vu_dev, goto free; } - rc = vhost_user_recv_resp(vu_dev, msg, msg_size); + rc = vhost_user_recv_resp(vu_dev, msg, payload_size); if (rc) { vu_err(vu_dev, "receiving VHOST_USER_GET_CONFIG response failed: %d\n", @@ -1274,14 +1274,7 @@ static void virtio_uml_remove(struct platform_device *pdev) /* Command line device list */ -static void vu_cmdline_release_dev(struct device *d) -{ -} - -static struct device vu_cmdline_parent = { - .init_name = "virtio-uml-cmdline", - .release = vu_cmdline_release_dev, -}; +static struct device *vu_cmdline_parent; static DEFINE_MUTEX(vu_cmdline_lock); static bool vu_cmdline_parent_registered; @@ -1333,11 +1326,10 @@ static int vu_cmdline_set_device(const char *device) return -EINVAL; if (!vu_cmdline_parent_registered) { - err = device_register(&vu_cmdline_parent); - if (err) { + vu_cmdline_parent = __root_device_register("virtio-uml-cmdline", NULL); + if (IS_ERR(vu_cmdline_parent)) { pr_err("Failed to register parent device!\n"); - put_device(&vu_cmdline_parent); - return err; + return PTR_ERR(vu_cmdline_parent); } vu_cmdline_parent_registered = true; } @@ -1352,7 +1344,7 @@ static int vu_cmdline_set_device(const char *device) pr_info("Registering device virtio-uml.%d id=%d at %s\n", vu_cmdline_id, virtio_device_id, socket_path); - pdev = platform_device_register_data(&vu_cmdline_parent, "virtio-uml", + pdev = platform_device_register_data(vu_cmdline_parent, "virtio-uml", vu_cmdline_id++, &pdata, sizeof(pdata)); err = PTR_ERR_OR_ZERO(pdev); @@ -1393,7 +1385,7 @@ static int vu_cmdline_get(char *buffer, const struct kernel_param *kp) buffer[0] = '\0'; if (vu_cmdline_parent_registered) - device_for_each_child(&vu_cmdline_parent, buffer, + device_for_each_child(vu_cmdline_parent, buffer, vu_cmdline_get_device); return strlen(buffer) + 1; } @@ -1417,9 +1409,9 @@ static void vu_unregister_cmdline_devices(void) guard(mutex)(&vu_cmdline_lock); if (vu_cmdline_parent_registered) { - device_for_each_child(&vu_cmdline_parent, NULL, + device_for_each_child(vu_cmdline_parent, NULL, vu_unregister_cmdline_device); - device_unregister(&vu_cmdline_parent); + root_device_unregister(vu_cmdline_parent); vu_cmdline_parent_registered = false; } }
diff --git a/arch/um/include/asm/common.lds.S b/arch/um/include/asm/common.lds.S index fd481ac..6585cb93 100644 --- a/arch/um/include/asm/common.lds.S +++ b/arch/um/include/asm/common.lds.S
@@ -11,6 +11,8 @@ RO_DATA(4096) + .lrodata : { *(.lrodata .lrodata.[0-9a-zA-Z_]* .lrodata..L*) } + .unprotected : { *(.unprotected) } . = ALIGN(4096); PROVIDE (_unprotected_end = .);
diff --git a/arch/um/include/asm/futex.h b/arch/um/include/asm/futex.h index 780aa6bf..07ab81f 100644 --- a/arch/um/include/asm/futex.h +++ b/arch/um/include/asm/futex.h
@@ -7,8 +7,61 @@ #include <asm/errno.h> +#ifdef CONFIG_MMU int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, u32 __user *uaddr); int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, u32 oldval, u32 newval); +#else +#include <linux/atomic.h> +#include <asm-generic/futex.h> + +#ifdef CONFIG_SMP +static inline int +arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, u32 __user *uaddr) +{ + u32 oldval, newval; + u32 *p = (u32 __force *)uaddr; + + do { + oldval = READ_ONCE(*p); + + switch (op) { + case FUTEX_OP_SET: + newval = oparg; + break; + case FUTEX_OP_ADD: + newval = oldval + oparg; + break; + case FUTEX_OP_OR: + newval = oldval | oparg; + break; + case FUTEX_OP_ANDN: + newval = oldval & ~oparg; + break; + case FUTEX_OP_XOR: + newval = oldval ^ oparg; + break; + default: + return -ENOSYS; + } + } while (!try_cmpxchg(p, &oldval, newval)); + + *oval = oldval; + return 0; +} + +static inline int +futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, + u32 oldval, u32 newval) +{ + u32 *p = (u32 __force *)uaddr; + + *uval = cmpxchg(p, oldval, newval); + + return 0; +} +#endif /* CONFIG_SMP */ + +#endif /* CONFIG_MMU */ #endif
diff --git a/arch/um/include/asm/mmu.h b/arch/um/include/asm/mmu.h index 07d4873..c0b9ce3 100644 --- a/arch/um/include/asm/mmu.h +++ b/arch/um/include/asm/mmu.h
@@ -21,6 +21,14 @@ typedef struct mm_context { spinlock_t sync_tlb_lock; unsigned long sync_tlb_range_from; unsigned long sync_tlb_range_to; + +#ifndef CONFIG_MMU + unsigned long end_brk; +#ifdef CONFIG_BINFMT_ELF_FDPIC + unsigned long exec_fdpic_loadmap; + unsigned long interp_fdpic_loadmap; +#endif +#endif /* !CONFIG_MMU */ } mm_context_t; #define INIT_MM_CONTEXT(mm) \
diff --git a/arch/um/include/asm/mmu_context.h b/arch/um/include/asm/mmu_context.h index c727e56..528b217 100644 --- a/arch/um/include/asm/mmu_context.h +++ b/arch/um/include/asm/mmu_context.h
@@ -18,11 +18,13 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, { } +#ifdef CONFIG_MMU #define init_new_context init_new_context extern int init_new_context(struct task_struct *task, struct mm_struct *mm); #define destroy_context destroy_context extern void destroy_context(struct mm_struct *mm); +#endif #include <asm-generic/mmu_context.h>
diff --git a/arch/um/include/asm/perf_event.h b/arch/um/include/asm/perf_event.h new file mode 100644 index 0000000..9f774e2d --- /dev/null +++ b/arch/um/include/asm/perf_event.h
@@ -0,0 +1,7 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __UM_PERF_EVENT_H +#define __UM_PERF_EVENT_H + +/* nothing here - clearly no real hardware support */ + +#endif /* __UM_PERF_EVENT_H */
diff --git a/arch/um/include/asm/pgtable.h b/arch/um/include/asm/pgtable.h index 88ea843..6304026 100644 --- a/arch/um/include/asm/pgtable.h +++ b/arch/um/include/asm/pgtable.h
@@ -13,6 +13,7 @@ #define _PAGE_PRESENT 0x001 #define _PAGE_NEEDSYNC 0x002 +#define _PAGE_EXEC 0x004 #define _PAGE_RW 0x020 #define _PAGE_USER 0x040 #define _PAGE_ACCESSED 0x080 @@ -55,14 +56,19 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; #define _PAGE_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY) #define _KERNPG_TABLE (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY) -#define __PAGE_KERNEL_EXEC \ - (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) -#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) -#define PAGE_SHARED __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED) -#define PAGE_COPY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) -#define PAGE_READONLY __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) -#define PAGE_KERNEL __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) -#define PAGE_KERNEL_EXEC __pgprot(__PAGE_KERNEL_EXEC) + +#define _PAGE_BASE (_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED) +#define PAGE_NONE __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED) +#define PAGE_SHARED __pgprot(_PAGE_BASE | _PAGE_RW) +#define PAGE_SHARED_EXEC __pgprot(_PAGE_BASE | _PAGE_RW | _PAGE_EXEC) +#define PAGE_COPY __pgprot(_PAGE_BASE) +#define PAGE_COPY_EXEC __pgprot(_PAGE_BASE | _PAGE_EXEC) +#define PAGE_READONLY __pgprot(_PAGE_BASE) +#define PAGE_READONLY_EXEC __pgprot(_PAGE_BASE | _PAGE_EXEC) + +#define _PAGE_KERNEL (_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED) +#define PAGE_KERNEL __pgprot(_PAGE_KERNEL) +#define PAGE_KERNEL_EXEC __pgprot(_PAGE_KERNEL | _PAGE_EXEC) /* * The i386 can't do page protection for execute, and considers that the same @@ -117,7 +123,8 @@ static inline int pte_read(pte_t pte) static inline int pte_exec(pte_t pte) { - return !pte_get_bits(pte, _PAGE_PROTNONE); + return pte_get_bits(pte, _PAGE_EXEC) && + !pte_get_bits(pte, _PAGE_PROTNONE); } static inline int pte_write(pte_t pte)
diff --git a/arch/um/include/asm/ptrace-generic.h b/arch/um/include/asm/ptrace-generic.h index 86d74f9..62e9916 100644 --- a/arch/um/include/asm/ptrace-generic.h +++ b/arch/um/include/asm/ptrace-generic.h
@@ -29,6 +29,12 @@ struct pt_regs { #define PTRACE_OLDSETOPTIONS 21 +#ifdef CONFIG_BINFMT_ELF_FDPIC +#define PTRACE_GETFDPIC 31 +#define PTRACE_GETFDPIC_EXEC 0 +#define PTRACE_GETFDPIC_INTERP 1 +#endif + struct task_struct; extern long subarch_ptrace(struct task_struct *child, long request,
diff --git a/arch/um/include/asm/tlbflush.h b/arch/um/include/asm/tlbflush.h index 13a3009..f73b568 100644 --- a/arch/um/include/asm/tlbflush.h +++ b/arch/um/include/asm/tlbflush.h
@@ -30,6 +30,8 @@ * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages */ +#ifdef CONFIG_MMU + extern int um_tlb_sync(struct mm_struct *mm); extern void flush_tlb_all(void); @@ -56,4 +58,22 @@ static inline void flush_tlb_kernel_range(unsigned long start, um_tlb_sync(&init_mm); } +#else /* !CONFIG_MMU */ + +/* + * With NOMMU the kernel and userspace share a single host address space, + * so there is nothing to synchronise and all TLB flushes are no-ops. + */ +static inline int um_tlb_sync(struct mm_struct *mm) { return 0; } +static inline void flush_tlb_all(void) { } +static inline void flush_tlb_mm(struct mm_struct *mm) { } +static inline void flush_tlb_page(struct vm_area_struct *vma, + unsigned long address) { } +static inline void flush_tlb_range(struct vm_area_struct *vma, + unsigned long start, unsigned long end) { } +static inline void flush_tlb_kernel_range(unsigned long start, + unsigned long end) { } + +#endif /* CONFIG_MMU */ + #endif
diff --git a/arch/um/include/asm/uaccess.h b/arch/um/include/asm/uaccess.h index 4417c8b..e493596f6 100644 --- a/arch/um/include/asm/uaccess.h +++ b/arch/um/include/asm/uaccess.h
@@ -18,6 +18,7 @@ #define __addr_range_nowrap(addr, size) \ ((unsigned long) (addr) <= ((unsigned long) (addr) + (size))) +#ifdef CONFIG_MMU extern unsigned long raw_copy_from_user(void *to, const void __user *from, unsigned long n); extern unsigned long raw_copy_to_user(void __user *to, const void *from, unsigned long n); extern unsigned long __clear_user(void __user *mem, unsigned long len); @@ -29,8 +30,6 @@ static inline int __access_ok(const void __user *ptr, unsigned long size); #define INLINE_COPY_USER -#include <asm-generic/uaccess.h> - static inline int __access_ok(const void __user *ptr, unsigned long size) { unsigned long addr = (unsigned long)ptr; @@ -62,5 +61,8 @@ do { \ barrier(); \ current->thread.segv_continue = NULL; \ } while (0) +#endif + +#include <asm-generic/uaccess.h> #endif
diff --git a/arch/um/include/shared/as-layout.h b/arch/um/include/shared/as-layout.h index 02ef258..7c4ccb6 100644 --- a/arch/um/include/shared/as-layout.h +++ b/arch/um/include/shared/as-layout.h
@@ -29,6 +29,7 @@ #ifndef __ASSEMBLER__ +#include <linux/compiler_types.h> #include <sysdep/ptrace.h> struct task_struct; @@ -46,7 +47,7 @@ extern unsigned long brk_start; extern unsigned long stub_start; -extern int linux_main(int argc, char **argv, char **envp); +extern void __noreturn linux_main(int argc, char **argv, char **envp); extern void uml_finishsetup(void); struct siginfo;
diff --git a/arch/um/include/shared/kern_util.h b/arch/um/include/shared/kern_util.h index 9812efd..7950d58 100644 --- a/arch/um/include/shared/kern_util.h +++ b/arch/um/include/shared/kern_util.h
@@ -6,6 +6,7 @@ #ifndef __KERN_UTIL_H__ #define __KERN_UTIL_H__ +#include <linux/compiler_types.h> #include <sysdep/ptrace.h> #include <sysdep/faultinfo.h> @@ -37,7 +38,7 @@ extern void timer_handler(int sig, struct siginfo *unused_si, struct uml_pt_regs extern void uml_pm_wake(void); -extern int start_uml(void); +extern void __noreturn start_uml(void); extern void uml_cleanup(void); extern void do_uml_exitcalls(void);
diff --git a/arch/um/include/shared/longjmp.h b/arch/um/include/shared/longjmp.h index c53e43d..b35ed75 100644 --- a/arch/um/include/shared/longjmp.h +++ b/arch/um/include/shared/longjmp.h
@@ -2,11 +2,12 @@ #ifndef __UML_LONGJMP_H #define __UML_LONGJMP_H +#include <linux/compiler_types.h> #include <sysdep/archsetjmp.h> #include <os.h> extern int setjmp(jmp_buf); -extern void longjmp(jmp_buf, int); +extern void __noreturn longjmp(jmp_buf, int); #define UML_LONGJMP(buf, val) do { \ longjmp(*buf, val); \
diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h index b26e942..0067c52 100644 --- a/arch/um/include/shared/os.h +++ b/arch/um/include/shared/os.h
@@ -15,6 +15,7 @@ #ifndef __UM_HOST__ #include <linux/types.h> #else +#include <stdbool.h> #include <sys/types.h> #endif @@ -196,6 +197,9 @@ extern int create_mem_file(unsigned long long len); /* tlb.c */ extern void report_enomem(void); +/* main.c */ +extern void __noreturn os_exit(bool reboot); + /* process.c */ pid_t os_reap_child(void); extern void os_alarm_process(int pid); @@ -295,7 +299,7 @@ extern int start_userspace(struct mm_id *mm_id); extern void userspace(struct uml_pt_regs *regs); extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)); extern void switch_threads(jmp_buf *me, jmp_buf *you); -extern int start_idle_thread(void *stack, jmp_buf *switch_buf); +extern void __noreturn start_idle_thread(void *stack, jmp_buf *switch_buf); extern void initial_thread_cb_skas(void (*proc)(void *), void *arg); extern void halt_skas(void);
diff --git a/arch/um/include/shared/skas/stub-data.h b/arch/um/include/shared/skas/stub-data.h index 27db38e..1230a32 100644 --- a/arch/um/include/shared/skas/stub-data.h +++ b/arch/um/include/shared/skas/stub-data.h
@@ -9,11 +9,20 @@ #define __STUB_DATA_H #include <linux/compiler_types.h> +#include <asm/unistd.h> #include <as-layout.h> #include <sysdep/tls.h> #include <sysdep/stub-data.h> #include <mm_id.h> +#ifndef __NR_close_range +# if defined(__alpha__) +# define __NR_close_range 546 +# else +# define __NR_close_range 436 +# endif +#endif + #define FUTEX_IN_CHILD 0 #define FUTEX_IN_KERN 1
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile index be60bc4..b087b42 100644 --- a/arch/um/kernel/Makefile +++ b/arch/um/kernel/Makefile
@@ -16,9 +16,13 @@ obj-y = config.o exec.o exitcode.o irq.o ksyms.o mem.o \ physmem.o process.o ptrace.o reboot.o sigio.o \ - signal.o sysrq.o time.o tlb.o trap.o \ + signal.o sysrq.o time.o trap.o \ um_arch.o umid.o kmsg_dump.o capflags.o skas/ obj-y += load_file.o +obj-$(CONFIG_MMU) += mem-pgtable.o tlb.o trap-mmu.o +ifneq ($(CONFIG_MMU),y) +obj-y += trap-nommu.o +endif obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o obj-$(CONFIG_GPROF) += gprof_syms.o
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S index ad3cefe..31adf94 100644 --- a/arch/um/kernel/dyn.lds.S +++ b/arch/um/kernel/dyn.lds.S
@@ -20,9 +20,12 @@ __binary_start = .; . = ALIGN(4096); /* Init code and data */ _text = .; + __init_begin = .; INIT_TEXT_SECTION(PAGE_SIZE) + init.data : { INIT_DATA } . = ALIGN(PAGE_SIZE); + __init_end = .; /* Read-only sections, merged into text segment: */ .hash : { *(.hash) } @@ -98,10 +101,6 @@ #include <asm/common.lds.S> - __init_begin = .; - init.data : { INIT_DATA } - __init_end = .; - /* Ensure the __preinit_array_start label is properly aligned. We could instead move the label definition inside the section, but the linker would then create the section even if it turns out to @@ -117,6 +116,7 @@ .data : { INIT_TASK_DATA(KERNEL_STACK_SIZE) DATA_DATA + *(.ldata .ldata.[0-9a-zA-Z_]* .ldata..L*) *(.data.* .gnu.linkonce.d.*) SORT(CONSTRUCTORS) } @@ -159,6 +159,7 @@ __bss_start = .; *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) + *(.lbss .lbss.[0-9a-zA-Z_]* .lbss..L*) *(COMMON) /* Align here to ensure that the .bss section occupies space up to _end. Align after .bss to ensure correct alignment even if the
diff --git a/arch/um/kernel/mem-pgtable.c b/arch/um/kernel/mem-pgtable.c new file mode 100644 index 0000000..e338944 --- /dev/null +++ b/arch/um/kernel/mem-pgtable.c
@@ -0,0 +1,55 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + */ + +#include <linux/stddef.h> +#include <linux/module.h> +#include <linux/memblock.h> +#include <linux/swap.h> +#include <linux/slab.h> +#include <asm/page.h> +#include <asm/pgalloc.h> +#include <as-layout.h> +#include <init.h> +#include <kern.h> +#include <kern_util.h> +#include <mem_user.h> +#include <os.h> +#include <um_malloc.h> + + +/* Allocate and free page tables. */ + +pgd_t *pgd_alloc(struct mm_struct *mm) +{ + pgd_t *pgd = (pgd_t *)__get_free_page(GFP_KERNEL); + + if (pgd) { + memset(pgd, 0, USER_PTRS_PER_PGD * sizeof(pgd_t)); + memcpy(pgd + USER_PTRS_PER_PGD, + swapper_pg_dir + USER_PTRS_PER_PGD, + (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); + } + return pgd; +} + +static const pgprot_t protection_map[16] = { + [VM_NONE] = PAGE_NONE, + [VM_READ] = PAGE_READONLY, + [VM_WRITE] = PAGE_COPY, + [VM_WRITE | VM_READ] = PAGE_COPY, + [VM_EXEC] = PAGE_READONLY_EXEC, + [VM_EXEC | VM_READ] = PAGE_READONLY_EXEC, + [VM_EXEC | VM_WRITE] = PAGE_COPY_EXEC, + [VM_EXEC | VM_WRITE | VM_READ] = PAGE_COPY_EXEC, + [VM_SHARED] = PAGE_NONE, + [VM_SHARED | VM_READ] = PAGE_READONLY, + [VM_SHARED | VM_WRITE] = PAGE_SHARED, + [VM_SHARED | VM_WRITE | VM_READ] = PAGE_SHARED, + [VM_SHARED | VM_EXEC] = PAGE_READONLY_EXEC, + [VM_SHARED | VM_EXEC | VM_READ] = PAGE_READONLY_EXEC, + [VM_SHARED | VM_EXEC | VM_WRITE] = PAGE_SHARED_EXEC, + [VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = PAGE_SHARED_EXEC +}; +DECLARE_VM_GET_PAGE_PROT
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c index 1eef0e4..2219827 100644 --- a/arch/um/kernel/mem.c +++ b/arch/um/kernel/mem.c
@@ -6,7 +6,6 @@ #include <linux/stddef.h> #include <linux/module.h> #include <linux/memblock.h> -#include <linux/mm.h> #include <linux/swap.h> #include <linux/slab.h> #include <linux/init.h> @@ -65,7 +64,8 @@ void __init arch_mm_preinit(void) * to be turned on. */ brk_end = PAGE_ALIGN((unsigned long) sbrk(0)); - map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, 0); + map_memory(brk_end, __pa(brk_end), uml_reserved - brk_end, 1, 1, + !IS_ENABLED(CONFIG_MMU)); memblock_free((void *)brk_end, uml_reserved - brk_end); uml_reserved = brk_end; min_low_pfn = PFN_UP(__pa(uml_reserved)); @@ -83,26 +83,17 @@ void __init arch_zone_limits_init(unsigned long *max_zone_pfns) } /* - * This can't do anything because nothing in the kernel image can be freed - * since it's not in kernel physical memory. + * We could munmap() this instead, but then libc allocations could + * land in this area and stray initdata access could erroneously + * succeed - just mprotect() it to reliably catch bad accesses. */ - void free_initmem(void) { -} + unsigned long start = PAGE_ALIGN((unsigned long)__init_begin); + unsigned long end = round_down((unsigned long)__init_end, PAGE_SIZE); -/* Allocate and free page tables. */ - -pgd_t *pgd_alloc(struct mm_struct *mm) -{ - pgd_t *pgd = __pgd_alloc(mm, 0); - - if (pgd) - memcpy(pgd + USER_PTRS_PER_PGD, - swapper_pg_dir + USER_PTRS_PER_PGD, - (PTRS_PER_PGD - USER_PTRS_PER_PGD) * sizeof(pgd_t)); - - return pgd; + if (end > start) + os_protect_memory((void *)start, end - start, 0, 0, 0); } void *uml_kmalloc(int size, int flags) @@ -110,26 +101,6 @@ void *uml_kmalloc(int size, int flags) return kmalloc(size, flags); } -static const pgprot_t protection_map[16] = { - [VM_NONE] = PAGE_NONE, - [VM_READ] = PAGE_READONLY, - [VM_WRITE] = PAGE_COPY, - [VM_WRITE | VM_READ] = PAGE_COPY, - [VM_EXEC] = PAGE_READONLY, - [VM_EXEC | VM_READ] = PAGE_READONLY, - [VM_EXEC | VM_WRITE] = PAGE_COPY, - [VM_EXEC | VM_WRITE | VM_READ] = PAGE_COPY, - [VM_SHARED] = PAGE_NONE, - [VM_SHARED | VM_READ] = PAGE_READONLY, - [VM_SHARED | VM_WRITE] = PAGE_SHARED, - [VM_SHARED | VM_WRITE | VM_READ] = PAGE_SHARED, - [VM_SHARED | VM_EXEC] = PAGE_READONLY, - [VM_SHARED | VM_EXEC | VM_READ] = PAGE_READONLY, - [VM_SHARED | VM_EXEC | VM_WRITE] = PAGE_SHARED, - [VM_SHARED | VM_EXEC | VM_WRITE | VM_READ] = PAGE_SHARED -}; -DECLARE_VM_GET_PAGE_PROT - void mark_rodata_ro(void) { unsigned long rodata_start = PFN_ALIGN(__start_rodata);
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c index ae6ca37..ae9b8f3 100644 --- a/arch/um/kernel/physmem.c +++ b/arch/um/kernel/physmem.c
@@ -110,6 +110,13 @@ int phys_mapping(unsigned long phys, unsigned long long *offset_out) } EXPORT_SYMBOL(phys_mapping); +void report_enomem(void) +{ + printk(KERN_ERR "UML ran out of memory on the host side! " + "This can happen due to a memory limitation or " + "vm.max_map_count has been reached.\n"); +} + static int __init uml_mem_setup(char *line, int *add) { char *retptr;
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c index 63b38a3..dfca9e0 100644 --- a/arch/um/kernel/process.c +++ b/arch/um/kernel/process.c
@@ -276,16 +276,12 @@ unsigned long arch_align_stack(unsigned long sp) } #endif -unsigned long __get_wchan(struct task_struct *p) +static unsigned long ___get_wchan(struct task_struct *p) { unsigned long stack_page, sp, ip; bool seen_sched = 0; stack_page = (unsigned long) task_stack_page(p); - /* Bail if the process has no kernel stack for some reason */ - if (stack_page == 0) - return 0; - sp = p->thread.switch_buf->JB_SP; /* * Bail if the stack pointer is below the bottom of the kernel @@ -306,4 +302,21 @@ unsigned long __get_wchan(struct task_struct *p) } return 0; + +} + +unsigned long __get_wchan(struct task_struct *p) +{ + unsigned long ret; + + /* Bail if the process has no kernel stack for some reason */ + if (!try_get_task_stack(p)) + return 0; + + ret = ___get_wchan(p); + + put_task_stack(p); + + return ret; + }
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile index 3384be4..2cf82eb 100644 --- a/arch/um/kernel/skas/Makefile +++ b/arch/um/kernel/skas/Makefile
@@ -3,8 +3,12 @@ # Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) # -obj-y := stub.o mmu.o process.o syscall.o uaccess.o \ +obj-y := stub.o process.o syscall.o \ stub_exe_embed.o +obj-$(CONFIG_MMU) += mmu.o uaccess.o +ifneq ($(CONFIG_MMU),y) +obj-y += nommu.o +endif # Stub executable @@ -40,8 +44,14 @@ CFLAGS_stub.o := $(CFLAGS_NO_HARDENING) CFLAGS_stub_exe.o := $(CFLAGS_NO_HARDENING) -# Clang will call memset() from __builtin_alloca() when stack variable -# initialization is enabled, which is used in stub_exe.c. +# stub_signal_restorer() must not touch stack pointer, clang doesn't +# always omit the frame pointer automatically +CFLAGS_stub.o += -fomit-frame-pointer +CFLAGS_stub_exe.o += -fomit-frame-pointer + +# Clang's stack var initialisation can use memset() or similar and that +# cannot be done for this code since we embed/move the stub +CFLAGS_stub.o += $(call cc-option, -ftrivial-auto-var-init=uninitialized) CFLAGS_stub_exe.o += $(call cc-option, -ftrivial-auto-var-init=uninitialized) UNPROFILE_OBJS := stub.o stub_exe.o
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c index b501709..facb88d 100644 --- a/arch/um/kernel/skas/mmu.c +++ b/arch/um/kernel/skas/mmu.c
@@ -12,6 +12,7 @@ #include <asm/pgalloc.h> #include <asm/sections.h> #include <asm/mmu_context.h> +#include <asm/tlbflush.h> #include <as-layout.h> #include <os.h> #include <skas.h> @@ -40,6 +41,30 @@ void exit_turnstile(struct mm_id *mm_id) mutex_unlock(__get_turnstile(mm_id)); } +unsigned long current_stub_stack(void) +{ + if (current->mm == NULL) + return 0; + + return current->mm->context.id.stack; +} + +struct mm_id *current_mm_id(void) +{ + if (current->mm == NULL) + return NULL; + + return ¤t->mm->context.id; +} + +void current_mm_sync(void) +{ + if (current->mm == NULL) + return; + + um_tlb_sync(current->mm); +} + int init_new_context(struct task_struct *task, struct mm_struct *mm) { struct mm_id *new_id = &mm->context.id;
diff --git a/arch/um/kernel/skas/nommu.c b/arch/um/kernel/skas/nommu.c new file mode 100644 index 0000000..80d5c4ea --- /dev/null +++ b/arch/um/kernel/skas/nommu.c
@@ -0,0 +1,91 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/cpumask.h> +#include <linux/gfp.h> +#include <linux/init.h> +#include <linux/kernel.h> +#include <linux/log2.h> +#include <linux/mutex.h> +#include <linux/panic.h> +#include <linux/smp.h> +#include <linux/threads.h> +#include <as-layout.h> +#include <mem.h> +#include <os.h> +#include <skas.h> +#include <mm_id.h> + +struct nommu_runner { + struct mm_id mm_id; + struct mutex turnstile; +}; + +static struct nommu_runner nommu_runners[NR_CPUS]; + +static struct nommu_runner *this_runner(void) +{ + return &nommu_runners[raw_smp_processor_id()]; +} + +struct mutex *__get_turnstile(struct mm_id *mm_id) +{ + return &container_of(mm_id, struct nommu_runner, mm_id)->turnstile; +} + +void enter_turnstile(struct mm_id *mm_id) +{ + mutex_lock(__get_turnstile(mm_id)); +} + +void exit_turnstile(struct mm_id *mm_id) +{ + mutex_unlock(__get_turnstile(mm_id)); +} + +unsigned long current_stub_stack(void) +{ + return this_runner()->mm_id.stack; +} + +struct mm_id *current_mm_id(void) +{ + return &this_runner()->mm_id; +} + +void current_mm_sync(void) +{ +} + +static int __init nommu_start_runners(void) +{ + unsigned long long offset; + struct nommu_runner *r; + int cpu, err, fd; + + fd = phys_mapping(uml_reserved - uml_physmem, &offset); + + for_each_possible_cpu(cpu) { + r = &nommu_runners[cpu]; + mutex_init(&r->turnstile); + + r->mm_id.stack = __get_free_pages(GFP_KERNEL | __GFP_ZERO, + ilog2(STUB_DATA_PAGES)); + if (!r->mm_id.stack) + panic("OOM allocating userspace stack for CPU %d", cpu); + + err = start_userspace(&r->mm_id); + if (err < 0) + panic("userspace startup for CPU %d failed: %d", + cpu, err); + + map(&r->mm_id, uml_reserved, high_physmem - uml_reserved, + UM_PROT_READ | UM_PROT_WRITE | UM_PROT_EXEC, fd, offset); + + err = syscall_stub_flush(&r->mm_id); + if (err < 0) + panic("physmem map/flush failed for CPU%d: %d", + cpu, err); + } + + return 0; +} +arch_initcall(nommu_start_runners);
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c index 4a7673b..f60541d 100644 --- a/arch/um/kernel/skas/process.c +++ b/arch/um/kernel/skas/process.c
@@ -9,8 +9,6 @@ #include <linux/sched/task.h> #include <linux/smp-internal.h> -#include <asm/tlbflush.h> - #include <as-layout.h> #include <kern.h> #include <os.h> @@ -29,7 +27,7 @@ static int __init start_kernel_proc(void *unused) char cpu_irqstacks[NR_CPUS][THREAD_SIZE] __aligned(THREAD_SIZE); -int __init start_uml(void) +void __init start_uml(void) { stack_protections((unsigned long) &cpu_irqstacks[0]); set_sigstack(cpu_irqstacks[0], THREAD_SIZE); @@ -38,32 +36,8 @@ int __init start_uml(void) init_task.thread.request.thread.proc = start_kernel_proc; init_task.thread.request.thread.arg = NULL; - return start_idle_thread(task_stack_page(&init_task), - &init_task.thread.switch_buf); -} - -unsigned long current_stub_stack(void) -{ - if (current->mm == NULL) - return 0; - - return current->mm->context.id.stack; -} - -struct mm_id *current_mm_id(void) -{ - if (current->mm == NULL) - return NULL; - - return ¤t->mm->context.id; -} - -void current_mm_sync(void) -{ - if (current->mm == NULL) - return; - - um_tlb_sync(current->mm); + start_idle_thread(task_stack_page(&init_task), + &init_task.thread.switch_buf); } static DEFINE_SPINLOCK(initial_jmpbuf_spinlock);
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c index bc11773..914b90a 100644 --- a/arch/um/kernel/skas/syscall.c +++ b/arch/um/kernel/skas/syscall.c
@@ -35,12 +35,13 @@ void handle_syscall(struct uml_pt_regs *r) /* * If no time passes, then sched_yield may not actually yield, causing * broken spinlock implementations in userspace (ASAN) to hang for long - * periods of time. + * periods of time. Advance the time-travel clock a bit so sched_yield() + * in a loop (like ping does for small intervals) also works correctly. */ if ((time_travel_mode == TT_MODE_INFCPU || time_travel_mode == TT_MODE_EXTERNAL) && syscall == __NR_sched_yield) - tt_extra_sched_jiffies += 1; + time_travel_ndelay(1000); if (syscall >= 0 && syscall < __NR_syscalls) { unsigned long ret;
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c index caef1de..f48f0e7c 100644 --- a/arch/um/kernel/skas/uaccess.c +++ b/arch/um/kernel/skas/uaccess.c
@@ -231,116 +231,90 @@ long strnlen_user(const char __user *str, long len) } EXPORT_SYMBOL(strnlen_user); -/** - * arch_futex_atomic_op_inuser() - Atomic arithmetic operation with constant - * argument and comparison of the previous - * futex value with another constant. - * - * @op: operation to execute - * @oparg: argument to operation - * @oval: old value at uaddr - * @uaddr: pointer to user space address - * - * Return: - * 0 - On success - * -EFAULT - User access resulted in a page fault - * -EAGAIN - Atomic operation was unable to complete due to contention - * -ENOSYS - Operation not supported - */ - int arch_futex_atomic_op_inuser(int op, u32 oparg, int *oval, u32 __user *uaddr) { - int oldval, ret; - struct page *page; unsigned long addr = (unsigned long) uaddr; + u32 *p, oldval, newval; + struct page *page; pte_t *pte; - ret = -EFAULT; if (!access_ok(uaddr, sizeof(*uaddr))) return -EFAULT; + + switch (op) { + case FUTEX_OP_SET: + case FUTEX_OP_ADD: + case FUTEX_OP_OR: + case FUTEX_OP_ANDN: + case FUTEX_OP_XOR: + break; + default: + return -ENOSYS; + } + preempt_disable(); pte = maybe_map(addr, 1); - if (pte == NULL) - goto out_inuser; + if (pte == NULL) { + preempt_enable(); + return -EFAULT; + } page = pte_page(*pte); #ifdef CONFIG_64BIT pagefault_disable(); - addr = (unsigned long) page_address(page) + - (((unsigned long) addr) & ~PAGE_MASK); + p = page_address(page) + (addr & ~PAGE_MASK); #else - addr = (unsigned long) kmap_atomic(page) + - ((unsigned long) addr & ~PAGE_MASK); + p = kmap_atomic(page) + (addr & ~PAGE_MASK); #endif - uaddr = (u32 *) addr; - oldval = *uaddr; - ret = 0; + do { + oldval = READ_ONCE(*p); - switch (op) { - case FUTEX_OP_SET: - *uaddr = oparg; - break; - case FUTEX_OP_ADD: - *uaddr += oparg; - break; - case FUTEX_OP_OR: - *uaddr |= oparg; - break; - case FUTEX_OP_ANDN: - *uaddr &= ~oparg; - break; - case FUTEX_OP_XOR: - *uaddr ^= oparg; - break; - default: - ret = -ENOSYS; - } + switch (op) { + case FUTEX_OP_SET: + newval = oparg; + break; + case FUTEX_OP_ADD: + newval = oldval + oparg; + break; + case FUTEX_OP_OR: + newval = oldval | oparg; + break; + case FUTEX_OP_ANDN: + newval = oldval & ~oparg; + break; + case FUTEX_OP_XOR: + newval = oldval ^ oparg; + break; + } + } while (!try_cmpxchg(p, &oldval, newval)); + + *oval = oldval; + #ifdef CONFIG_64BIT pagefault_enable(); #else kunmap_atomic((void *)addr); #endif - -out_inuser: preempt_enable(); - - if (ret == 0) - *oval = oldval; - - return ret; + return 0; } -EXPORT_SYMBOL(arch_futex_atomic_op_inuser); - -/** - * futex_atomic_cmpxchg_inatomic() - Compare and exchange the content of the - * uaddr with newval if the current value is - * oldval. - * @uval: pointer to store content of @uaddr - * @uaddr: pointer to user space address - * @oldval: old value - * @newval: new value to store to @uaddr - * - * Return: - * 0 - On success - * -EFAULT - User access resulted in a page fault - * -EAGAIN - Atomic operation was unable to complete due to contention - */ int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, - u32 oldval, u32 newval) + u32 oldval, u32 newval) { struct page *page; pte_t *pte; - int ret = -EFAULT; if (!access_ok(uaddr, sizeof(*uaddr))) return -EFAULT; preempt_disable(); pte = maybe_map((unsigned long) uaddr, 1); - if (pte == NULL) - goto out_inatomic; + if (pte == NULL) { + preempt_enable(); + return -EFAULT; + } page = pte_page(*pte); #ifdef CONFIG_64BIT @@ -350,19 +324,13 @@ int futex_atomic_cmpxchg_inatomic(u32 *uval, u32 __user *uaddr, uaddr = kmap_atomic(page) + ((unsigned long) uaddr & ~PAGE_MASK); #endif - *uval = *uaddr; - - ret = cmpxchg(uaddr, oldval, newval); + *uval = cmpxchg(uaddr, oldval, newval); #ifdef CONFIG_64BIT pagefault_enable(); #else kunmap_atomic(uaddr); #endif - ret = 0; - -out_inatomic: preempt_enable(); - return ret; + return 0; } -EXPORT_SYMBOL(futex_atomic_cmpxchg_inatomic);
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c index f1e52b7..92ea1be 100644 --- a/arch/um/kernel/smp.c +++ b/arch/um/kernel/smp.c
@@ -20,6 +20,7 @@ #include <init.h> #include <kern.h> #include <os.h> +#include <skas.h> #include <smp.h> enum { @@ -66,7 +67,7 @@ static void ipi_handler(int vector, struct uml_pt_regs *regs) irq_enter(); if (current->mm) - os_alarm_process(current->mm->context.id.pid); + os_alarm_process(current_mm_id()->pid); switch (vector) { case UML_IPI_RES:
diff --git a/arch/um/kernel/sysrq.c b/arch/um/kernel/sysrq.c index 13ee566..5a2c28e 100644 --- a/arch/um/kernel/sysrq.c +++ b/arch/um/kernel/sysrq.c
@@ -18,7 +18,7 @@ static void _print_addr(void *data, unsigned long address, int reliable) { const char *loglvl = data; - printk("%s [<%08lx>] %s%pS\n", loglvl, address, reliable ? "" : "? ", + printk("%s [<%08lx>] %s%pB\n", loglvl, address, reliable ? "" : "? ", (void *)address); }
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c index b344a36..d620b6d 100644 --- a/arch/um/kernel/time.c +++ b/arch/um/kernel/time.c
@@ -19,6 +19,7 @@ #include <asm/param.h> #include <kern_util.h> #include <os.h> +#include <skas.h> #include <linux/delay.h> #include <linux/time-internal.h> #include <linux/um_timetravel.h> @@ -873,7 +874,7 @@ static irqreturn_t um_timer(int irq, void *dev) if (time_travel_mode != TT_MODE_INFCPU && time_travel_mode != TT_MODE_EXTERNAL && get_current()->mm) - os_alarm_process(get_current()->mm->context.id.pid); + os_alarm_process(current_mm_id()->pid); evt->event_handler(evt);
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c index 1f17571..012bcc7 100644 --- a/arch/um/kernel/tlb.c +++ b/arch/um/kernel/tlb.c
@@ -40,13 +40,6 @@ static int kern_unmap(struct mm_id *mm_idp, return os_unmap_memory((void *)virt, len); } -void report_enomem(void) -{ - printk(KERN_ERR "UML ran out of memory on the host side! " - "This can happen due to a memory limitation or " - "vm.max_map_count has been reached.\n"); -} - static inline int update_pte_range(pmd_t *pmd, unsigned long addr, unsigned long end, struct vm_ops *ops)
diff --git a/arch/um/kernel/trap-mmu.c b/arch/um/kernel/trap-mmu.c new file mode 100644 index 0000000..467c100 --- /dev/null +++ b/arch/um/kernel/trap-mmu.c
@@ -0,0 +1,237 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) + */ + +#include <linux/mm.h> +#include <linux/sched/signal.h> +#include <linux/hardirq.h> +#include <linux/module.h> +#include <linux/uaccess.h> +#include <linux/sched/debug.h> +#include <asm/current.h> +#include <asm/tlbflush.h> +#include <arch.h> +#include <as-layout.h> +#include <kern_util.h> +#include <os.h> +#include <skas.h> + +/* + * NOTE: UML does not have exception tables. As such, this is almost a copy + * of the code in mm/memory.c, only adjusting the logic to simply check whether + * we are coming from the kernel instead of doing an additional lookup in the + * exception table. + * We can do this simplification because we never get here if the exception was + * fixable. + */ +static inline bool get_mmap_lock_carefully(struct mm_struct *mm, bool is_user) +{ + if (likely(mmap_read_trylock(mm))) + return true; + + if (!is_user) + return false; + + return !mmap_read_lock_killable(mm); +} + +static inline bool mmap_upgrade_trylock(struct mm_struct *mm) +{ + /* + * We don't have this operation yet. + * + * It should be easy enough to do: it's basically a + * atomic_long_try_cmpxchg_acquire() + * from RWSEM_READER_BIAS -> RWSEM_WRITER_LOCKED, but + * it also needs the proper lockdep magic etc. + */ + return false; +} + +static inline bool upgrade_mmap_lock_carefully(struct mm_struct *mm, bool is_user) +{ + mmap_read_unlock(mm); + if (!is_user) + return false; + + return !mmap_write_lock_killable(mm); +} + +/* + * Helper for page fault handling. + * + * This is kind of equivalend to "mmap_read_lock()" followed + * by "find_extend_vma()", except it's a lot more careful about + * the locking (and will drop the lock on failure). + * + * For example, if we have a kernel bug that causes a page + * fault, we don't want to just use mmap_read_lock() to get + * the mm lock, because that would deadlock if the bug were + * to happen while we're holding the mm lock for writing. + * + * So this checks the exception tables on kernel faults in + * order to only do this all for instructions that are actually + * expected to fault. + * + * We can also actually take the mm lock for writing if we + * need to extend the vma, which helps the VM layer a lot. + */ +static struct vm_area_struct * +um_lock_mm_and_find_vma(struct mm_struct *mm, + unsigned long addr, bool is_user) +{ + struct vm_area_struct *vma; + + if (!get_mmap_lock_carefully(mm, is_user)) + return NULL; + + vma = find_vma(mm, addr); + if (likely(vma && (vma->vm_start <= addr))) + return vma; + + /* + * Well, dang. We might still be successful, but only + * if we can extend a vma to do so. + */ + if (!vma || !(vma->vm_flags & VM_GROWSDOWN)) { + mmap_read_unlock(mm); + return NULL; + } + + /* + * We can try to upgrade the mmap lock atomically, + * in which case we can continue to use the vma + * we already looked up. + * + * Otherwise we'll have to drop the mmap lock and + * re-take it, and also look up the vma again, + * re-checking it. + */ + if (!mmap_upgrade_trylock(mm)) { + if (!upgrade_mmap_lock_carefully(mm, is_user)) + return NULL; + + vma = find_vma(mm, addr); + if (!vma) + goto fail; + if (vma->vm_start <= addr) + goto success; + if (!(vma->vm_flags & VM_GROWSDOWN)) + goto fail; + } + + if (expand_stack_locked(vma, addr)) + goto fail; + +success: + mmap_write_downgrade(mm); + return vma; + +fail: + mmap_write_unlock(mm); + return NULL; +} + +/* + * Note this is constrained to return 0, -EFAULT, -EACCES, -ENOMEM by + * segv(). + */ +int handle_page_fault(unsigned long address, unsigned long ip, + int is_write, int is_user, int *code_out) +{ + struct mm_struct *mm = current->mm; + struct vm_area_struct *vma; + pmd_t *pmd; + pte_t *pte; + int err = -EFAULT; + unsigned int flags = FAULT_FLAG_DEFAULT; + + *code_out = SEGV_MAPERR; + + /* + * If the fault was with pagefaults disabled, don't take the fault, just + * fail. + */ + if (faulthandler_disabled()) + goto out_nosemaphore; + + if (is_user) + flags |= FAULT_FLAG_USER; +retry: + vma = um_lock_mm_and_find_vma(mm, address, is_user); + if (!vma) + goto out_nosemaphore; + + *code_out = SEGV_ACCERR; + if (is_write) { + if (!(vma->vm_flags & VM_WRITE)) + goto out; + flags |= FAULT_FLAG_WRITE; + } else { + /* Don't require VM_READ|VM_EXEC for write faults! */ + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) + goto out; + } + + do { + vm_fault_t fault; + + fault = handle_mm_fault(vma, address, flags, NULL); + + if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) + goto out_nosemaphore; + + /* The fault is fully completed (including releasing mmap lock) */ + if (fault & VM_FAULT_COMPLETED) + return 0; + + if (unlikely(fault & VM_FAULT_ERROR)) { + if (fault & VM_FAULT_OOM) { + goto out_of_memory; + } else if (fault & VM_FAULT_SIGSEGV) { + goto out; + } else if (fault & VM_FAULT_SIGBUS) { + err = -EACCES; + goto out; + } + BUG(); + } + if (fault & VM_FAULT_RETRY) { + flags |= FAULT_FLAG_TRIED; + + goto retry; + } + + pmd = pmd_off(mm, address); + pte = pte_offset_kernel(pmd, address); + } while (!pte_present(*pte)); + err = 0; + /* + * The below warning was added in place of + * pte_mkyoung(); if (is_write) pte_mkdirty(); + * If it's triggered, we'd see normally a hang here (a clean pte is + * marked read-only to emulate the dirty bit). + * However, the generic code can mark a PTE writable but clean on a + * concurrent read fault, triggering this harmlessly. So comment it out. + */ +#if 0 + WARN_ON(!pte_young(*pte) || (is_write && !pte_dirty(*pte))); +#endif + +out: + mmap_read_unlock(mm); +out_nosemaphore: + return err; + +out_of_memory: + /* + * We ran out of memory, call the OOM killer, and return the userspace + * (which will retry the fault, or kill us if we got oom-killed). + */ + mmap_read_unlock(mm); + if (!is_user) + goto out_nosemaphore; + pagefault_out_of_memory(); + return 0; +}
diff --git a/arch/um/kernel/trap-nommu.c b/arch/um/kernel/trap-nommu.c new file mode 100644 index 0000000..891a9ce --- /dev/null +++ b/arch/um/kernel/trap-nommu.c
@@ -0,0 +1,13 @@ +// SPDX-License-Identifier: GPL-2.0 +#include <linux/types.h> +#include <linux/errno.h> +#include <linux/signal.h> +#include <shared/kern_util.h> + +int handle_page_fault(unsigned long address, unsigned long ip, + int is_write, int is_user, int *code_out) +{ + /* everything that's valid is already mapped in NOMMU */ + *code_out = SEGV_MAPERR; + return -EFAULT; +}
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c index 1776158..ab60bab 100644 --- a/arch/um/kernel/trap.c +++ b/arch/um/kernel/trap.c
@@ -17,225 +17,6 @@ #include <os.h> #include <skas.h> -/* - * NOTE: UML does not have exception tables. As such, this is almost a copy - * of the code in mm/memory.c, only adjusting the logic to simply check whether - * we are coming from the kernel instead of doing an additional lookup in the - * exception table. - * We can do this simplification because we never get here if the exception was - * fixable. - */ -static inline bool get_mmap_lock_carefully(struct mm_struct *mm, bool is_user) -{ - if (likely(mmap_read_trylock(mm))) - return true; - - if (!is_user) - return false; - - return !mmap_read_lock_killable(mm); -} - -static inline bool mmap_upgrade_trylock(struct mm_struct *mm) -{ - /* - * We don't have this operation yet. - * - * It should be easy enough to do: it's basically a - * atomic_long_try_cmpxchg_acquire() - * from RWSEM_READER_BIAS -> RWSEM_WRITER_LOCKED, but - * it also needs the proper lockdep magic etc. - */ - return false; -} - -static inline bool upgrade_mmap_lock_carefully(struct mm_struct *mm, bool is_user) -{ - mmap_read_unlock(mm); - if (!is_user) - return false; - - return !mmap_write_lock_killable(mm); -} - -/* - * Helper for page fault handling. - * - * This is kind of equivalend to "mmap_read_lock()" followed - * by "find_extend_vma()", except it's a lot more careful about - * the locking (and will drop the lock on failure). - * - * For example, if we have a kernel bug that causes a page - * fault, we don't want to just use mmap_read_lock() to get - * the mm lock, because that would deadlock if the bug were - * to happen while we're holding the mm lock for writing. - * - * So this checks the exception tables on kernel faults in - * order to only do this all for instructions that are actually - * expected to fault. - * - * We can also actually take the mm lock for writing if we - * need to extend the vma, which helps the VM layer a lot. - */ -static struct vm_area_struct * -um_lock_mm_and_find_vma(struct mm_struct *mm, - unsigned long addr, bool is_user) -{ - struct vm_area_struct *vma; - - if (!get_mmap_lock_carefully(mm, is_user)) - return NULL; - - vma = find_vma(mm, addr); - if (likely(vma && (vma->vm_start <= addr))) - return vma; - - /* - * Well, dang. We might still be successful, but only - * if we can extend a vma to do so. - */ - if (!vma || !(vma->vm_flags & VM_GROWSDOWN)) { - mmap_read_unlock(mm); - return NULL; - } - - /* - * We can try to upgrade the mmap lock atomically, - * in which case we can continue to use the vma - * we already looked up. - * - * Otherwise we'll have to drop the mmap lock and - * re-take it, and also look up the vma again, - * re-checking it. - */ - if (!mmap_upgrade_trylock(mm)) { - if (!upgrade_mmap_lock_carefully(mm, is_user)) - return NULL; - - vma = find_vma(mm, addr); - if (!vma) - goto fail; - if (vma->vm_start <= addr) - goto success; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto fail; - } - - if (expand_stack_locked(vma, addr)) - goto fail; - -success: - mmap_write_downgrade(mm); - return vma; - -fail: - mmap_write_unlock(mm); - return NULL; -} - -/* - * Note this is constrained to return 0, -EFAULT, -EACCES, -ENOMEM by - * segv(). - */ -int handle_page_fault(unsigned long address, unsigned long ip, - int is_write, int is_user, int *code_out) -{ - struct mm_struct *mm = current->mm; - struct vm_area_struct *vma; - pmd_t *pmd; - pte_t *pte; - int err = -EFAULT; - unsigned int flags = FAULT_FLAG_DEFAULT; - - *code_out = SEGV_MAPERR; - - /* - * If the fault was with pagefaults disabled, don't take the fault, just - * fail. - */ - if (faulthandler_disabled()) - goto out_nosemaphore; - - if (is_user) - flags |= FAULT_FLAG_USER; -retry: - vma = um_lock_mm_and_find_vma(mm, address, is_user); - if (!vma) - goto out_nosemaphore; - - *code_out = SEGV_ACCERR; - if (is_write) { - if (!(vma->vm_flags & VM_WRITE)) - goto out; - flags |= FAULT_FLAG_WRITE; - } else { - /* Don't require VM_READ|VM_EXEC for write faults! */ - if (!(vma->vm_flags & (VM_READ | VM_EXEC))) - goto out; - } - - do { - vm_fault_t fault; - - fault = handle_mm_fault(vma, address, flags, NULL); - - if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) - goto out_nosemaphore; - - /* The fault is fully completed (including releasing mmap lock) */ - if (fault & VM_FAULT_COMPLETED) - return 0; - - if (unlikely(fault & VM_FAULT_ERROR)) { - if (fault & VM_FAULT_OOM) { - goto out_of_memory; - } else if (fault & VM_FAULT_SIGSEGV) { - goto out; - } else if (fault & VM_FAULT_SIGBUS) { - err = -EACCES; - goto out; - } - BUG(); - } - if (fault & VM_FAULT_RETRY) { - flags |= FAULT_FLAG_TRIED; - - goto retry; - } - - pmd = pmd_off(mm, address); - pte = pte_offset_kernel(pmd, address); - } while (!pte_present(*pte)); - err = 0; - /* - * The below warning was added in place of - * pte_mkyoung(); if (is_write) pte_mkdirty(); - * If it's triggered, we'd see normally a hang here (a clean pte is - * marked read-only to emulate the dirty bit). - * However, the generic code can mark a PTE writable but clean on a - * concurrent read fault, triggering this harmlessly. So comment it out. - */ -#if 0 - WARN_ON(!pte_young(*pte) || (is_write && !pte_dirty(*pte))); -#endif - -out: - mmap_read_unlock(mm); -out_nosemaphore: - return err; - -out_of_memory: - /* - * We ran out of memory, call the OOM killer, and return the userspace - * (which will retry the fault, or kill us if we got oom-killed). - */ - mmap_read_unlock(mm); - if (!is_user) - goto out_nosemaphore; - pagefault_out_of_memory(); - return 0; -} - static void show_segv_info(struct uml_pt_regs *regs) { struct task_struct *tsk = current;
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c index 9d53cc6..c3f83e8 100644 --- a/arch/um/kernel/um_arch.c +++ b/arch/um/kernel/um_arch.c
@@ -44,7 +44,12 @@ static char __initdata command_line[COMMAND_LINE_SIZE] = { 0 }; static void __init add_arg(char *arg) { - if (strlen(command_line) + strlen(arg) + 1 > COMMAND_LINE_SIZE) { + size_t len = strlen(command_line) + strlen(arg) + 1; + + if (command_line[0]) + len++; + + if (len > COMMAND_LINE_SIZE) { os_warn("add_arg: Too many command line arguments!\n"); exit(1); } @@ -379,7 +384,7 @@ static unsigned long __init get_top_address(char **envp) return PAGE_ALIGN(top_addr + 1); } -int __init linux_main(int argc, char **argv, char **envp) +void __init linux_main(int argc, char **argv, char **envp) { unsigned long avail, diff; unsigned long virtmem_size, max_physmem; @@ -472,7 +477,7 @@ int __init linux_main(int argc, char **argv, char **envp) os_flush_stdout(); - return start_uml(); + start_uml(); } int __init __weak read_initrd(void)
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S index 30aa2434..f6e1001 100644 --- a/arch/um/kernel/uml.lds.S +++ b/arch/um/kernel/uml.lds.S
@@ -28,8 +28,13 @@ . = ALIGN(PAGE_SIZE); _text = .; + __init_begin = .; INIT_TEXT_SECTION(0) + init.data : { INIT_DATA } + . = ALIGN(PAGE_SIZE); + __init_end = .; + .text : { _stext = .; @@ -70,14 +75,11 @@ #include <asm/common.lds.S> - __init_begin = .; - init.data : { INIT_DATA } - __init_end = .; - .data : { INIT_TASK_DATA(KERNEL_STACK_SIZE) DATA_DATA + *(.ldata .ldata.[0-9a-zA-Z_]* .ldata..L*) *(.gnu.linkonce.d*) CONSTRUCTORS } @@ -107,6 +109,7 @@ PROVIDE(_bss_start = .); SBSS(0) BSS(0) + .lbss : { *(.lbss .lbss.[0-9a-zA-Z_]* .lbss..L*) } __bss_stop = .; _end = .; PROVIDE (end = .);
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c index 7e11486..ea41188 100644 --- a/arch/um/os-Linux/main.c +++ b/arch/um/os-Linux/main.c
@@ -100,10 +100,11 @@ static void __init setup_env_path(void) } } +static char **new_argv; + int __init main(int argc, char **argv, char **envp) { - char **new_argv; - int ret, i, err; + int ret, i; /* Disable randomization and re-exec if it was changed successfully */ ret = personality(PER_LINUX | ADDR_NO_RANDOMIZE); @@ -150,7 +151,12 @@ int __init main(int argc, char **argv, char **envp) scan_elf_aux(envp); change_sig(SIGPIPE, 0); - ret = linux_main(argc, argv, envp); + linux_main(argc, argv, envp); +} + +void os_exit(bool reboot) +{ + int err; /* * Disable SIGPROF - I have no idea why libc doesn't do this or turn @@ -183,12 +189,11 @@ int __init main(int argc, char **argv, char **envp) os_info("\n"); /* Reboot */ - if (ret) { + if (reboot) { execvp(new_argv[0], new_argv); perror("Failed to exec kernel"); - ret = 1; } - return uml_exitcode; + exit(uml_exitcode); } extern void *__real_malloc(int);
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c index 6c993bc..57f0a5e 100644 --- a/arch/um/os-Linux/signal.c +++ b/arch/um/os-Linux/signal.c
@@ -453,7 +453,7 @@ void unblock_signals_hard(void) * call _within_ e.g. vu_req_read_message(), where we observed this * issue, which loops. Thus, if the inner call handles the recorded * pending signals, we can get out of the inner call with the real - * signal hander no longer blocked, and still have a race. Thus don't + * signal handler no longer blocked, and still have a race. Thus don't * handle unblocking in the inner call, if it happens, but only in * the outermost call - 'unblocking' serves as an ownership for the * signals_blocked_pending decrement.
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c index d6c22f8..bca05a5 100644 --- a/arch/um/os-Linux/skas/process.c +++ b/arch/um/os-Linux/skas/process.c
@@ -816,7 +816,7 @@ static __thread void (*cb_proc)(void *arg); static __thread void *cb_arg; static __thread jmp_buf *cb_back; -int start_idle_thread(void *stack, jmp_buf *switch_buf) +void start_idle_thread(void *stack, jmp_buf *switch_buf) { int n; @@ -843,21 +843,16 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf) break; case INIT_JMP_HALT: kmalloc_ok = 0; - return 0; + os_exit(false); case INIT_JMP_REBOOT: kmalloc_ok = 0; - return 1; + os_exit(true); default: printk(UM_KERN_ERR "Bad sigsetjmp return in %s - %d\n", __func__, n); fatal_sigsegv(); } longjmp(*switch_buf, 1); - - /* unreachable */ - printk(UM_KERN_ERR "impossible long jump!"); - fatal_sigsegv(); - return 0; } void initial_thread_cb_skas(void (*proc)(void *), void *arg)
diff --git a/arch/x86/um/Makefile b/arch/x86/um/Makefile index f9ea75b..100b68f 100644 --- a/arch/x86/um/Makefile +++ b/arch/x86/um/Makefile
@@ -47,4 +47,7 @@ UNPROFILE_OBJS := stub_segv.o CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) +# see arch/um/kernel/skas/Makefile - this goes into the stub +CFLAGS_stub_segv.o += $(call cc-option, -ftrivial-auto-var-init=uninitialized) + include $(srctree)/arch/um/scripts/Makefile.rules
diff --git a/arch/x86/um/asm/elf.h b/arch/x86/um/asm/elf.h index 22d0111..388fe66 100644 --- a/arch/x86/um/asm/elf.h +++ b/arch/x86/um/asm/elf.h
@@ -9,6 +9,7 @@ #include <skas.h> #define CORE_DUMP_USE_REGSET +#define ELF_FDPIC_CORE_EFLAGS 0 #ifdef CONFIG_X86_32 @@ -158,8 +159,11 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm, extern unsigned long um_vdso_addr; #define AT_SYSINFO_EHDR 33 -#define ARCH_DLINFO NEW_AUX_ENT(AT_SYSINFO_EHDR, um_vdso_addr) - +#define ARCH_DLINFO \ +do { \ + NEW_AUX_ENT(AT_SYSINFO_EHDR, um_vdso_addr); \ + NEW_AUX_ENT(AT_MINSIGSTKSZ, 0); \ +} while (0) #endif typedef unsigned long elf_greg_t;
diff --git a/arch/x86/um/vdso/vma.c b/arch/x86/um/vdso/vma.c index 51a2b9f..8e1f5ee 100644 --- a/arch/x86/um/vdso/vma.c +++ b/arch/x86/um/vdso/vma.c
@@ -9,6 +9,7 @@ #include <asm/page.h> #include <asm/elf.h> #include <linux/init.h> +#include <os.h> unsigned long um_vdso_addr; static struct page *um_vdso; @@ -20,18 +21,25 @@ static int __init init_vdso(void) { BUG_ON(vdso_end - vdso_start > PAGE_SIZE); - um_vdso_addr = task_size - PAGE_SIZE; - um_vdso = alloc_page(GFP_KERNEL); if (!um_vdso) panic("Cannot allocate vdso\n"); copy_page(page_address(um_vdso), vdso_start); +#ifdef CONFIG_MMU + um_vdso_addr = task_size - PAGE_SIZE; +#else + /* this is fine with NOMMU as everything is accessible */ + um_vdso_addr = (unsigned long)page_address(um_vdso); + os_protect_memory((void *)um_vdso_addr, vdso_end - vdso_start, 1, 0, 1); +#endif + return 0; } subsys_initcall(init_vdso); +#ifdef CONFIG_MMU int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) { struct vm_area_struct *vma; @@ -53,3 +61,4 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int uses_interp) return IS_ERR(vma) ? PTR_ERR(vma) : 0; } +#endif /* CONFIG_MMU */
diff --git a/block/blk-cgroup.c b/block/blk-cgroup.c index b56db1c..82b6614 100644 --- a/block/blk-cgroup.c +++ b/block/blk-cgroup.c
@@ -1189,10 +1189,17 @@ static int blkcg_print_stat(struct seq_file *sf, void *v) struct blkcg *blkcg = css_to_blkcg(seq_css(sf)); struct blkcg_gq *blkg; - if (!seq_css(sf)->parent) + if (!seq_css(sf)->parent) { blkcg_fill_root_iostats(); - else + } else { + /* + * Descendant blkgs imply ancestor blkgs, so an empty + * ->blkg_list has no stats to report. + */ + if (hlist_empty(&blkcg->blkg_list)) + return 0; css_rstat_flush(&blkcg->css); + } guard(spinlock_irq)(&blkcg->lock); hlist_for_each_entry(blkg, &blkcg->blkg_list, blkcg_node)
diff --git a/crypto/algapi.c b/crypto/algapi.c index 37de377..a6839e2 100644 --- a/crypto/algapi.c +++ b/crypto/algapi.c
@@ -424,7 +424,6 @@ static void crypto_free_alg(struct crypto_alg *alg) unsigned int algsize = alg->cra_type->algsize; u8 *p = (u8 *)alg - algsize; - crypto_destroy_alg(alg); kfree(p); } @@ -494,9 +493,31 @@ void crypto_unregister_alg(struct crypto_alg *alg) LIST_HEAD(list); down_write(&crypto_alg_sem); + if (alg->cra_flags & CRYPTO_ALG_DUP_FIRST) { + struct crypto_alg *q, *r = NULL; + + list_for_each_entry(q, &crypto_alg_list, cra_list) { + if (crypto_is_larval(q)) + continue; + if (strcmp(q->cra_driver_name, alg->cra_driver_name)) + continue; + r = q; + break; + } + + if (!r) { + up_write(&crypto_alg_sem); + ret = -ENOENT; + goto not_found; + } + + alg = r; + } + ret = crypto_remove_alg(alg, &list); up_write(&crypto_alg_sem); +not_found: if (WARN(ret, "Algorithm %s is not registered", alg->cra_driver_name)) return;
diff --git a/crypto/algif_hash.c b/crypto/algif_hash.c index 6e8b5fb..0d3ec57 100644 --- a/crypto/algif_hash.c +++ b/crypto/algif_hash.c
@@ -23,7 +23,7 @@ static const struct af_alg_allowlist_entry hash_allowlist[] = { { "hmac(sha224)" }, /* iwd */ { "hmac(sha256)" }, /* iwd */ { "hmac(sha384)" }, /* iwd */ - { "hmac(sha512)" }, /* iwd, sha512hmac */ + { "hmac(sha512)", AF_ALG_UNPRIVILEGED }, /* iwd, sha512hmac */ { "md4" }, /* iwd */ { "md5" }, /* iwd */ { "sha1", AF_ALG_UNPRIVILEGED }, /* iwd, iproute2 < 7.0 */
diff --git a/crypto/algif_skcipher.c b/crypto/algif_skcipher.c index 1e61fe6..291dbd6 100644 --- a/crypto/algif_skcipher.c +++ b/crypto/algif_skcipher.c
@@ -135,12 +135,16 @@ static int _skcipher_recvmsg(struct socket *sock, struct msghdr *msg, * full block size buffers. */ if (ctx->more || len < ctx->used) { - if (len < bs) { + size_t excess = len % bs; + + len -= excess; + iov_iter_revert(&msg->msg_iter, excess); + + if (!len) { err = -EINVAL; goto free; } - len -= len % bs; cflags |= CRYPTO_SKCIPHER_REQ_NOTFINAL; }
diff --git a/crypto/asymmetric_keys/Kconfig b/crypto/asymmetric_keys/Kconfig index 6a2f664..c73979b 100644 --- a/crypto/asymmetric_keys/Kconfig +++ b/crypto/asymmetric_keys/Kconfig
@@ -114,4 +114,16 @@ depends on CRYPTO_SHA256=y || CRYPTO_SHA256=FIPS_SIGNATURE_SELFTEST depends on CRYPTO_ECDSA=y || CRYPTO_ECDSA=FIPS_SIGNATURE_SELFTEST +config VERIFY_PEFILE_KUNIT_TEST + bool "KUnit tests for signed PE file parsing" if !KUNIT_ALL_TESTS + depends on KUNIT=y && SIGNED_PE_FILE_VERIFICATION + default KUNIT_ALL_TESTS + help + Enable KUnit tests for the PE binary parser used by signed PE file + signature verification. The tests build small malformed PE images in + memory and check that pefile_parse_binary() rejects them instead of + reading out of bounds. + + If unsure, say N. + endif # ASYMMETRIC_KEY_TYPE
diff --git a/crypto/asymmetric_keys/Makefile b/crypto/asymmetric_keys/Makefile index bc65d3b..3517268 100644 --- a/crypto/asymmetric_keys/Makefile +++ b/crypto/asymmetric_keys/Makefile
@@ -79,3 +79,5 @@ $(obj)/mscode_parser.o: $(obj)/mscode.asn1.h $(obj)/mscode.asn1.h $(obj)/mscode.asn1.o: $(obj)/mscode.asn1.c $(obj)/mscode.asn1.h + +obj-$(CONFIG_VERIFY_PEFILE_KUNIT_TEST) += verify_pefile_test.o
diff --git a/crypto/asymmetric_keys/pkcs7_parser.c b/crypto/asymmetric_keys/pkcs7_parser.c index 6e3ffda..7f00e45 100644 --- a/crypto/asymmetric_keys/pkcs7_parser.c +++ b/crypto/asymmetric_keys/pkcs7_parser.c
@@ -111,6 +111,12 @@ static int pkcs7_check_authattrs(struct pkcs7_message *msg) if (!!sinfo->authattrs != want) goto inconsistent; +#ifdef CONFIG_PKCS7_WAIVE_AUTHATTRS_REJECTION_FOR_MLDSA + if (sinfo->authattrs && + strncmp(sinfo->sig->pkey_algo, "mldsa", 5) != 0) + msg->authattrs_rej_waivable = false; +#endif + if (!sinfo->authattrs && sinfo->sig->algo_takes_data) sinfo->sig->hash_algo = "none";
diff --git a/crypto/asymmetric_keys/restrict.c b/crypto/asymmetric_keys/restrict.c index 8629296..0e4783f 100644 --- a/crypto/asymmetric_keys/restrict.c +++ b/crypto/asymmetric_keys/restrict.c
@@ -243,10 +243,14 @@ static int key_or_keyring_common(struct key *dest_keyring, if (IS_ERR(key)) key = NULL; } else if (trusted->type == &key_type_asymmetric) { + const struct asymmetric_key_ids *kids; const struct asymmetric_key_id **signer_ids; - signer_ids = (const struct asymmetric_key_id **) - asymmetric_key_ids(trusted)->id; + kids = asymmetric_key_ids(trusted); + if (!kids) + return -ENOKEY; + + signer_ids = (const struct asymmetric_key_id **)kids->id; /* * The auth_ids come from the candidate key (the
diff --git a/crypto/asymmetric_keys/verify_pefile.c b/crypto/asymmetric_keys/verify_pefile.c index cec99db..1efd5c0 100644 --- a/crypto/asymmetric_keys/verify_pefile.c +++ b/crypto/asymmetric_keys/verify_pefile.c
@@ -87,6 +87,11 @@ static int pefile_parse_binary(const void *pebuf, unsigned int pelen, if (ctx->n_data_dirents > (ctx->header_size - cursor) / sizeof(*dde)) return -ELIBBAD; + /* the certificate table entry must be present in the data directory */ + if (ctx->n_data_dirents <= + offsetof(struct data_directory, certs) / sizeof(*dde)) + return -ELIBBAD; + ddir = pebuf + cursor; cursor += sizeof(*dde) * ctx->n_data_dirents;
diff --git a/crypto/asymmetric_keys/verify_pefile_test.c b/crypto/asymmetric_keys/verify_pefile_test.c new file mode 100644 index 0000000..8b42eb4 --- /dev/null +++ b/crypto/asymmetric_keys/verify_pefile_test.c
@@ -0,0 +1,100 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * KUnit tests for the signed PE binary parser in verify_pefile.c. + * + * The cases build small malformed PE images in memory and call + * verify_pefile_signature(), which parses the image before any signature + * check, so the parser is exercised without a keyring or a real signature. + */ +#include <kunit/test.h> +#include <linux/slab.h> +#include <linux/pe.h> +#include <linux/verification.h> + +/* + * Build a minimal PE32 image whose optional header declares @data_dirs data + * directory entries. header_size is sized to hold them and the image is a few + * bytes larger. With @data_dirs < 5 the certificate table entry (fixed index + * 4) lies outside the declared directory. + */ +static void *build_pe32(u16 data_dirs, unsigned int *out_len) +{ + size_t cursor = sizeof(struct mz_hdr) + sizeof(struct pe_hdr) + + sizeof(struct pe32_opt_hdr); + size_t header_size = cursor + ((size_t)data_dirs + 1) * + sizeof(struct data_dirent); + size_t pelen = header_size + 8; + struct mz_hdr *mz; + struct pe_hdr *pe; + struct pe32_opt_hdr *opt; + void *buf = kzalloc(pelen, GFP_KERNEL); + + if (!buf) + return NULL; + + mz = buf; + mz->magic = IMAGE_DOS_SIGNATURE; + mz->peaddr = sizeof(struct mz_hdr); + + pe = buf + sizeof(struct mz_hdr); + pe->magic = IMAGE_NT_SIGNATURE; + + opt = buf + sizeof(struct mz_hdr) + sizeof(struct pe_hdr); + opt->magic = IMAGE_NT_OPTIONAL_HDR32_MAGIC; + opt->header_size = header_size; + opt->data_dirs = data_dirs; + + *out_len = pelen; + return buf; +} + +/* + * data_dirs = 0: the certificate table entry (index 4) is absent, so the + * parser must reject the image instead of reading ddir->certs past the end. + */ +static void pefile_missing_certs_dirent(struct kunit *test) +{ + unsigned int len; + void *buf = build_pe32(0, &len); + int ret; + + KUNIT_ASSERT_NOT_NULL(test, buf); + ret = verify_pefile_signature(buf, len, NULL, + VERIFYING_KEXEC_PE_SIGNATURE); + KUNIT_EXPECT_EQ(test, ret, -ELIBBAD); + kfree(buf); +} + +/* + * data_dirs = 5: the certificate table entry is present (and zero, i.e. + * unsigned), so the parser gets past the directory bound and rejects the image + * as unsigned (-ENODATA) rather than -ELIBBAD. + */ +static void pefile_present_certs_dirent(struct kunit *test) +{ + unsigned int len; + void *buf = build_pe32(5, &len); + int ret; + + KUNIT_ASSERT_NOT_NULL(test, buf); + ret = verify_pefile_signature(buf, len, NULL, + VERIFYING_KEXEC_PE_SIGNATURE); + KUNIT_EXPECT_EQ(test, ret, -ENODATA); + kfree(buf); +} + +static struct kunit_case verify_pefile_cases[] = { + KUNIT_CASE(pefile_missing_certs_dirent), + KUNIT_CASE(pefile_present_certs_dirent), + {} +}; + +static struct kunit_suite verify_pefile_suite = { + .name = "verify_pefile", + .test_cases = verify_pefile_cases, +}; + +kunit_test_suite(verify_pefile_suite); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("KUnit tests for the signed PE binary parser");
diff --git a/crypto/asymmetric_keys/x509_public_key.c b/crypto/asymmetric_keys/x509_public_key.c index 25cf8ac..5c9165a 100644 --- a/crypto/asymmetric_keys/x509_public_key.c +++ b/crypto/asymmetric_keys/x509_public_key.c
@@ -53,9 +53,11 @@ int x509_get_sig_params(struct x509_certificate *cert) if (sig->algo_takes_data) { /* The signature algorithm does whatever passes for hashing. */ - sig->m = (u8 *)cert->tbs; + sig->m = kmemdup(cert->tbs, cert->tbs_size, GFP_KERNEL); + if (!sig->m) + return -ENOMEM; sig->m_size = cert->tbs_size; - sig->m_free = false; + sig->m_free = true; goto out; }
diff --git a/crypto/cast5_generic.c b/crypto/cast5_generic.c index f683307..1de0dc9 100644 --- a/crypto/cast5_generic.c +++ b/crypto/cast5_generic.c
@@ -483,9 +483,7 @@ int cast5_setkey(struct crypto_tfm *tfm, const u8 *key, unsigned int key_len) c->rr = key_len <= 10 ? 1 : 0; - memset(p_key, 0, 16); - memcpy(p_key, key, key_len); - + memcpy_and_pad(p_key, sizeof(p_key), key, key_len, 0); x[0] = be32_to_cpu(p_key[0]); x[1] = be32_to_cpu(p_key[1]);
diff --git a/crypto/cast6_generic.c b/crypto/cast6_generic.c index 4c08c42..9b6bdd2 100644 --- a/crypto/cast6_generic.c +++ b/crypto/cast6_generic.c
@@ -112,8 +112,7 @@ int __cast6_setkey(struct cast6_ctx *c, const u8 *in_key, unsigned int key_len) if (key_len % 4 != 0) return -EINVAL; - memset(p_key, 0, 32); - memcpy(p_key, in_key, key_len); + memcpy_and_pad(p_key, sizeof(p_key), in_key, key_len, 0); key[0] = be32_to_cpu(p_key[0]); /* A */ key[1] = be32_to_cpu(p_key[1]); /* B */
diff --git a/crypto/ecc.c b/crypto/ecc.c index 3250a46..c7366eb 100644 --- a/crypto/ecc.c +++ b/crypto/ecc.c
@@ -1423,9 +1423,22 @@ static void ecc_point_add(const struct ecc_point *result, vli_set(result->x, q->x, ndigits); vli_set(result->y, q->y, ndigits); vli_mod_sub(z, result->x, p->x, curve->p, ndigits); + if (vli_is_zero(z, ndigits)) { + if (vli_cmp(p->y, q->y, ndigits)) { + /* P + (-P) is the point at infinity. */ + vli_clear(result->x, ndigits); + vli_clear(result->y, ndigits); + return; + } + /* The co-Z addition formula does not handle P == Q. */ + z[0] = 1; + ecc_point_double_jacobian(result->x, result->y, z, curve); + goto out; + } vli_set(px, p->x, ndigits); vli_set(py, p->y, ndigits); xycz_add(px, py, result->x, result->y, curve); +out: vli_mod_inv(z, z, curve->p, ndigits); apply_z(result->x, result->y, z, curve); } @@ -1465,22 +1478,38 @@ void ecc_point_mult_shamir(const struct ecc_point *result, vli_set(rx, point->x, ndigits); vli_set(ry, point->y, ndigits); vli_clear(z + 1, ndigits - 1); - z[0] = 1; + z[0] = !ecc_point_is_zero(point); for (--i; i >= 0; i--) { ecc_point_double_jacobian(rx, ry, z, curve); idx = !!vli_test_bit(u1, i); idx |= (!!vli_test_bit(u2, i)) << 1; point = points[idx]; - if (point) { + if (point && !ecc_point_is_zero(point)) { u64 tx[ECC_MAX_DIGITS]; u64 ty[ECC_MAX_DIGITS]; u64 tz[ECC_MAX_DIGITS]; + if (vli_is_zero(z, ndigits)) { + /* Adding to infinity starts a new accumulator. */ + vli_set(rx, point->x, ndigits); + vli_set(ry, point->y, ndigits); + z[0] = 1; + continue; + } vli_set(tx, point->x, ndigits); vli_set(ty, point->y, ndigits); apply_z(tx, ty, z, curve); vli_mod_sub(tz, rx, tx, curve->p, ndigits); + if (vli_is_zero(tz, ndigits)) { + if (!vli_cmp(ry, ty, ndigits)) + ecc_point_double_jacobian(rx, ry, z, + curve); + else + /* Adding opposite points yields infinity. */ + vli_clear(z, ndigits); + continue; + } xycz_add(tx, ty, rx, ry, curve); vli_mod_mult_fast(z, z, tz, curve); }
diff --git a/crypto/lskcipher.c b/crypto/lskcipher.c index a8b0759..6c30436 100644 --- a/crypto/lskcipher.c +++ b/crypto/lskcipher.c
@@ -75,6 +75,7 @@ static int crypto_lskcipher_crypt_unaligned( unsigned ivsize = crypto_lskcipher_ivsize(tfm); unsigned bs = crypto_lskcipher_blocksize(tfm); unsigned cs = crypto_lskcipher_chunksize(tfm); + u32 flags = 0; int err; u8 *tiv; u8 *p; @@ -98,13 +99,16 @@ static int crypto_lskcipher_crypt_unaligned( if (chunk > cs) chunk &= ~(cs - 1); + if (chunk == len) + flags |= CRYPTO_LSKCIPHER_FLAG_FINAL; memcpy(p, src, chunk); - err = crypt(tfm, p, p, chunk, tiv, CRYPTO_LSKCIPHER_FLAG_FINAL); + err = crypt(tfm, p, p, chunk, tiv, flags); if (err) goto out; memcpy(dst, p, chunk); + flags |= CRYPTO_LSKCIPHER_FLAG_CONT; src += chunk; dst += chunk; len -= chunk;
diff --git a/crypto/rsassa-pkcs1.c b/crypto/rsassa-pkcs1.c index 94fa5e9..3913747 100644 --- a/crypto/rsassa-pkcs1.c +++ b/crypto/rsassa-pkcs1.c
@@ -169,7 +169,7 @@ static int rsassa_pkcs1_sign(struct crypto_sig *tfm, u8 *in_buf; int err; - if (!ctx->key_size) + if (ctx->key_size < 11) return -EINVAL; if (dlen < ctx->key_size) @@ -231,7 +231,7 @@ static int rsassa_pkcs1_verify(struct crypto_sig *tfm, int err; /* RFC 8017 sec 8.2.2 step 1 - length checking */ - if (!ctx->key_size || + if (ctx->key_size < 11 || slen != ctx->key_size || rsassa_pkcs1_invalid_hash_len(dlen, hash_prefix)) return -EINVAL;
diff --git a/crypto/tcrypt.c b/crypto/tcrypt.c index 61a2501..e6834bd 100644 --- a/crypto/tcrypt.c +++ b/crypto/tcrypt.c
@@ -56,6 +56,21 @@ */ #define get_driver_name(tfm_type, tfm) crypto_tfm_alg_driver_name(tfm_type ## _tfm(tfm)) +struct tcrypt_aead_request { + struct aead_request *req; + struct crypto_wait wait; +}; + +struct tcrypt_ahash_request { + struct ahash_request *req; + struct crypto_wait wait; +}; + +struct tcrypt_skcipher_request { + struct skcipher_request *req; + struct crypto_wait wait; +}; + /* * Used by test_cipher_speed() */ @@ -129,18 +144,15 @@ static void sg_init_aead(struct scatterlist *sg, char *xbuf[XBUFSIZE], sg_set_buf(&sg[k + 1], xbuf[k], rem); } -static inline int do_one_aead_op(struct aead_request *req, int ret) +static inline int do_one_aead_op(struct tcrypt_aead_request *req, int ret) { - struct crypto_wait *wait = req->base.data; - - return crypto_wait_req(ret, wait); + return crypto_wait_req(ret, &req->wait); } struct test_mb_aead_data { struct scatterlist sg[XBUFSIZE]; struct scatterlist sgout[XBUFSIZE]; - struct aead_request *req; - struct crypto_wait wait; + struct tcrypt_aead_request req; char *xbuf[XBUFSIZE]; char *xoutbuf[XBUFSIZE]; char *axbuf[XBUFSIZE]; @@ -154,14 +166,14 @@ static int do_mult_aead_op(struct test_mb_aead_data *data, int enc, /* Fire up a bunch of concurrent requests */ for (i = 0; i < num_mb; i++) { if (enc == ENCRYPT) - rc[i] = crypto_aead_encrypt(data[i].req); + rc[i] = crypto_aead_encrypt(data[i].req.req); else - rc[i] = crypto_aead_decrypt(data[i].req); + rc[i] = crypto_aead_decrypt(data[i].req.req); } /* Wait for all requests to finish */ for (i = 0; i < num_mb; i++) { - rc[i] = crypto_wait_req(rc[i], &data[i].wait); + rc[i] = crypto_wait_req(rc[i], &data[i].req.wait); if (rc[i]) { pr_info("concurrent request %d error %d\n", i, rc[i]); @@ -310,21 +322,21 @@ static void test_mb_aead_speed(const char *algo, int enc, int secs, } for (i = 0; i < num_mb; ++i) { - data[i].req = aead_request_alloc(tfm, GFP_KERNEL); - if (!data[i].req) { + data[i].req.req = aead_request_alloc(tfm, GFP_KERNEL); + if (!data[i].req.req) { pr_err("alg: aead: Failed to allocate request for %s\n", algo); while (i--) - aead_request_free(data[i].req); + aead_request_free(data[i].req.req); goto out_free_xoutbuf; } } for (i = 0; i < num_mb; ++i) { - crypto_init_wait(&data[i].wait); - aead_request_set_callback(data[i].req, + crypto_init_wait(&data[i].req.wait); + aead_request_set_callback(data[i].req.req, CRYPTO_TFM_REQ_MAY_BACKLOG, - crypto_req_done, &data[i].wait); + crypto_req_done, &data[i].req.wait); } pr_info("testing speed of multibuffer %s (%s) %s\n", algo, @@ -386,16 +398,16 @@ static void test_mb_aead_speed(const char *algo, int enc, int secs, bs + (enc ? authsize : 0), assoc, aad_size); - aead_request_set_ad(cur->req, aad_size); + aead_request_set_ad(cur->req.req, aad_size); if (!enc) { - aead_request_set_crypt(cur->req, + aead_request_set_crypt(cur->req.req, cur->sgout, cur->sg, bs, iv); - ret = crypto_aead_encrypt(cur->req); - ret = do_one_aead_op(cur->req, ret); + ret = crypto_aead_encrypt(cur->req.req); + ret = do_one_aead_op(&cur->req, ret); if (ret) { pr_err("calculating auth failed (%d)\n", @@ -404,7 +416,7 @@ static void test_mb_aead_speed(const char *algo, int enc, int secs, } } - aead_request_set_crypt(cur->req, cur->sg, + aead_request_set_crypt(cur->req.req, cur->sg, cur->sgout, bs + (enc ? 0 : authsize), iv); @@ -432,7 +444,7 @@ static void test_mb_aead_speed(const char *algo, int enc, int secs, out: for (i = 0; i < num_mb; ++i) - aead_request_free(data[i].req); + aead_request_free(data[i].req.req); out_free_xoutbuf: for (i = 0; i < num_mb; ++i) testmgr_free_buf(data[i].xoutbuf); @@ -450,9 +462,10 @@ static void test_mb_aead_speed(const char *algo, int enc, int secs, kfree(iv); } -static int test_aead_jiffies(struct aead_request *req, int enc, +static int test_aead_jiffies(struct tcrypt_aead_request *treq, int enc, int blen, int secs) { + struct aead_request *req = treq->req; unsigned long start, end; int bcount; int ret; @@ -460,9 +473,9 @@ static int test_aead_jiffies(struct aead_request *req, int enc, for (start = jiffies, end = start + secs * HZ, bcount = 0; time_before(jiffies, end); bcount++) { if (enc) - ret = do_one_aead_op(req, crypto_aead_encrypt(req)); + ret = do_one_aead_op(treq, crypto_aead_encrypt(req)); else - ret = do_one_aead_op(req, crypto_aead_decrypt(req)); + ret = do_one_aead_op(treq, crypto_aead_decrypt(req)); if (ret) return ret; @@ -473,8 +486,9 @@ static int test_aead_jiffies(struct aead_request *req, int enc, return 0; } -static int test_aead_cycles(struct aead_request *req, int enc, int blen) +static int test_aead_cycles(struct tcrypt_aead_request *treq, int enc, int blen) { + struct aead_request *req = treq->req; unsigned long cycles = 0; int ret = 0; int i; @@ -482,9 +496,9 @@ static int test_aead_cycles(struct aead_request *req, int enc, int blen) /* Warm-up run. */ for (i = 0; i < 4; i++) { if (enc) - ret = do_one_aead_op(req, crypto_aead_encrypt(req)); + ret = do_one_aead_op(treq, crypto_aead_encrypt(req)); else - ret = do_one_aead_op(req, crypto_aead_decrypt(req)); + ret = do_one_aead_op(treq, crypto_aead_decrypt(req)); if (ret) goto out; @@ -496,9 +510,9 @@ static int test_aead_cycles(struct aead_request *req, int enc, int blen) start = get_cycles(); if (enc) - ret = do_one_aead_op(req, crypto_aead_encrypt(req)); + ret = do_one_aead_op(treq, crypto_aead_encrypt(req)); else - ret = do_one_aead_op(req, crypto_aead_decrypt(req)); + ret = do_one_aead_op(treq, crypto_aead_decrypt(req)); end = get_cycles(); if (ret) @@ -520,6 +534,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, unsigned int tcount, u8 authsize, unsigned int aad_size, u8 *keysize) { + struct tcrypt_aead_request treq; unsigned int i, j; struct crypto_aead *tfm; int ret = -ENOMEM; @@ -535,7 +550,6 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, char *axbuf[XBUFSIZE]; const int *b_size; unsigned int iv_len; - struct crypto_wait wait; iv = kzalloc(MAX_IVLEN, GFP_KERNEL); if (!iv) @@ -577,7 +591,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, goto out_noreq; } - crypto_init_wait(&wait); + crypto_init_wait(&treq.wait); pr_info("testing speed of %s (%s) %s\n", algo, get_driver_name(crypto_aead, tfm), e); @@ -587,9 +601,10 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, algo); goto out_noreq; } + treq.req = req; aead_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, - crypto_req_done, &wait); + crypto_req_done, &treq.wait); i = 0; do { @@ -650,7 +665,7 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, */ aead_request_set_crypt(req, sgout, sg, bs, iv); - ret = do_one_aead_op(req, + ret = do_one_aead_op(&treq, crypto_aead_encrypt(req)); if (ret) { @@ -665,11 +680,11 @@ static void test_aead_speed(const char *algo, int enc, unsigned int secs, iv); if (secs) { - ret = test_aead_jiffies(req, enc, bs, + ret = test_aead_jiffies(&treq, enc, bs, secs); cond_resched(); } else { - ret = test_aead_cycles(req, enc, bs); + ret = test_aead_cycles(&treq, enc, bs); } if (ret) { @@ -709,23 +724,22 @@ static void test_hash_sg_init(struct scatterlist *sg) } } -static inline int do_one_ahash_op(struct ahash_request *req, int ret) +static inline int do_one_ahash_op(struct tcrypt_ahash_request *treq, int ret) { - struct crypto_wait *wait = req->base.data; - - return crypto_wait_req(ret, wait); + return crypto_wait_req(ret, &treq->wait); } -static int test_ahash_jiffies_digest(struct ahash_request *req, int blen, - char *out, int secs) +static int test_ahash_jiffies_digest(struct tcrypt_ahash_request *treq, + int blen, char *out, int secs) { + struct ahash_request *req = treq->req; unsigned long start, end; int bcount; int ret; for (start = jiffies, end = start + secs * HZ, bcount = 0; time_before(jiffies, end); bcount++) { - ret = do_one_ahash_op(req, crypto_ahash_digest(req)); + ret = do_one_ahash_op(treq, crypto_ahash_digest(req)); if (ret) return ret; } @@ -736,28 +750,29 @@ static int test_ahash_jiffies_digest(struct ahash_request *req, int blen, return 0; } -static int test_ahash_jiffies(struct ahash_request *req, int blen, +static int test_ahash_jiffies(struct tcrypt_ahash_request *treq, int blen, int plen, char *out, int secs) { + struct ahash_request *req = treq->req; unsigned long start, end; int bcount, pcount; int ret; if (plen == blen) - return test_ahash_jiffies_digest(req, blen, out, secs); + return test_ahash_jiffies_digest(treq, blen, out, secs); for (start = jiffies, end = start + secs * HZ, bcount = 0; time_before(jiffies, end); bcount++) { - ret = do_one_ahash_op(req, crypto_ahash_init(req)); + ret = do_one_ahash_op(treq, crypto_ahash_init(req)); if (ret) return ret; for (pcount = 0; pcount < blen; pcount += plen) { - ret = do_one_ahash_op(req, crypto_ahash_update(req)); + ret = do_one_ahash_op(treq, crypto_ahash_update(req)); if (ret) return ret; } /* we assume there is enough space in 'out' for the result */ - ret = do_one_ahash_op(req, crypto_ahash_final(req)); + ret = do_one_ahash_op(treq, crypto_ahash_final(req)); if (ret) return ret; } @@ -768,15 +783,16 @@ static int test_ahash_jiffies(struct ahash_request *req, int blen, return 0; } -static int test_ahash_cycles_digest(struct ahash_request *req, int blen, - char *out) +static int test_ahash_cycles_digest(struct tcrypt_ahash_request *treq, + int blen, char *out) { + struct ahash_request *req = treq->req; unsigned long cycles = 0; int ret, i; /* Warm-up run. */ for (i = 0; i < 4; i++) { - ret = do_one_ahash_op(req, crypto_ahash_digest(req)); + ret = do_one_ahash_op(treq, crypto_ahash_digest(req)); if (ret) goto out; } @@ -787,7 +803,7 @@ static int test_ahash_cycles_digest(struct ahash_request *req, int blen, start = get_cycles(); - ret = do_one_ahash_op(req, crypto_ahash_digest(req)); + ret = do_one_ahash_op(treq, crypto_ahash_digest(req)); if (ret) goto out; @@ -806,26 +822,27 @@ static int test_ahash_cycles_digest(struct ahash_request *req, int blen, return 0; } -static int test_ahash_cycles(struct ahash_request *req, int blen, +static int test_ahash_cycles(struct tcrypt_ahash_request *treq, int blen, int plen, char *out) { + struct ahash_request *req = treq->req; unsigned long cycles = 0; int i, pcount, ret; if (plen == blen) - return test_ahash_cycles_digest(req, blen, out); + return test_ahash_cycles_digest(treq, blen, out); /* Warm-up run. */ for (i = 0; i < 4; i++) { - ret = do_one_ahash_op(req, crypto_ahash_init(req)); + ret = do_one_ahash_op(treq, crypto_ahash_init(req)); if (ret) goto out; for (pcount = 0; pcount < blen; pcount += plen) { - ret = do_one_ahash_op(req, crypto_ahash_update(req)); + ret = do_one_ahash_op(treq, crypto_ahash_update(req)); if (ret) goto out; } - ret = do_one_ahash_op(req, crypto_ahash_final(req)); + ret = do_one_ahash_op(treq, crypto_ahash_final(req)); if (ret) goto out; } @@ -836,15 +853,15 @@ static int test_ahash_cycles(struct ahash_request *req, int blen, start = get_cycles(); - ret = do_one_ahash_op(req, crypto_ahash_init(req)); + ret = do_one_ahash_op(treq, crypto_ahash_init(req)); if (ret) goto out; for (pcount = 0; pcount < blen; pcount += plen) { - ret = do_one_ahash_op(req, crypto_ahash_update(req)); + ret = do_one_ahash_op(treq, crypto_ahash_update(req)); if (ret) goto out; } - ret = do_one_ahash_op(req, crypto_ahash_final(req)); + ret = do_one_ahash_op(treq, crypto_ahash_final(req)); if (ret) goto out; @@ -867,7 +884,7 @@ static void test_ahash_speed_common(const char *algo, unsigned int secs, struct hash_speed *speed, unsigned mask) { struct scatterlist sg[TVMEMSIZE]; - struct crypto_wait wait; + struct tcrypt_ahash_request treq; struct ahash_request *req; struct crypto_ahash *tfm; char *output; @@ -896,9 +913,10 @@ static void test_ahash_speed_common(const char *algo, unsigned int secs, goto out; } - crypto_init_wait(&wait); + treq.req = req; + crypto_init_wait(&treq.wait); ahash_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, - crypto_req_done, &wait); + crypto_req_done, &treq.wait); output = kmalloc(MAX_DIGEST_SIZE, GFP_KERNEL); if (!output) @@ -927,11 +945,11 @@ static void test_ahash_speed_common(const char *algo, unsigned int secs, ahash_request_set_crypt(req, sg, output, speed[i].plen); if (secs) { - ret = test_ahash_jiffies(req, speed[i].blen, + ret = test_ahash_jiffies(&treq, speed[i].blen, speed[i].plen, output, secs); cond_resched(); } else { - ret = test_ahash_cycles(req, speed[i].blen, + ret = test_ahash_cycles(&treq, speed[i].blen, speed[i].plen, output); } @@ -1217,16 +1235,16 @@ static void test_mb_skcipher_speed(const char *algo, int enc, int secs, kfree(data); } -static inline int do_one_acipher_op(struct skcipher_request *req, int ret) +static inline int do_one_acipher_op(struct tcrypt_skcipher_request *req, + int ret) { - struct crypto_wait *wait = req->base.data; - - return crypto_wait_req(ret, wait); + return crypto_wait_req(ret, &req->wait); } -static int test_acipher_jiffies(struct skcipher_request *req, int enc, +static int test_acipher_jiffies(struct tcrypt_skcipher_request *treq, int enc, int blen, int secs) { + struct skcipher_request *req = treq->req; unsigned long start, end; int bcount; int ret; @@ -1234,10 +1252,10 @@ static int test_acipher_jiffies(struct skcipher_request *req, int enc, for (start = jiffies, end = start + secs * HZ, bcount = 0; time_before(jiffies, end); bcount++) { if (enc) - ret = do_one_acipher_op(req, + ret = do_one_acipher_op(treq, crypto_skcipher_encrypt(req)); else - ret = do_one_acipher_op(req, + ret = do_one_acipher_op(treq, crypto_skcipher_decrypt(req)); if (ret) @@ -1249,9 +1267,10 @@ static int test_acipher_jiffies(struct skcipher_request *req, int enc, return 0; } -static int test_acipher_cycles(struct skcipher_request *req, int enc, +static int test_acipher_cycles(struct tcrypt_skcipher_request *treq, int enc, int blen) { + struct skcipher_request *req = treq->req; unsigned long cycles = 0; int ret = 0; int i; @@ -1259,10 +1278,10 @@ static int test_acipher_cycles(struct skcipher_request *req, int enc, /* Warm-up run. */ for (i = 0; i < 4; i++) { if (enc) - ret = do_one_acipher_op(req, + ret = do_one_acipher_op(treq, crypto_skcipher_encrypt(req)); else - ret = do_one_acipher_op(req, + ret = do_one_acipher_op(treq, crypto_skcipher_decrypt(req)); if (ret) @@ -1275,10 +1294,10 @@ static int test_acipher_cycles(struct skcipher_request *req, int enc, start = get_cycles(); if (enc) - ret = do_one_acipher_op(req, + ret = do_one_acipher_op(treq, crypto_skcipher_encrypt(req)); else - ret = do_one_acipher_op(req, + ret = do_one_acipher_op(treq, crypto_skcipher_decrypt(req)); end = get_cycles(); @@ -1300,8 +1319,8 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs, struct cipher_speed_template *template, unsigned int tcount, u8 *keysize, bool async) { + struct tcrypt_skcipher_request treq; unsigned int ret, i, j, k, iv_len; - struct crypto_wait wait; const char *key; char iv[128]; struct skcipher_request *req; @@ -1314,7 +1333,7 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs, else e = "decryption"; - crypto_init_wait(&wait); + crypto_init_wait(&treq.wait); tfm = crypto_alloc_skcipher(algo, 0, async ? 0 : CRYPTO_ALG_ASYNC); @@ -1333,8 +1352,9 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs, goto out; } + treq.req = req; skcipher_request_set_callback(req, CRYPTO_TFM_REQ_MAY_BACKLOG, - crypto_req_done, &wait); + crypto_req_done, &treq.wait); i = 0; do { @@ -1401,11 +1421,11 @@ static void test_skcipher_speed(const char *algo, int enc, unsigned int secs, skcipher_request_set_crypt(req, sg, sg, bs, iv); if (secs) { - ret = test_acipher_jiffies(req, enc, + ret = test_acipher_jiffies(&treq, enc, bs, secs); cond_resched(); } else { - ret = test_acipher_cycles(req, enc, + ret = test_acipher_cycles(&treq, enc, bs); }
diff --git a/crypto/testmgr.c b/crypto/testmgr.c index 4958211..9419d61 100644 --- a/crypto/testmgr.c +++ b/crypto/testmgr.c
@@ -3958,16 +3958,17 @@ static int test_sig_one(struct crypto_sig *tfm, const struct sig_testvec *vecs) */ err = crypto_sig_verify(tfm, vecs->c, vecs->c_size, vecs->m, vecs->m_size); - if (err) { - pr_err("alg: sig: verify test failed: err %d\n", err); - return err; + if (err != vecs->verify_error) { + pr_err("alg: sig: verify test failed: expected %d, got %d\n", + vecs->verify_error, err); + return err ?: -EINVAL; } /* * Don't invoke sign test (which requires a private key) - * for vectors with only a public key. + * for vectors with only a public key or an invalid signature. */ - if (vecs->public_key_vec) + if (vecs->public_key_vec || vecs->verify_error) return 0; sig_size = crypto_sig_maxsize(tfm);
diff --git a/crypto/testmgr.h b/crypto/testmgr.h index c4a15e7..0ee15a8f 100644 --- a/crypto/testmgr.h +++ b/crypto/testmgr.h
@@ -161,6 +161,7 @@ struct sig_testvec { unsigned int param_len; unsigned int m_size; unsigned int c_size; + int verify_error; bool public_key_vec; enum OID algo; }; @@ -1443,6 +1444,140 @@ static const struct sig_testvec x962_ecdsa_nist_p192_tv_template[] = { }; static const struct sig_testvec x962_ecdsa_nist_p256_tv_template[] = { + /* Invalid signature: Q = G, r = s, e = 3r mod n. */ + { + .key = + "\x04\x6b\x17\xd1\xf2\xe1\x2c\x42\x47\xf8\xbc\xe6\xe5\x63\xa4\x40" + "\xf2\x77\x03\x7d\x81\x2d\xeb\x33\xa0\xf4\xa1\x39\x45\xd8\x98\xc2" + "\x96\x4f\xe3\x42\xe2\xfe\x1a\x7f\x9b\x8e\xe7\xeb\x4a\x7c\x0f\x9e" + "\x16\x2b\xce\x33\x57\x6b\x31\x5e\xce\xcb\xb6\x40\x68\x37\xbf\x51" + "\xf5", + .key_len = 65, + .m = + "\xb2\xc3\x09\x72\x03\x17\x9d\xaa\x5c\x4a\xd8\xff\x02\xfe\xcb\x15" + "\x21\x53\x81\x77\x45\xec\x45\x24\x3d\x68\x10\xb9\xf2\xa5\x88\x3a", + .m_size = 32, + .c = + "\x30\x46\x02\x21\x00\x90\xeb\xad\xd0\x56\x5d\x34\x8e\x74\x18\xf2" + "\xff\xab\xaa\x43\xb1\x9f\x68\xd4\x0c\x4f\x01\x4b\xe3\x10\x60\x9e" + "\x7e\xfa\x58\x39\xd9\x02\x21\x00\x90\xeb\xad\xd0\x56\x5d\x34\x8e" + "\x74\x18\xf2\xff\xab\xaa\x43\xb1\x9f\x68\xd4\x0c\x4f\x01\x4b\xe3" + "\x10\x60\x9e\x7e\xfa\x58\x39\xd9", + .c_size = 72, + .verify_error = -EKEYREJECTED, + .public_key_vec = true, + }, + /* Invalid signature: Q = -G, r = s, e = 3r mod n. */ + { + .key = + "\x04\x6b\x17\xd1\xf2\xe1\x2c\x42\x47\xf8\xbc\xe6\xe5\x63\xa4\x40" + "\xf2\x77\x03\x7d\x81\x2d\xeb\x33\xa0\xf4\xa1\x39\x45\xd8\x98\xc2" + "\x96\xb0\x1c\xbd\x1c\x01\xe5\x80\x65\x71\x18\x14\xb5\x83\xf0\x61" + "\xe9\xd4\x31\xcc\xa9\x94\xce\xa1\x31\x34\x49\xbf\x97\xc8\x40\xae" + "\x0a", + .key_len = 65, + .m = + "\xb2\xc3\x09\x72\x03\x17\x9d\xaa\x5c\x4a\xd8\xff\x02\xfe\xcb\x15" + "\x21\x53\x81\x77\x45\xec\x45\x24\x3d\x68\x10\xb9\xf2\xa5\x88\x3a", + .m_size = 32, + .c = + "\x30\x46\x02\x21\x00\x90\xeb\xad\xd0\x56\x5d\x34\x8e\x74\x18\xf2" + "\xff\xab\xaa\x43\xb1\x9f\x68\xd4\x0c\x4f\x01\x4b\xe3\x10\x60\x9e" + "\x7e\xfa\x58\x39\xd9\x02\x21\x00\x90\xeb\xad\xd0\x56\x5d\x34\x8e" + "\x74\x18\xf2\xff\xab\xaa\x43\xb1\x9f\x68\xd4\x0c\x4f\x01\x4b\xe3" + "\x10\x60\x9e\x7e\xfa\x58\x39\xd9", + .c_size = 72, + .verify_error = -EKEYREJECTED, + .public_key_vec = true, + }, + /* Wycheproof secp256r1/SHA-256 tcId 60. */ + { + .key = + "\x04\x29\x27\xb1\x05\x12\xba\xe3\xed\xdc\xfe\x46\x78\x28\x12\x8b" + "\xad\x29\x03\x26\x99\x19\xf7\x08\x60\x69\xc8\xc4\xdf\x6c\x73\x28" + "\x38\xc7\x78\x79\x64\xea\xac\x00\xe5\x92\x1f\xb1\x49\x8a\x60\xf4" + "\x60\x67\x66\xb3\xd9\x68\x50\x01\x55\x8d\x1a\x97\x4e\x73\x41\x51" + "\x3e", + .key_len = 65, + .m = + "\x70\x23\x9d\xd8\x77\xf7\xc9\x44\xc4\x22\xf4\x4d\xea\x4e\xd1\xa5" + "\x2f\x26\x27\x41\x6f\xaf\x2f\x07\x2f\xa5\x0c\x77\x2e\xd6\xf8\x07", + .m_size = 32, + .c = + "\x30\x44\x02\x20\x64\xa1\xaa\xb5\x00\x0d\x0e\x80\x4f\x3e\x2f\xc0" + "\x2b\xde\xe9\xbe\x8f\xf3\x12\x33\x4e\x2b\xa1\x6d\x11\x54\x7c\x97" + "\x71\x1c\x89\x8e\x02\x20\x6a\xf0\x15\x97\x1c\xc3\x0b\xe6\xd1\xa2" + "\x06\xd4\xe0\x13\xe0\x99\x77\x72\xa2\xf9\x1d\x73\x28\x6f\xfd\x68" + "\x3b\x9b\xb2\xcf\x4f\x1b", + .c_size = 70, + .public_key_vec = true, + }, + /* Wycheproof secp256r1/SHA-256 tcId 210. */ + { + .key = + "\x04\xc6\xa7\x71\x52\x70\x24\x22\x77\x92\x17\x0a\x6f\x8e\xee\x73" + "\x5b\xf3\x2b\x7f\x98\xaf\x66\x9e\xad\x29\x98\x02\xe3\x2d\x7c\x31" + "\x07\xbc\x3b\x4b\x5e\x65\xab\x88\x7b\xbd\x34\x35\x72\xb3\xe5\x61" + "\x92\x61\xfe\x3a\x07\x3e\x2f\xfd\x78\x41\x2f\x72\x68\x67\xdb\x58" + "\x9e", + .key_len = 65, + .m = + "\xbb\x5a\x52\xf4\x2f\x9c\x92\x61\xed\x43\x61\xf5\x94\x22\xa1\xe3" + "\x00\x36\xe7\xc3\x2b\x27\x0c\x88\x07\xa4\x19\xfe\xca\x60\x50\x23", + .m_size = 32, + .c = + "\x30\x45\x02\x20\x7c\xf2\x7b\x18\x8d\x03\x4f\x7e\x8a\x52\x38\x03" + "\x04\xb5\x1a\xc3\xc0\x89\x69\xe2\x77\xf2\x1b\x35\xa6\x0b\x48\xfc" + "\x47\x66\x99\x78\x02\x21\x00\xb6\xdb\x6d\xb6\x24\x92\x49\x25\x49" + "\x24\x92\x49\x24\x92\x49\x24\x62\x5b\xd7\xa0\x9b\xec\x4c\xa8\x1b" + "\xcd\xd9\xf8\xfd\x6b\x63\xcc", + .c_size = 71, + .public_key_vec = true, + }, + /* Q = G, d = 1, k = 2. */ + { + .key = + "\x04\x6b\x17\xd1\xf2\xe1\x2c\x42\x47\xf8\xbc\xe6\xe5\x63\xa4\x40" + "\xf2\x77\x03\x7d\x81\x2d\xeb\x33\xa0\xf4\xa1\x39\x45\xd8\x98\xc2" + "\x96\x4f\xe3\x42\xe2\xfe\x1a\x7f\x9b\x8e\xe7\xeb\x4a\x7c\x0f\x9e" + "\x16\x2b\xce\x33\x57\x6b\x31\x5e\xce\xcb\xb6\x40\x68\x37\xbf\x51" + "\xf5", + .key_len = 65, + .m = + "\x35\x9d\x17\x29\xb9\x1a\x52\xe9\x8b\xb5\x95\xc3\x86\x28\x3c\x10" + "\x30\x44\x95\x1a\xa1\x08\x20\xf0\xa0\x22\xc4\x18\xc2\x71\xa0\xcc", + .m_size = 32, + .c = + "\x30\x44\x02\x20\x7c\xf2\x7b\x18\x8d\x03\x4f\x7e\x8a\x52\x38\x03" + "\x04\xb5\x1a\xc3\xc0\x89\x69\xe2\x77\xf2\x1b\x35\xa6\x0b\x48\xfc" + "\x47\x66\x99\x78\x02\x20\x59\x47\xc9\x21\x23\x0e\xd1\x34\x0b\x03" + "\xe6\xe3\x45\x6e\xab\x69\xf8\x66\xff\x7e\x8c\x7d\x1e\x13\x23\x17" + "\x06\x8a\x84\xec\x1d\x22", + .c_size = 70, + .public_key_vec = true, + }, + /* Q = -G, d = n - 1, k = 2. */ + { + .key = + "\x04\x6b\x17\xd1\xf2\xe1\x2c\x42\x47\xf8\xbc\xe6\xe5\x63\xa4\x40" + "\xf2\x77\x03\x7d\x81\x2d\xeb\x33\xa0\xf4\xa1\x39\x45\xd8\x98\xc2" + "\x96\xb0\x1c\xbd\x1c\x01\xe5\x80\x65\x71\x18\x14\xb5\x83\xf0\x61" + "\xe9\xd4\x31\xcc\xa9\x94\xce\xa1\x31\x34\x49\xbf\x97\xc8\x40\xae" + "\x0a", + .key_len = 65, + .m = + "\x35\x9d\x17\x29\xb9\x1a\x52\xe9\x8b\xb5\x95\xc3\x86\x28\x3c\x10" + "\x30\x44\x95\x1a\xa1\x08\x20\xf0\xa0\x22\xc4\x18\xc2\x71\xa0\xcc", + .m_size = 32, + .c = + "\x30\x45\x02\x20\x7c\xf2\x7b\x18\x8d\x03\x4f\x7e\x8a\x52\x38\x03" + "\x04\xb5\x1a\xc3\xc0\x89\x69\xe2\x77\xf2\x1b\x35\xa6\x0b\x48\xfc" + "\x47\x66\x99\x78\x02\x21\x00\xdc\x55\x4e\x07\x96\x0b\x81\xb6\x80" + "\xb1\xae\xe0\x40\xb9\x90\xa5\xf4\xc4\x90\x49\xbb\xa2\xa1\x62\x70" + "\xc5\x88\x51\x39\xe8\xa8\xfb", + .c_size = 71, + .public_key_vec = true, + }, { .key = /* secp256r1(sha1) */ "\x04\xb9\x7b\xbb\xd7\x17\x64\xd2\x7e\xfc\x81\x5d\x87\x06\x83\x41" @@ -1827,7 +1962,8 @@ static const struct sig_testvec p1363_ecdsa_nist_p256_tv_template[] = { }; /* - * EC-RDSA test vectors are generated by gost-engine. + * EC-RDSA test vectors generated by gost-engine, followed by constructed + * exceptional-point regression vectors. */ static const struct sig_testvec ecrdsa_tv_template[] = { { @@ -1973,6 +2109,195 @@ static const struct sig_testvec ecrdsa_tv_template[] = { .m_size = 64, .public_key_vec = true, }, + /* + * Constructed EC-RDSA exceptional-point vectors. + * With Q = dG, choose k = z1 + d*z2 (mod n), r = x(kG) mod n, + * e = -r/z2 (mod n), and s = r*d + k*e (mod n). + * The input digest is e, encoded little-endian. + */ + /* cp256a: Q=G, z1 = 3, z2 = 1. */ + { + .key = + "\x04\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x14\x1e\x9f\x9e\x9c\xc9\xac\x22\xb1\xe3\x23\xdf\x2d\x4f" + "\x29\x35\x76\x2b\x3f\x45\x5a\x50\xdf\x27\xda\x9c\x98\xe0\x71\xe4" + "\x91\x8d", + .key_len = 66, + .params = /* OID_gostCPSignA */ + "\x30\x13\x06\x07\x2a\x85\x03\x02\x02\x23\x01\x06\x08\x2a\x85\x03" + "\x07\x01\x01\x02\x02", + .param_len = 21, + .c = + "\x1a\xed\x44\xae\xd4\x4a\xed\x44\xae\xd4\x4a\xed\x44\xae\xd4\x49" + "\x32\x67\xe0\x26\x16\xfd\xb7\xaf\xa4\xd7\x3e\x61\xd4\xf9\x7b\x94" + "\xf7\x06\x3e\x70\x63\xe7\x06\x3e\x70\x63\xe7\x06\x3e\x70\x63\xe7" + "\x06\x3e\x70\x63\xe7\x06\x3e\x70\x63\xe7\x06\x3e\x70\x63\xe4\xb7", + .c_size = 64, + .m = + "\xdc\xd3\xfd\x46\xcb\x14\x9d\xe1\x8f\x92\x54\xb2\x0c\xa0\x22\x66" + "\x18\x9c\x8f\xc1\xf9\x18\x9c\x8f\xc1\xf9\x18\x9c\x8f\xc1\xf9\x08", + .m_size = 32, + .algo = OID_gost2012PKey256, + .public_key_vec = true, + }, + /* cp256a: Q=-G, z1 = 7, z2 = 6. */ + { + .key = + "\x04\x40\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x83\xdf\x60\x61\x63\x36\x53\xdd\x4e\x1c\xdc\x20\xd2\xb0" + "\xd6\xca\x89\xd4\xc0\xba\xa5\xaf\x20\xd8\x25\x63\x67\x1f\x8e\x1b" + "\x6e\x72", + .key_len = 66, + .params = /* OID_gostCPSignA */ + "\x30\x13\x06\x07\x2a\x85\x03\x02\x02\x23\x01\x06\x08\x2a\x85\x03" + "\x07\x01\x01\x02\x02", + .param_len = 21, + .c = + "\x2a\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\x92\x10\x2d\x68\x19\x8f\x22\xd5\x60\xeb\x59\xd6\xf3\xe5\x9e\xc2" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", + .c_size = 64, + .m = + "\xc3\x9e\xe5\xf3\xd6\x59\xeb\x60\xd5\x22\x8f\x19\x68\x2d\x10\x92" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\x2a", + .m_size = 32, + .algo = OID_gost2012PKey256, + .public_key_vec = true, + }, + /* cp256a: Q=-2G, z1 = 5, z2 = 2. */ + { + .key = + "\x04\x40\x95\xfd\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\x14\x1e\x9f\x9e\x9c\xc9\xac\x22\xb1\xe3\x23\xdf\x2d\x4f" + "\x29\x35\x76\x2b\x3f\x45\x5a\x50\xdf\x27\xda\x9c\x98\xe0\x71\xe4" + "\x91\x8d", + .key_len = 66, + .params = /* OID_gostCPSignA */ + "\x30\x13\x06\x07\x2a\x85\x03\x02\x02\x23\x01\x06\x08\x2a\x85\x03" + "\x07\x01\x01\x02\x02", + .param_len = 21, + .c = + "\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xb6\x30\x88\x38\x4c\xad\x68\x80\x22\xc2\x0d\x84\xdb\xb0\xdc\x47" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01", + .c_size = 64, + .m = + "\x49\xdc\xb0\xdb\x84\x0d\xc2\x22\x80\x68\xad\x4c\x38\x88\x30\xb6" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f", + .m_size = 32, + .algo = OID_gost2012PKey256, + .public_key_vec = true, + }, + /* tc512a: Q=G, z1 = 3, z2 = 1. */ + { + .key = + "\x04\x81\x80\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\xa4\xf2\x15\x52\xcb\x89\xa5\x89\xb8\xf5\x35\xc2\x5f" + "\xfe\x28\x80\xe9\x41\x3a\x0e\xa5\xe6\x75\x3d\xe9\x36\xd0\x4f\xbe" + "\x26\x16\xdf\x21\xa9\xef\xcb\xfd\x64\x80\x77\xc1\xab\xf1\xac\x93" + "\x1c\x5e\xce\xe6\x50\x54\xe2\x16\x88\x1b\xa6\xe3\x6a\x83\x7a\xe8" + "\xcf\x03\x75", + .key_len = 131, + .params = /* OID_gostTC26Sign512A */ + "\x30\x0b\x06\x09\x2a\x85\x03\x07\x01\x02\x01\x02\x01", + .param_len = 13, + .c = + "\xd8\xc0\xd7\xe3\xfb\xa6\xca\xff\x6a\xd1\xb4\xb4\x82\x1d\x15\x6f" + "\xa7\xc7\xbd\x63\x95\xb8\x29\x0d\xd4\xfa\xb1\x1c\x36\xbd\x32\x8d" + "\x1a\xba\xf1\x2e\xbc\x7b\xf2\x02\x96\xf8\xef\x2a\x5e\x72\x64\x86" + "\x67\x62\xfb\x62\x8e\x83\x53\x63\xb7\xe6\x78\x3c\x42\xd7\x0d\x1d" + "\xb7\xbf\xb8\x09\x56\xc8\x67\x00\x31\xba\x19\x19\x29\xf6\x4e\x30" + "\x1d\x68\x16\x34\x23\x6d\x47\xa6\x0e\x57\x1a\x4b\xed\xc0\xef\x25" + "\x74\x52\xef\x78\xb5\xb9\x8d\xbb\x3d\x9f\x31\x29\xd9\x34\x94\x33" + "\xce\x2a\x3a\x35\xcb\x51\x9c\x91\xe2\xd6\x33\xd7\xb3\x73\xae\x16", + .c_size = 128, + .m = + "\x5f\x04\x9d\x6b\x69\x7d\xf7\xe7\xcb\x1b\x81\x2f\x76\xfe\x20\xcd" + "\x2c\xcc\xd0\x74\x63\xfa\x52\x32\x56\xfb\xd3\x3e\xba\xa5\x93\xb3" + "\xd9\x10\x3f\x12\xb4\xe5\xa8\xf1\x59\xb8\x92\xdc\xcb\xe9\x97\xe2" + "\xcf\xb1\x09\xd6\xe6\xe6\x45\xce\xff\x98\x37\xa9\xf6\x47\x40\x48", + .m_size = 64, + .algo = OID_gost2012PKey512, + .public_key_vec = true, + }, + /* tc512a: Q=-G, z1 = 7, z2 = 6. */ + { + .key = + "\x04\x81\x80\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x23\x0b\xea\xad\x34\x76\x5a\x76\x47\x0a\xca\x3d\xa0" + "\x01\xd7\x7f\x16\xbe\xc5\xf1\x5a\x19\x8a\xc2\x16\xc9\x2f\xb0\x41" + "\xd9\xe9\x20\xde\x56\x10\x34\x02\x9b\x7f\x88\x3e\x54\x0e\x53\x6c" + "\xe3\xa1\x31\x19\xaf\xab\x1d\xe9\x77\xe4\x59\x1c\x95\x7c\x85\x17" + "\x30\xfc\x8a", + .key_len = 131, + .params = /* OID_gostTC26Sign512A */ + "\x30\x0b\x06\x09\x2a\x85\x03\x07\x01\x02\x01\x02\x01", + .param_len = 13, + .c = + "\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\x93\xf3\x4a\x99\x7a\x46\xc4\x88\xb7\xf9\x15\xc6\xa7\x02\xb0\x30" + "\x4d\xa5\x9c\x55\xfd\x69\x5c\x2e\xe5\x66\xd8\xa0\x8f\x88\x59\x37" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03", + .c_size = 128, + .m = + "\x3a\x59\x88\x8f\xa0\xd8\x66\xe5\x2e\x5c\x69\xfd\x55\x9c\xa5\x4d" + "\x30\xb0\x02\xa7\xc6\x15\xf9\xb7\x88\xc4\x46\x7a\x99\x4a\xf3\x93" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f", + .m_size = 64, + .algo = OID_gost2012PKey512, + .public_key_vec = true, + }, + /* tc512a: Q=-2G, z1 = 5, z2 = 2. */ + { + .key = + "\x04\x81\x80\x7c\x13\xea\xd2\xd9\xaf\x82\xb9\x1f\xb2\xfd\xe1\x8d" + "\xf4\x5b\x37\xe4\xf2\x04\x6a\x2a\x1d\x15\x16\x95\x2a\x5d\x40\xcd" + "\xbb\x34\x44\x2f\x2b\x13\x0a\x47\xb0\xf6\xe5\xa5\x58\x3a\xf4\x54" + "\x09\xb0\x1d\xf5\x5c\xf1\xbf\x9d\x86\xa5\x97\xab\x96\x29\x62\xfc" + "\xdc\x89\x3b\x76\x3d\x50\x6e\x8a\xcf\x02\x4c\x74\x0e\x6e\xe0\x1f" + "\x28\xab\x27\x9b\x20\x02\xc8\xc4\x12\xcb\x8a\xe3\xa4\x27\xce\x39" + "\x62\xdf\x35\x6d\xc1\x65\x7f\x7b\x48\x90\x11\x8f\x19\x7c\x1e\x67" + "\x91\x97\xeb\x90\x85\x25\xfc\x86\xb3\x88\x6e\x5c\x57\x1f\x1d\x1d" + "\x3b\xec\x37", + .key_len = 131, + .params = /* OID_gostTC26Sign512A */ + "\x30\x0b\x06\x09\x2a\x85\x03\x07\x01\x02\x01\x02\x01", + .param_len = 13, + .c = + "\x7f\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\x93\xf3\x4a\x99\x7a\x46\xc4\x88\xb7\xf9\x15\xc6\xa7\x02\xb0\x30" + "\x4d\xa5\x9c\x55\xfd\x69\x5c\x2e\xe5\x66\xd8\xa0\x8f\x88\x59\x33" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" + "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x03", + .c_size = 128, + .m = + "\x39\x59\x88\x8f\xa0\xd8\x66\xe5\x2e\x5c\x69\xfd\x55\x9c\xa5\x4d" + "\x30\xb0\x02\xa7\xc6\x15\xf9\xb7\x88\xc4\x46\x7a\x99\x4a\xf3\x93" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" + "\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\x7f", + .m_size = 64, + .algo = OID_gost2012PKey512, + .public_key_vec = true, + }, }; /*
diff --git a/crypto/zstd.c b/crypto/zstd.c index 556f5d2..76bdaca 100644 --- a/crypto/zstd.c +++ b/crypto/zstd.c
@@ -96,6 +96,7 @@ static int zstd_compress_one(struct acomp_req *req, struct zstd_ctx *ctx, static int zstd_compress(struct acomp_req *req) { + bool stream_initialized = false; struct crypto_acomp_stream *s; unsigned int pos, scur, dcur; unsigned int total_out = 0; @@ -115,12 +116,6 @@ static int zstd_compress(struct acomp_req *req) if (ret) goto out; - ctx->cctx = zstd_init_cstream(&ctx->params, 0, ctx->wksp, ctx->wksp_size); - if (!ctx->cctx) { - ret = -EINVAL; - goto out; - } - do { dcur = acomp_walk_next_dst(&walk); if (!dcur) { @@ -142,6 +137,19 @@ static int zstd_compress(struct acomp_req *req) goto out; } + if (!stream_initialized) { + ctx->cctx = zstd_init_cstream(&ctx->params, 0, + ctx->wksp, ctx->wksp_size); + if (!ctx->cctx) { + /* Release in the reverse of the map order. */ + acomp_walk_done_src(&walk, 0); + acomp_walk_done_dst(&walk, 0); + ret = -EINVAL; + goto out; + } + stream_initialized = true; + } + if (scur) { inbuf.pos = 0; inbuf.src = walk.src.virt.addr; @@ -207,6 +215,7 @@ static int zstd_decompress_one(struct acomp_req *req, struct zstd_ctx *ctx, static int zstd_decompress(struct acomp_req *req) { + bool stream_initialized = false; struct crypto_acomp_stream *s; unsigned int total_out = 0; unsigned int scur, dcur; @@ -224,12 +233,6 @@ static int zstd_decompress(struct acomp_req *req) if (ret) goto out; - ctx->dctx = zstd_init_dstream(ZSTD_MAX_SIZE, ctx->wksp, ctx->wksp_size); - if (!ctx->dctx) { - ret = -EINVAL; - goto out; - } - do { scur = acomp_walk_next_src(&walk); if (scur) { @@ -255,6 +258,19 @@ static int zstd_decompress(struct acomp_req *req) goto out; } + if (!stream_initialized) { + ctx->dctx = zstd_init_dstream(ZSTD_MAX_SIZE, ctx->wksp, + ctx->wksp_size); + if (!ctx->dctx) { + /* Release in the reverse of the map order. */ + acomp_walk_done_dst(&walk, 0); + acomp_walk_done_src(&walk, 0); + ret = -EINVAL; + goto out; + } + stream_initialized = true; + } + outbuf.pos = 0; outbuf.dst = (u8 *)walk.dst.virt.addr; outbuf.size = dcur;
diff --git a/drivers/auxdisplay/arm-charlcd.c b/drivers/auxdisplay/arm-charlcd.c index 70efda4..ea684f3 100644 --- a/drivers/auxdisplay/arm-charlcd.c +++ b/drivers/auxdisplay/arm-charlcd.c
@@ -306,10 +306,7 @@ static int charlcd_resume(struct device *dev) return 0; } -static const struct dev_pm_ops charlcd_pm_ops = { - .suspend = charlcd_suspend, - .resume = charlcd_resume, -}; +static DEFINE_SIMPLE_DEV_PM_OPS(charlcd_pm_ops, charlcd_suspend, charlcd_resume); static const struct of_device_id charlcd_match[] = { { .compatible = "arm,versatile-lcd", }, @@ -319,7 +316,7 @@ static const struct of_device_id charlcd_match[] = { static struct platform_driver charlcd_driver = { .driver = { .name = DRIVERNAME, - .pm = &charlcd_pm_ops, + .pm = pm_sleep_ptr(&charlcd_pm_ops), .suppress_bind_attrs = true, .of_match_table = charlcd_match, },
diff --git a/drivers/auxdisplay/panel.c b/drivers/auxdisplay/panel.c index a7dfc53..2a567a0 100644 --- a/drivers/auxdisplay/panel.c +++ b/drivers/auxdisplay/panel.c
@@ -714,10 +714,7 @@ static void lcd_backlight(struct charlcd *charlcd, enum charlcd_onoff on) /* The backlight is activated by setting the AUTOFEED line to +5V */ spin_lock_irq(&pprt_lock); - if (on) - set_bit(LCD_BIT_BL, bits); - else - clear_bit(LCD_BIT_BL, bits); + assign_bit(LCD_BIT_BL, bits, on); panel_set_bits(); spin_unlock_irq(&pprt_lock); }
diff --git a/drivers/base/regmap/internal.h b/drivers/base/regmap/internal.h index a6e4689..ea375cc 100644 --- a/drivers/base/regmap/internal.h +++ b/drivers/base/regmap/internal.h
@@ -10,6 +10,7 @@ #ifndef _REGMAP_INTERNAL_H #define _REGMAP_INTERNAL_H +#include <linux/cleanup.h> #include <linux/device.h> #include <linux/regmap.h> #include <linux/fs.h> @@ -185,6 +186,16 @@ struct regmap { struct hwspinlock *hwlock; }; +/* + * Scoped guard for the regmap lock. The lock/unlock callbacks are selected + * at init time (mutex, spinlock, raw spinlock, hwspinlock or none) and never + * fail, so an unconditional guard is sufficient. Use with guard(regmap)(map) + * or scoped_guard(regmap, map) { ... }. + */ +DEFINE_GUARD(regmap, struct regmap *, + _T->lock(_T->lock_arg), + _T->unlock(_T->lock_arg)) + struct regcache_ops { const char *name; enum regcache_type type; @@ -322,6 +333,7 @@ static inline unsigned int regcache_get_index_by_order(const struct regmap *map, } struct regmap_ram_data { + unsigned int base_reg; unsigned int *vals; /* Allocatd by caller */ bool *read; bool *written;
diff --git a/drivers/base/regmap/regcache-rbtree.c b/drivers/base/regmap/regcache-rbtree.c index 520d5f8..e2feed6 100644 --- a/drivers/base/regmap/regcache-rbtree.c +++ b/drivers/base/regmap/regcache-rbtree.c
@@ -141,7 +141,7 @@ static int rbtree_show(struct seq_file *s, void *ignored) int registers = 0; int this_registers, average; - map->lock(map->lock_arg); + guard(regmap)(map); mem_size = sizeof(*rbtree_ctx); @@ -168,8 +168,6 @@ static int rbtree_show(struct seq_file *s, void *ignored) seq_printf(s, "%d nodes, %d registers, average %d registers, used %zu bytes\n", nodes, registers, average, mem_size); - map->unlock(map->lock_arg); - return 0; }
diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index b137ded..774e9c9b 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c
@@ -22,6 +22,8 @@ static const struct regcache_ops *cache_types[] = { ®cache_flat_ops, }; +static int regcache_default_sync(struct regmap *map, unsigned int min, unsigned int max); + static int regcache_defaults_cmp(const void *a, const void *b) { const struct reg_default *x = a; @@ -56,12 +58,15 @@ static int regcache_count_cacheable_registers(struct regmap *map) return count; } -static int regcache_hw_init(struct regmap *map) +static int regcache_hw_init(struct regmap *map, int count) { int ret; unsigned int reg, val; void *tmp_buf; + if (!count) + return 0; + if (!map->reg_defaults_raw) { bool cache_bypass = map->cache_bypass; dev_dbg(map->dev, "No cache defaults, reading back from HW\n"); @@ -121,6 +126,29 @@ static void regcache_hw_exit(struct regmap *map) kfree(map->reg_defaults_raw); } +static int regcache_locked_op(struct regmap *map, + int (*op)(struct regmap *map), + const char *action) +{ + if (!op) + return 0; + + dev_dbg(map->dev, "%s %s cache\n", action, map->cache_ops->name); + guard(regmap)(map); + return op(map); +} + +static int __regcache_sync(struct regmap *map, unsigned int min, unsigned int max) +{ + if (!map->cache_dirty) + return 0; + + if (map->cache_ops->sync) + return map->cache_ops->sync(map, min, max); + + return regcache_default_sync(map, min, max); +} + int regcache_init(struct regmap *map, const struct regmap_config *config) { bool sort_defaults = false; @@ -139,15 +167,8 @@ int regcache_init(struct regmap *map, const struct regmap_config *config) return 0; } - if (config->reg_defaults && !config->num_reg_defaults) { - dev_err(map->dev, - "Register defaults are set without the number!\n"); - return -EINVAL; - } - - if (config->num_reg_defaults && !config->reg_defaults) { - dev_err(map->dev, - "Register defaults number are set without the reg!\n"); + if (!!config->reg_defaults != !!config->num_reg_defaults) { + dev_err(map->dev, "reg_defaults and num_reg_defaults must both be specified\n"); return -EINVAL; } @@ -180,9 +201,7 @@ int regcache_init(struct regmap *map, const struct regmap_config *config) map->cache = NULL; map->cache_ops = cache_types[i]; - if (!map->cache_ops->read || - !map->cache_ops->write || - !map->cache_ops->name) + if (!map->cache_ops->read || !map->cache_ops->write || !map->cache_ops->name) return -EINVAL; /* We still need to ensure that the reg_defaults @@ -235,21 +254,17 @@ int regcache_init(struct regmap *map, const struct regmap_config *config) * we cope with this by reading back the HW registers and * crafting the cache defaults by hand. */ - if (count) { - ret = regcache_hw_init(map); - if (ret) - goto err_exit; - } + ret = regcache_hw_init(map, count); + if (ret) + goto err_exit; - if (map->cache_ops->populate && - (map->num_reg_defaults || map->reg_default_cb)) { - dev_dbg(map->dev, "Populating %s cache\n", map->cache_ops->name); - map->lock(map->lock_arg); - ret = map->cache_ops->populate(map); - map->unlock(map->lock_arg); - if (ret) - goto err_free; - } + if (!map->num_reg_defaults && !map->reg_default_cb) + return 0; + + ret = regcache_locked_op(map, map->cache_ops->populate, "Populating"); + if (ret) + goto err_free; + return 0; err_free: @@ -273,7 +288,6 @@ void regcache_exit(struct regmap *map) BUG_ON(!map->cache_ops); regcache_hw_exit(map); - if (map->cache_ops->exit) { dev_dbg(map->dev, "Destroying %s cache\n", map->cache_ops->name); @@ -281,6 +295,7 @@ void regcache_exit(struct regmap *map) } kfree(map->reg_defaults); + map->reg_defaults = NULL; } /** @@ -455,11 +470,7 @@ int regcache_sync(struct regmap *map) } map->cache_bypass = false; - if (map->cache_ops->sync) - sync_ret = map->cache_ops->sync(map, 0, map->max_register); - else - sync_ret = regcache_default_sync(map, 0, map->max_register); - + sync_ret = __regcache_sync(map, 0, map->max_register); if (sync_ret == 0) map->cache_dirty = false; @@ -539,17 +550,10 @@ int regcache_sync_region(struct regmap *map, unsigned int min, trace_regcache_sync(map, name, "start region"); - if (!map->cache_dirty) - goto out; - map->async = true; - if (map->cache_ops->sync) - ret = map->cache_ops->sync(map, min, max); - else - ret = regcache_default_sync(map, min, max); + ret = __regcache_sync(map, min, max); -out: /* Restore the bypass state */ map->cache_bypass = bypass; map->async = false; @@ -578,20 +582,14 @@ EXPORT_SYMBOL_GPL(regcache_sync_region); int regcache_drop_region(struct regmap *map, unsigned int min, unsigned int max) { - int ret = 0; - if (!map->cache_ops || !map->cache_ops->drop) return -EINVAL; - map->lock(map->lock_arg); + guard(regmap)(map); trace_regcache_drop_region(map, min, max); - ret = map->cache_ops->drop(map, min, max); - - map->unlock(map->lock_arg); - - return ret; + return map->cache_ops->drop(map, min, max); } EXPORT_SYMBOL_GPL(regcache_drop_region); @@ -609,12 +607,11 @@ EXPORT_SYMBOL_GPL(regcache_drop_region); */ void regcache_cache_only(struct regmap *map, bool enable) { - map->lock(map->lock_arg); + guard(regmap)(map); WARN_ON(map->cache_type != REGCACHE_NONE && map->cache_bypass && enable); map->cache_only = enable; trace_regmap_cache_only(map, enable); - map->unlock(map->lock_arg); } EXPORT_SYMBOL_GPL(regcache_cache_only); @@ -633,10 +630,9 @@ EXPORT_SYMBOL_GPL(regcache_cache_only); */ void regcache_mark_dirty(struct regmap *map) { - map->lock(map->lock_arg); + guard(regmap)(map); map->cache_dirty = true; map->no_sync_defaults = true; - map->unlock(map->lock_arg); } EXPORT_SYMBOL_GPL(regcache_mark_dirty); @@ -653,11 +649,10 @@ EXPORT_SYMBOL_GPL(regcache_mark_dirty); */ void regcache_cache_bypass(struct regmap *map, bool enable) { - map->lock(map->lock_arg); + guard(regmap)(map); WARN_ON(map->cache_only && enable); map->cache_bypass = enable; trace_regmap_cache_bypass(map, enable); - map->unlock(map->lock_arg); } EXPORT_SYMBOL_GPL(regcache_cache_bypass); @@ -674,12 +669,10 @@ bool regcache_reg_cached(struct regmap *map, unsigned int reg) unsigned int val; int ret; - map->lock(map->lock_arg); + guard(regmap)(map); ret = regcache_read(map, reg, &val); - map->unlock(map->lock_arg); - return ret == 0; } EXPORT_SYMBOL_GPL(regcache_reg_cached); @@ -765,8 +758,8 @@ int regcache_lookup_reg(struct regmap *map, unsigned int reg) if (r) return r - map->reg_defaults; - else - return -ENOENT; + + return -ENOENT; } static bool regcache_reg_present(unsigned long *cache_present, unsigned int idx) @@ -903,7 +896,7 @@ int regcache_sync_block(struct regmap *map, void *block, if (regmap_can_raw_write(map) && !map->use_single_write) return regcache_sync_block_raw(map, block, cache_present, block_base, start, end); - else - return regcache_sync_block_single(map, block, cache_present, - block_base, start, end); + + return regcache_sync_block_single(map, block, cache_present, + block_base, start, end); }
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 9a09df2..b86048c 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c
@@ -38,10 +38,9 @@ static ssize_t regmap_name_read_file(struct file *file, { struct regmap *map = file->private_data; const char *name = "nodev"; + char *buf __free(kfree) = kmalloc(PAGE_SIZE, GFP_KERNEL); int ret; - char *buf; - buf = kmalloc(PAGE_SIZE, GFP_KERNEL); if (!buf) return -ENOMEM; @@ -49,14 +48,10 @@ static ssize_t regmap_name_read_file(struct file *file, name = map->dev->driver->name; ret = snprintf(buf, PAGE_SIZE, "%s\n", name); - if (ret >= PAGE_SIZE) { - kfree(buf); + if (ret >= PAGE_SIZE) return ret; - } - ret = simple_read_from_buffer(user_buf, count, ppos, buf, ret); - kfree(buf); - return ret; + return simple_read_from_buffer(user_buf, count, ppos, buf, ret); } static const struct file_operations regmap_name_fops = { @@ -112,7 +107,7 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map, * If we don't have a cache build one so we don't have to do a * linear scan each time. */ - mutex_lock(&map->cache_lock); + guard(mutex)(&map->cache_lock); i = base; if (list_empty(&map->debugfs_off_cache)) { for (; i <= map->max_register; i += map->reg_stride) { @@ -134,7 +129,6 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map, c = kzalloc_obj(*c); if (!c) { regmap_debugfs_free_dump_cache(map); - mutex_unlock(&map->cache_lock); return base; } c->min = p; @@ -167,14 +161,12 @@ static unsigned int regmap_debugfs_get_dump_start(struct regmap *map, fpos_offset = from - c->min; reg_offset = fpos_offset / map->debugfs_tot_len; *pos = c->min + (reg_offset * map->debugfs_tot_len); - mutex_unlock(&map->cache_lock); return c->base_reg + (reg_offset * map->reg_stride); } *pos = c->max; ret = c->max_reg; } - mutex_unlock(&map->cache_lock); return ret; } @@ -196,10 +188,10 @@ static int regmap_next_readable_reg(struct regmap *map, int reg) struct regmap_debugfs_off_cache *c; int ret = -EINVAL; - if (regmap_printable(map, reg + map->reg_stride)) { - ret = reg + map->reg_stride; - } else { - mutex_lock(&map->cache_lock); + if (regmap_printable(map, reg + map->reg_stride)) + return reg + map->reg_stride; + + scoped_guard(mutex, &map->cache_lock) { list_for_each_entry(c, &map->debugfs_off_cache, list) { if (reg > c->max_reg) continue; @@ -208,8 +200,8 @@ static int regmap_next_readable_reg(struct regmap *map, int reg) break; } } - mutex_unlock(&map->cache_lock); } + return ret; } @@ -366,8 +358,6 @@ static ssize_t regmap_reg_ranges_read_file(struct file *file, struct regmap_debugfs_off_cache *c; loff_t p = 0; size_t buf_pos = 0; - char *buf; - char *entry; int ret; unsigned int entry_len; @@ -377,15 +367,13 @@ static ssize_t regmap_reg_ranges_read_file(struct file *file, if (count > (PAGE_SIZE << MAX_PAGE_ORDER)) count = PAGE_SIZE << MAX_PAGE_ORDER; - buf = kmalloc(count, GFP_KERNEL); + char *buf __free(kfree) = kmalloc(count, GFP_KERNEL); if (!buf) return -ENOMEM; - entry = kmalloc(PAGE_SIZE, GFP_KERNEL); - if (!entry) { - kfree(buf); + char *entry __free(kfree) = kmalloc(PAGE_SIZE, GFP_KERNEL); + if (!entry) return -ENOMEM; - } /* While we are at it, build the register dump cache * now so the read() operation on the `registers' file @@ -398,31 +386,27 @@ static ssize_t regmap_reg_ranges_read_file(struct file *file, /* Reset file pointer as the fixed-format of the `registers' * file is not compatible with the `range' file */ p = 0; - mutex_lock(&map->cache_lock); - list_for_each_entry(c, &map->debugfs_off_cache, list) { - entry_len = snprintf(entry, PAGE_SIZE, "%x-%x\n", - c->base_reg, c->max_reg); - if (p >= *ppos) { - if (buf_pos + entry_len > count) - break; - memcpy(buf + buf_pos, entry, entry_len); - buf_pos += entry_len; + scoped_guard(mutex, &map->cache_lock) { + list_for_each_entry(c, &map->debugfs_off_cache, list) { + entry_len = snprintf(entry, PAGE_SIZE, "%x-%x\n", + c->base_reg, c->max_reg); + if (p >= *ppos) { + if (buf_pos + entry_len > count) + break; + memcpy(buf + buf_pos, entry, entry_len); + buf_pos += entry_len; + } + p += entry_len; } - p += entry_len; } - mutex_unlock(&map->cache_lock); - kfree(entry); ret = buf_pos; - if (copy_to_user(user_buf, buf, buf_pos)) { - ret = -EFAULT; - goto out_buf; - } + if (copy_to_user(user_buf, buf, buf_pos)) + return -EFAULT; *ppos += buf_pos; -out_buf: - kfree(buf); + return ret; } @@ -471,18 +455,16 @@ static ssize_t regmap_cache_only_write_file(struct file *file, if (err) return count; - map->lock(map->lock_arg); - - if (new_val && !map->cache_only) { - dev_warn(map->dev, "debugfs cache_only=Y forced\n"); - add_taint(TAINT_USER, LOCKDEP_STILL_OK); - } else if (!new_val && map->cache_only) { - dev_warn(map->dev, "debugfs cache_only=N forced: syncing cache\n"); - require_sync = true; + scoped_guard(regmap, map) { + if (new_val && !map->cache_only) { + dev_warn(map->dev, "debugfs cache_only=Y forced\n"); + add_taint(TAINT_USER, LOCKDEP_STILL_OK); + } else if (!new_val && map->cache_only) { + dev_warn(map->dev, "debugfs cache_only=N forced: syncing cache\n"); + require_sync = true; + } + map->cache_only = new_val; } - map->cache_only = new_val; - - map->unlock(map->lock_arg); if (require_sync) { err = regcache_sync(map); @@ -513,7 +495,7 @@ static ssize_t regmap_cache_bypass_write_file(struct file *file, if (err) return count; - map->lock(map->lock_arg); + guard(regmap)(map); if (new_val && !map->cache_bypass) { dev_warn(map->dev, "debugfs cache_bypass=Y forced\n"); @@ -523,8 +505,6 @@ static ssize_t regmap_cache_bypass_write_file(struct file *file, } map->cache_bypass = new_val; - map->unlock(map->lock_arg); - return count; } @@ -561,9 +541,8 @@ void regmap_debugfs_init(struct regmap *map) if (!node) return; node->map = map; - mutex_lock(®map_debugfs_early_lock); - list_add(&node->link, ®map_debugfs_early_list); - mutex_unlock(®map_debugfs_early_lock); + scoped_guard(mutex, ®map_debugfs_early_lock) + list_add(&node->link, ®map_debugfs_early_list); return; } @@ -662,30 +641,30 @@ void regmap_debugfs_init(struct regmap *map) void regmap_debugfs_exit(struct regmap *map) { + struct regmap_debugfs_node *node, *tmp; + if (map->debugfs) { debugfs_remove_recursive(map->debugfs); map->debugfs = NULL; - mutex_lock(&map->cache_lock); - regmap_debugfs_free_dump_cache(map); - mutex_unlock(&map->cache_lock); + scoped_guard(mutex, &map->cache_lock) + regmap_debugfs_free_dump_cache(map); if (map->debugfs_dummy_id >= 0) { ida_free(&dummy_ida, map->debugfs_dummy_id); map->debugfs_dummy_id = -1; } kfree(map->debugfs_name); map->debugfs_name = NULL; - } else { - struct regmap_debugfs_node *node, *tmp; - mutex_lock(®map_debugfs_early_lock); - list_for_each_entry_safe(node, tmp, ®map_debugfs_early_list, - link) { + return; + } + + scoped_guard(mutex, ®map_debugfs_early_lock) { + list_for_each_entry_safe(node, tmp, ®map_debugfs_early_list, link) { if (node->map == map) { list_del(&node->link); kfree(node); } } - mutex_unlock(®map_debugfs_early_lock); } } @@ -695,11 +674,10 @@ void regmap_debugfs_initcall(void) regmap_debugfs_root = debugfs_create_dir("regmap", NULL); - mutex_lock(®map_debugfs_early_lock); + guard(mutex)(®map_debugfs_early_lock); list_for_each_entry_safe(node, tmp, ®map_debugfs_early_list, link) { regmap_debugfs_init(node->map); list_del(&node->link); kfree(node); } - mutex_unlock(®map_debugfs_early_lock); }
diff --git a/drivers/base/regmap/regmap-kunit.c b/drivers/base/regmap/regmap-kunit.c index 2999d9c..c78772b 100644 --- a/drivers/base/regmap/regmap-kunit.c +++ b/drivers/base/regmap/regmap-kunit.c
@@ -11,6 +11,8 @@ #define BLOCK_TEST_SIZE 12 +#define HIGH_BIT_REG ((UINT_MAX / 2) - 3) + KUNIT_DEFINE_ACTION_WRAPPER(regmap_exit_action, regmap_exit, struct regmap *); struct regmap_test_priv { @@ -23,6 +25,7 @@ struct regmap_test_param { enum regcache_type cache; enum regmap_endian val_endian; + unsigned int base_reg; unsigned int from_reg; bool fast_io; }; @@ -204,7 +207,8 @@ static struct regmap *gen_regmap(struct kunit *test, config->max_register += (BLOCK_TEST_SIZE * config->reg_stride); } - size = array_size(config->max_register + 1, sizeof(*buf)); + size = array_size(config->max_register - param->base_reg + 1, + sizeof(*buf)); buf = kmalloc(size, GFP_KERNEL); if (!buf) return ERR_PTR(-ENOMEM); @@ -215,6 +219,7 @@ static struct regmap *gen_regmap(struct kunit *test, if (!(*data)) goto out_free; (*data)->vals = buf; + (*data)->base_reg = param->base_reg; if (config->num_reg_defaults) { defaults = kunit_kcalloc(test, @@ -227,8 +232,8 @@ static struct regmap *gen_regmap(struct kunit *test, config->reg_defaults = defaults; for (i = 0; i < config->num_reg_defaults; i++) { - defaults[i].reg = param->from_reg + (i * config->reg_stride); - defaults[i].def = buf[param->from_reg + (i * config->reg_stride)]; + defaults[i].reg = param->from_reg - param->base_reg + (i * config->reg_stride); + defaults[i].def = buf[param->from_reg - param->base_reg + (i * config->reg_stride)]; } } @@ -1648,6 +1653,92 @@ static void cache_write_zero(struct kunit *test) KUNIT_ASSERT_FALSE(test, regcache_reg_cached(map, 1)); } +static const struct regmap_test_param high_bit_cache_types_list[] = { + { .cache = REGCACHE_RBTREE, .from_reg = HIGH_BIT_REG, + .base_reg = HIGH_BIT_REG }, + { .cache = REGCACHE_MAPLE, .from_reg = HIGH_BIT_REG, + .base_reg = HIGH_BIT_REG }, +}; + +KUNIT_ARRAY_PARAM(high_bit_cache_types, high_bit_cache_types_list, param_to_desc); + +/* + * Dynamically allocated cache types should support registers with the + * high bit set, the backend will return an error for any operation on + * a register below the expected window. + */ +static void cache_high_bit_reg(struct kunit *test) +{ + const struct regmap_test_param *param = test->param_value; + struct regmap_ram_data *data; + struct regmap_config config; + struct regmap *map; + unsigned int val[BLOCK_TEST_SIZE], rval; + int i; + + config = test_regmap_config; + + map = gen_regmap(test, &config, &data); + KUNIT_ASSERT_FALSE(test, IS_ERR(map)); + if (IS_ERR(map)) + return; + + get_random_bytes(&val, sizeof(val)); + + /* No defaults so no registers cached */ + for (i = 0; i < BLOCK_TEST_SIZE; i++) + KUNIT_EXPECT_FALSE(test, regcache_reg_cached(map, param->from_reg + i)); + + /* Writes should reach the device */ + for (i = 0; i < BLOCK_TEST_SIZE; i++) + KUNIT_EXPECT_EQ(test, 0, regmap_write(map, param->from_reg + i, + val[i])); + for (i = 0; i < BLOCK_TEST_SIZE; i++) { + KUNIT_EXPECT_TRUE(test, data->written[i]); + KUNIT_EXPECT_EQ(test, val[i], data->vals[i]); + } + + /* Reads should be satisfied from the cache */ + for (i = 0; i < BLOCK_TEST_SIZE; i++) { + KUNIT_EXPECT_TRUE(test, regcache_reg_cached(map, param->from_reg + i)); + KUNIT_EXPECT_EQ(test, 0, regmap_read(map, param->from_reg + i, + &rval)); + KUNIT_EXPECT_EQ(test, val[i], rval); + KUNIT_EXPECT_FALSE(test, data->read[i]); + } + + /* Trash the data on the device then resync */ + regcache_mark_dirty(map); + for (i = 0; i < BLOCK_TEST_SIZE; i++) { + data->vals[i] = 0; + data->written[i] = false; + } + KUNIT_EXPECT_EQ(test, 0, regcache_sync(map)); + + /* Did we just write the correct data out? */ + for (i = 0; i < BLOCK_TEST_SIZE; i++) { + KUNIT_EXPECT_TRUE(test, data->written[i]); + KUNIT_EXPECT_EQ(test, val[i], data->vals[i]); + } + + /* Drop some registers */ + KUNIT_EXPECT_EQ(test, 0, regcache_drop_region(map, param->from_reg + 3, + param->from_reg + 5)); + for (i = 0; i < BLOCK_TEST_SIZE; i++) + KUNIT_EXPECT_EQ(test, i < 3 || i > 5, + regcache_reg_cached(map, param->from_reg + i)); + + /* Reread and check only the dropped registers hit the device */ + for (i = 0; i < BLOCK_TEST_SIZE; i++) + data->read[i] = false; + for (i = 0; i < BLOCK_TEST_SIZE; i++) { + KUNIT_EXPECT_EQ(test, 0, regmap_read(map, param->from_reg + i, + &rval)); + KUNIT_EXPECT_EQ(test, val[i], rval); + KUNIT_EXPECT_EQ(test, i >= 3 && i <= 5, data->read[i]); + } +} + /* Check that caching the window register works with sync */ static void cache_range_window_reg(struct kunit *test) { @@ -2168,6 +2259,7 @@ static struct kunit_case regmap_test_cases[] = { KUNIT_CASE_PARAM(cache_drop_all_and_sync_has_defaults, sparse_cache_types_gen_params), KUNIT_CASE_PARAM(cache_present, sparse_cache_types_gen_params), KUNIT_CASE_PARAM(cache_write_zero, sparse_cache_types_gen_params), + KUNIT_CASE_PARAM(cache_high_bit_reg, high_bit_cache_types_gen_params), KUNIT_CASE_PARAM(cache_range_window_reg, real_cache_types_only_gen_params), KUNIT_CASE_PARAM(raw_read_defaults_single, raw_test_types_gen_params),
diff --git a/drivers/base/regmap/regmap-ram.c b/drivers/base/regmap/regmap-ram.c index c7356b0..a666bfb 100644 --- a/drivers/base/regmap/regmap-ram.c +++ b/drivers/base/regmap/regmap-ram.c
@@ -20,8 +20,11 @@ static int regmap_ram_write(void *context, unsigned int reg, unsigned int val) { struct regmap_ram_data *data = context; - data->vals[reg] = val; - data->written[reg] = true; + if (reg < data->base_reg) + return -EINVAL; + + data->vals[reg - data->base_reg] = val; + data->written[reg - data->base_reg] = true; return 0; } @@ -30,8 +33,11 @@ static int regmap_ram_read(void *context, unsigned int reg, unsigned int *val) { struct regmap_ram_data *data = context; - *val = data->vals[reg]; - data->read[reg] = true; + if (reg < data->base_reg) + return -EINVAL; + + *val = data->vals[reg - data->base_reg]; + data->read[reg - data->base_reg] = true; return 0; } @@ -60,17 +66,25 @@ struct regmap *__regmap_init_ram(struct device *dev, const char *lock_name) { struct regmap *map; + unsigned int num_regs; if (!config->max_register) { pr_crit("No max_register specified for RAM regmap\n"); return ERR_PTR(-EINVAL); } - data->read = kzalloc_objs(bool, config->max_register + 1); + if (data->base_reg > config->max_register) { + pr_crit("base_reg above max_register for RAM regmap\n"); + return ERR_PTR(-EINVAL); + } + + num_regs = config->max_register - data->base_reg + 1; + + data->read = kzalloc_objs(bool, num_regs); if (!data->read) return ERR_PTR(-ENOMEM); - data->written = kzalloc_objs(bool, config->max_register + 1); + data->written = kzalloc_objs(bool, num_regs); if (!data->written) { kfree(data->read); return ERR_PTR(-ENOMEM);
diff --git a/drivers/base/regmap/regmap-raw-ram.c b/drivers/base/regmap/regmap-raw-ram.c index 60d6e95..c63c464 100644 --- a/drivers/base/regmap/regmap-raw-ram.c +++ b/drivers/base/regmap/regmap-raw-ram.c
@@ -16,14 +16,17 @@ #include "internal.h" -static unsigned int decode_reg(enum regmap_endian endian, const void *reg) +static unsigned int decode_reg(struct regmap_ram_data *data, const void *reg) { const u16 *r = reg; + unsigned int decode; - if (endian == REGMAP_ENDIAN_BIG) - return be16_to_cpu(*r); + if (data->reg_endian == REGMAP_ENDIAN_BIG) + decode = be16_to_cpu(*r); else - return le16_to_cpu(*r); + decode = le16_to_cpu(*r); + + return decode - data->base_reg; } static int regmap_raw_ram_gather_write(void *context, @@ -40,7 +43,7 @@ static int regmap_raw_ram_gather_write(void *context, if (val_len % 2) return -EINVAL; - r = decode_reg(data->reg_endian, reg); + r = decode_reg(data, reg); if (data->noinc_reg && data->noinc_reg(data, r)) { memcpy(&our_buf[r], val + val_len - 2, 2); data->written[r] = true; @@ -74,7 +77,7 @@ static int regmap_raw_ram_read(void *context, if (val_len % 2) return -EINVAL; - r = decode_reg(data->reg_endian, reg); + r = decode_reg(data, reg); if (data->noinc_reg && data->noinc_reg(data, r)) { for (i = 0; i < val_len; i += 2) memcpy(val + i, &our_buf[r], 2); @@ -114,6 +117,7 @@ struct regmap *__regmap_init_raw_ram(struct device *dev, const char *lock_name) { struct regmap *map; + unsigned int regs; if (config->reg_bits != 16) return ERR_PTR(-EINVAL); @@ -123,11 +127,12 @@ struct regmap *__regmap_init_raw_ram(struct device *dev, return ERR_PTR(-EINVAL); } - data->read = kzalloc_objs(bool, config->max_register + 1); + regs = config->max_register - data->base_reg + 1; + data->read = kzalloc_objs(bool, regs); if (!data->read) return ERR_PTR(-ENOMEM); - data->written = kzalloc_objs(bool, config->max_register + 1); + data->written = kzalloc_objs(bool, regs); if (!data->written) return ERR_PTR(-ENOMEM);
diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c index 8e50a05..83f1f59 100644 --- a/drivers/base/regmap/regmap.c +++ b/drivers/base/regmap/regmap.c
@@ -115,9 +115,8 @@ bool regmap_cached(struct regmap *map, unsigned int reg) if (map->max_register_is_set && reg > map->max_register) return false; - map->lock(map->lock_arg); - ret = regcache_read(map, reg, &val); - map->unlock(map->lock_arg); + scoped_guard(regmap, map) + ret = regcache_read(map, reg, &val); if (ret) return false; @@ -1980,18 +1979,12 @@ int _regmap_write(struct regmap *map, unsigned int reg, */ int regmap_write(struct regmap *map, unsigned int reg, unsigned int val) { - int ret; - if (!IS_ALIGNED(reg, map->reg_stride)) return -EINVAL; - map->lock(map->lock_arg); + guard(regmap)(map); - ret = _regmap_write(map, reg, val); - - map->unlock(map->lock_arg); - - return ret; + return _regmap_write(map, reg, val); } EXPORT_SYMBOL_GPL(regmap_write); @@ -2012,7 +2005,7 @@ int regmap_write_async(struct regmap *map, unsigned int reg, unsigned int val) if (!IS_ALIGNED(reg, map->reg_stride)) return -EINVAL; - map->lock(map->lock_arg); + guard(regmap)(map); map->async = true; @@ -2020,8 +2013,6 @@ int regmap_write_async(struct regmap *map, unsigned int reg, unsigned int val) map->async = false; - map->unlock(map->lock_arg); - return ret; } EXPORT_SYMBOL_GPL(regmap_write_async); @@ -2083,20 +2074,14 @@ int _regmap_raw_write(struct regmap *map, unsigned int reg, int regmap_raw_write(struct regmap *map, unsigned int reg, const void *val, size_t val_len) { - int ret; - if (!regmap_can_raw_write(map)) return -EINVAL; if (val_len % map->format.val_bytes) return -EINVAL; - map->lock(map->lock_arg); + guard(regmap)(map); - ret = _regmap_raw_write(map, reg, val, val_len, false); - - map->unlock(map->lock_arg); - - return ret; + return _regmap_raw_write(map, reg, val, val_len, false); } EXPORT_SYMBOL_GPL(regmap_raw_write); @@ -2214,21 +2199,17 @@ int regmap_noinc_write(struct regmap *map, unsigned int reg, if (val_len == 0) return -EINVAL; - map->lock(map->lock_arg); + guard(regmap)(map); - if (!regmap_volatile(map, reg) || !regmap_writeable_noinc(map, reg)) { - ret = -EINVAL; - goto out_unlock; - } + if (!regmap_volatile(map, reg) || !regmap_writeable_noinc(map, reg)) + return -EINVAL; /* * Use the accelerated operation if we can. The val drops the const * typing in order to facilitate code reuse in regmap_noinc_readwrite(). */ - if (map->bus->reg_noinc_write) { - ret = regmap_noinc_readwrite(map, reg, (void *)val, val_len, true); - goto out_unlock; - } + if (map->bus->reg_noinc_write) + return regmap_noinc_readwrite(map, reg, (void *)val, val_len, true); while (val_len) { if (map->max_raw_write && map->max_raw_write < val_len) @@ -2237,14 +2218,12 @@ int regmap_noinc_write(struct regmap *map, unsigned int reg, write_len = val_len; ret = _regmap_raw_write(map, reg, val, write_len, true); if (ret) - goto out_unlock; + return ret; val = ((u8 *)val) + write_len; val_len -= write_len; } -out_unlock: - map->unlock(map->lock_arg); - return ret; + return 0; } EXPORT_SYMBOL_GPL(regmap_noinc_write); @@ -2360,7 +2339,8 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, * single write operations. */ if (!map->write || !map->format.parse_inplace) { - map->lock(map->lock_arg); + guard(regmap)(map); + for (i = 0; i < val_count; i++) { unsigned int ival; @@ -2375,18 +2355,15 @@ int regmap_bulk_write(struct regmap *map, unsigned int reg, const void *val, ival = *(u32 *)(val + (i * val_bytes)); break; default: - ret = -EINVAL; - goto out; + return -EINVAL; } ret = _regmap_write(map, reg + regmap_get_offset(map, i), ival); if (ret != 0) - goto out; + return ret; } -out: - map->unlock(map->lock_arg); } else { void *wval; @@ -2656,15 +2633,9 @@ static int _regmap_multi_reg_write(struct regmap *map, int regmap_multi_reg_write(struct regmap *map, const struct reg_sequence *regs, int num_regs) { - int ret; + guard(regmap)(map); - map->lock(map->lock_arg); - - ret = _regmap_multi_reg_write(map, regs, num_regs); - - map->unlock(map->lock_arg); - - return ret; + return _regmap_multi_reg_write(map, regs, num_regs); } EXPORT_SYMBOL_GPL(regmap_multi_reg_write); @@ -2693,7 +2664,7 @@ int regmap_multi_reg_write_bypassed(struct regmap *map, int ret; bool bypass; - map->lock(map->lock_arg); + guard(regmap)(map); bypass = map->cache_bypass; map->cache_bypass = true; @@ -2702,8 +2673,6 @@ int regmap_multi_reg_write_bypassed(struct regmap *map, map->cache_bypass = bypass; - map->unlock(map->lock_arg); - return ret; } EXPORT_SYMBOL_GPL(regmap_multi_reg_write_bypassed); @@ -2725,7 +2694,7 @@ EXPORT_SYMBOL_GPL(regmap_multi_reg_write_bypassed); * If supported by the underlying bus the write will be scheduled * asynchronously, helping maximise I/O speed on higher speed buses * like SPI. regmap_async_complete() can be called to ensure that all - * asynchrnous writes have been completed. + * asynchronous writes have been completed. * * A value of zero will be returned on success, a negative errno will * be returned in error cases. @@ -2740,7 +2709,7 @@ int regmap_raw_write_async(struct regmap *map, unsigned int reg, if (!IS_ALIGNED(reg, map->reg_stride)) return -EINVAL; - map->lock(map->lock_arg); + guard(regmap)(map); map->async = true; @@ -2748,8 +2717,6 @@ int regmap_raw_write_async(struct regmap *map, unsigned int reg, map->async = false; - map->unlock(map->lock_arg); - return ret; } EXPORT_SYMBOL_GPL(regmap_raw_write_async); @@ -2866,18 +2833,12 @@ static int _regmap_read(struct regmap *map, unsigned int reg, */ int regmap_read(struct regmap *map, unsigned int reg, unsigned int *val) { - int ret; - if (!IS_ALIGNED(reg, map->reg_stride)) return -EINVAL; - map->lock(map->lock_arg); + guard(regmap)(map); - ret = _regmap_read(map, reg, val); - - map->unlock(map->lock_arg); - - return ret; + return _regmap_read(map, reg, val); } EXPORT_SYMBOL_GPL(regmap_read); @@ -2900,7 +2861,7 @@ int regmap_read_bypassed(struct regmap *map, unsigned int reg, unsigned int *val if (!IS_ALIGNED(reg, map->reg_stride)) return -EINVAL; - map->lock(map->lock_arg); + guard(regmap)(map); bypass = map->cache_bypass; cache_only = map->cache_only; @@ -2912,8 +2873,6 @@ int regmap_read_bypassed(struct regmap *map, unsigned int reg, unsigned int *val map->cache_bypass = bypass; map->cache_only = cache_only; - map->unlock(map->lock_arg); - return ret; } EXPORT_SYMBOL_GPL(regmap_read_bypassed); @@ -2944,22 +2903,18 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, if (val_count == 0) return -EINVAL; - map->lock(map->lock_arg); + guard(regmap)(map); if (regmap_volatile_range(map, reg, val_count) || map->cache_bypass || map->cache_type == REGCACHE_NONE) { size_t chunk_count, chunk_bytes; size_t chunk_regs = val_count; - if (!map->cache_bypass && map->cache_only) { - ret = -EBUSY; - goto out; - } + if (!map->cache_bypass && map->cache_only) + return -EBUSY; - if (!map->read) { - ret = -ENOTSUPP; - goto out; - } + if (!map->read) + return -ENOTSUPP; if (map->use_single_read) chunk_regs = 1; @@ -2973,7 +2928,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, for (i = 0; i < chunk_count; i++) { ret = _regmap_raw_read(map, reg, val, chunk_bytes, false); if (ret != 0) - goto out; + return ret; reg += regmap_get_offset(map, chunk_regs); val += chunk_bytes; @@ -2984,7 +2939,7 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, if (val_len) { ret = _regmap_raw_read(map, reg, val, val_len, false); if (ret != 0) - goto out; + return ret; } } else { /* Otherwise go word by word for the cache; should be low @@ -2994,16 +2949,13 @@ int regmap_raw_read(struct regmap *map, unsigned int reg, void *val, ret = _regmap_read(map, reg + regmap_get_offset(map, i), &v); if (ret != 0) - goto out; + return ret; map->format.format_val(val + (i * val_bytes), v, 0); } } - out: - map->unlock(map->lock_arg); - - return ret; + return 0; } EXPORT_SYMBOL_GPL(regmap_raw_read); @@ -3044,12 +2996,10 @@ int regmap_noinc_read(struct regmap *map, unsigned int reg, if (val_len == 0) return -EINVAL; - map->lock(map->lock_arg); + guard(regmap)(map); - if (!regmap_volatile(map, reg) || !regmap_readable_noinc(map, reg)) { - ret = -EINVAL; - goto out_unlock; - } + if (!regmap_volatile(map, reg) || !regmap_readable_noinc(map, reg)) + return -EINVAL; /* * We have not defined the FIFO semantics for cache, as the @@ -3057,16 +3007,12 @@ int regmap_noinc_read(struct regmap *map, unsigned int reg, * written value? Just avoid this by always reading the FIFO * even when using cache. Cache only will not work. */ - if (!map->cache_bypass && map->cache_only) { - ret = -EBUSY; - goto out_unlock; - } + if (!map->cache_bypass && map->cache_only) + return -EBUSY; /* Use the accelerated operation if we can */ - if (map->bus->reg_noinc_read) { - ret = regmap_noinc_readwrite(map, reg, val, val_len, false); - goto out_unlock; - } + if (map->bus->reg_noinc_read) + return regmap_noinc_readwrite(map, reg, val, val_len, false); while (val_len) { if (map->max_raw_read && map->max_raw_read < val_len) @@ -3075,14 +3021,12 @@ int regmap_noinc_read(struct regmap *map, unsigned int reg, read_len = val_len; ret = _regmap_raw_read(map, reg, val, read_len, true); if (ret) - goto out_unlock; + return ret; val = ((u8 *)val) + read_len; val_len -= read_len; } -out_unlock: - map->unlock(map->lock_arg); - return ret; + return 0; } EXPORT_SYMBOL_GPL(regmap_noinc_read); @@ -3152,22 +3096,20 @@ static int _regmap_bulk_read(struct regmap *map, unsigned int reg, u8 *u8 = val; int ret, i; - map->lock(map->lock_arg); + guard(regmap)(map); for (i = 0; i < val_count; i++) { unsigned int ival; if (regs) { - if (!IS_ALIGNED(regs[i], map->reg_stride)) { - ret = -EINVAL; - goto out; - } + if (!IS_ALIGNED(regs[i], map->reg_stride)) + return -EINVAL; ret = _regmap_read(map, regs[i], &ival); } else { ret = _regmap_read(map, reg + regmap_get_offset(map, i), &ival); } if (ret != 0) - goto out; + return ret; switch (map->format.val_bytes) { case 4: @@ -3180,13 +3122,11 @@ static int _regmap_bulk_read(struct regmap *map, unsigned int reg, u8[i] = ival; break; default: - ret = -EINVAL; - goto out; + return -EINVAL; } } -out: - map->unlock(map->lock_arg); - return ret; + + return 0; } /** @@ -3313,7 +3253,7 @@ int regmap_update_bits_base(struct regmap *map, unsigned int reg, { int ret; - map->lock(map->lock_arg); + guard(regmap)(map); map->async = async; @@ -3321,8 +3261,6 @@ int regmap_update_bits_base(struct regmap *map, unsigned int reg, map->async = false; - map->unlock(map->lock_arg); - return ret; } EXPORT_SYMBOL_GPL(regmap_update_bits_base); @@ -3444,31 +3382,26 @@ int regmap_register_patch(struct regmap *map, const struct reg_sequence *regs, num_regs)) return 0; - p = krealloc(map->patch, - sizeof(struct reg_sequence) * (map->patch_regs + num_regs), - GFP_KERNEL); - if (p) { - memcpy(p + map->patch_regs, regs, num_regs * sizeof(*regs)); - map->patch = p; - map->patch_regs += num_regs; - } else { + p = krealloc_array(map->patch, map->patch_regs + num_regs, sizeof(*p), GFP_KERNEL); + if (!p) return -ENOMEM; + + memcpy(p + map->patch_regs, regs, num_regs * sizeof(*regs)); + map->patch = p; + map->patch_regs += num_regs; + + scoped_guard(regmap, map) { + bypass = map->cache_bypass; + + map->cache_bypass = true; + map->async = true; + + ret = _regmap_multi_reg_write(map, regs, num_regs); + + map->async = false; + map->cache_bypass = bypass; } - map->lock(map->lock_arg); - - bypass = map->cache_bypass; - - map->cache_bypass = true; - map->async = true; - - ret = _regmap_multi_reg_write(map, regs, num_regs); - - map->async = false; - map->cache_bypass = bypass; - - map->unlock(map->lock_arg); - regmap_async_complete(map); return ret;
diff --git a/drivers/bus/arm-cci.c b/drivers/bus/arm-cci.c index 7f2baf0..4359526 100644 --- a/drivers/bus/arm-cci.c +++ b/drivers/bus/arm-cci.c
@@ -167,9 +167,12 @@ static int __cci_ace_get_port(struct device_node *dn, int type) cci_portn = of_parse_phandle(dn, "cci-control-port", 0); for (i = 0; i < nb_cci_ports; i++) { ace_match = ports[i].type == type; - if (ace_match && cci_portn == ports[i].dn) + if (ace_match && cci_portn == ports[i].dn) { + of_node_put(cci_portn); return i; + } } + of_node_put(cci_portn); return -ENODEV; } @@ -199,6 +202,7 @@ static void cci_ace_init_ports(void) continue; port = __cci_ace_get_port(cpun, ACE_PORT); + of_node_put(cpun); if (port < 0) continue;
diff --git a/drivers/bus/fsl-mc/fsl-mc-bus.c b/drivers/bus/fsl-mc/fsl-mc-bus.c index 66a4fa7..0c37b67 100644 --- a/drivers/bus/fsl-mc/fsl-mc-bus.c +++ b/drivers/bus/fsl-mc/fsl-mc-bus.c
@@ -11,6 +11,7 @@ #define pr_fmt(fmt) "fsl-mc: " fmt #include <linux/module.h> +#include <linux/fwnode.h> #include <linux/of_device.h> #include <linux/of_address.h> #include <linux/ioport.h> @@ -797,6 +798,10 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, } dev_set_name(&mc_dev->dev, "%s.%d", obj_desc->type, obj_desc->id); + mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK; + mc_dev->dev.dma_mask = &mc_dev->dma_mask; + mc_dev->dev.coherent_dma_mask = mc_dev->dma_mask; + if (strcmp(obj_desc->type, "dprc") == 0) { struct fsl_mc_io *mc_io2; @@ -838,9 +843,6 @@ int fsl_mc_device_add(struct fsl_mc_obj_desc *obj_desc, * parent's ICID. */ mc_dev->icid = parent_mc_dev->icid; - mc_dev->dma_mask = FSL_MC_DEFAULT_DMA_MASK; - mc_dev->dev.dma_mask = &mc_dev->dma_mask; - mc_dev->dev.coherent_dma_mask = mc_dev->dma_mask; } /* @@ -1032,6 +1034,20 @@ static int fsl_mc_firmware_check(struct platform_device *pdev) return 0; } +static void fsl_mc_purge_dpmac_fwnode_links(struct device *dev) +{ + struct device_node *dpmacs, *child; + + dpmacs = of_get_child_by_name(dev->of_node, "dpmacs"); + if (!dpmacs) + return; + + for_each_child_of_node(dpmacs, child) + fwnode_links_purge(of_fwnode_handle(child)); + + of_node_put(dpmacs); +} + /* * fsl_mc_bus_probe - callback invoked when the root MC bus is being * added @@ -1133,6 +1149,8 @@ static int fsl_mc_bus_probe(struct platform_device *pdev) &mc->num_translation_ranges); if (error < 0) goto error_cleanup_mc_io; + + fsl_mc_purge_dpmac_fwnode_links(&pdev->dev); } error = dprc_get_container_id(mc_io, 0, &container_id); @@ -1264,35 +1282,43 @@ static int __init fsl_mc_bus_driver_init(void) error = bus_register(&fsl_mc_bus_type); if (error < 0) { pr_err("bus type registration failed: %d\n", error); - goto error_cleanup_cache; + return error; } - error = platform_driver_register(&fsl_mc_bus_driver); - if (error < 0) { - pr_err("platform_driver_register() failed: %d\n", error); + error = bus_register_notifier(&platform_bus_type, &fsl_mc_nb); + if (error < 0) goto error_cleanup_bus; - } + + return 0; + +error_cleanup_bus: + bus_unregister(&fsl_mc_bus_type); + return error; +} +postcore_initcall(fsl_mc_bus_driver_init); + +static int __init fsl_mc_bus_drivers_init(void) +{ + int error; error = dprc_driver_init(); if (error < 0) - goto error_cleanup_driver; + return error; error = fsl_mc_allocator_driver_init(); if (error < 0) goto error_cleanup_dprc_driver; - return bus_register_notifier(&platform_bus_type, &fsl_mc_nb); + error = platform_driver_register(&fsl_mc_bus_driver); + if (error < 0) { + pr_err("platform_driver_register() failed: %d\n", error); + goto error_cleanup_dprc_driver; + } + + return 0; error_cleanup_dprc_driver: dprc_driver_exit(); - -error_cleanup_driver: - platform_driver_unregister(&fsl_mc_bus_driver); - -error_cleanup_bus: - bus_unregister(&fsl_mc_bus_type); - -error_cleanup_cache: return error; } -postcore_initcall(fsl_mc_bus_driver_init); +subsys_initcall_sync(fsl_mc_bus_drivers_init);
diff --git a/drivers/bus/fsl-mc/fsl-mc-msi.c b/drivers/bus/fsl-mc/fsl-mc-msi.c index be38b43..7d760bf 100644 --- a/drivers/bus/fsl-mc/fsl-mc-msi.c +++ b/drivers/bus/fsl-mc/fsl-mc-msi.c
@@ -57,7 +57,7 @@ static void fsl_mc_write_msi_msg(struct msi_desc *msi_desc, struct msi_msg *msg) } } else { /* - * IRQ is for for a child device of mc_bus_dev + * IRQ is for a child device of mc_bus_dev */ error = dprc_set_obj_irq(mc_bus_dev->mc_io, MC_CMD_FLAG_INTR_DIS | MC_CMD_FLAG_PRI,
diff --git a/drivers/cache/hisi_soc_hha.c b/drivers/cache/hisi_soc_hha.c index 756c433..f0f6c03 100644 --- a/drivers/cache/hisi_soc_hha.c +++ b/drivers/cache/hisi_soc_hha.c
@@ -170,7 +170,7 @@ static void hisi_soc_hha_remove(struct platform_device *pdev) } static const struct acpi_device_id hisi_soc_hha_ids[] = { - { "HISI0511", }, + { .id = "HISI0511" }, { } }; MODULE_DEVICE_TABLE(acpi, hisi_soc_hha_ids);
diff --git a/drivers/cache/sifive_ccache.c b/drivers/cache/sifive_ccache.c index 2acb8bd..71d3f94 100644 --- a/drivers/cache/sifive_ccache.c +++ b/drivers/cache/sifive_ccache.c
@@ -275,7 +275,7 @@ static int sifive_ccache_probe(struct platform_device *pdev) rc = devm_request_irq(dev, g_irq[i], ccache_int_handler, 0, "ccache_ecc", NULL); if (rc) - return dev_err_probe(dev, rc, "Could not request IRQ %d\n", g_irq[i]); + return rc; } return 0;
diff --git a/drivers/char/hw_random/amd-rng.c b/drivers/char/hw_random/amd-rng.c index dff80da..ef177c9 100644 --- a/drivers/char/hw_random/amd-rng.c +++ b/drivers/char/hw_random/amd-rng.c
@@ -80,7 +80,7 @@ static int amd_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) if (timeout-- == 0) return read; } else { - return 0; + return read; } } else { *data = ioread32(priv->iobase + RNGDATA); @@ -129,19 +129,15 @@ static int __init amd_rng_mod_init(void) { int err; struct pci_dev *pdev = NULL; - const struct pci_device_id *ent; u32 pmbase; struct amd768_priv *priv; - for_each_pci_dev(pdev) { - ent = pci_match_id(pci_tbl, pdev); - if (ent) - goto found; - } - /* Device not found. */ - return -ENODEV; + for_each_pci_dev(pdev) + if (pci_match_id(pci_tbl, pdev)) + break; + if (!pdev) + return -ENODEV; -found: err = pci_read_config_dword(pdev, 0x58, &pmbase); if (err) { err = pcibios_err_to_errno(err); @@ -162,16 +158,16 @@ static int __init amd_rng_mod_init(void) if (!request_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE, DRV_NAME)) { dev_err(&pdev->dev, DRV_NAME " region 0x%x already in use!\n", - pmbase + 0xF0); + pmbase + PMBASE_OFFSET); err = -EBUSY; goto out; } priv->iobase = ioport_map(pmbase + PMBASE_OFFSET, PMBASE_SIZE); if (!priv->iobase) { - pr_err(DRV_NAME "Cannot map ioport\n"); + pr_err(DRV_NAME " cannot map ioport\n"); err = -EINVAL; - goto err_iomap; + goto err; } amd_rng.priv = (unsigned long)priv; @@ -182,13 +178,12 @@ static int __init amd_rng_mod_init(void) err = hwrng_register(&amd_rng); if (err) { pr_err(DRV_NAME " registering failed (%d)\n", err); - goto err_hwrng; + ioport_unmap(priv->iobase); + goto err; } return 0; -err_hwrng: - ioport_unmap(priv->iobase); -err_iomap: +err: release_region(pmbase + PMBASE_OFFSET, PMBASE_SIZE); out: kfree(priv);
diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c index 06e79d5..fe44419 100644 --- a/drivers/char/hw_random/atmel-rng.c +++ b/drivers/char/hw_random/atmel-rng.c
@@ -17,6 +17,7 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/units.h> #define TRNG_CR 0x00 #define TRNG_MR 0x04 @@ -85,20 +86,14 @@ static int atmel_trng_read(struct hwrng *rng, void *buf, size_t max, static int atmel_trng_init(struct atmel_trng *trng) { - unsigned long rate; int ret; ret = clk_prepare_enable(trng->clk); if (ret) return ret; - if (trng->has_half_rate) { - rate = clk_get_rate(trng->clk); - - /* if peripheral clk is above 100MHz, set HALFR */ - if (rate > 100000000) - writel(TRNG_HALFR, trng->base + TRNG_MR); - } + if (trng->has_half_rate && clk_get_rate(trng->clk) > 100 * HZ_PER_MHZ) + writel(TRNG_HALFR, trng->base + TRNG_MR); writel(TRNG_KEY | 1, trng->base + TRNG_CR);
diff --git a/drivers/char/hw_random/ba431-rng.c b/drivers/char/hw_random/ba431-rng.c index b0a3903..810c8cd 100644 --- a/drivers/char/hw_random/ba431-rng.c +++ b/drivers/char/hw_random/ba431-rng.c
@@ -147,7 +147,7 @@ static int ba431_trng_read(struct hwrng *rng, void *buf, size_t max, bool wait) } } - n *= sizeof(data); + n *= sizeof(*data); return (n || !wait) ? n : -EIO; }
diff --git a/drivers/char/hw_random/cctrng.c b/drivers/char/hw_random/cctrng.c index a692521..03401ee 100644 --- a/drivers/char/hw_random/cctrng.c +++ b/drivers/char/hw_random/cctrng.c
@@ -86,17 +86,12 @@ static inline u32 cc_ioread(struct cctrng_drvdata *drvdata, u32 reg) static int cc_trng_pm_get(struct device *dev) { - int rc = 0; - - rc = pm_runtime_get_sync(dev); - - /* pm_runtime_get_sync() can return 1 as a valid return code */ - return (rc == 1 ? 0 : rc); + return pm_runtime_resume_and_get(dev); } static void cc_trng_pm_put_suspend(struct device *dev) { - int rc = 0; + int rc; rc = pm_runtime_put_autosuspend(dev); if (rc) @@ -213,7 +208,7 @@ static int cctrng_read(struct hwrng *rng, void *data, size_t max, bool wait) struct cctrng_drvdata *drvdata = (struct cctrng_drvdata *)rng->priv; struct device *dev = &(drvdata->pdev->dev); u32 *buf = (u32 *)drvdata->circ.buf; - size_t copied = 0; + size_t copied; size_t cnt_w; size_t size; size_t left; @@ -273,7 +268,7 @@ static int cctrng_read(struct hwrng *rng, void *data, size_t max, bool wait) static void cc_trng_hw_trigger(struct cctrng_drvdata *drvdata) { - u32 tmp_smpl_cnt = 0; + u32 tmp_smpl_cnt; struct device *dev = &(drvdata->pdev->dev); dev_dbg(dev, "cctrng hw trigger.\n"); @@ -314,8 +309,8 @@ static void cc_trng_hw_trigger(struct cctrng_drvdata *drvdata) static void cc_trng_compwork_handler(struct work_struct *w) { - u32 isr = 0; - u32 ehr_valid = 0; + u32 isr; + u32 ehr_valid; struct cctrng_drvdata *drvdata = container_of(w, struct cctrng_drvdata, compwork); struct device *dev = &(drvdata->pdev->dev); @@ -458,7 +453,7 @@ static int cctrng_probe(struct platform_device *pdev) { struct cctrng_drvdata *drvdata; struct device *dev = &pdev->dev; - int rc = 0; + int rc; u32 val; int irq; @@ -539,7 +534,8 @@ static int cctrng_probe(struct platform_device *pdev) rc = devm_hwrng_register(dev, &drvdata->rng); if (rc) { dev_err(dev, "Could not register hwrng device.\n"); - goto post_pm_err; + cc_trng_pm_fini(drvdata); + return rc; } /* trigger HW to start generate data */ @@ -552,11 +548,6 @@ static int cctrng_probe(struct platform_device *pdev) dev_info(dev, "ARM cctrng device initialized\n"); return 0; - -post_pm_err: - cc_trng_pm_fini(drvdata); - - return rc; } static void cctrng_remove(struct platform_device *pdev)
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c index 57eeefe..1f9e31c 100644 --- a/drivers/char/hw_random/core.c +++ b/drivers/char/hw_random/core.c
@@ -376,6 +376,7 @@ static ssize_t rng_current_store(struct device *dev, cur_rng_set_by_user = 1; drop_current_rng(); } else { + err = -ENODEV; list_for_each_entry(rng, &rng_list, list) { if (sysfs_streq(rng->name, buf)) { err = set_current_rng(rng);
diff --git a/drivers/char/hw_random/imx-rngc.c b/drivers/char/hw_random/imx-rngc.c index 7693328..a095323 100644 --- a/drivers/char/hw_random/imx-rngc.c +++ b/drivers/char/hw_random/imx-rngc.c
@@ -258,7 +258,7 @@ static int __init imx_rngc_probe(struct platform_device *pdev) if (IS_ERR(rngc->base)) return PTR_ERR(rngc->base); - rngc->clk = devm_clk_get(&pdev->dev, NULL); + rngc->clk = devm_clk_get_optional(&pdev->dev, NULL); if (IS_ERR(rngc->clk)) return dev_err_probe(&pdev->dev, PTR_ERR(rngc->clk), "Cannot get rng_clk\n"); @@ -266,7 +266,9 @@ static int __init imx_rngc_probe(struct platform_device *pdev) if (irq < 0) return irq; - clk_prepare_enable(rngc->clk); + ret = clk_prepare_enable(rngc->clk); + if (ret) + return dev_err_probe(&pdev->dev, ret, "Cannot enable rng_clk\n"); ver_id = readl(rngc->base + RNGC_VER_ID); rng_type = FIELD_GET(RNG_TYPE, ver_id); @@ -338,9 +340,7 @@ static int imx_rngc_resume(struct device *dev) { struct imx_rngc *rngc = dev_get_drvdata(dev); - clk_prepare_enable(rngc->clk); - - return 0; + return clk_prepare_enable(rngc->clk); } static const struct dev_pm_ops imx_rngc_pm_ops = {
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c index d24e747..b6a50e3 100644 --- a/drivers/char/hw_random/intel-rng.c +++ b/drivers/char/hw_random/intel-rng.c
@@ -305,11 +305,11 @@ static int __init intel_init_hw_struct(struct intel_rng_hw *intel_rng_hw, if ((intel_rng_hw->bios_cntl_val & (BIOS_CNTL_LOCK_ENABLE_MASK|BIOS_CNTL_WRITE_ENABLE_MASK)) == BIOS_CNTL_LOCK_ENABLE_MASK) { - static __initdata /*const*/ char warning[] = -PFX "Firmware space is locked read-only. If you can't or\n" -PFX "don't want to disable this in firmware setup, and if\n" -PFX "you are certain that your system has a functional\n" -PFX "RNG, try using the 'no_fwh_detect' option.\n"; + static const char warning[] __initconst = + PFX "Firmware space is locked read-only. If you can't or\n" + PFX "don't want to disable this in firmware setup, and if\n" + PFX "you are certain that your system has a functional\n" + PFX "RNG, try using the 'no_fwh_detect' option.\n"; if (no_fwh_detect) return -ENODEV; @@ -318,8 +318,8 @@ PFX "RNG, try using the 'no_fwh_detect' option.\n"; } intel_rng_hw->mem = ioremap(INTEL_FWH_ADDR, INTEL_FWH_ADDR_LEN); - if (intel_rng_hw->mem == NULL) - return -EBUSY; + if (!intel_rng_hw->mem) + return -ENOMEM; return 0; } @@ -327,7 +327,7 @@ PFX "RNG, try using the 'no_fwh_detect' option.\n"; static int __init intel_rng_mod_init(void) { - int err = -ENODEV; + int err; int i; struct pci_dev *dev = NULL; void __iomem *mem; @@ -339,7 +339,7 @@ static int __init intel_rng_mod_init(void) NULL); if (!dev) - goto out; /* Device not found. */ + return -ENODEV; if (no_fwh_detect < 0) { pci_dev_put(dev); @@ -349,7 +349,7 @@ static int __init intel_rng_mod_init(void) intel_rng_hw = kmalloc_obj(*intel_rng_hw); if (!intel_rng_hw) { pci_dev_put(dev); - goto out; + return -ENOMEM; } err = intel_init_hw_struct(intel_rng_hw, dev); @@ -358,7 +358,7 @@ static int __init intel_rng_mod_init(void) kfree(intel_rng_hw); if (err == -ENODEV) goto fwh_done; - goto out; + return err; } /* @@ -374,21 +374,19 @@ static int __init intel_rng_mod_init(void) iounmap(intel_rng_hw->mem); kfree(intel_rng_hw); if (err) - goto out; + return err; fwh_done: - err = -ENOMEM; mem = ioremap(INTEL_RNG_ADDR, INTEL_RNG_ADDR_LEN); if (!mem) - goto out; + return -ENOMEM; intel_rng.priv = (unsigned long)mem; /* Check for Random Number Generator */ - err = -ENODEV; hw_status = hwstatus_get(mem); if ((hw_status & INTEL_RNG_PRESENT) == 0) { iounmap(mem); - goto out; + return -ENODEV; } pr_info("Intel 82802 RNG detected\n"); @@ -397,10 +395,10 @@ static int __init intel_rng_mod_init(void) pr_err(PFX "RNG registering failed (%d)\n", err); iounmap(mem); + return err; } -out: - return err; + return 0; } static void __exit intel_rng_mod_exit(void)
diff --git a/drivers/char/hw_random/jh7110-trng.c b/drivers/char/hw_random/jh7110-trng.c index aee12ca..61eb4db 100644 --- a/drivers/char/hw_random/jh7110-trng.c +++ b/drivers/char/hw_random/jh7110-trng.c
@@ -320,9 +320,17 @@ static int starfive_trng_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(trng->rst), "Error getting hardware reset line\n"); - clk_prepare_enable(trng->hclk); - clk_prepare_enable(trng->ahb); - reset_control_deassert(trng->rst); + ret = clk_prepare_enable(trng->hclk); + if (ret) + return ret; + + ret = clk_prepare_enable(trng->ahb); + if (ret) + goto disable_hclk; + + ret = reset_control_deassert(trng->rst); + if (ret) + goto disable_ahb; trng->rng.name = dev_driver_string(&pdev->dev); trng->rng.init = starfive_trng_init; @@ -342,13 +350,18 @@ static int starfive_trng_probe(struct platform_device *pdev) pm_runtime_disable(&pdev->dev); reset_control_assert(trng->rst); - clk_disable_unprepare(trng->ahb); - clk_disable_unprepare(trng->hclk); - - return dev_err_probe(&pdev->dev, ret, "Failed to register hwrng\n"); + ret = dev_err_probe(&pdev->dev, ret, "Failed to register hwrng\n"); + goto disable_ahb; } return 0; + +disable_ahb: + clk_disable_unprepare(trng->ahb); +disable_hclk: + clk_disable_unprepare(trng->hclk); + + return ret; } static int __maybe_unused starfive_trng_suspend(struct device *dev) @@ -364,11 +377,17 @@ static int __maybe_unused starfive_trng_suspend(struct device *dev) static int __maybe_unused starfive_trng_resume(struct device *dev) { struct starfive_trng *trng = dev_get_drvdata(dev); + int ret; - clk_prepare_enable(trng->hclk); - clk_prepare_enable(trng->ahb); + ret = clk_prepare_enable(trng->hclk); + if (ret) + return ret; - return 0; + ret = clk_prepare_enable(trng->ahb); + if (ret) + clk_disable_unprepare(trng->hclk); + + return ret; } static const struct dev_pm_ops starfive_trng_pm_ops = {
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c index 9f0545c..22cde35ebe 100644 --- a/drivers/char/hw_random/omap-rng.c +++ b/drivers/char/hw_random/omap-rng.c
@@ -530,7 +530,7 @@ static void omap_rng_remove(struct platform_device *pdev) clk_disable_unprepare(priv->clk_reg); } -static int __maybe_unused omap_rng_suspend(struct device *dev) +static int omap_rng_suspend(struct device *dev) { struct omap_rng_dev *priv = dev_get_drvdata(dev); @@ -540,7 +540,7 @@ static int __maybe_unused omap_rng_suspend(struct device *dev) return 0; } -static int __maybe_unused omap_rng_resume(struct device *dev) +static int omap_rng_resume(struct device *dev) { struct omap_rng_dev *priv = dev_get_drvdata(dev); int ret; @@ -556,12 +556,12 @@ static int __maybe_unused omap_rng_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(omap_rng_pm, omap_rng_suspend, omap_rng_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(omap_rng_pm, omap_rng_suspend, omap_rng_resume); static struct platform_driver omap_rng_driver = { .driver = { .name = "omap_rng", - .pm = &omap_rng_pm, + .pm = pm_sleep_ptr(&omap_rng_pm), .of_match_table = of_match_ptr(omap_rng_of_match), }, .probe = omap_rng_probe,
diff --git a/drivers/char/hw_random/omap3-rom-rng.c b/drivers/char/hw_random/omap3-rom-rng.c index aa71f61..0797add 100644 --- a/drivers/char/hw_random/omap3-rom-rng.c +++ b/drivers/char/hw_random/omap3-rom-rng.c
@@ -42,12 +42,9 @@ static int omap3_rom_rng_read(struct hwrng *rng, void *data, size_t max, bool w) ddata = (struct omap_rom_rng *)rng->priv; - r = pm_runtime_get_sync(ddata->dev); - if (r < 0) { - pm_runtime_put_noidle(ddata->dev); - + r = pm_runtime_resume_and_get(ddata->dev); + if (r < 0) return r; - } ptr = virt_to_phys(data); r = ddata->rom_rng_call(ptr, 4, RNG_GEN_HW);
diff --git a/drivers/char/hw_random/stm32-rng.c b/drivers/char/hw_random/stm32-rng.c index f5bfe54..739263e 100644 --- a/drivers/char/hw_random/stm32-rng.c +++ b/drivers/char/hw_random/stm32-rng.c
@@ -156,7 +156,7 @@ static int stm32_rng_conceal_seed_error_cond_reset(struct stm32_rng_private *pri */ static int stm32_rng_conceal_seed_error_sw_reset(struct stm32_rng_private *priv) { - unsigned int i = 0; + unsigned int i; u32 sr = readl_relaxed(priv->base + RNG_SR); writel_relaxed(sr & ~RNG_SR_SEIS, priv->base + RNG_SR); @@ -187,7 +187,7 @@ static int stm32_rng_read(struct hwrng *rng, void *data, size_t max, bool wait) { struct stm32_rng_private *priv = container_of(rng, struct stm32_rng_private, rng); unsigned int i = 0; - int retval = 0, err = 0; + int retval, err; u32 sr; retval = pm_runtime_resume_and_get(priv->dev); @@ -264,7 +264,7 @@ static uint stm32_rng_clock_freq_restrain(struct hwrng *rng) { struct stm32_rng_private *priv = container_of(rng, struct stm32_rng_private, rng); - unsigned long clock_rate = 0; + unsigned long clock_rate; uint clock_div = 0; clock_rate = clk_get_rate(priv->clk_bulk[0].clk); @@ -277,7 +277,7 @@ static uint stm32_rng_clock_freq_restrain(struct hwrng *rng) while ((clock_rate >> clock_div) > priv->data->max_clock_rate) clock_div++; - pr_debug("RNG clk rate : %lu\n", clk_get_rate(priv->clk_bulk[0].clk) >> clock_div); + pr_debug("RNG clk rate: %lu\n", clock_rate >> clock_div); return clock_div; } @@ -528,14 +528,13 @@ static int stm32_rng_probe(struct platform_device *ofdev) struct device *dev = &ofdev->dev; struct device_node *np = ofdev->dev.of_node; struct stm32_rng_private *priv; - struct resource *res; int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; - priv->base = devm_platform_get_and_ioremap_resource(ofdev, 0, &res); + priv->base = devm_platform_ioremap_resource(ofdev, 0); if (IS_ERR(priv->base)) return PTR_ERR(priv->base); @@ -569,18 +568,11 @@ static int stm32_rng_probe(struct platform_device *ofdev) return dev_err_probe(dev, -EINVAL, "Failed to get clocks: %d\n", ret); if (priv->data->nb_clock == 2) { - const char *id = priv->clk_bulk[1].id; - struct clk *clk = priv->clk_bulk[1].clk; - if (!priv->clk_bulk[0].id || !priv->clk_bulk[1].id) return dev_err_probe(dev, -EINVAL, "Missing clock name\n"); - if (strcmp(priv->clk_bulk[0].id, "core")) { - priv->clk_bulk[1].id = priv->clk_bulk[0].id; - priv->clk_bulk[1].clk = priv->clk_bulk[0].clk; - priv->clk_bulk[0].id = id; - priv->clk_bulk[0].clk = clk; - } + if (strcmp(priv->clk_bulk[0].id, "core")) + swap(priv->clk_bulk[0], priv->clk_bulk[1]); } pm_runtime_set_autosuspend_delay(dev, 100);
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 5e83ffa..f998221 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c
@@ -81,13 +81,13 @@ static unsigned int copy_data(struct virtrng_info *vi, void *buf, * steered into adjacent slab memory, including under * speculation. */ - avail = min_t(unsigned int, vi->data_avail, sizeof(vi->data)); + avail = min(vi->data_avail, sizeof(vi->data)); if (vi->data_idx >= avail) { vi->data_avail = 0; request_entropy(vi); return 0; } - size = min_t(unsigned int, size, avail - vi->data_idx); + size = min(size, avail - vi->data_idx); idx = array_index_nospec(vi->data_idx, sizeof(vi->data)); memcpy(buf, vi->data + idx, size); vi->data_idx += size; @@ -162,7 +162,7 @@ static int probe_common(struct virtio_device *vdev) err = index; goto err_ida; } - sprintf(vi->name, "virtio_rng.%d", index); + snprintf(vi->name, sizeof(vi->name), "virtio_rng.%d", vi->index); init_completion(&vi->have_data); vi->hwrng = (struct hwrng) {
diff --git a/drivers/clk/clk-bd718x7.c b/drivers/clk/clk-bd718x7.c index 8ddb50c..1698b76 100644 --- a/drivers/clk/clk-bd718x7.c +++ b/drivers/clk/clk-bd718x7.c
@@ -21,6 +21,9 @@ #define BD718XX_REG_OUT32K 0x2E /* BD72720 */ #define BD72720_REG_OUT32K 0x9a +/* BD73800 */ +#define BD73800_REG_OUT32K 0x50 + /* * BD71837, BD71847, and BD71828 all use bit [0] to clk output control */ @@ -123,6 +126,10 @@ static int bd71837_clk_probe(struct platform_device *pdev) c->reg = BD72720_REG_OUT32K; c->mask = CLK_OUT_EN_MASK; break; + case ROHM_CHIP_TYPE_BD73800: + c->reg = BD73800_REG_OUT32K; + c->mask = CLK_OUT_EN_MASK; + break; default: dev_err(&pdev->dev, "Unknown clk chip\n"); return -EINVAL; @@ -152,6 +159,7 @@ static const struct platform_device_id bd718x7_clk_id[] = { { .name = "bd71828-clk", .driver_data = ROHM_CHIP_TYPE_BD71828 }, { .name = "bd71815-clk", .driver_data = ROHM_CHIP_TYPE_BD71815 }, { .name = "bd72720-clk", .driver_data = ROHM_CHIP_TYPE_BD72720 }, + { .name = "bd73800-clk", .driver_data = ROHM_CHIP_TYPE_BD73800 }, { } }; MODULE_DEVICE_TABLE(platform, bd718x7_clk_id);
diff --git a/drivers/cpuidle/cpuidle-psci-domain.c b/drivers/cpuidle/cpuidle-psci-domain.c index b9e4ad7..5722365 100644 --- a/drivers/cpuidle/cpuidle-psci-domain.c +++ b/drivers/cpuidle/cpuidle-psci-domain.c
@@ -68,9 +68,8 @@ static int psci_pd_init(struct device_node *np, bool use_osi) */ if (use_osi) { pd->power_off = psci_pd_power_off; - pd->flags |= GENPD_FLAG_ACTIVE_WAKEUP; - if (IS_ENABLED(CONFIG_PREEMPT_RT)) - pd->flags |= GENPD_FLAG_RPM_ALWAYS_ON; + pd->flags |= GENPD_FLAG_ACTIVE_WAKEUP | GENPD_FLAG_POWER_UNKNOWN; + pd->state_idx = pd->state_count ? pd->state_count - 1 : 0; } else { pd->flags |= GENPD_FLAG_ALWAYS_ON; } @@ -78,7 +77,7 @@ static int psci_pd_init(struct device_node *np, bool use_osi) /* Use governor for CPU PM domains if it has some states to manage. */ pd_gov = pd->states ? &pm_domain_cpu_gov : NULL; - ret = pm_genpd_init(pd, pd_gov, false); + ret = pm_genpd_init(pd, pd_gov, use_osi); if (ret) goto free_pd_prov;
diff --git a/drivers/cpuidle/cpuidle-psci.c b/drivers/cpuidle/cpuidle-psci.c index b250d0d..0187d6a 100644 --- a/drivers/cpuidle/cpuidle-psci.c +++ b/drivers/cpuidle/cpuidle-psci.c
@@ -479,4 +479,4 @@ static int __init psci_idle_init(void) return 0; } -device_initcall(psci_idle_init); +subsys_initcall(psci_idle_init);
diff --git a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c index 36a1ebc..56ba4ff 100644 --- a/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c +++ b/drivers/crypto/allwinner/sun8i-ss/sun8i-ss-hash.c
@@ -120,12 +120,11 @@ int sun8i_ss_hash_init_tfm(struct crypto_ahash *tfm) memcpy(algt->fbname, crypto_ahash_driver_name(op->fallback_tfm), CRYPTO_MAX_ALG_NAME); - err = pm_runtime_get_sync(op->ss->dev); + err = pm_runtime_resume_and_get(op->ss->dev); if (err < 0) goto error_pm; return 0; error_pm: - pm_runtime_put_noidle(op->ss->dev); crypto_free_ahash(op->fallback_tfm); return err; }
diff --git a/drivers/crypto/amcc/crypto4xx_core.c b/drivers/crypto/amcc/crypto4xx_core.c index fd010bf..acf18b7 100644 --- a/drivers/crypto/amcc/crypto4xx_core.c +++ b/drivers/crypto/amcc/crypto4xx_core.c
@@ -1046,8 +1046,7 @@ static void crypto4xx_bh_tasklet_cb(unsigned long data) static inline irqreturn_t crypto4xx_interrupt_handler(int irq, void *data, u32 clr_val) { - struct device *dev = data; - struct crypto4xx_core_device *core_dev = dev_get_drvdata(dev); + struct crypto4xx_core_device *core_dev = data; writel(clr_val, core_dev->dev->ce_base + CRYPTO4XX_INT_CLR); tasklet_schedule(&core_dev->tasklet); @@ -1206,9 +1205,19 @@ static int crypto4xx_probe(struct platform_device *ofdev) struct device *dev = &ofdev->dev; struct crypto4xx_core_device *core_dev; struct device_node *np; + void __iomem *ce_base; + int irq; u32 pvr; bool is_revb = true; + irq = platform_get_irq(ofdev, 0); + if (irq < 0) + return irq; + + ce_base = devm_platform_ioremap_resource(ofdev, 0); + if (IS_ERR(ce_base)) + return PTR_ERR(ce_base); + np = of_find_compatible_node(NULL, NULL, "amcc,ppc460ex-crypto"); if (np) { mtdcri(SDR0, PPC460EX_SDR0_SRST, @@ -1251,9 +1260,7 @@ static int crypto4xx_probe(struct platform_device *ofdev) if (!core_dev->dev) return -ENOMEM; - core_dev->dev->ce_base = devm_platform_ioremap_resource(ofdev, 0); - if (IS_ERR(core_dev->dev->ce_base)) - return PTR_ERR(core_dev->dev->ce_base); + core_dev->dev->ce_base = ce_base; /* * Older version of 460EX/GT have a hardware bug. @@ -1291,15 +1298,11 @@ static int crypto4xx_probe(struct platform_device *ofdev) (unsigned long) dev); /* Register for Crypto isr, Crypto Engine IRQ */ - core_dev->irq = platform_get_irq(ofdev, 0); - if (core_dev->irq < 0) { - rc = core_dev->irq; - goto err_tasklet; - } + core_dev->irq = irq; rc = request_irq(core_dev->irq, is_revb ? crypto4xx_ce_interrupt_handler_revb : crypto4xx_ce_interrupt_handler, - 0, KBUILD_MODNAME, dev); + 0, KBUILD_MODNAME, core_dev); if (rc) goto err_tasklet; @@ -1312,11 +1315,15 @@ static int crypto4xx_probe(struct platform_device *ofdev) if (rc) goto err_irq; - ppc4xx_trng_probe(core_dev); + rc = ppc4xx_trng_probe(core_dev); + if (rc) + goto err_crypto; return 0; +err_crypto: + crypto4xx_unregister_alg(core_dev->dev); err_irq: - free_irq(core_dev->irq, dev); + free_irq(core_dev->irq, core_dev); err_tasklet: tasklet_kill(&core_dev->tasklet); err_build_sdr: @@ -1337,7 +1344,7 @@ static void crypto4xx_remove(struct platform_device *ofdev) * Free IRQ before killing the tasklet to prevent the interrupt * handler from rescheduling the tasklet after it has been killed. */ - free_irq(core_dev->irq, dev); + free_irq(core_dev->irq, core_dev); tasklet_kill(&core_dev->tasklet); /* Un-register with Linux CryptoAPI */ crypto4xx_unregister_alg(core_dev->dev);
diff --git a/drivers/crypto/amcc/crypto4xx_trng.c b/drivers/crypto/amcc/crypto4xx_trng.c index cfd66b7..83e9353 100644 --- a/drivers/crypto/amcc/crypto4xx_trng.c +++ b/drivers/crypto/amcc/crypto4xx_trng.c
@@ -68,7 +68,7 @@ static const struct of_device_id ppc4xx_trng_match[] = { {}, }; -void ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev) +int ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev) { struct crypto4xx_device *dev = core_dev->dev; struct device_node *trng = NULL; @@ -79,17 +79,21 @@ void ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev) trng = of_find_matching_node(NULL, ppc4xx_trng_match); if (!trng || !of_device_is_available(trng)) { of_node_put(trng); - return; + return 0; } dev->trng_base = of_iomap(trng, 0); of_node_put(trng); - if (!dev->trng_base) + if (!dev->trng_base) { + err = -EINVAL; goto err_out; + } rng = kzalloc_obj(*rng); - if (!rng) + if (!rng) { + err = -ENOMEM; goto err_out; + } rng->name = KBUILD_MODNAME; rng->data_present = ppc4xx_trng_data_present; @@ -105,13 +109,14 @@ void ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev) err); goto err_out; } - return; + return 0; err_out: iounmap(dev->trng_base); kfree(rng); dev->trng_base = NULL; core_dev->trng = NULL; + return err; } void ppc4xx_trng_remove(struct crypto4xx_core_device *core_dev)
diff --git a/drivers/crypto/amcc/crypto4xx_trng.h b/drivers/crypto/amcc/crypto4xx_trng.h index 7356716..1030c3c 100644 --- a/drivers/crypto/amcc/crypto4xx_trng.h +++ b/drivers/crypto/amcc/crypto4xx_trng.h
@@ -13,11 +13,11 @@ #define __CRYPTO4XX_TRNG_H__ #ifdef CONFIG_HW_RANDOM_PPC4XX -void ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev); +int ppc4xx_trng_probe(struct crypto4xx_core_device *core_dev); void ppc4xx_trng_remove(struct crypto4xx_core_device *core_dev); #else -static inline void ppc4xx_trng_probe( - struct crypto4xx_core_device *dev __maybe_unused) { } +static inline int ppc4xx_trng_probe( + struct crypto4xx_core_device *dev __maybe_unused) { return 0; } static inline void ppc4xx_trng_remove( struct crypto4xx_core_device *dev __maybe_unused) { } #endif
diff --git a/drivers/crypto/amlogic/amlogic-gxl-cipher.c b/drivers/crypto/amlogic/amlogic-gxl-cipher.c index 29048da6..d78815b 100644 --- a/drivers/crypto/amlogic/amlogic-gxl-cipher.c +++ b/drivers/crypto/amlogic/amlogic-gxl-cipher.c
@@ -177,10 +177,13 @@ static int meson_cipher(struct skcipher_request *areq) if (areq->src == areq->dst) { nr_sgs = dma_map_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_BIDIRECTIONAL); - if (!nr_sgs) { - dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs); + if (!nr_sgs || nr_sgs > MAXDESC - 3) { + dev_err(mc->dev, "Invalid BIDIR SG count %d\n", nr_sgs); err = -EINVAL; - goto theend; + + if (nr_sgs) + dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_BIDIRECTIONAL); + goto error_keyiv; } nr_sgd = nr_sgs; } else { @@ -189,14 +192,20 @@ static int meson_cipher(struct skcipher_request *areq) if (!nr_sgs || nr_sgs > MAXDESC - 3) { dev_err(mc->dev, "Invalid SG count %d\n", nr_sgs); err = -EINVAL; - goto theend; + + if (nr_sgs) + dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE); + goto error_keyiv; } nr_sgd = dma_map_sg(mc->dev, areq->dst, sg_nents(areq->dst), DMA_FROM_DEVICE); if (!nr_sgd || nr_sgd > MAXDESC - 3) { dev_err(mc->dev, "Invalid SG count %d\n", nr_sgd); err = -EINVAL; - goto theend; + + if (nr_sgd) + dma_unmap_sg(mc->dev, areq->dst, sg_nents(areq->dst), DMA_FROM_DEVICE); + goto error_src; } } @@ -251,6 +260,12 @@ static int meson_cipher(struct skcipher_request *areq) ivsize, 0); } } + goto theend; + +error_src: + dma_unmap_sg(mc->dev, areq->src, sg_nents(areq->src), DMA_TO_DEVICE); +error_keyiv: + dma_unmap_single(mc->dev, phykeyiv, keyivlen, DMA_TO_DEVICE); theend: kfree_sensitive(bkeyiv); kfree_sensitive(backup_iv);
diff --git a/drivers/crypto/amlogic/amlogic-gxl-core.c b/drivers/crypto/amlogic/amlogic-gxl-core.c index 169c6ee..d5d8452 100644 --- a/drivers/crypto/amlogic/amlogic-gxl-core.c +++ b/drivers/crypto/amlogic/amlogic-gxl-core.c
@@ -37,12 +37,13 @@ static irqreturn_t meson_irq_handler(int irq, void *data) complete(&mc->chanlist[flow].complete); return IRQ_HANDLED; } - dev_err(mc->dev, "%s %d Got irq for flow %d but ctrl is empty\n", __func__, irq, flow); + dev_err_ratelimited(mc->dev, "%s %d Got irq for flow %d but ctrl is empty\n", __func__, irq, flow); + return IRQ_NONE; } } - dev_err(mc->dev, "%s %d from unknown irq\n", __func__, irq); - return IRQ_HANDLED; + dev_err_ratelimited(mc->dev, "%s %d from unknown irq\n", __func__, irq); + return IRQ_NONE; } static struct meson_alg_template mc_algs[] = { @@ -243,33 +244,29 @@ static int meson_crypto_probe(struct platform_device *pdev) if (IS_ERR(mc->base)) return PTR_ERR(mc->base); - mc->busclk = devm_clk_get(&pdev->dev, "blkmv"); + mc->busclk = devm_clk_get_enabled(&pdev->dev, "blkmv"); if (IS_ERR(mc->busclk)) { err = PTR_ERR(mc->busclk); - dev_err(&pdev->dev, "Cannot get core clock err=%d\n", err); - return err; - } - - for (i = 0; i < MAXFLOW; i++) { - mc->irqs[i] = platform_get_irq(pdev, i); - if (mc->irqs[i] < 0) - return mc->irqs[i]; - - err = devm_request_irq(&pdev->dev, mc->irqs[i], meson_irq_handler, 0, - "gxl-crypto", mc); - if (err < 0) - return err; - } - - err = clk_prepare_enable(mc->busclk); - if (err != 0) { - dev_err(&pdev->dev, "Cannot prepare_enable busclk\n"); + dev_err(&pdev->dev, "Cannot get/enable core clock err=%d\n", err); return err; } err = meson_allocate_chanlist(mc); if (err) - goto error_flow; + return err; + + for (i = 0; i < MAXFLOW; i++) { + mc->irqs[i] = platform_get_irq(pdev, i); + if (mc->irqs[i] < 0) { + err = mc->irqs[i]; + goto error_chanlist; + } + + err = devm_request_irq(&pdev->dev, mc->irqs[i], meson_irq_handler, 0, + "gxl-crypto", mc); + if (err < 0) + goto error_chanlist; + } err = meson_register_algs(mc); if (err) @@ -289,9 +286,8 @@ static int meson_crypto_probe(struct platform_device *pdev) return 0; error_alg: meson_unregister_algs(mc); +error_chanlist: meson_free_chanlist(mc, MAXFLOW - 1); -error_flow: - clk_disable_unprepare(mc->busclk); return err; } @@ -306,8 +302,6 @@ static void meson_crypto_remove(struct platform_device *pdev) meson_unregister_algs(mc); meson_free_chanlist(mc, MAXFLOW - 1); - - clk_disable_unprepare(mc->busclk); } static const struct of_device_id meson_crypto_of_match_table[] = {
diff --git a/drivers/crypto/aspeed/aspeed-hace-crypto.c b/drivers/crypto/aspeed/aspeed-hace-crypto.c index fa201dae..e7d3f611 100644 --- a/drivers/crypto/aspeed/aspeed-hace-crypto.c +++ b/drivers/crypto/aspeed/aspeed-hace-crypto.c
@@ -576,7 +576,6 @@ static int aspeed_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, { struct aspeed_cipher_ctx *ctx = crypto_skcipher_ctx(cipher); struct aspeed_hace_dev *hace_dev = ctx->hace_dev; - struct crypto_aes_ctx gen_aes_key; CIPHER_DBG(hace_dev, "keylen: %d bits\n", (keylen * 8)); @@ -585,9 +584,9 @@ static int aspeed_aes_setkey(struct crypto_skcipher *cipher, const u8 *key, return -EINVAL; if (ctx->hace_dev->version == AST2500_VERSION) { + struct crypto_aes_ctx gen_aes_key __cleanup(aes_zeroize_ctx); aes_expandkey(&gen_aes_key, key, keylen); memcpy(ctx->key, gen_aes_key.key_enc, AES_MAX_KEYLENGTH); - } else { memcpy(ctx->key, key, keylen); }
diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c index 50d97ce..8439241 100644 --- a/drivers/crypto/atmel-aes.c +++ b/drivers/crypto/atmel-aes.c
@@ -1267,7 +1267,7 @@ static int atmel_aes_gcm_ghash_init(struct atmel_aes_dev *dd) struct atmel_aes_gcm_ctx *ctx = atmel_aes_gcm_ctx_cast(dd->ctx); /* Set the data length. */ - atmel_aes_write(dd, AES_AADLENR, dd->total); + atmel_aes_write(dd, AES_AADLENR, dd->datalen); atmel_aes_write(dd, AES_CLENR, 0); /* If needed, overwrite the GCM Intermediate Hash Word Registers */ @@ -1826,6 +1826,8 @@ static int atmel_aes_authenc_transfer(struct atmel_aes_dev *dd, int err, dd->is_async = true; if (err) return atmel_aes_complete(dd, err); + if (!rctx->textlen) + return atmel_aes_authenc_digest(dd); /* Prepare src and dst scatter-lists to transfer cipher/plain texts. */ src = scatterwalk_ffwd(rctx->src, req->src, req->assoclen);
diff --git a/drivers/crypto/atmel-ecc.c b/drivers/crypto/atmel-ecc.c index 075f38a..b538e81 100644 --- a/drivers/crypto/atmel-ecc.c +++ b/drivers/crypto/atmel-ecc.c
@@ -177,16 +177,14 @@ static int atmel_ecdh_compute_shared_secret(struct kpp_request *req) work_data->client = ctx->client; ret = atmel_i2c_init_ecdh_cmd(&work_data->cmd, req->src); - if (ret) - goto free_work_data; + if (ret) { + kfree(work_data); + return ret; + } atmel_i2c_enqueue(work_data, atmel_ecdh_done, req); return -EINPROGRESS; - -free_work_data: - kfree(work_data); - return ret; } static struct i2c_client *atmel_ecc_i2c_client_alloc(void) @@ -348,6 +346,7 @@ static void atmel_ecc_remove(struct i2c_client *client) static const struct of_device_id atmel_ecc_dt_ids[] = { { .compatible = "atmel,atecc508a", }, + { .compatible = "atmel,atecc608a", }, { .compatible = "atmel,atecc608b", }, { } }; @@ -355,6 +354,7 @@ MODULE_DEVICE_TABLE(of, atmel_ecc_dt_ids); static const struct i2c_device_id atmel_ecc_id[] = { { .name = "atecc508a" }, + { .name = "atecc608a" }, { .name = "atecc608b" }, { } };
diff --git a/drivers/crypto/atmel-sha.c b/drivers/crypto/atmel-sha.c index 48f54b6..4b883a8 100644 --- a/drivers/crypto/atmel-sha.c +++ b/drivers/crypto/atmel-sha.c
@@ -422,6 +422,9 @@ static int atmel_sha_init(struct ahash_request *req) struct atmel_sha_reqctx *ctx = ahash_request_ctx(req); struct atmel_sha_dev *dd = atmel_sha_find_dev(tctx); + if (!dd) + return -ENODEV; + ctx->dd = dd; ctx->flags = 0; @@ -1203,7 +1206,7 @@ static int atmel_sha_finup(struct ahash_request *req) /* * final() has to be always called to cleanup resources - * even if udpate() failed, except EINPROGRESS + * even if update() failed, except EINPROGRESS */ err2 = atmel_sha_final(req); @@ -1338,7 +1341,7 @@ static int atmel_sha_done(struct atmel_sha_dev *dd) return err; finish: - /* finish curent request */ + /* finish current request */ atmel_sha_finish_req(dd->req, err); return err; @@ -2383,11 +2386,25 @@ static int atmel_sha_authenc_final_done(struct atmel_sha_dev *dd) { struct ahash_request *req = dd->req; struct atmel_sha_authenc_reqctx *authctx = ahash_request_ctx(req); + atmel_aes_authenc_fn_t cb; + struct atmel_aes_dev *aes_dev; size_t i, num_words = authctx->digestlen / sizeof(u32); for (i = 0; i < num_words; ++i) authctx->digest[i] = atmel_sha_read(dd, SHA_REG_DIGEST(i)); + if (!dd->is_async) { + /* + * Return the AES finalizer's status directly for synchronous requests. + * The ahash callback cannot propagate it. + */ + cb = authctx->cb; + aes_dev = authctx->aes_dev; + dd->force_complete = false; + (void)atmel_sha_complete(dd, 0); + return cb(aes_dev, 0, false); + } + return atmel_sha_complete(dd, 0); }
diff --git a/drivers/crypto/atmel-tdes.c b/drivers/crypto/atmel-tdes.c index ffea1db..6b561b3 100644 --- a/drivers/crypto/atmel-tdes.c +++ b/drivers/crypto/atmel-tdes.c
@@ -308,45 +308,33 @@ static int atmel_tdes_crypt_pdc_stop(struct atmel_tdes_dev *dd) static int atmel_tdes_buff_init(struct atmel_tdes_dev *dd) { - int err = -ENOMEM; - dd->buf_in = (void *)__get_free_page(GFP_KERNEL); dd->buf_out = (void *)__get_free_page(GFP_KERNEL); - dd->buflen = PAGE_SIZE; - dd->buflen &= ~(DES_BLOCK_SIZE - 1); + dd->buflen = PAGE_SIZE & ~(DES_BLOCK_SIZE - 1); if (!dd->buf_in || !dd->buf_out) { - dev_dbg(dd->dev, "unable to alloc pages.\n"); + dev_err(dd->dev, "failed to allocate DMA buffers\n"); goto err_alloc; } - /* MAP here */ - dd->dma_addr_in = dma_map_single(dd->dev, dd->buf_in, - dd->buflen, DMA_TO_DEVICE); - err = dma_mapping_error(dd->dev, dd->dma_addr_in); - if (err) { - dev_dbg(dd->dev, "dma %zd bytes error\n", dd->buflen); - goto err_map_in; - } + dd->dma_addr_in = dma_map_single(dd->dev, dd->buf_in, dd->buflen, DMA_TO_DEVICE); + if (dma_mapping_error(dd->dev, dd->dma_addr_in)) + goto err_map; - dd->dma_addr_out = dma_map_single(dd->dev, dd->buf_out, - dd->buflen, DMA_FROM_DEVICE); - err = dma_mapping_error(dd->dev, dd->dma_addr_out); - if (err) { - dev_dbg(dd->dev, "dma %zd bytes error\n", dd->buflen); - goto err_map_out; + dd->dma_addr_out = dma_map_single(dd->dev, dd->buf_out, dd->buflen, DMA_FROM_DEVICE); + if (dma_mapping_error(dd->dev, dd->dma_addr_out)) { + dma_unmap_single(dd->dev, dd->dma_addr_in, dd->buflen, DMA_TO_DEVICE); + goto err_map; } return 0; -err_map_out: - dma_unmap_single(dd->dev, dd->dma_addr_in, dd->buflen, - DMA_TO_DEVICE); -err_map_in: +err_map: + dev_err(dd->dev, "failed to map %zu bytes for DMA\n", dd->buflen); err_alloc: free_page((unsigned long)dd->buf_out); free_page((unsigned long)dd->buf_in); - return err; + return -ENOMEM; } static void atmel_tdes_buff_cleanup(struct atmel_tdes_dev *dd) @@ -361,18 +349,9 @@ static void atmel_tdes_buff_cleanup(struct atmel_tdes_dev *dd) static int atmel_tdes_crypt_pdc(struct atmel_tdes_dev *dd, dma_addr_t dma_addr_in, - dma_addr_t dma_addr_out, int length) + dma_addr_t dma_addr_out) { - int len32; - - dd->dma_size = length; - - if (!(dd->flags & TDES_FLAGS_FAST)) { - dma_sync_single_for_device(dd->dev, dma_addr_in, length, - DMA_TO_DEVICE); - } - - len32 = DIV_ROUND_UP(length, sizeof(u32)); + u32 len32 = DIV_ROUND_UP(dd->dma_size, sizeof(u32)); atmel_tdes_write(dd, TDES_PTCR, TDES_PTCR_TXTDIS|TDES_PTCR_RXTDIS); atmel_tdes_write(dd, TDES_TPR, dma_addr_in); @@ -391,46 +370,34 @@ static int atmel_tdes_crypt_pdc(struct atmel_tdes_dev *dd, static int atmel_tdes_crypt_dma(struct atmel_tdes_dev *dd, dma_addr_t dma_addr_in, - dma_addr_t dma_addr_out, int length) + dma_addr_t dma_addr_out) { - struct scatterlist sg[2]; - struct dma_async_tx_descriptor *in_desc, *out_desc; - enum dma_slave_buswidth addr_width; + struct scatterlist sg_in, sg_out; + struct dma_async_tx_descriptor *in_desc, *out_desc; - dd->dma_size = length; - - if (!(dd->flags & TDES_FLAGS_FAST)) { - dma_sync_single_for_device(dd->dev, dma_addr_in, length, - DMA_TO_DEVICE); - } - - addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - - dd->dma_lch_in.dma_conf.dst_addr_width = addr_width; - dd->dma_lch_out.dma_conf.src_addr_width = addr_width; + dd->dma_lch_in.dma_conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + dd->dma_lch_out.dma_conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; dmaengine_slave_config(dd->dma_lch_in.chan, &dd->dma_lch_in.dma_conf); dmaengine_slave_config(dd->dma_lch_out.chan, &dd->dma_lch_out.dma_conf); dd->flags |= TDES_FLAGS_DMA; - sg_init_table(&sg[0], 1); - sg_dma_address(&sg[0]) = dma_addr_in; - sg_dma_len(&sg[0]) = length; + sg_init_table(&sg_in, 1); + sg_dma_address(&sg_in) = dma_addr_in; + sg_dma_len(&sg_in) = dd->dma_size; - sg_init_table(&sg[1], 1); - sg_dma_address(&sg[1]) = dma_addr_out; - sg_dma_len(&sg[1]) = length; + sg_init_table(&sg_out, 1); + sg_dma_address(&sg_out) = dma_addr_out; + sg_dma_len(&sg_out) = dd->dma_size; - in_desc = dmaengine_prep_slave_sg(dd->dma_lch_in.chan, &sg[0], - 1, DMA_MEM_TO_DEV, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + in_desc = dmaengine_prep_slave_sg(dd->dma_lch_in.chan, &sg_in, 1, DMA_MEM_TO_DEV, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!in_desc) return -EINVAL; - out_desc = dmaengine_prep_slave_sg(dd->dma_lch_out.chan, &sg[1], - 1, DMA_DEV_TO_MEM, - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); + out_desc = dmaengine_prep_slave_sg(dd->dma_lch_out.chan, &sg_out, 1, DMA_DEV_TO_MEM, + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!out_desc) return -EINVAL; @@ -494,13 +461,19 @@ static int atmel_tdes_crypt_start(struct atmel_tdes_dev *dd) } dd->total -= count; + dd->dma_size = count; + + if (!fast) { + dma_sync_single_for_device(dd->dev, addr_in, dd->dma_size, DMA_TO_DEVICE); + dma_sync_single_for_device(dd->dev, addr_out, dd->dma_size, DMA_FROM_DEVICE); + } if (dd->caps.has_dma) - err = atmel_tdes_crypt_dma(dd, addr_in, addr_out, count); + err = atmel_tdes_crypt_dma(dd, addr_in, addr_out); else - err = atmel_tdes_crypt_pdc(dd, addr_in, addr_out, count); + err = atmel_tdes_crypt_pdc(dd, addr_in, addr_out); - if (err && (dd->flags & TDES_FLAGS_FAST)) { + if (err && fast) { dma_unmap_sg(dd->dev, dd->in_sg, 1, DMA_TO_DEVICE); dma_unmap_sg(dd->dev, dd->out_sg, 1, DMA_FROM_DEVICE); } @@ -660,7 +633,7 @@ static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd) dd->dma_lch_in.chan = dma_request_chan(dd->dev, "tx"); if (IS_ERR(dd->dma_lch_in.chan)) { ret = PTR_ERR(dd->dma_lch_in.chan); - goto err_dma_in; + goto err_dma; } dd->dma_lch_in.dma_conf.dst_addr = dd->phys_base + @@ -676,7 +649,8 @@ static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd) dd->dma_lch_out.chan = dma_request_chan(dd->dev, "rx"); if (IS_ERR(dd->dma_lch_out.chan)) { ret = PTR_ERR(dd->dma_lch_out.chan); - goto err_dma_out; + dma_release_channel(dd->dma_lch_in.chan); + goto err_dma; } dd->dma_lch_out.dma_conf.src_addr = dd->phys_base + @@ -691,9 +665,7 @@ static int atmel_tdes_dma_init(struct atmel_tdes_dev *dd) return 0; -err_dma_out: - dma_release_channel(dd->dma_lch_in.chan); -err_dma_in: +err_dma: dev_err(dd->dev, "no DMA channel available\n"); return ret; } @@ -933,7 +905,7 @@ static int atmel_tdes_probe(struct platform_device *pdev) struct resource *tdes_res; int err; - tdes_dd = devm_kmalloc(&pdev->dev, sizeof(*tdes_dd), GFP_KERNEL); + tdes_dd = devm_kzalloc(&pdev->dev, sizeof(*tdes_dd), GFP_KERNEL); if (!tdes_dd) return -ENOMEM;
diff --git a/drivers/crypto/caam/caamalg_qi.c b/drivers/crypto/caam/caamalg_qi.c index aa779ca..2f2682c 100644 --- a/drivers/crypto/caam/caamalg_qi.c +++ b/drivers/crypto/caam/caamalg_qi.c
@@ -637,6 +637,8 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, ctx->cdata.keylen = keylen; ctx->cdata.key_virt = key; ctx->cdata.key_inline = true; + ctx->cdata.plain_keylen = keylen; + ctx->cdata.key_cmd_opt = 0; /* skcipher encrypt, decrypt shared descriptors */ cnstr_shdsc_skcipher_encap(ctx->sh_desc_enc, &ctx->cdata, ivsize,
diff --git a/drivers/crypto/caam/caamalg_qi2.c b/drivers/crypto/caam/caamalg_qi2.c index 6b47bcc..c95afcb 100644 --- a/drivers/crypto/caam/caamalg_qi2.c +++ b/drivers/crypto/caam/caamalg_qi2.c
@@ -26,7 +26,7 @@ #include <crypto/xts.h> #include <linux/unaligned.h> -#define CAAM_CRA_PRIORITY 2000 +#define CAAM_CRA_PRIORITY 100 /* max key is sum of AES_MAX_KEY_SIZE, max split key size */ #define CAAM_MAX_KEY_SIZE (AES_MAX_KEY_SIZE + CTR_RFC3686_NONCE_SIZE + \ @@ -961,6 +961,8 @@ static int skcipher_setkey(struct crypto_skcipher *skcipher, const u8 *key, ctx->cdata.keylen = keylen; ctx->cdata.key_virt = key; ctx->cdata.key_inline = true; + ctx->cdata.plain_keylen = keylen; + ctx->cdata.key_cmd_opt = 0; /* skcipher_encrypt shared descriptor */ flc = &ctx->flc[ENCRYPT]; @@ -5041,11 +5043,22 @@ static int __cold dpaa2_dpseci_setup(struct fsl_mc_device *ls_dev) dev_info(dev, "dpseci v%d.%d\n", priv->major_ver, priv->minor_ver); if (DPSECI_VER(priv->major_ver, priv->minor_ver) > DPSECI_VER(5, 3)) { - err = dpseci_reset(priv->mc_io, 0, ls_dev->mc_handle); + int enabled; + + err = dpseci_is_enabled(priv->mc_io, 0, ls_dev->mc_handle, + &enabled); if (err) { - dev_err(dev, "dpseci_reset() failed\n"); + dev_err(dev, "dpseci_is_enabled() failed\n"); goto err_get_vers; } + + if (enabled) { + err = dpseci_reset(priv->mc_io, 0, ls_dev->mc_handle); + if (err) { + dev_err(dev, "dpseci_reset() failed\n"); + goto err_get_vers; + } + } } err = dpseci_get_attributes(priv->mc_io, 0, ls_dev->mc_handle,
diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c index cb001aa..ac515ed 100644 --- a/drivers/crypto/caam/caampkc.c +++ b/drivers/crypto/caam/caampkc.c
@@ -1033,16 +1033,22 @@ static int caam_rsa_set_priv_key_form(struct caam_rsa_ctx *ctx, free_dq: kfree_sensitive(rsa_key->dq); + rsa_key->dq = NULL; free_dp: kfree_sensitive(rsa_key->dp); + rsa_key->dp = NULL; free_tmp2: kfree_sensitive(rsa_key->tmp2); + rsa_key->tmp2 = NULL; free_tmp1: kfree_sensitive(rsa_key->tmp1); + rsa_key->tmp1 = NULL; free_q: kfree_sensitive(rsa_key->q); + rsa_key->q = NULL; free_p: kfree_sensitive(rsa_key->p); + rsa_key->p = NULL; return -ENOMEM; }
diff --git a/drivers/crypto/cavium/cpt/cptpf_main.c b/drivers/crypto/cavium/cpt/cptpf_main.c index 9358c1c..4234f9f 100644 --- a/drivers/crypto/cavium/cpt/cptpf_main.c +++ b/drivers/crypto/cavium/cpt/cptpf_main.c
@@ -90,19 +90,19 @@ static void cpt_configure_group(struct cpt_device *cpt, u8 grp, static void cpt_disable_mbox_interrupts(struct cpt_device *cpt) { - /* Clear mbox(0) interupts for all vfs */ + /* Clear mbox(0) interrupts for all vfs */ cpt_write_csr64(cpt->reg_base, CPTX_PF_MBOX_ENA_W1CX(0, 0), ~0ull); } static void cpt_disable_ecc_interrupts(struct cpt_device *cpt) { - /* Clear ecc(0) interupts for all vfs */ + /* Clear ecc(0) interrupts for all vfs */ cpt_write_csr64(cpt->reg_base, CPTX_PF_ECC0_ENA_W1C(0), ~0ull); } static void cpt_disable_exec_interrupts(struct cpt_device *cpt) { - /* Clear exec interupts for all vfs */ + /* Clear exec interrupts for all vfs */ cpt_write_csr64(cpt->reg_base, CPTX_PF_EXEC_ENA_W1C(0), ~0ull); } @@ -115,7 +115,7 @@ static void cpt_disable_all_interrupts(struct cpt_device *cpt) static void cpt_enable_mbox_interrupts(struct cpt_device *cpt) { - /* Set mbox(0) interupts for all vfs */ + /* Set mbox(0) interrupts for all vfs */ cpt_write_csr64(cpt->reg_base, CPTX_PF_MBOX_ENA_W1SX(0, 0), ~0ull); } @@ -140,10 +140,10 @@ static int cpt_load_microcode(struct cpt_device *cpt, struct microcode *mcode) */ if (mcode->is_ae) { core = CPT_MAX_SE_CORES; /* start couting from 10 */ - total_cores = CPT_MAX_TOTAL_CORES; /* upto 15 */ + total_cores = CPT_MAX_TOTAL_CORES; /* up to 15 */ } else { core = 0; /* start couting from 0 */ - total_cores = CPT_MAX_SE_CORES; /* upto 9 */ + total_cores = CPT_MAX_SE_CORES; /* up to 9 */ } /* Point to microcode for each core of the group */
diff --git a/drivers/crypto/cavium/cpt/cptvf_main.c b/drivers/crypto/cavium/cpt/cptvf_main.c index db76df1..e0744809 100644 --- a/drivers/crypto/cavium/cpt/cptvf_main.c +++ b/drivers/crypto/cavium/cpt/cptvf_main.c
@@ -417,7 +417,7 @@ static void cptvf_enable_swerr_interrupts(struct cpt_vf *cptvf) vqx_misc_ena.u = cpt_read_csr64(cptvf->reg_base, CPTX_VQX_MISC_ENA_W1S(0, 0)); - /* Set mbox(0) interupts for the requested vf */ + /* Set mbox(0) interrupts for the requested vf */ vqx_misc_ena.s.swerr = 1; cpt_write_csr64(cptvf->reg_base, CPTX_VQX_MISC_ENA_W1S(0, 0), vqx_misc_ena.u); @@ -429,7 +429,7 @@ static void cptvf_enable_mbox_interrupts(struct cpt_vf *cptvf) vqx_misc_ena.u = cpt_read_csr64(cptvf->reg_base, CPTX_VQX_MISC_ENA_W1S(0, 0)); - /* Set mbox(0) interupts for the requested vf */ + /* Set mbox(0) interrupts for the requested vf */ vqx_misc_ena.s.mbox = 1; cpt_write_csr64(cptvf->reg_base, CPTX_VQX_MISC_ENA_W1S(0, 0), vqx_misc_ena.u);
diff --git a/drivers/crypto/cavium/cpt/cptvf_mbox.c b/drivers/crypto/cavium/cpt/cptvf_mbox.c index 1267e1e..9f2ae10b 100644 --- a/drivers/crypto/cavium/cpt/cptvf_mbox.c +++ b/drivers/crypto/cavium/cpt/cptvf_mbox.c
@@ -120,7 +120,7 @@ int cptvf_send_vq_size_msg(struct cpt_vf *cptvf) } /* - * Communicate VF group required to PF and get the VQ binded to that group + * Communicate VF group required to PF and get the VQ bound to that group */ int cptvf_send_vf_to_grp_msg(struct cpt_vf *cptvf) { @@ -139,7 +139,7 @@ int cptvf_send_vf_to_grp_msg(struct cpt_vf *cptvf) } /* - * Communicate VF group required to PF and get the VQ binded to that group + * Communicate VF group required to PF and get the VQ bound to that group */ int cptvf_send_vf_priority_msg(struct cpt_vf *cptvf) {
diff --git a/drivers/crypto/cavium/nitrox/nitrox_main.c b/drivers/crypto/cavium/nitrox/nitrox_main.c index e474c84..54b2db6 100644 --- a/drivers/crypto/cavium/nitrox/nitrox_main.c +++ b/drivers/crypto/cavium/nitrox/nitrox_main.c
@@ -468,7 +468,7 @@ static int nitrox_probe(struct pci_dev *pdev, err = -EIO; goto ioremap_err; } - /* allocate command queus based on cpus, max queues are 64 */ + /* allocate command queues based on cpus, max queues are 64 */ ndev->nr_queues = min_t(u32, MAX_PF_QUEUES, num_online_cpus()); ndev->qlen = qlen;
diff --git a/drivers/crypto/ccp/ccp-dev-v3.c b/drivers/crypto/ccp/ccp-dev-v3.c index 60a133e..d92de4a 100644 --- a/drivers/crypto/ccp/ccp-dev-v3.c +++ b/drivers/crypto/ccp/ccp-dev-v3.c
@@ -506,6 +506,8 @@ static int ccp_init(struct ccp_device *ccp) kthread_stop(ccp->cmd_q[i].kthread); sp_free_ccp_irq(ccp->sp, ccp); + if (ccp->use_tasklet) + tasklet_kill(&ccp->irq_tasklet); e_pool: for (i = 0; i < ccp->cmd_q_count; i++) @@ -545,6 +547,8 @@ static void ccp_destroy(struct ccp_device *ccp) kthread_stop(ccp->cmd_q[i].kthread); sp_free_ccp_irq(ccp->sp, ccp); + if (ccp->use_tasklet) + tasklet_kill(&ccp->irq_tasklet); for (i = 0; i < ccp->cmd_q_count; i++) dma_pool_destroy(ccp->cmd_q[i].dma_pool);
diff --git a/drivers/crypto/ccp/ccp-dev-v5.c b/drivers/crypto/ccp/ccp-dev-v5.c index dcd6aab..dacde96 100644 --- a/drivers/crypto/ccp/ccp-dev-v5.c +++ b/drivers/crypto/ccp/ccp-dev-v5.c
@@ -995,6 +995,8 @@ static int ccp5_init(struct ccp_device *ccp) e_irq: sp_free_ccp_irq(ccp->sp, ccp); + if (ccp->use_tasklet) + tasklet_kill(&ccp->irq_tasklet); e_pool: for (i = 0; i < ccp->cmd_q_count; i++) @@ -1046,6 +1048,8 @@ static void ccp5_destroy(struct ccp_device *ccp) kthread_stop(ccp->cmd_q[i].kthread); sp_free_ccp_irq(ccp->sp, ccp); + if (ccp->use_tasklet) + tasklet_kill(&ccp->irq_tasklet); /* Flush the cmd and backlog queue */ while (!list_empty(&ccp->cmd)) {
diff --git a/drivers/crypto/ccp/ccp-dev.c b/drivers/crypto/ccp/ccp-dev.c index 2468019..aff3348 100644 --- a/drivers/crypto/ccp/ccp-dev.c +++ b/drivers/crypto/ccp/ccp-dev.c
@@ -30,7 +30,7 @@ #define MAX_CCPS 32 -/* Limit CCP use to a specifed number of queues per device */ +/* Limit CCP use to a specified number of queues per device */ static unsigned int nqueues; module_param(nqueues, uint, 0444); MODULE_PARM_DESC(nqueues, "Number of queues per CCP (minimum 1; default: all available)");
diff --git a/drivers/crypto/ccp/dbc.c b/drivers/crypto/ccp/dbc.c index 410084a..4db49a1 100644 --- a/drivers/crypto/ccp/dbc.c +++ b/drivers/crypto/ccp/dbc.c
@@ -236,6 +236,8 @@ int dbc_dev_init(struct psp_device *psp) goto cleanup_mbox; } + mutex_init(&dbc_dev->ioctl_mutex); + dbc_dev->char_dev.minor = MISC_DYNAMIC_MINOR; dbc_dev->char_dev.name = "dbc"; dbc_dev->char_dev.fops = &dbc_fops; @@ -244,8 +246,6 @@ int dbc_dev_init(struct psp_device *psp) if (ret) goto cleanup_mbox; - mutex_init(&dbc_dev->ioctl_mutex); - return 0; cleanup_mbox:
diff --git a/drivers/crypto/ccp/sfs.c b/drivers/crypto/ccp/sfs.c index a477783..530141f 100644 --- a/drivers/crypto/ccp/sfs.c +++ b/drivers/crypto/ccp/sfs.c
@@ -111,13 +111,13 @@ static long sfs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) struct sfs_device *sfs_dev; int ret = 0; + guard(mutex)(&sfs_ioctl_mutex); + if (!psp_master || !psp_master->sfs_data) return -ENODEV; sfs_dev = psp_master->sfs_data; - guard(mutex)(&sfs_ioctl_mutex); - switch (cmd) { case SFSIOCFWVERS: dev_dbg(sfs_dev->dev, "in SFSIOCFWVERS\n"); @@ -191,8 +191,11 @@ static void sfs_exit(struct kref *ref) void sfs_dev_destroy(struct psp_device *psp) { - struct sfs_device *sfs_dev = psp->sfs_data; + struct sfs_device *sfs_dev; + guard(mutex)(&sfs_ioctl_mutex); + + sfs_dev = psp->sfs_data; if (!sfs_dev) return;
diff --git a/drivers/crypto/ccp/sp-platform.c b/drivers/crypto/ccp/sp-platform.c index 3f9843f..c7ac840 100644 --- a/drivers/crypto/ccp/sp-platform.c +++ b/drivers/crypto/ccp/sp-platform.c
@@ -40,8 +40,8 @@ static const struct sp_dev_vdata dev_vdata[] = { }; static const struct acpi_device_id sp_acpi_match[] = { - { "AMDI0C00", (kernel_ulong_t)&dev_vdata[0] }, - { }, + { .id = "AMDI0C00", .driver_data = (kernel_ulong_t)&dev_vdata[0] }, + { } }; MODULE_DEVICE_TABLE(acpi, sp_acpi_match);
diff --git a/drivers/crypto/ccree/cc_aead.c b/drivers/crypto/ccree/cc_aead.c index 088c460..d57a98f 100644 --- a/drivers/crypto/ccree/cc_aead.c +++ b/drivers/crypto/ccree/cc_aead.c
@@ -226,8 +226,8 @@ static void cc_aead_complete(struct device *dev, void *cc_req, int err) goto done; if (areq_ctx->gen_ctx.op_type == DRV_CRYPTO_DIRECTION_DECRYPT) { - if (memcmp(areq_ctx->mac_buf, areq_ctx->icv_virt_addr, - ctx->authsize) != 0) { + if (crypto_memneq(areq_ctx->mac_buf, areq_ctx->icv_virt_addr, + ctx->authsize)) { dev_dbg(dev, "Payload authentication failure, (auth-size=%d, cipher=%d)\n", ctx->authsize, ctx->cipher_mode); /* In case of payload authentication failure, MUST NOT
diff --git a/drivers/crypto/ccree/cc_buffer_mgr.c b/drivers/crypto/ccree/cc_buffer_mgr.c index dc7e0cd..a592f5e 100644 --- a/drivers/crypto/ccree/cc_buffer_mgr.c +++ b/drivers/crypto/ccree/cc_buffer_mgr.c
@@ -717,7 +717,7 @@ static void cc_prepare_aead_data_mlli(struct cc_drvdata *drvdata, } } else { /* Contig. ICV */ sg = &areq_ctx->src_sgl[areq_ctx->src.nents - 1]; - /*Should hanlde if the sg is not contig.*/ + /*Should handle if the sg is not contig.*/ areq_ctx->icv_dma_addr = sg_dma_address(sg) + (*src_last_bytes - authsize); areq_ctx->icv_virt_addr = sg_virt(sg) + @@ -749,7 +749,7 @@ static void cc_prepare_aead_data_mlli(struct cc_drvdata *drvdata, } else { /* Contig. ICV */ sg = &areq_ctx->src_sgl[areq_ctx->src.nents - 1]; - /*Should hanlde if the sg is not contig.*/ + /*Should handle if the sg is not contig.*/ areq_ctx->icv_dma_addr = sg_dma_address(sg) + (*src_last_bytes - authsize); areq_ctx->icv_virt_addr = sg_virt(sg) +
diff --git a/drivers/crypto/ccree/cc_pm.c b/drivers/crypto/ccree/cc_pm.c index bbd118f..6668661 100644 --- a/drivers/crypto/ccree/cc_pm.c +++ b/drivers/crypto/ccree/cc_pm.c
@@ -66,13 +66,7 @@ const struct dev_pm_ops ccree_pm = { int cc_pm_get(struct device *dev) { - int rc = pm_runtime_get_sync(dev); - if (rc < 0) { - pm_runtime_put_noidle(dev); - return rc; - } - - return 0; + return pm_runtime_resume_and_get(dev); } void cc_pm_put_suspend(struct device *dev)
diff --git a/drivers/crypto/chelsio/chcr_algo.c b/drivers/crypto/chelsio/chcr_algo.c index 6dec422..e2f2b2a 100644 --- a/drivers/crypto/chelsio/chcr_algo.c +++ b/drivers/crypto/chelsio/chcr_algo.c
@@ -1605,7 +1605,7 @@ static struct sk_buff *create_hash_wr(struct ahash_request *req, req_ctx->hctx_wr.dma_addr = 0; } chcr_add_hash_src_ent(req, ulptx, param); - /* Request upto max wr size */ + /* Request up to max wr size */ temp = param->kctx_len + DUMMY_BYTES + (req_ctx->hctx_wr.imm ? (param->sg_len + param->bfr_len) : 0); atomic_inc(&adap->chcr_stats.digest_rqst);
diff --git a/drivers/crypto/gemini/sl3516-ce-cipher.c b/drivers/crypto/gemini/sl3516-ce-cipher.c index 02ec428..eba46ae 100644 --- a/drivers/crypto/gemini/sl3516-ce-cipher.c +++ b/drivers/crypto/gemini/sl3516-ce-cipher.c
@@ -331,13 +331,12 @@ int sl3516_ce_cipher_init(struct crypto_tfm *tfm) crypto_tfm_alg_driver_name(&sktfm->base), crypto_tfm_alg_driver_name(crypto_skcipher_tfm(op->fallback_tfm))); - err = pm_runtime_get_sync(op->ce->dev); + err = pm_runtime_resume_and_get(op->ce->dev); if (err < 0) goto error_pm; return 0; error_pm: - pm_runtime_put_noidle(op->ce->dev); crypto_free_skcipher(op->fallback_tfm); return err; }
diff --git a/drivers/crypto/gemini/sl3516-ce-rng.c b/drivers/crypto/gemini/sl3516-ce-rng.c index 76931ec..19af03b 100644 --- a/drivers/crypto/gemini/sl3516-ce-rng.c +++ b/drivers/crypto/gemini/sl3516-ce-rng.c
@@ -24,11 +24,9 @@ static int sl3516_ce_rng_read(struct hwrng *rng, void *buf, size_t max, bool wai ce->hwrng_stat_bytes += max; #endif - err = pm_runtime_get_sync(ce->dev); - if (err < 0) { - pm_runtime_put_noidle(ce->dev); + err = pm_runtime_resume_and_get(ce->dev); + if (err < 0) return err; - } while (read < max) { *data = readl(ce->base + IPSEC_RAND_NUM_REG);
diff --git a/drivers/crypto/hisilicon/Kconfig b/drivers/crypto/hisilicon/Kconfig index aeff08cc..e38a71d 100644 --- a/drivers/crypto/hisilicon/Kconfig +++ b/drivers/crypto/hisilicon/Kconfig
@@ -1,19 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 -config CRYPTO_DEV_HISI_SEC - tristate "Support for Hisilicon SEC crypto block cipher accelerator" - select CRYPTO_SKCIPHER - select CRYPTO_ALGAPI - select CRYPTO_LIB_DES - select SG_SPLIT - depends on ARM64 || COMPILE_TEST - depends on HAS_IOMEM - help - Support for Hisilicon SEC Engine in Hip06 and Hip07 - - To compile this as a module, choose M here: the module - will be called hisi_sec. - config CRYPTO_DEV_HISI_SEC2 tristate "Support for HiSilicon SEC2 crypto block cipher accelerator" select CRYPTO_SKCIPHER
diff --git a/drivers/crypto/hisilicon/Makefile b/drivers/crypto/hisilicon/Makefile index e1068ee..a62965b 100644 --- a/drivers/crypto/hisilicon/Makefile +++ b/drivers/crypto/hisilicon/Makefile
@@ -1,6 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_CRYPTO_DEV_HISI_HPRE) += hpre/ -obj-$(CONFIG_CRYPTO_DEV_HISI_SEC) += sec/ obj-$(CONFIG_CRYPTO_DEV_HISI_SEC2) += sec2/ obj-$(CONFIG_CRYPTO_DEV_HISI_QM) += hisi_qm.o hisi_qm-objs = qm.o sgl.o debugfs.o
diff --git a/drivers/crypto/hisilicon/hpre/hpre.h b/drivers/crypto/hisilicon/hpre/hpre.h index 021dbd9..f73d01f 100644 --- a/drivers/crypto/hisilicon/hpre/hpre.h +++ b/drivers/crypto/hisilicon/hpre/hpre.h
@@ -70,7 +70,6 @@ struct hpre_debug { struct hpre { struct hisi_qm qm; struct hpre_debug debug; - unsigned long status; }; enum hpre_alg_type {
diff --git a/drivers/crypto/hisilicon/hpre/hpre_crypto.c b/drivers/crypto/hisilicon/hpre/hpre_crypto.c index 09077ab..66a2767 100644 --- a/drivers/crypto/hisilicon/hpre/hpre_crypto.c +++ b/drivers/crypto/hisilicon/hpre/hpre_crypto.c
@@ -21,19 +21,15 @@ struct hpre_ctx; #define HPRE_CRYPTO_ALG_PRI 1000 #define HPRE_ALIGN_SZ 64 #define HPRE_BITS_2_BYTES_SHIFT 3 -#define HPRE_RSA_512BITS_KSZ 64 -#define HPRE_RSA_1536BITS_KSZ 192 #define HPRE_CRT_PRMS 5 #define HPRE_CRT_Q 2 #define HPRE_CRT_P 3 #define HPRE_CRT_INV 4 #define HPRE_DH_G_FLAG 0x02 #define HPRE_TRY_SEND_TIMES 100 -#define HPRE_INVLD_REQ_ID (-1) #define HPRE_SQE_ALG_BITS 5 #define HPRE_SQE_DONE_SHIFT 30 -#define HPRE_DH_MAX_P_SZ 512 #define HPRE_DFX_SEC_TO_US 1000000 #define HPRE_DFX_US_TO_NS 1000 @@ -56,7 +52,6 @@ struct hpre_ctx; #define HPRE_DRV_RSA_MASK_CAP BIT(0) #define HPRE_DRV_DH_MASK_CAP BIT(1) #define HPRE_DRV_ECDH_MASK_CAP BIT(2) -#define HPRE_DRV_X25519_MASK_CAP BIT(5) static DEFINE_MUTEX(hpre_algs_lock); static unsigned int hpre_available_devs; @@ -135,9 +130,9 @@ struct hpre_asym_request { struct kpp_request *dh; struct kpp_request *ecdh; } areq; - int err; hpre_cb cb; struct timespec64 req_time; + u32 flags; }; static inline unsigned int hpre_align_sz(void) @@ -186,6 +181,7 @@ static int hpre_prepare_dma_buf(struct hpre_asym_request *hpre_req, struct scatterlist *data, unsigned int len, int is_src, dma_addr_t *tmp) { + gfp_t gfp = hpre_req->flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC; struct hpre_ctx *ctx = hpre_req->ctx; struct device *dev = ctx->dev; void *ptr; @@ -195,7 +191,7 @@ static int hpre_prepare_dma_buf(struct hpre_asym_request *hpre_req, if (unlikely(shift < 0)) return -EINVAL; - ptr = dma_alloc_coherent(dev, ctx->key_sz, tmp, GFP_ATOMIC); + ptr = dma_alloc_coherent(dev, ctx->key_sz, tmp, gfp); if (unlikely(!ptr)) return -ENOMEM; @@ -419,6 +415,7 @@ static int hpre_msg_request_set(struct hpre_ctx *ctx, void *req, bool is_rsa) h_req = PTR_ALIGN(tmp, hpre_align_sz()); h_req->cb = hpre_rsa_cb; h_req->areq.rsa = akreq; + h_req->flags = akreq->base.flags; msg = &h_req->req; memset(msg, 0, sizeof(*msg)); } else { @@ -433,6 +430,7 @@ static int hpre_msg_request_set(struct hpre_ctx *ctx, void *req, bool is_rsa) h_req = PTR_ALIGN(tmp, hpre_align_sz()); h_req->cb = hpre_dh_cb; h_req->areq.dh = kreq; + h_req->flags = kreq->base.flags; msg = &h_req->req; memset(msg, 0, sizeof(*msg)); msg->key = cpu_to_le64(ctx->dh.dma_xa_p); @@ -720,7 +718,7 @@ static void hpre_dh_exit_tfm(struct crypto_kpp *tfm) static void hpre_rsa_drop_leading_zeros(const char **ptr, size_t *len) { - while (!**ptr && *len) { + while (*len && !**ptr) { (*ptr)++; (*len)--; } @@ -1407,8 +1405,6 @@ static void hpre_ecdh_hw_data_clr_all(struct hpre_ctx *ctx, if (unlikely(dma_mapping_error(dev, dma))) return; - if (req->dst) - dma_free_coherent(dev, ctx->key_sz << 1, req->dst, dma); if (dst) dma_unmap_single(dev, dma, ctx->key_sz << 1, DMA_FROM_DEVICE); } @@ -1452,13 +1448,14 @@ static int hpre_ecdh_msg_request_set(struct hpre_ctx *ctx, if (req->dst_len < ctx->key_sz << 1) { req->dst_len = ctx->key_sz << 1; - return -EINVAL; + return -EOVERFLOW; } tmp = kpp_request_ctx(req); h_req = PTR_ALIGN(tmp, hpre_align_sz()); h_req->cb = hpre_ecdh_cb; h_req->areq.ecdh = req; + h_req->flags = req->base.flags; msg = &h_req->req; memset(msg, 0, sizeof(*msg)); msg->in = cpu_to_le64(DMA_MAPPING_ERROR); @@ -1477,6 +1474,7 @@ static int hpre_ecdh_msg_request_set(struct hpre_ctx *ctx, static int hpre_ecdh_src_data_init(struct hpre_asym_request *hpre_req, struct scatterlist *data, unsigned int len) { + gfp_t gfp = hpre_req->flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC; struct hpre_sqe *msg = &hpre_req->req; struct hpre_ctx *ctx = hpre_req->ctx; struct device *dev = ctx->dev; @@ -1490,7 +1488,7 @@ static int hpre_ecdh_src_data_init(struct hpre_asym_request *hpre_req, if (unlikely(shift < 0)) return -EINVAL; - ptr = dma_alloc_coherent(dev, ctx->key_sz << 2, &dma, GFP_KERNEL); + ptr = dma_alloc_coherent(dev, ctx->key_sz << 2, &dma, gfp); if (unlikely(!ptr)) return -ENOMEM; @@ -1512,13 +1510,13 @@ static int hpre_ecdh_dst_data_init(struct hpre_asym_request *hpre_req, struct device *dev = ctx->dev; dma_addr_t dma; - if (unlikely(!data || !sg_is_last(data) || len != ctx->key_sz << 1)) { - dev_err(dev, "data or data length is illegal!\n"); + if (unlikely(!data || !sg_is_last(data))) { + dev_err(dev, "data is illegal!\n"); return -EINVAL; } hpre_req->dst = NULL; - dma = dma_map_single(dev, sg_virt(data), len, DMA_FROM_DEVICE); + dma = dma_map_single(dev, sg_virt(data), ctx->key_sz << 1, DMA_FROM_DEVICE); if (unlikely(dma_mapping_error(dev, dma))) { dev_err(dev, "dma map data err!\n"); return -ENOMEM;
diff --git a/drivers/crypto/hisilicon/hpre/hpre_main.c b/drivers/crypto/hisilicon/hpre/hpre_main.c index b6903fc..fd3c34d 100644 --- a/drivers/crypto/hisilicon/hpre/hpre_main.c +++ b/drivers/crypto/hisilicon/hpre/hpre_main.c
@@ -16,7 +16,6 @@ #define CAP_FILE_PERMISSION 0444 #define HPRE_CTRL_CNT_CLR_CE_BIT BIT(0) #define HPRE_CTRL_CNT_CLR_CE 0x301000 -#define HPRE_FSM_MAX_CNT 0x301008 #define HPRE_VFG_AXQOS 0x30100c #define HPRE_VFG_AXCACHE 0x301010 #define HPRE_RDCHN_INI_CFG 0x301014 @@ -41,7 +40,6 @@ #define HPRE_HAC_INT_SET 0x301500 #define HPRE_AXI_ERROR_MASK GENMASK(21, 10) #define HPRE_RNG_TIMEOUT_NUM 0x301A34 -#define HPRE_CORE_INT_ENABLE 0 #define HPRE_RDCHN_INI_ST 0x301a00 #define HPRE_CLSTR_BASE 0x302000 #define HPRE_CORE_EN_OFFSET 0x04 @@ -61,8 +59,6 @@ #define HPRE_CORE_ENB (HPRE_CLSTR_BASE + HPRE_CORE_EN_OFFSET) #define HPRE_CORE_INI_CFG (HPRE_CLSTR_BASE + HPRE_CORE_INI_CFG_OFFSET) #define HPRE_CORE_INI_STATUS (HPRE_CLSTR_BASE + HPRE_CORE_INI_STATUS_OFFSET) -#define HPRE_HAC_ECC1_CNT 0x301a04 -#define HPRE_HAC_ECC2_CNT 0x301a08 #define HPRE_HAC_SOURCE_INT 0x301600 #define HPRE_CLSTR_ADDR_INTRVL 0x1000 #define HPRE_CLUSTER_INQURY 0x100 @@ -381,6 +377,14 @@ static const char *hpre_channel_name[HPRE_MAX_CHANNEL_NUM] = { static const struct hisi_qm_err_ini hpre_err_ini; +static inline u8 hpre_get_clusters_num(struct hisi_qm *qm) +{ + u32 cap = qm->cap_tables.dev_cap_table[HPRE_CORE_INFO].cap_val; + + return (cap >> hpre_basic_info[HPRE_CLUSTER_NUM_CAP].shift) & + hpre_basic_info[HPRE_CLUSTER_NUM_CAP].mask; +} + bool hpre_check_alg_support(struct hisi_qm *qm, u32 alg) { u32 cap_val; @@ -557,15 +561,12 @@ static int hpre_set_cluster(struct hisi_qm *qm) struct device *dev = &qm->pdev->dev; u32 cluster_core_mask; unsigned long offset; - u32 hpre_core_info; u8 clusters_num; u32 val = 0; int ret, i; cluster_core_mask = qm->cap_tables.dev_cap_table[HPRE_CORE_EN].cap_val; - hpre_core_info = qm->cap_tables.dev_cap_table[HPRE_CORE_INFO].cap_val; - clusters_num = (hpre_core_info >> hpre_basic_info[HPRE_CLUSTER_NUM_CAP].shift) & - hpre_basic_info[HPRE_CLUSTER_NUM_CAP].mask; + clusters_num = hpre_get_clusters_num(qm); for (i = 0; i < clusters_num; i++) { offset = i * HPRE_CLSTR_ADDR_INTRVL; @@ -659,7 +660,6 @@ static void hpre_enable_clock_gate(struct hisi_qm *qm) { unsigned long offset; u8 clusters_num, i; - u32 hpre_core_info; u32 val; if (qm->ver < QM_HW_V3) @@ -673,9 +673,7 @@ static void hpre_enable_clock_gate(struct hisi_qm *qm) val |= HPRE_PEH_CFG_AUTO_GATE_EN; writel(val, qm->io_base + HPRE_PEH_CFG_AUTO_GATE); - hpre_core_info = qm->cap_tables.dev_cap_table[HPRE_CORE_INFO].cap_val; - clusters_num = (hpre_core_info >> hpre_basic_info[HPRE_CLUSTER_NUM_CAP].shift) & - hpre_basic_info[HPRE_CLUSTER_NUM_CAP].mask; + clusters_num = hpre_get_clusters_num(qm); for (i = 0; i < clusters_num; i++) { offset = (unsigned long)i * HPRE_CLSTR_ADDR_INTRVL; val = readl(qm->io_base + offset + HPRE_CLUSTER_DYN_CTL); @@ -692,7 +690,6 @@ static void hpre_disable_clock_gate(struct hisi_qm *qm) { unsigned long offset; u8 clusters_num, i; - u32 hpre_core_info; u32 val; if (qm->ver < QM_HW_V3) @@ -706,9 +703,7 @@ static void hpre_disable_clock_gate(struct hisi_qm *qm) val &= ~HPRE_PEH_CFG_AUTO_GATE_EN; writel(val, qm->io_base + HPRE_PEH_CFG_AUTO_GATE); - hpre_core_info = qm->cap_tables.dev_cap_table[HPRE_CORE_INFO].cap_val; - clusters_num = (hpre_core_info >> hpre_basic_info[HPRE_CLUSTER_NUM_CAP].shift) & - hpre_basic_info[HPRE_CLUSTER_NUM_CAP].mask; + clusters_num = hpre_get_clusters_num(qm); for (i = 0; i < clusters_num; i++) { offset = (unsigned long)i * HPRE_CLSTR_ADDR_INTRVL; val = readl(qm->io_base + offset + HPRE_CLUSTER_DYN_CTL); @@ -782,14 +777,11 @@ static int hpre_set_user_domain_and_cache(struct hisi_qm *qm) static void hpre_cnt_regs_clear(struct hisi_qm *qm) { unsigned long offset; - u32 hpre_core_info; u8 clusters_num; int i; /* clear clusterX/cluster_ctrl */ - hpre_core_info = qm->cap_tables.dev_cap_table[HPRE_CORE_INFO].cap_val; - clusters_num = (hpre_core_info >> hpre_basic_info[HPRE_CLUSTER_NUM_CAP].shift) & - hpre_basic_info[HPRE_CLUSTER_NUM_CAP].mask; + clusters_num = hpre_get_clusters_num(qm); for (i = 0; i < clusters_num; i++) { offset = HPRE_CLSTR_BASE + i * HPRE_CLSTR_ADDR_INTRVL; writel(0x0, qm->io_base + offset + HPRE_CLUSTER_INQURY); @@ -1072,13 +1064,10 @@ static int hpre_cluster_debugfs_init(struct hisi_qm *qm) char buf[HPRE_DBGFS_VAL_MAX_LEN]; struct debugfs_regset32 *regset; struct dentry *tmp_d; - u32 hpre_core_info; u8 clusters_num; int i, ret; - hpre_core_info = qm->cap_tables.dev_cap_table[HPRE_CORE_INFO].cap_val; - clusters_num = (hpre_core_info >> hpre_basic_info[HPRE_CLUSTER_NUM_CAP].shift) & - hpre_basic_info[HPRE_CLUSTER_NUM_CAP].mask; + clusters_num = hpre_get_clusters_num(qm); for (i = 0; i < clusters_num; i++) { ret = snprintf(buf, HPRE_DBGFS_VAL_MAX_LEN, "cluster%d", i); if (ret >= HPRE_DBGFS_VAL_MAX_LEN) @@ -1234,8 +1223,8 @@ static int hpre_pre_store_cap_reg(struct hisi_qm *qm) return -EINVAL; } - qm->cap_tables.dev_cap_table = hpre_cap; qm->cap_tables.dev_cap_size = size; + qm->cap_tables.dev_cap_table = hpre_cap; return 0; } @@ -1308,13 +1297,10 @@ static int hpre_show_last_regs_init(struct hisi_qm *qm) int com_dfx_regs_num = ARRAY_SIZE(hpre_com_dfx_regs); struct qm_debug *debug = &qm->debug; void __iomem *io_base; - u32 hpre_core_info; u8 clusters_num; int i, j, idx; - hpre_core_info = qm->cap_tables.dev_cap_table[HPRE_CORE_INFO].cap_val; - clusters_num = (hpre_core_info >> hpre_basic_info[HPRE_CLUSTER_NUM_CAP].shift) & - hpre_basic_info[HPRE_CLUSTER_NUM_CAP].mask; + clusters_num = hpre_get_clusters_num(qm); debug->last_words = kcalloc(cluster_dfx_regs_num * clusters_num + com_dfx_regs_num, sizeof(unsigned int), GFP_KERNEL); if (!debug->last_words) @@ -1354,7 +1340,6 @@ static void hpre_show_last_dfx_regs(struct hisi_qm *qm) struct qm_debug *debug = &qm->debug; struct pci_dev *pdev = qm->pdev; void __iomem *io_base; - u32 hpre_core_info; u8 clusters_num; int i, j, idx; u32 val; @@ -1370,9 +1355,7 @@ static void hpre_show_last_dfx_regs(struct hisi_qm *qm) hpre_com_dfx_regs[i].name, debug->last_words[i], val); } - hpre_core_info = qm->cap_tables.dev_cap_table[HPRE_CORE_INFO].cap_val; - clusters_num = (hpre_core_info >> hpre_basic_info[HPRE_CLUSTER_NUM_CAP].shift) & - hpre_basic_info[HPRE_CLUSTER_NUM_CAP].mask; + clusters_num = hpre_get_clusters_num(qm); for (i = 0; i < clusters_num; i++) { io_base = qm->io_base + hpre_cluster_offsets[i]; for (j = 0; j < cluster_dfx_regs_num; j++) {
diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c index c01966a..7d13476 100644 --- a/drivers/crypto/hisilicon/qm.c +++ b/drivers/crypto/hisilicon/qm.c
@@ -5743,8 +5743,8 @@ static int qm_pre_store_caps(struct hisi_qm *qm) i, qm->cap_ver); } - qm->cap_tables.qm_cap_table = qm_cap; qm->cap_tables.qm_cap_size = size; + qm->cap_tables.qm_cap_table = qm_cap; return 0; }
diff --git a/drivers/crypto/hisilicon/sec/Makefile b/drivers/crypto/hisilicon/sec/Makefile deleted file mode 100644 index a55b698..0000000 --- a/drivers/crypto/hisilicon/sec/Makefile +++ /dev/null
@@ -1,3 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_CRYPTO_DEV_HISI_SEC) += hisi_sec.o -hisi_sec-y = sec_algs.o sec_drv.o
diff --git a/drivers/crypto/hisilicon/sec/sec_algs.c b/drivers/crypto/hisilicon/sec/sec_algs.c deleted file mode 100644 index 85eecbb..0000000 --- a/drivers/crypto/hisilicon/sec/sec_algs.c +++ /dev/null
@@ -1,1122 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* Copyright (c) 2016-2017 HiSilicon Limited. */ -#include <linux/crypto.h> -#include <linux/dma-mapping.h> -#include <linux/dmapool.h> -#include <linux/module.h> -#include <linux/mutex.h> -#include <linux/slab.h> - -#include <crypto/aes.h> -#include <crypto/algapi.h> -#include <crypto/internal/des.h> -#include <crypto/skcipher.h> -#include <crypto/xts.h> -#include <crypto/internal/skcipher.h> - -#include "sec_drv.h" - -#define SEC_MAX_CIPHER_KEY 64 -#define SEC_REQ_LIMIT SZ_32M - -struct sec_c_alg_cfg { - unsigned c_alg : 3; - unsigned c_mode : 3; - unsigned key_len : 2; - unsigned c_width : 2; -}; - -static const struct sec_c_alg_cfg sec_c_alg_cfgs[] = { - [SEC_C_DES_ECB_64] = { - .c_alg = SEC_C_ALG_DES, - .c_mode = SEC_C_MODE_ECB, - .key_len = SEC_KEY_LEN_DES, - }, - [SEC_C_DES_CBC_64] = { - .c_alg = SEC_C_ALG_DES, - .c_mode = SEC_C_MODE_CBC, - .key_len = SEC_KEY_LEN_DES, - }, - [SEC_C_3DES_ECB_192_3KEY] = { - .c_alg = SEC_C_ALG_3DES, - .c_mode = SEC_C_MODE_ECB, - .key_len = SEC_KEY_LEN_3DES_3_KEY, - }, - [SEC_C_3DES_ECB_192_2KEY] = { - .c_alg = SEC_C_ALG_3DES, - .c_mode = SEC_C_MODE_ECB, - .key_len = SEC_KEY_LEN_3DES_2_KEY, - }, - [SEC_C_3DES_CBC_192_3KEY] = { - .c_alg = SEC_C_ALG_3DES, - .c_mode = SEC_C_MODE_CBC, - .key_len = SEC_KEY_LEN_3DES_3_KEY, - }, - [SEC_C_3DES_CBC_192_2KEY] = { - .c_alg = SEC_C_ALG_3DES, - .c_mode = SEC_C_MODE_CBC, - .key_len = SEC_KEY_LEN_3DES_2_KEY, - }, - [SEC_C_AES_ECB_128] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_ECB, - .key_len = SEC_KEY_LEN_AES_128, - }, - [SEC_C_AES_ECB_192] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_ECB, - .key_len = SEC_KEY_LEN_AES_192, - }, - [SEC_C_AES_ECB_256] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_ECB, - .key_len = SEC_KEY_LEN_AES_256, - }, - [SEC_C_AES_CBC_128] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_CBC, - .key_len = SEC_KEY_LEN_AES_128, - }, - [SEC_C_AES_CBC_192] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_CBC, - .key_len = SEC_KEY_LEN_AES_192, - }, - [SEC_C_AES_CBC_256] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_CBC, - .key_len = SEC_KEY_LEN_AES_256, - }, - [SEC_C_AES_CTR_128] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_CTR, - .key_len = SEC_KEY_LEN_AES_128, - }, - [SEC_C_AES_CTR_192] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_CTR, - .key_len = SEC_KEY_LEN_AES_192, - }, - [SEC_C_AES_CTR_256] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_CTR, - .key_len = SEC_KEY_LEN_AES_256, - }, - [SEC_C_AES_XTS_128] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_XTS, - .key_len = SEC_KEY_LEN_AES_128, - }, - [SEC_C_AES_XTS_256] = { - .c_alg = SEC_C_ALG_AES, - .c_mode = SEC_C_MODE_XTS, - .key_len = SEC_KEY_LEN_AES_256, - }, - [SEC_C_NULL] = { - }, -}; - -/* - * Mutex used to ensure safe operation of reference count of - * alg providers - */ -static DEFINE_MUTEX(algs_lock); -static unsigned int active_devs; - -static void sec_alg_skcipher_init_template(struct sec_alg_tfm_ctx *ctx, - struct sec_bd_info *req, - enum sec_cipher_alg alg) -{ - const struct sec_c_alg_cfg *cfg = &sec_c_alg_cfgs[alg]; - - memset(req, 0, sizeof(*req)); - req->w0 |= cfg->c_mode << SEC_BD_W0_C_MODE_S; - req->w1 |= cfg->c_alg << SEC_BD_W1_C_ALG_S; - req->w3 |= cfg->key_len << SEC_BD_W3_C_KEY_LEN_S; - req->w0 |= cfg->c_width << SEC_BD_W0_C_WIDTH_S; - - req->cipher_key_addr_lo = lower_32_bits(ctx->pkey); - req->cipher_key_addr_hi = upper_32_bits(ctx->pkey); -} - -static void sec_alg_skcipher_init_context(struct crypto_skcipher *atfm, - const u8 *key, - unsigned int keylen, - enum sec_cipher_alg alg) -{ - struct crypto_tfm *tfm = crypto_skcipher_tfm(atfm); - struct sec_alg_tfm_ctx *ctx = crypto_tfm_ctx(tfm); - - ctx->cipher_alg = alg; - memcpy(ctx->key, key, keylen); - sec_alg_skcipher_init_template(ctx, &ctx->req_template, - ctx->cipher_alg); -} - -static void sec_free_hw_sgl(struct sec_hw_sgl *hw_sgl, - dma_addr_t psec_sgl, struct sec_dev_info *info) -{ - struct sec_hw_sgl *sgl_current, *sgl_next; - dma_addr_t sgl_next_dma; - - sgl_current = hw_sgl; - while (sgl_current) { - sgl_next = sgl_current->next; - sgl_next_dma = sgl_current->next_sgl; - - dma_pool_free(info->hw_sgl_pool, sgl_current, psec_sgl); - - sgl_current = sgl_next; - psec_sgl = sgl_next_dma; - } -} - -static int sec_alloc_and_fill_hw_sgl(struct sec_hw_sgl **sec_sgl, - dma_addr_t *psec_sgl, - struct scatterlist *sgl, - int count, - struct sec_dev_info *info, - gfp_t gfp) -{ - struct sec_hw_sgl *sgl_current = NULL; - struct sec_hw_sgl *sgl_next; - dma_addr_t sgl_next_dma; - struct scatterlist *sg; - int ret, sge_index, i; - - if (!count) - return -EINVAL; - - for_each_sg(sgl, sg, count, i) { - sge_index = i % SEC_MAX_SGE_NUM; - if (sge_index == 0) { - sgl_next = dma_pool_zalloc(info->hw_sgl_pool, - gfp, &sgl_next_dma); - if (!sgl_next) { - ret = -ENOMEM; - goto err_free_hw_sgls; - } - - if (!sgl_current) { /* First one */ - *psec_sgl = sgl_next_dma; - *sec_sgl = sgl_next; - } else { /* Chained */ - sgl_current->entry_sum_in_sgl = SEC_MAX_SGE_NUM; - sgl_current->next_sgl = sgl_next_dma; - sgl_current->next = sgl_next; - } - sgl_current = sgl_next; - } - sgl_current->sge_entries[sge_index].buf = sg_dma_address(sg); - sgl_current->sge_entries[sge_index].len = sg_dma_len(sg); - sgl_current->data_bytes_in_sgl += sg_dma_len(sg); - } - sgl_current->entry_sum_in_sgl = count % SEC_MAX_SGE_NUM; - sgl_current->next_sgl = 0; - (*sec_sgl)->entry_sum_in_chain = count; - - return 0; - -err_free_hw_sgls: - sec_free_hw_sgl(*sec_sgl, *psec_sgl, info); - *psec_sgl = 0; - - return ret; -} - -static int sec_alg_skcipher_setkey(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen, - enum sec_cipher_alg alg) -{ - struct sec_alg_tfm_ctx *ctx = crypto_skcipher_ctx(tfm); - struct device *dev = ctx->queue->dev_info->dev; - - mutex_lock(&ctx->lock); - if (ctx->key) { - /* rekeying */ - memset(ctx->key, 0, SEC_MAX_CIPHER_KEY); - } else { - /* new key */ - ctx->key = dma_alloc_coherent(dev, SEC_MAX_CIPHER_KEY, - &ctx->pkey, GFP_KERNEL); - if (!ctx->key) { - mutex_unlock(&ctx->lock); - return -ENOMEM; - } - } - mutex_unlock(&ctx->lock); - sec_alg_skcipher_init_context(tfm, key, keylen, alg); - - return 0; -} - -static int sec_alg_skcipher_setkey_aes_ecb(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen) -{ - enum sec_cipher_alg alg; - - switch (keylen) { - case AES_KEYSIZE_128: - alg = SEC_C_AES_ECB_128; - break; - case AES_KEYSIZE_192: - alg = SEC_C_AES_ECB_192; - break; - case AES_KEYSIZE_256: - alg = SEC_C_AES_ECB_256; - break; - default: - return -EINVAL; - } - - return sec_alg_skcipher_setkey(tfm, key, keylen, alg); -} - -static int sec_alg_skcipher_setkey_aes_cbc(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen) -{ - enum sec_cipher_alg alg; - - switch (keylen) { - case AES_KEYSIZE_128: - alg = SEC_C_AES_CBC_128; - break; - case AES_KEYSIZE_192: - alg = SEC_C_AES_CBC_192; - break; - case AES_KEYSIZE_256: - alg = SEC_C_AES_CBC_256; - break; - default: - return -EINVAL; - } - - return sec_alg_skcipher_setkey(tfm, key, keylen, alg); -} - -static int sec_alg_skcipher_setkey_aes_ctr(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen) -{ - enum sec_cipher_alg alg; - - switch (keylen) { - case AES_KEYSIZE_128: - alg = SEC_C_AES_CTR_128; - break; - case AES_KEYSIZE_192: - alg = SEC_C_AES_CTR_192; - break; - case AES_KEYSIZE_256: - alg = SEC_C_AES_CTR_256; - break; - default: - return -EINVAL; - } - - return sec_alg_skcipher_setkey(tfm, key, keylen, alg); -} - -static int sec_alg_skcipher_setkey_aes_xts(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen) -{ - enum sec_cipher_alg alg; - int ret; - - ret = xts_verify_key(tfm, key, keylen); - if (ret) - return ret; - - switch (keylen) { - case AES_KEYSIZE_128 * 2: - alg = SEC_C_AES_XTS_128; - break; - case AES_KEYSIZE_256 * 2: - alg = SEC_C_AES_XTS_256; - break; - default: - return -EINVAL; - } - - return sec_alg_skcipher_setkey(tfm, key, keylen, alg); -} - -static int sec_alg_skcipher_setkey_des_ecb(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen) -{ - return verify_skcipher_des_key(tfm, key) ?: - sec_alg_skcipher_setkey(tfm, key, keylen, SEC_C_DES_ECB_64); -} - -static int sec_alg_skcipher_setkey_des_cbc(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen) -{ - return verify_skcipher_des_key(tfm, key) ?: - sec_alg_skcipher_setkey(tfm, key, keylen, SEC_C_DES_CBC_64); -} - -static int sec_alg_skcipher_setkey_3des_ecb(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen) -{ - return verify_skcipher_des3_key(tfm, key) ?: - sec_alg_skcipher_setkey(tfm, key, keylen, - SEC_C_3DES_ECB_192_3KEY); -} - -static int sec_alg_skcipher_setkey_3des_cbc(struct crypto_skcipher *tfm, - const u8 *key, unsigned int keylen) -{ - return verify_skcipher_des3_key(tfm, key) ?: - sec_alg_skcipher_setkey(tfm, key, keylen, - SEC_C_3DES_CBC_192_3KEY); -} - -static void sec_alg_free_el(struct sec_request_el *el, - struct sec_dev_info *info) -{ - sec_free_hw_sgl(el->out, el->dma_out, info); - sec_free_hw_sgl(el->in, el->dma_in, info); - kfree(el->sgl_in); - kfree(el->sgl_out); - kfree(el); -} - -/* queuelock must be held */ -static int sec_send_request(struct sec_request *sec_req, struct sec_queue *queue) -{ - struct sec_request_el *el, *temp; - int ret = 0; - - mutex_lock(&sec_req->lock); - list_for_each_entry_safe(el, temp, &sec_req->elements, head) { - /* - * Add to hardware queue only under following circumstances - * 1) Software and hardware queue empty so no chain dependencies - * 2) No dependencies as new IV - (check software queue empty - * to maintain order) - * 3) No dependencies because the mode does no chaining. - * - * In other cases first insert onto the software queue which - * is then emptied as requests complete - */ - if (!queue->havesoftqueue || - (kfifo_is_empty(&queue->softqueue) && - sec_queue_empty(queue))) { - ret = sec_queue_send(queue, &el->req, sec_req); - if (ret == -EAGAIN) { - /* Wait unti we can send then try again */ - /* DEAD if here - should not happen */ - ret = -EBUSY; - goto err_unlock; - } - } else { - kfifo_put(&queue->softqueue, el); - } - } -err_unlock: - mutex_unlock(&sec_req->lock); - - return ret; -} - -static void sec_skcipher_alg_callback(struct sec_bd_info *sec_resp, - struct crypto_async_request *req_base) -{ - struct skcipher_request *skreq = container_of(req_base, - struct skcipher_request, - base); - struct sec_request *sec_req = skcipher_request_ctx(skreq); - struct sec_request *backlog_req; - struct sec_request_el *sec_req_el, *nextrequest; - struct sec_alg_tfm_ctx *ctx = sec_req->tfm_ctx; - struct crypto_skcipher *atfm = crypto_skcipher_reqtfm(skreq); - struct device *dev = ctx->queue->dev_info->dev; - int icv_or_skey_en, ret; - bool done; - - sec_req_el = list_first_entry(&sec_req->elements, struct sec_request_el, - head); - icv_or_skey_en = (sec_resp->w0 & SEC_BD_W0_ICV_OR_SKEY_EN_M) >> - SEC_BD_W0_ICV_OR_SKEY_EN_S; - if (sec_resp->w1 & SEC_BD_W1_BD_INVALID || icv_or_skey_en == 3) { - dev_err(dev, "Got an invalid answer %lu %d\n", - sec_resp->w1 & SEC_BD_W1_BD_INVALID, - icv_or_skey_en); - sec_req->err = -EINVAL; - /* - * We need to muddle on to avoid getting stuck with elements - * on the queue. Error will be reported so requester so - * it should be able to handle appropriately. - */ - } - - spin_lock_bh(&ctx->queue->queuelock); - /* Put the IV in place for chained cases */ - switch (ctx->cipher_alg) { - case SEC_C_AES_CBC_128: - case SEC_C_AES_CBC_192: - case SEC_C_AES_CBC_256: - if (sec_req_el->req.w0 & SEC_BD_W0_DE) - sg_pcopy_to_buffer(sec_req_el->sgl_out, - sg_nents(sec_req_el->sgl_out), - skreq->iv, - crypto_skcipher_ivsize(atfm), - sec_req_el->el_length - - crypto_skcipher_ivsize(atfm)); - else - sg_pcopy_to_buffer(sec_req_el->sgl_in, - sg_nents(sec_req_el->sgl_in), - skreq->iv, - crypto_skcipher_ivsize(atfm), - sec_req_el->el_length - - crypto_skcipher_ivsize(atfm)); - /* No need to sync to the device as coherent DMA */ - break; - case SEC_C_AES_CTR_128: - case SEC_C_AES_CTR_192: - case SEC_C_AES_CTR_256: - crypto_inc(skreq->iv, 16); - break; - default: - /* Do not update */ - break; - } - - if (ctx->queue->havesoftqueue && - !kfifo_is_empty(&ctx->queue->softqueue) && - sec_queue_empty(ctx->queue)) { - ret = kfifo_get(&ctx->queue->softqueue, &nextrequest); - if (ret <= 0) - dev_err(dev, - "Error getting next element from kfifo %d\n", - ret); - else - /* We know there is space so this cannot fail */ - sec_queue_send(ctx->queue, &nextrequest->req, - nextrequest->sec_req); - } else if (!list_empty(&ctx->backlog)) { - /* Need to verify there is room first */ - backlog_req = list_first_entry(&ctx->backlog, - typeof(*backlog_req), - backlog_head); - if (sec_queue_can_enqueue(ctx->queue, - backlog_req->num_elements) || - (ctx->queue->havesoftqueue && - kfifo_avail(&ctx->queue->softqueue) > - backlog_req->num_elements)) { - sec_send_request(backlog_req, ctx->queue); - crypto_request_complete(backlog_req->req_base, - -EINPROGRESS); - list_del(&backlog_req->backlog_head); - } - } - spin_unlock_bh(&ctx->queue->queuelock); - - mutex_lock(&sec_req->lock); - list_del(&sec_req_el->head); - mutex_unlock(&sec_req->lock); - sec_alg_free_el(sec_req_el, ctx->queue->dev_info); - - /* - * Request is done. - * The dance is needed as the lock is freed in the completion - */ - mutex_lock(&sec_req->lock); - done = list_empty(&sec_req->elements); - mutex_unlock(&sec_req->lock); - if (done) { - if (crypto_skcipher_ivsize(atfm)) { - dma_unmap_single(dev, sec_req->dma_iv, - crypto_skcipher_ivsize(atfm), - DMA_TO_DEVICE); - } - dma_unmap_sg(dev, skreq->src, sec_req->len_in, - DMA_BIDIRECTIONAL); - if (skreq->src != skreq->dst) - dma_unmap_sg(dev, skreq->dst, sec_req->len_out, - DMA_BIDIRECTIONAL); - skcipher_request_complete(skreq, sec_req->err); - } -} - -void sec_alg_callback(struct sec_bd_info *resp, void *shadow) -{ - struct sec_request *sec_req = shadow; - - sec_req->cb(resp, sec_req->req_base); -} - -static int sec_alg_alloc_and_calc_split_sizes(int length, size_t **split_sizes, - int *steps, gfp_t gfp) -{ - size_t *sizes; - int i; - - /* Split into suitable sized blocks */ - *steps = roundup(length, SEC_REQ_LIMIT) / SEC_REQ_LIMIT; - sizes = kzalloc_objs(*sizes, *steps, gfp); - if (!sizes) - return -ENOMEM; - - for (i = 0; i < *steps - 1; i++) - sizes[i] = SEC_REQ_LIMIT; - sizes[*steps - 1] = length - SEC_REQ_LIMIT * (*steps - 1); - *split_sizes = sizes; - - return 0; -} - -static int sec_map_and_split_sg(struct scatterlist *sgl, size_t *split_sizes, - int steps, struct scatterlist ***splits, - int **splits_nents, - int sgl_len_in, - struct device *dev, gfp_t gfp) -{ - int ret, count; - - count = dma_map_sg(dev, sgl, sgl_len_in, DMA_BIDIRECTIONAL); - if (!count) - return -EINVAL; - - *splits = kzalloc_objs(struct scatterlist *, steps, gfp); - if (!*splits) { - ret = -ENOMEM; - goto err_unmap_sg; - } - *splits_nents = kzalloc_objs(int, steps, gfp); - if (!*splits_nents) { - ret = -ENOMEM; - goto err_free_splits; - } - - /* output the scatter list before and after this */ - ret = sg_split(sgl, count, 0, steps, split_sizes, - *splits, *splits_nents, gfp); - if (ret) { - ret = -ENOMEM; - goto err_free_splits_nents; - } - - return 0; - -err_free_splits_nents: - kfree(*splits_nents); -err_free_splits: - kfree(*splits); -err_unmap_sg: - dma_unmap_sg(dev, sgl, sgl_len_in, DMA_BIDIRECTIONAL); - - return ret; -} - -/* - * Reverses the sec_map_and_split_sg call for messages not yet added to - * the queues. - */ -static void sec_unmap_sg_on_err(struct scatterlist *sgl, int steps, - struct scatterlist **splits, int *splits_nents, - int sgl_len_in, struct device *dev) -{ - int i; - - for (i = 0; i < steps; i++) - kfree(splits[i]); - kfree(splits_nents); - kfree(splits); - - dma_unmap_sg(dev, sgl, sgl_len_in, DMA_BIDIRECTIONAL); -} - -static struct sec_request_el -*sec_alg_alloc_and_fill_el(struct sec_bd_info *template, int encrypt, - int el_size, bool different_dest, - struct scatterlist *sgl_in, int n_ents_in, - struct scatterlist *sgl_out, int n_ents_out, - struct sec_dev_info *info, gfp_t gfp) -{ - struct sec_request_el *el; - struct sec_bd_info *req; - int ret; - - el = kzalloc_obj(*el, gfp); - if (!el) - return ERR_PTR(-ENOMEM); - el->el_length = el_size; - req = &el->req; - memcpy(req, template, sizeof(*req)); - - req->w0 &= ~SEC_BD_W0_CIPHER_M; - if (encrypt) - req->w0 |= SEC_CIPHER_ENCRYPT << SEC_BD_W0_CIPHER_S; - else - req->w0 |= SEC_CIPHER_DECRYPT << SEC_BD_W0_CIPHER_S; - - req->w0 &= ~SEC_BD_W0_C_GRAN_SIZE_19_16_M; - req->w0 |= ((el_size >> 16) << SEC_BD_W0_C_GRAN_SIZE_19_16_S) & - SEC_BD_W0_C_GRAN_SIZE_19_16_M; - - req->w0 &= ~SEC_BD_W0_C_GRAN_SIZE_21_20_M; - req->w0 |= ((el_size >> 20) << SEC_BD_W0_C_GRAN_SIZE_21_20_S) & - SEC_BD_W0_C_GRAN_SIZE_21_20_M; - - /* Writing whole u32 so no need to take care of masking */ - req->w2 = ((1 << SEC_BD_W2_GRAN_NUM_S) & SEC_BD_W2_GRAN_NUM_M) | - ((el_size << SEC_BD_W2_C_GRAN_SIZE_15_0_S) & - SEC_BD_W2_C_GRAN_SIZE_15_0_M); - - req->w3 &= ~SEC_BD_W3_CIPHER_LEN_OFFSET_M; - req->w1 |= SEC_BD_W1_ADDR_TYPE; - - el->sgl_in = sgl_in; - - ret = sec_alloc_and_fill_hw_sgl(&el->in, &el->dma_in, el->sgl_in, - n_ents_in, info, gfp); - if (ret) - goto err_free_el; - - req->data_addr_lo = lower_32_bits(el->dma_in); - req->data_addr_hi = upper_32_bits(el->dma_in); - - if (different_dest) { - el->sgl_out = sgl_out; - ret = sec_alloc_and_fill_hw_sgl(&el->out, &el->dma_out, - el->sgl_out, - n_ents_out, info, gfp); - if (ret) - goto err_free_hw_sgl_in; - - req->w0 |= SEC_BD_W0_DE; - req->cipher_destin_addr_lo = lower_32_bits(el->dma_out); - req->cipher_destin_addr_hi = upper_32_bits(el->dma_out); - - } else { - req->w0 &= ~SEC_BD_W0_DE; - req->cipher_destin_addr_lo = lower_32_bits(el->dma_in); - req->cipher_destin_addr_hi = upper_32_bits(el->dma_in); - } - - return el; - -err_free_hw_sgl_in: - sec_free_hw_sgl(el->in, el->dma_in, info); -err_free_el: - kfree(el); - - return ERR_PTR(ret); -} - -static int sec_alg_skcipher_crypto(struct skcipher_request *skreq, - bool encrypt) -{ - struct crypto_skcipher *atfm = crypto_skcipher_reqtfm(skreq); - struct crypto_tfm *tfm = crypto_skcipher_tfm(atfm); - struct sec_alg_tfm_ctx *ctx = crypto_tfm_ctx(tfm); - struct sec_queue *queue = ctx->queue; - struct sec_request *sec_req = skcipher_request_ctx(skreq); - struct sec_dev_info *info = queue->dev_info; - int i, ret, steps; - size_t *split_sizes; - struct scatterlist **splits_in; - struct scatterlist **splits_out = NULL; - int *splits_in_nents; - int *splits_out_nents = NULL; - struct sec_request_el *el, *temp; - bool split = skreq->src != skreq->dst; - gfp_t gfp = skreq->base.flags & CRYPTO_TFM_REQ_MAY_SLEEP ? GFP_KERNEL : GFP_ATOMIC; - - mutex_init(&sec_req->lock); - sec_req->req_base = &skreq->base; - sec_req->err = 0; - /* SGL mapping out here to allow us to break it up as necessary */ - sec_req->len_in = sg_nents(skreq->src); - - ret = sec_alg_alloc_and_calc_split_sizes(skreq->cryptlen, &split_sizes, - &steps, gfp); - if (ret) - return ret; - sec_req->num_elements = steps; - ret = sec_map_and_split_sg(skreq->src, split_sizes, steps, &splits_in, - &splits_in_nents, sec_req->len_in, - info->dev, gfp); - if (ret) - goto err_free_split_sizes; - - if (split) { - sec_req->len_out = sg_nents(skreq->dst); - ret = sec_map_and_split_sg(skreq->dst, split_sizes, steps, - &splits_out, &splits_out_nents, - sec_req->len_out, info->dev, gfp); - if (ret) - goto err_unmap_in_sg; - } - /* Shared info stored in seq_req - applies to all BDs */ - sec_req->tfm_ctx = ctx; - sec_req->cb = sec_skcipher_alg_callback; - INIT_LIST_HEAD(&sec_req->elements); - - /* - * Future optimization. - * In the chaining case we can't use a dma pool bounce buffer - * but in the case where we know there is no chaining we can - */ - if (crypto_skcipher_ivsize(atfm)) { - sec_req->dma_iv = dma_map_single(info->dev, skreq->iv, - crypto_skcipher_ivsize(atfm), - DMA_TO_DEVICE); - if (dma_mapping_error(info->dev, sec_req->dma_iv)) { - ret = -ENOMEM; - goto err_unmap_out_sg; - } - } - - /* Set them all up then queue - cleaner error handling. */ - for (i = 0; i < steps; i++) { - el = sec_alg_alloc_and_fill_el(&ctx->req_template, - encrypt ? 1 : 0, - split_sizes[i], - skreq->src != skreq->dst, - splits_in[i], splits_in_nents[i], - split ? splits_out[i] : NULL, - split ? splits_out_nents[i] : 0, - info, gfp); - if (IS_ERR(el)) { - ret = PTR_ERR(el); - goto err_free_elements; - } - el->req.cipher_iv_addr_lo = lower_32_bits(sec_req->dma_iv); - el->req.cipher_iv_addr_hi = upper_32_bits(sec_req->dma_iv); - el->sec_req = sec_req; - list_add_tail(&el->head, &sec_req->elements); - } - - /* - * Only attempt to queue if the whole lot can fit in the queue - - * we can't successfully cleanup after a partial queing so this - * must succeed or fail atomically. - * - * Big hammer test of both software and hardware queues - could be - * more refined but this is unlikely to happen so no need. - */ - - /* Grab a big lock for a long time to avoid concurrency issues */ - spin_lock_bh(&queue->queuelock); - - /* - * Can go on to queue if we have space in either: - * 1) The hardware queue and no software queue - * 2) The software queue - * AND there is nothing in the backlog. If there is backlog we - * have to only queue to the backlog queue and return busy. - */ - if ((!sec_queue_can_enqueue(queue, steps) && - (!queue->havesoftqueue || - kfifo_avail(&queue->softqueue) > steps)) || - !list_empty(&ctx->backlog)) { - ret = -EBUSY; - if ((skreq->base.flags & CRYPTO_TFM_REQ_MAY_BACKLOG)) { - list_add_tail(&sec_req->backlog_head, &ctx->backlog); - spin_unlock_bh(&queue->queuelock); - goto out; - } - - spin_unlock_bh(&queue->queuelock); - goto err_free_elements; - } - ret = sec_send_request(sec_req, queue); - spin_unlock_bh(&queue->queuelock); - if (ret) - goto err_free_elements; - - ret = -EINPROGRESS; -out: - /* Cleanup - all elements in pointer arrays have been copied */ - kfree(splits_in_nents); - kfree(splits_in); - kfree(splits_out_nents); - kfree(splits_out); - kfree(split_sizes); - return ret; - -err_free_elements: - list_for_each_entry_safe(el, temp, &sec_req->elements, head) { - list_del(&el->head); - sec_alg_free_el(el, info); - } - if (crypto_skcipher_ivsize(atfm)) - dma_unmap_single(info->dev, sec_req->dma_iv, - crypto_skcipher_ivsize(atfm), - DMA_TO_DEVICE); -err_unmap_out_sg: - if (split) - sec_unmap_sg_on_err(skreq->dst, steps, splits_out, - splits_out_nents, sec_req->len_out, - info->dev); -err_unmap_in_sg: - sec_unmap_sg_on_err(skreq->src, steps, splits_in, splits_in_nents, - sec_req->len_in, info->dev); -err_free_split_sizes: - kfree(split_sizes); - - return ret; -} - -static int sec_alg_skcipher_encrypt(struct skcipher_request *req) -{ - return sec_alg_skcipher_crypto(req, true); -} - -static int sec_alg_skcipher_decrypt(struct skcipher_request *req) -{ - return sec_alg_skcipher_crypto(req, false); -} - -static int sec_alg_skcipher_init(struct crypto_skcipher *tfm) -{ - struct sec_alg_tfm_ctx *ctx = crypto_skcipher_ctx(tfm); - - mutex_init(&ctx->lock); - INIT_LIST_HEAD(&ctx->backlog); - crypto_skcipher_set_reqsize(tfm, sizeof(struct sec_request)); - - ctx->queue = sec_queue_alloc_start_safe(); - if (IS_ERR(ctx->queue)) - return PTR_ERR(ctx->queue); - - spin_lock_init(&ctx->queue->queuelock); - ctx->queue->havesoftqueue = false; - - return 0; -} - -static void sec_alg_skcipher_exit(struct crypto_skcipher *tfm) -{ - struct sec_alg_tfm_ctx *ctx = crypto_skcipher_ctx(tfm); - struct device *dev = ctx->queue->dev_info->dev; - - if (ctx->key) { - memzero_explicit(ctx->key, SEC_MAX_CIPHER_KEY); - dma_free_coherent(dev, SEC_MAX_CIPHER_KEY, ctx->key, - ctx->pkey); - } - sec_queue_stop_release(ctx->queue); -} - -static int sec_alg_skcipher_init_with_queue(struct crypto_skcipher *tfm) -{ - struct sec_alg_tfm_ctx *ctx = crypto_skcipher_ctx(tfm); - int ret; - - ret = sec_alg_skcipher_init(tfm); - if (ret) - return ret; - - INIT_KFIFO(ctx->queue->softqueue); - ret = kfifo_alloc(&ctx->queue->softqueue, 512, GFP_KERNEL); - if (ret) { - sec_alg_skcipher_exit(tfm); - return ret; - } - ctx->queue->havesoftqueue = true; - - return 0; -} - -static void sec_alg_skcipher_exit_with_queue(struct crypto_skcipher *tfm) -{ - struct sec_alg_tfm_ctx *ctx = crypto_skcipher_ctx(tfm); - - kfifo_free(&ctx->queue->softqueue); - sec_alg_skcipher_exit(tfm); -} - -static struct skcipher_alg sec_algs[] = { - { - .base = { - .cra_name = "ecb(aes)", - .cra_driver_name = "hisi_sec_aes_ecb", - .cra_priority = 4001, - .cra_flags = CRYPTO_ALG_ASYNC | - CRYPTO_ALG_ALLOCATES_MEMORY, - .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx), - .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - .init = sec_alg_skcipher_init, - .exit = sec_alg_skcipher_exit, - .setkey = sec_alg_skcipher_setkey_aes_ecb, - .decrypt = sec_alg_skcipher_decrypt, - .encrypt = sec_alg_skcipher_encrypt, - .min_keysize = AES_MIN_KEY_SIZE, - .max_keysize = AES_MAX_KEY_SIZE, - .ivsize = 0, - }, { - .base = { - .cra_name = "cbc(aes)", - .cra_driver_name = "hisi_sec_aes_cbc", - .cra_priority = 4001, - .cra_flags = CRYPTO_ALG_ASYNC | - CRYPTO_ALG_ALLOCATES_MEMORY, - .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx), - .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - .init = sec_alg_skcipher_init_with_queue, - .exit = sec_alg_skcipher_exit_with_queue, - .setkey = sec_alg_skcipher_setkey_aes_cbc, - .decrypt = sec_alg_skcipher_decrypt, - .encrypt = sec_alg_skcipher_encrypt, - .min_keysize = AES_MIN_KEY_SIZE, - .max_keysize = AES_MAX_KEY_SIZE, - .ivsize = AES_BLOCK_SIZE, - }, { - .base = { - .cra_name = "ctr(aes)", - .cra_driver_name = "hisi_sec_aes_ctr", - .cra_priority = 4001, - .cra_flags = CRYPTO_ALG_ASYNC | - CRYPTO_ALG_ALLOCATES_MEMORY, - .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx), - .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - .init = sec_alg_skcipher_init_with_queue, - .exit = sec_alg_skcipher_exit_with_queue, - .setkey = sec_alg_skcipher_setkey_aes_ctr, - .decrypt = sec_alg_skcipher_decrypt, - .encrypt = sec_alg_skcipher_encrypt, - .min_keysize = AES_MIN_KEY_SIZE, - .max_keysize = AES_MAX_KEY_SIZE, - .ivsize = AES_BLOCK_SIZE, - }, { - .base = { - .cra_name = "xts(aes)", - .cra_driver_name = "hisi_sec_aes_xts", - .cra_priority = 4001, - .cra_flags = CRYPTO_ALG_ASYNC | - CRYPTO_ALG_ALLOCATES_MEMORY, - .cra_blocksize = AES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx), - .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - .init = sec_alg_skcipher_init, - .exit = sec_alg_skcipher_exit, - .setkey = sec_alg_skcipher_setkey_aes_xts, - .decrypt = sec_alg_skcipher_decrypt, - .encrypt = sec_alg_skcipher_encrypt, - .min_keysize = 2 * AES_MIN_KEY_SIZE, - .max_keysize = 2 * AES_MAX_KEY_SIZE, - .ivsize = AES_BLOCK_SIZE, - }, { - /* Unable to find any test vectors so untested */ - .base = { - .cra_name = "ecb(des)", - .cra_driver_name = "hisi_sec_des_ecb", - .cra_priority = 4001, - .cra_flags = CRYPTO_ALG_ASYNC | - CRYPTO_ALG_ALLOCATES_MEMORY, - .cra_blocksize = DES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx), - .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - .init = sec_alg_skcipher_init, - .exit = sec_alg_skcipher_exit, - .setkey = sec_alg_skcipher_setkey_des_ecb, - .decrypt = sec_alg_skcipher_decrypt, - .encrypt = sec_alg_skcipher_encrypt, - .min_keysize = DES_KEY_SIZE, - .max_keysize = DES_KEY_SIZE, - .ivsize = 0, - }, { - .base = { - .cra_name = "cbc(des)", - .cra_driver_name = "hisi_sec_des_cbc", - .cra_priority = 4001, - .cra_flags = CRYPTO_ALG_ASYNC | - CRYPTO_ALG_ALLOCATES_MEMORY, - .cra_blocksize = DES_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx), - .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - .init = sec_alg_skcipher_init_with_queue, - .exit = sec_alg_skcipher_exit_with_queue, - .setkey = sec_alg_skcipher_setkey_des_cbc, - .decrypt = sec_alg_skcipher_decrypt, - .encrypt = sec_alg_skcipher_encrypt, - .min_keysize = DES_KEY_SIZE, - .max_keysize = DES_KEY_SIZE, - .ivsize = DES_BLOCK_SIZE, - }, { - .base = { - .cra_name = "cbc(des3_ede)", - .cra_driver_name = "hisi_sec_3des_cbc", - .cra_priority = 4001, - .cra_flags = CRYPTO_ALG_ASYNC | - CRYPTO_ALG_ALLOCATES_MEMORY, - .cra_blocksize = DES3_EDE_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx), - .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - .init = sec_alg_skcipher_init_with_queue, - .exit = sec_alg_skcipher_exit_with_queue, - .setkey = sec_alg_skcipher_setkey_3des_cbc, - .decrypt = sec_alg_skcipher_decrypt, - .encrypt = sec_alg_skcipher_encrypt, - .min_keysize = DES3_EDE_KEY_SIZE, - .max_keysize = DES3_EDE_KEY_SIZE, - .ivsize = DES3_EDE_BLOCK_SIZE, - }, { - .base = { - .cra_name = "ecb(des3_ede)", - .cra_driver_name = "hisi_sec_3des_ecb", - .cra_priority = 4001, - .cra_flags = CRYPTO_ALG_ASYNC | - CRYPTO_ALG_ALLOCATES_MEMORY, - .cra_blocksize = DES3_EDE_BLOCK_SIZE, - .cra_ctxsize = sizeof(struct sec_alg_tfm_ctx), - .cra_alignmask = 0, - .cra_module = THIS_MODULE, - }, - .init = sec_alg_skcipher_init, - .exit = sec_alg_skcipher_exit, - .setkey = sec_alg_skcipher_setkey_3des_ecb, - .decrypt = sec_alg_skcipher_decrypt, - .encrypt = sec_alg_skcipher_encrypt, - .min_keysize = DES3_EDE_KEY_SIZE, - .max_keysize = DES3_EDE_KEY_SIZE, - .ivsize = 0, - } -}; - -int sec_algs_register(void) -{ - int ret = 0; - - mutex_lock(&algs_lock); - if (++active_devs != 1) - goto unlock; - - ret = crypto_register_skciphers(sec_algs, ARRAY_SIZE(sec_algs)); - if (ret) - --active_devs; -unlock: - mutex_unlock(&algs_lock); - - return ret; -} - -void sec_algs_unregister(void) -{ - mutex_lock(&algs_lock); - if (--active_devs != 0) - goto unlock; - crypto_unregister_skciphers(sec_algs, ARRAY_SIZE(sec_algs)); - -unlock: - mutex_unlock(&algs_lock); -}
diff --git a/drivers/crypto/hisilicon/sec/sec_drv.c b/drivers/crypto/hisilicon/sec/sec_drv.c deleted file mode 100644 index 2514a5e..0000000 --- a/drivers/crypto/hisilicon/sec/sec_drv.c +++ /dev/null
@@ -1,1307 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Driver for the HiSilicon SEC units found on Hip06 Hip07 - * - * Copyright (c) 2016-2017 HiSilicon Limited. - */ -#include <linux/acpi.h> -#include <linux/atomic.h> -#include <linux/delay.h> -#include <linux/dma-direction.h> -#include <linux/dma-mapping.h> -#include <linux/dmapool.h> -#include <linux/io.h> -#include <linux/iommu.h> -#include <linux/interrupt.h> -#include <linux/irq.h> -#include <linux/irqreturn.h> -#include <linux/mm.h> -#include <linux/module.h> -#include <linux/of.h> -#include <linux/platform_device.h> -#include <linux/slab.h> - -#include "sec_drv.h" - -#define SEC_QUEUE_AR_FROCE_ALLOC 0 -#define SEC_QUEUE_AR_FROCE_NOALLOC 1 -#define SEC_QUEUE_AR_FROCE_DIS 2 - -#define SEC_QUEUE_AW_FROCE_ALLOC 0 -#define SEC_QUEUE_AW_FROCE_NOALLOC 1 -#define SEC_QUEUE_AW_FROCE_DIS 2 - -/* SEC_ALGSUB registers */ -#define SEC_ALGSUB_CLK_EN_REG 0x03b8 -#define SEC_ALGSUB_CLK_DIS_REG 0x03bc -#define SEC_ALGSUB_CLK_ST_REG 0x535c -#define SEC_ALGSUB_RST_REQ_REG 0x0aa8 -#define SEC_ALGSUB_RST_DREQ_REG 0x0aac -#define SEC_ALGSUB_RST_ST_REG 0x5a54 -#define SEC_ALGSUB_RST_ST_IS_RST BIT(0) - -#define SEC_ALGSUB_BUILD_RST_REQ_REG 0x0ab8 -#define SEC_ALGSUB_BUILD_RST_DREQ_REG 0x0abc -#define SEC_ALGSUB_BUILD_RST_ST_REG 0x5a5c -#define SEC_ALGSUB_BUILD_RST_ST_IS_RST BIT(0) - -#define SEC_SAA_BASE 0x00001000UL - -/* SEC_SAA registers */ -#define SEC_SAA_CTRL_REG(x) ((x) * SEC_SAA_ADDR_SIZE) -#define SEC_SAA_CTRL_GET_QM_EN BIT(0) - -#define SEC_ST_INTMSK1_REG 0x0200 -#define SEC_ST_RINT1_REG 0x0400 -#define SEC_ST_INTSTS1_REG 0x0600 -#define SEC_BD_MNG_STAT_REG 0x0800 -#define SEC_PARSING_STAT_REG 0x0804 -#define SEC_LOAD_TIME_OUT_CNT_REG 0x0808 -#define SEC_CORE_WORK_TIME_OUT_CNT_REG 0x080c -#define SEC_BACK_TIME_OUT_CNT_REG 0x0810 -#define SEC_BD1_PARSING_RD_TIME_OUT_CNT_REG 0x0814 -#define SEC_BD1_PARSING_WR_TIME_OUT_CNT_REG 0x0818 -#define SEC_BD2_PARSING_RD_TIME_OUT_CNT_REG 0x081c -#define SEC_BD2_PARSING_WR_TIME_OUT_CNT_REG 0x0820 -#define SEC_SAA_ACC_REG 0x083c -#define SEC_BD_NUM_CNT_IN_SEC_REG 0x0858 -#define SEC_LOAD_WORK_TIME_CNT_REG 0x0860 -#define SEC_CORE_WORK_WORK_TIME_CNT_REG 0x0864 -#define SEC_BACK_WORK_TIME_CNT_REG 0x0868 -#define SEC_SAA_IDLE_TIME_CNT_REG 0x086c -#define SEC_SAA_CLK_CNT_REG 0x0870 - -/* SEC_COMMON registers */ -#define SEC_CLK_EN_REG 0x0000 -#define SEC_CTRL_REG 0x0004 - -#define SEC_COMMON_CNT_CLR_CE_REG 0x0008 -#define SEC_COMMON_CNT_CLR_CE_CLEAR BIT(0) -#define SEC_COMMON_CNT_CLR_CE_SNAP_EN BIT(1) - -#define SEC_SECURE_CTRL_REG 0x000c -#define SEC_AXI_CACHE_CFG_REG 0x0010 -#define SEC_AXI_QOS_CFG_REG 0x0014 -#define SEC_IPV4_MASK_TABLE_REG 0x0020 -#define SEC_IPV6_MASK_TABLE_X_REG(x) (0x0024 + (x) * 4) -#define SEC_FSM_MAX_CNT_REG 0x0064 - -#define SEC_CTRL2_REG 0x0068 -#define SEC_CTRL2_DATA_AXI_RD_OTSD_CFG_M GENMASK(3, 0) -#define SEC_CTRL2_DATA_AXI_RD_OTSD_CFG_S 0 -#define SEC_CTRL2_DATA_AXI_WR_OTSD_CFG_M GENMASK(6, 4) -#define SEC_CTRL2_DATA_AXI_WR_OTSD_CFG_S 4 -#define SEC_CTRL2_CLK_GATE_EN BIT(7) -#define SEC_CTRL2_ENDIAN_BD BIT(8) -#define SEC_CTRL2_ENDIAN_BD_TYPE BIT(9) - -#define SEC_CNT_PRECISION_CFG_REG 0x006c -#define SEC_DEBUG_BD_CFG_REG 0x0070 -#define SEC_DEBUG_BD_CFG_WB_NORMAL BIT(0) -#define SEC_DEBUG_BD_CFG_WB_EN BIT(1) - -#define SEC_Q_SIGHT_SEL 0x0074 -#define SEC_Q_SIGHT_HIS_CLR 0x0078 -#define SEC_Q_VMID_CFG_REG(q) (0x0100 + (q) * 4) -#define SEC_Q_WEIGHT_CFG_REG(q) (0x200 + (q) * 4) -#define SEC_STAT_CLR_REG 0x0a00 -#define SEC_SAA_IDLE_CNT_CLR_REG 0x0a04 -#define SEC_QM_CPL_Q_IDBUF_DFX_CFG_REG 0x0b00 -#define SEC_QM_CPL_Q_IDBUF_DFX_RESULT_REG 0x0b04 -#define SEC_QM_BD_DFX_CFG_REG 0x0b08 -#define SEC_QM_BD_DFX_RESULT_REG 0x0b0c -#define SEC_QM_BDID_DFX_RESULT_REG 0x0b10 -#define SEC_QM_BD_DFIFO_STATUS_REG 0x0b14 -#define SEC_QM_BD_DFX_CFG2_REG 0x0b1c -#define SEC_QM_BD_DFX_RESULT2_REG 0x0b20 -#define SEC_QM_BD_IDFIFO_STATUS_REG 0x0b18 -#define SEC_QM_BD_DFIFO_STATUS2_REG 0x0b28 -#define SEC_QM_BD_IDFIFO_STATUS2_REG 0x0b2c - -#define SEC_HASH_IPV4_MASK 0xfff00000 -#define SEC_MAX_SAA_NUM 0xa -#define SEC_SAA_ADDR_SIZE 0x1000 - -#define SEC_Q_INIT_REG 0x0 -#define SEC_Q_INIT_WO_STAT_CLEAR 0x2 -#define SEC_Q_INIT_AND_STAT_CLEAR 0x3 - -#define SEC_Q_CFG_REG 0x8 -#define SEC_Q_CFG_REORDER BIT(0) - -#define SEC_Q_PROC_NUM_CFG_REG 0x10 -#define SEC_QUEUE_ENB_REG 0x18 - -#define SEC_Q_DEPTH_CFG_REG 0x50 -#define SEC_Q_DEPTH_CFG_DEPTH_M GENMASK(11, 0) -#define SEC_Q_DEPTH_CFG_DEPTH_S 0 - -#define SEC_Q_BASE_HADDR_REG 0x54 -#define SEC_Q_BASE_LADDR_REG 0x58 -#define SEC_Q_WR_PTR_REG 0x5c -#define SEC_Q_OUTORDER_BASE_HADDR_REG 0x60 -#define SEC_Q_OUTORDER_BASE_LADDR_REG 0x64 -#define SEC_Q_OUTORDER_RD_PTR_REG 0x68 -#define SEC_Q_OT_TH_REG 0x6c - -#define SEC_Q_ARUSER_CFG_REG 0x70 -#define SEC_Q_ARUSER_CFG_FA BIT(0) -#define SEC_Q_ARUSER_CFG_FNA BIT(1) -#define SEC_Q_ARUSER_CFG_RINVLD BIT(2) -#define SEC_Q_ARUSER_CFG_PKG BIT(3) - -#define SEC_Q_AWUSER_CFG_REG 0x74 -#define SEC_Q_AWUSER_CFG_FA BIT(0) -#define SEC_Q_AWUSER_CFG_FNA BIT(1) -#define SEC_Q_AWUSER_CFG_PKG BIT(2) - -#define SEC_Q_ERR_BASE_HADDR_REG 0x7c -#define SEC_Q_ERR_BASE_LADDR_REG 0x80 -#define SEC_Q_CFG_VF_NUM_REG 0x84 -#define SEC_Q_SOFT_PROC_PTR_REG 0x88 -#define SEC_Q_FAIL_INT_MSK_REG 0x300 -#define SEC_Q_FLOW_INT_MKS_REG 0x304 -#define SEC_Q_FAIL_RINT_REG 0x400 -#define SEC_Q_FLOW_RINT_REG 0x404 -#define SEC_Q_FAIL_INT_STATUS_REG 0x500 -#define SEC_Q_FLOW_INT_STATUS_REG 0x504 -#define SEC_Q_STATUS_REG 0x600 -#define SEC_Q_RD_PTR_REG 0x604 -#define SEC_Q_PRO_PTR_REG 0x608 -#define SEC_Q_OUTORDER_WR_PTR_REG 0x60c -#define SEC_Q_OT_CNT_STATUS_REG 0x610 -#define SEC_Q_INORDER_BD_NUM_ST_REG 0x650 -#define SEC_Q_INORDER_GET_FLAG_ST_REG 0x654 -#define SEC_Q_INORDER_ADD_FLAG_ST_REG 0x658 -#define SEC_Q_INORDER_TASK_INT_NUM_LEFT_ST_REG 0x65c -#define SEC_Q_RD_DONE_PTR_REG 0x660 -#define SEC_Q_CPL_Q_BD_NUM_ST_REG 0x700 -#define SEC_Q_CPL_Q_PTR_ST_REG 0x704 -#define SEC_Q_CPL_Q_H_ADDR_ST_REG 0x708 -#define SEC_Q_CPL_Q_L_ADDR_ST_REG 0x70c -#define SEC_Q_CPL_TASK_INT_NUM_LEFT_ST_REG 0x710 -#define SEC_Q_WRR_ID_CHECK_REG 0x714 -#define SEC_Q_CPLQ_FULL_CHECK_REG 0x718 -#define SEC_Q_SUCCESS_BD_CNT_REG 0x800 -#define SEC_Q_FAIL_BD_CNT_REG 0x804 -#define SEC_Q_GET_BD_CNT_REG 0x808 -#define SEC_Q_IVLD_CNT_REG 0x80c -#define SEC_Q_BD_PROC_GET_CNT_REG 0x810 -#define SEC_Q_BD_PROC_DONE_CNT_REG 0x814 -#define SEC_Q_LAT_CLR_REG 0x850 -#define SEC_Q_PKT_LAT_MAX_REG 0x854 -#define SEC_Q_PKT_LAT_AVG_REG 0x858 -#define SEC_Q_PKT_LAT_MIN_REG 0x85c -#define SEC_Q_ID_CLR_CFG_REG 0x900 -#define SEC_Q_1ST_BD_ERR_ID_REG 0x904 -#define SEC_Q_1ST_AUTH_FAIL_ID_REG 0x908 -#define SEC_Q_1ST_RD_ERR_ID_REG 0x90c -#define SEC_Q_1ST_ECC2_ERR_ID_REG 0x910 -#define SEC_Q_1ST_IVLD_ID_REG 0x914 -#define SEC_Q_1ST_BD_WR_ERR_ID_REG 0x918 -#define SEC_Q_1ST_ERR_BD_WR_ERR_ID_REG 0x91c -#define SEC_Q_1ST_BD_MAC_WR_ERR_ID_REG 0x920 - -struct sec_debug_bd_info { -#define SEC_DEBUG_BD_INFO_SOFT_ERR_CHECK_M GENMASK(22, 0) - u32 soft_err_check; -#define SEC_DEBUG_BD_INFO_HARD_ERR_CHECK_M GENMASK(9, 0) - u32 hard_err_check; - u32 icv_mac1st_word; -#define SEC_DEBUG_BD_INFO_GET_ID_M GENMASK(19, 0) - u32 sec_get_id; - /* W4---W15 */ - u32 reserv_left[12]; -}; - -struct sec_out_bd_info { -#define SEC_OUT_BD_INFO_Q_ID_M GENMASK(11, 0) -#define SEC_OUT_BD_INFO_ECC_2BIT_ERR BIT(14) - u16 data; -}; - -#define SEC_MAX_DEVICES 8 -static struct sec_dev_info *sec_devices[SEC_MAX_DEVICES]; -static DEFINE_MUTEX(sec_id_lock); - -static int sec_queue_map_io(struct sec_queue *queue) -{ - struct device *dev = queue->dev_info->dev; - struct resource *res; - - res = platform_get_resource(to_platform_device(dev), - IORESOURCE_MEM, - 2 + queue->queue_id); - if (!res) { - dev_err(dev, "Failed to get queue %u memory resource\n", - queue->queue_id); - return -ENOMEM; - } - queue->regs = ioremap(res->start, resource_size(res)); - if (!queue->regs) - return -ENOMEM; - - return 0; -} - -static void sec_queue_unmap_io(struct sec_queue *queue) -{ - iounmap(queue->regs); -} - -static int sec_queue_ar_pkgattr(struct sec_queue *queue, u32 ar_pkg) -{ - void __iomem *addr = queue->regs + SEC_Q_ARUSER_CFG_REG; - u32 regval; - - regval = readl_relaxed(addr); - if (ar_pkg) - regval |= SEC_Q_ARUSER_CFG_PKG; - else - regval &= ~SEC_Q_ARUSER_CFG_PKG; - writel_relaxed(regval, addr); - - return 0; -} - -static int sec_queue_aw_pkgattr(struct sec_queue *queue, u32 aw_pkg) -{ - void __iomem *addr = queue->regs + SEC_Q_AWUSER_CFG_REG; - u32 regval; - - regval = readl_relaxed(addr); - regval |= SEC_Q_AWUSER_CFG_PKG; - writel_relaxed(regval, addr); - - return 0; -} - -static int sec_clk_en(struct sec_dev_info *info) -{ - void __iomem *base = info->regs[SEC_COMMON]; - u32 i = 0; - - writel_relaxed(0x7, base + SEC_ALGSUB_CLK_EN_REG); - do { - usleep_range(1000, 10000); - if ((readl_relaxed(base + SEC_ALGSUB_CLK_ST_REG) & 0x7) == 0x7) - return 0; - i++; - } while (i < 10); - dev_err(info->dev, "sec clock enable fail!\n"); - - return -EIO; -} - -static int sec_clk_dis(struct sec_dev_info *info) -{ - void __iomem *base = info->regs[SEC_COMMON]; - u32 i = 0; - - writel_relaxed(0x7, base + SEC_ALGSUB_CLK_DIS_REG); - do { - usleep_range(1000, 10000); - if ((readl_relaxed(base + SEC_ALGSUB_CLK_ST_REG) & 0x7) == 0) - return 0; - i++; - } while (i < 10); - dev_err(info->dev, "sec clock disable fail!\n"); - - return -EIO; -} - -static int sec_reset_whole_module(struct sec_dev_info *info) -{ - void __iomem *base = info->regs[SEC_COMMON]; - bool is_reset, b_is_reset; - u32 i = 0; - - writel_relaxed(1, base + SEC_ALGSUB_RST_REQ_REG); - writel_relaxed(1, base + SEC_ALGSUB_BUILD_RST_REQ_REG); - while (1) { - usleep_range(1000, 10000); - is_reset = readl_relaxed(base + SEC_ALGSUB_RST_ST_REG) & - SEC_ALGSUB_RST_ST_IS_RST; - b_is_reset = readl_relaxed(base + SEC_ALGSUB_BUILD_RST_ST_REG) & - SEC_ALGSUB_BUILD_RST_ST_IS_RST; - if (is_reset && b_is_reset) - break; - i++; - if (i > 10) { - dev_err(info->dev, "Reset req failed\n"); - return -EIO; - } - } - - i = 0; - writel_relaxed(1, base + SEC_ALGSUB_RST_DREQ_REG); - writel_relaxed(1, base + SEC_ALGSUB_BUILD_RST_DREQ_REG); - while (1) { - usleep_range(1000, 10000); - is_reset = readl_relaxed(base + SEC_ALGSUB_RST_ST_REG) & - SEC_ALGSUB_RST_ST_IS_RST; - b_is_reset = readl_relaxed(base + SEC_ALGSUB_BUILD_RST_ST_REG) & - SEC_ALGSUB_BUILD_RST_ST_IS_RST; - if (!is_reset && !b_is_reset) - break; - - i++; - if (i > 10) { - dev_err(info->dev, "Reset dreq failed\n"); - return -EIO; - } - } - - return 0; -} - -static void sec_bd_endian_little(struct sec_dev_info *info) -{ - void __iomem *addr = info->regs[SEC_SAA] + SEC_CTRL2_REG; - u32 regval; - - regval = readl_relaxed(addr); - regval &= ~(SEC_CTRL2_ENDIAN_BD | SEC_CTRL2_ENDIAN_BD_TYPE); - writel_relaxed(regval, addr); -} - -/* - * sec_cache_config - configure optimum cache placement - */ -static void sec_cache_config(struct sec_dev_info *info) -{ - struct iommu_domain *domain; - void __iomem *addr = info->regs[SEC_SAA] + SEC_CTRL_REG; - - domain = iommu_get_domain_for_dev(info->dev); - - /* Check that translation is occurring */ - if (domain && (domain->type & __IOMMU_DOMAIN_PAGING)) - writel_relaxed(0x44cf9e, addr); - else - writel_relaxed(0x4cfd9, addr); -} - -static void sec_data_axiwr_otsd_cfg(struct sec_dev_info *info, u32 cfg) -{ - void __iomem *addr = info->regs[SEC_SAA] + SEC_CTRL2_REG; - u32 regval; - - regval = readl_relaxed(addr); - regval &= ~SEC_CTRL2_DATA_AXI_WR_OTSD_CFG_M; - regval |= (cfg << SEC_CTRL2_DATA_AXI_WR_OTSD_CFG_S) & - SEC_CTRL2_DATA_AXI_WR_OTSD_CFG_M; - writel_relaxed(regval, addr); -} - -static void sec_data_axird_otsd_cfg(struct sec_dev_info *info, u32 cfg) -{ - void __iomem *addr = info->regs[SEC_SAA] + SEC_CTRL2_REG; - u32 regval; - - regval = readl_relaxed(addr); - regval &= ~SEC_CTRL2_DATA_AXI_RD_OTSD_CFG_M; - regval |= (cfg << SEC_CTRL2_DATA_AXI_RD_OTSD_CFG_S) & - SEC_CTRL2_DATA_AXI_RD_OTSD_CFG_M; - writel_relaxed(regval, addr); -} - -static void sec_clk_gate_en(struct sec_dev_info *info, bool clkgate) -{ - void __iomem *addr = info->regs[SEC_SAA] + SEC_CTRL2_REG; - u32 regval; - - regval = readl_relaxed(addr); - if (clkgate) - regval |= SEC_CTRL2_CLK_GATE_EN; - else - regval &= ~SEC_CTRL2_CLK_GATE_EN; - writel_relaxed(regval, addr); -} - -static void sec_comm_cnt_cfg(struct sec_dev_info *info, bool clr_ce) -{ - void __iomem *addr = info->regs[SEC_SAA] + SEC_COMMON_CNT_CLR_CE_REG; - u32 regval; - - regval = readl_relaxed(addr); - if (clr_ce) - regval |= SEC_COMMON_CNT_CLR_CE_CLEAR; - else - regval &= ~SEC_COMMON_CNT_CLR_CE_CLEAR; - writel_relaxed(regval, addr); -} - -static void sec_commsnap_en(struct sec_dev_info *info, bool snap_en) -{ - void __iomem *addr = info->regs[SEC_SAA] + SEC_COMMON_CNT_CLR_CE_REG; - u32 regval; - - regval = readl_relaxed(addr); - if (snap_en) - regval |= SEC_COMMON_CNT_CLR_CE_SNAP_EN; - else - regval &= ~SEC_COMMON_CNT_CLR_CE_SNAP_EN; - writel_relaxed(regval, addr); -} - -static void sec_ipv6_hashmask(struct sec_dev_info *info, u32 hash_mask[]) -{ - void __iomem *base = info->regs[SEC_SAA]; - int i; - - for (i = 0; i < 10; i++) - writel_relaxed(hash_mask[0], - base + SEC_IPV6_MASK_TABLE_X_REG(i)); -} - -static int sec_ipv4_hashmask(struct sec_dev_info *info, u32 hash_mask) -{ - if (hash_mask & SEC_HASH_IPV4_MASK) { - dev_err(info->dev, "Sec Ipv4 Hash Mask Input Error!\n"); - return -EINVAL; - } - - writel_relaxed(hash_mask, - info->regs[SEC_SAA] + SEC_IPV4_MASK_TABLE_REG); - - return 0; -} - -static void sec_set_dbg_bd_cfg(struct sec_dev_info *info, u32 cfg) -{ - void __iomem *addr = info->regs[SEC_SAA] + SEC_DEBUG_BD_CFG_REG; - u32 regval; - - regval = readl_relaxed(addr); - /* Always disable write back of normal bd */ - regval &= ~SEC_DEBUG_BD_CFG_WB_NORMAL; - - if (cfg) - regval &= ~SEC_DEBUG_BD_CFG_WB_EN; - else - regval |= SEC_DEBUG_BD_CFG_WB_EN; - - writel_relaxed(regval, addr); -} - -static void sec_saa_getqm_en(struct sec_dev_info *info, u32 saa_indx, u32 en) -{ - void __iomem *addr = info->regs[SEC_SAA] + SEC_SAA_BASE + - SEC_SAA_CTRL_REG(saa_indx); - u32 regval; - - regval = readl_relaxed(addr); - if (en) - regval |= SEC_SAA_CTRL_GET_QM_EN; - else - regval &= ~SEC_SAA_CTRL_GET_QM_EN; - writel_relaxed(regval, addr); -} - -static void sec_saa_int_mask(struct sec_dev_info *info, u32 saa_indx, - u32 saa_int_mask) -{ - writel_relaxed(saa_int_mask, - info->regs[SEC_SAA] + SEC_SAA_BASE + SEC_ST_INTMSK1_REG + - saa_indx * SEC_SAA_ADDR_SIZE); -} - -static void sec_streamid(struct sec_dev_info *info, int i) -{ - #define SEC_SID 0x600 - #define SEC_VMID 0 - - writel_relaxed((SEC_VMID | ((SEC_SID & 0xffff) << 8)), - info->regs[SEC_SAA] + SEC_Q_VMID_CFG_REG(i)); -} - -static void sec_queue_ar_alloc(struct sec_queue *queue, u32 alloc) -{ - void __iomem *addr = queue->regs + SEC_Q_ARUSER_CFG_REG; - u32 regval; - - regval = readl_relaxed(addr); - if (alloc == SEC_QUEUE_AR_FROCE_ALLOC) { - regval |= SEC_Q_ARUSER_CFG_FA; - regval &= ~SEC_Q_ARUSER_CFG_FNA; - } else { - regval &= ~SEC_Q_ARUSER_CFG_FA; - regval |= SEC_Q_ARUSER_CFG_FNA; - } - - writel_relaxed(regval, addr); -} - -static void sec_queue_aw_alloc(struct sec_queue *queue, u32 alloc) -{ - void __iomem *addr = queue->regs + SEC_Q_AWUSER_CFG_REG; - u32 regval; - - regval = readl_relaxed(addr); - if (alloc == SEC_QUEUE_AW_FROCE_ALLOC) { - regval |= SEC_Q_AWUSER_CFG_FA; - regval &= ~SEC_Q_AWUSER_CFG_FNA; - } else { - regval &= ~SEC_Q_AWUSER_CFG_FA; - regval |= SEC_Q_AWUSER_CFG_FNA; - } - - writel_relaxed(regval, addr); -} - -static void sec_queue_reorder(struct sec_queue *queue, bool reorder) -{ - void __iomem *base = queue->regs; - u32 regval; - - regval = readl_relaxed(base + SEC_Q_CFG_REG); - if (reorder) - regval |= SEC_Q_CFG_REORDER; - else - regval &= ~SEC_Q_CFG_REORDER; - writel_relaxed(regval, base + SEC_Q_CFG_REG); -} - -static void sec_queue_depth(struct sec_queue *queue, u32 depth) -{ - void __iomem *addr = queue->regs + SEC_Q_DEPTH_CFG_REG; - u32 regval; - - regval = readl_relaxed(addr); - regval &= ~SEC_Q_DEPTH_CFG_DEPTH_M; - regval |= (depth << SEC_Q_DEPTH_CFG_DEPTH_S) & SEC_Q_DEPTH_CFG_DEPTH_M; - - writel_relaxed(regval, addr); -} - -static void sec_queue_cmdbase_addr(struct sec_queue *queue, u64 addr) -{ - writel_relaxed(upper_32_bits(addr), queue->regs + SEC_Q_BASE_HADDR_REG); - writel_relaxed(lower_32_bits(addr), queue->regs + SEC_Q_BASE_LADDR_REG); -} - -static void sec_queue_outorder_addr(struct sec_queue *queue, u64 addr) -{ - writel_relaxed(upper_32_bits(addr), - queue->regs + SEC_Q_OUTORDER_BASE_HADDR_REG); - writel_relaxed(lower_32_bits(addr), - queue->regs + SEC_Q_OUTORDER_BASE_LADDR_REG); -} - -static void sec_queue_errbase_addr(struct sec_queue *queue, u64 addr) -{ - writel_relaxed(upper_32_bits(addr), - queue->regs + SEC_Q_ERR_BASE_HADDR_REG); - writel_relaxed(lower_32_bits(addr), - queue->regs + SEC_Q_ERR_BASE_LADDR_REG); -} - -static void sec_queue_irq_disable(struct sec_queue *queue) -{ - writel_relaxed((u32)~0, queue->regs + SEC_Q_FLOW_INT_MKS_REG); -} - -static void sec_queue_irq_enable(struct sec_queue *queue) -{ - writel_relaxed(0, queue->regs + SEC_Q_FLOW_INT_MKS_REG); -} - -static void sec_queue_abn_irq_disable(struct sec_queue *queue) -{ - writel_relaxed((u32)~0, queue->regs + SEC_Q_FAIL_INT_MSK_REG); -} - -static void sec_queue_stop(struct sec_queue *queue) -{ - disable_irq(queue->task_irq); - sec_queue_irq_disable(queue); - writel_relaxed(0x0, queue->regs + SEC_QUEUE_ENB_REG); -} - -static void sec_queue_start(struct sec_queue *queue) -{ - sec_queue_irq_enable(queue); - enable_irq(queue->task_irq); - queue->expected = 0; - writel_relaxed(SEC_Q_INIT_AND_STAT_CLEAR, queue->regs + SEC_Q_INIT_REG); - writel_relaxed(0x1, queue->regs + SEC_QUEUE_ENB_REG); -} - -static struct sec_queue *sec_alloc_queue(struct sec_dev_info *info) -{ - int i; - - mutex_lock(&info->dev_lock); - - /* Get the first idle queue in SEC device */ - for (i = 0; i < SEC_Q_NUM; i++) - if (!info->queues[i].in_use) { - info->queues[i].in_use = true; - info->queues_in_use++; - mutex_unlock(&info->dev_lock); - - return &info->queues[i]; - } - mutex_unlock(&info->dev_lock); - - return ERR_PTR(-ENODEV); -} - -static int sec_queue_free(struct sec_queue *queue) -{ - struct sec_dev_info *info = queue->dev_info; - - if (queue->queue_id >= SEC_Q_NUM) { - dev_err(info->dev, "No queue %u\n", queue->queue_id); - return -ENODEV; - } - - if (!queue->in_use) { - dev_err(info->dev, "Queue %u is idle\n", queue->queue_id); - return -ENODEV; - } - - mutex_lock(&info->dev_lock); - queue->in_use = false; - info->queues_in_use--; - mutex_unlock(&info->dev_lock); - - return 0; -} - -static irqreturn_t sec_isr_handle_th(int irq, void *q) -{ - sec_queue_irq_disable(q); - return IRQ_WAKE_THREAD; -} - -static irqreturn_t sec_isr_handle(int irq, void *q) -{ - struct sec_queue *queue = q; - struct sec_queue_ring_cmd *msg_ring = &queue->ring_cmd; - struct sec_queue_ring_cq *cq_ring = &queue->ring_cq; - struct sec_out_bd_info *outorder_msg; - struct sec_bd_info *msg; - u32 ooo_read, ooo_write; - void __iomem *base = queue->regs; - int q_id; - - ooo_read = readl(base + SEC_Q_OUTORDER_RD_PTR_REG); - ooo_write = readl(base + SEC_Q_OUTORDER_WR_PTR_REG); - outorder_msg = cq_ring->vaddr + ooo_read; - q_id = outorder_msg->data & SEC_OUT_BD_INFO_Q_ID_M; - msg = msg_ring->vaddr + q_id; - - while ((ooo_write != ooo_read) && msg->w0 & SEC_BD_W0_DONE) { - /* - * Must be before callback otherwise blocks adding other chained - * elements - */ - set_bit(q_id, queue->unprocessed); - if (q_id == queue->expected) - while (test_bit(queue->expected, queue->unprocessed)) { - clear_bit(queue->expected, queue->unprocessed); - msg = msg_ring->vaddr + queue->expected; - msg->w0 &= ~SEC_BD_W0_DONE; - msg_ring->callback(msg, - queue->shadow[queue->expected]); - queue->shadow[queue->expected] = NULL; - queue->expected = (queue->expected + 1) % - SEC_QUEUE_LEN; - atomic_dec(&msg_ring->used); - } - - ooo_read = (ooo_read + 1) % SEC_QUEUE_LEN; - writel(ooo_read, base + SEC_Q_OUTORDER_RD_PTR_REG); - ooo_write = readl(base + SEC_Q_OUTORDER_WR_PTR_REG); - outorder_msg = cq_ring->vaddr + ooo_read; - q_id = outorder_msg->data & SEC_OUT_BD_INFO_Q_ID_M; - msg = msg_ring->vaddr + q_id; - } - - sec_queue_irq_enable(queue); - - return IRQ_HANDLED; -} - -static int sec_queue_irq_init(struct sec_queue *queue) -{ - struct sec_dev_info *info = queue->dev_info; - int irq = queue->task_irq; - int ret; - - ret = request_threaded_irq(irq, sec_isr_handle_th, sec_isr_handle, - IRQF_TRIGGER_RISING, queue->name, queue); - if (ret) { - dev_err(info->dev, "request irq(%d) failed %d\n", irq, ret); - return ret; - } - disable_irq(irq); - - return 0; -} - -static int sec_queue_irq_uninit(struct sec_queue *queue) -{ - free_irq(queue->task_irq, queue); - - return 0; -} - -static struct sec_dev_info *sec_device_get(void) -{ - struct sec_dev_info *sec_dev = NULL; - struct sec_dev_info *this_sec_dev; - int least_busy_n = SEC_Q_NUM + 1; - int i; - - /* Find which one is least busy and use that first */ - for (i = 0; i < SEC_MAX_DEVICES; i++) { - this_sec_dev = sec_devices[i]; - if (this_sec_dev && - this_sec_dev->queues_in_use < least_busy_n) { - least_busy_n = this_sec_dev->queues_in_use; - sec_dev = this_sec_dev; - } - } - - return sec_dev; -} - -static struct sec_queue *sec_queue_alloc_start(struct sec_dev_info *info) -{ - struct sec_queue *queue; - - queue = sec_alloc_queue(info); - if (IS_ERR(queue)) { - dev_err(info->dev, "alloc sec queue failed! %ld\n", - PTR_ERR(queue)); - return queue; - } - - sec_queue_start(queue); - - return queue; -} - -/** - * sec_queue_alloc_start_safe - get a hw queue from appropriate instance - * - * This function does extremely simplistic load balancing. It does not take into - * account NUMA locality of the accelerator, or which cpu has requested the - * queue. Future work may focus on optimizing this in order to improve full - * machine throughput. - */ -struct sec_queue *sec_queue_alloc_start_safe(void) -{ - struct sec_dev_info *info; - struct sec_queue *queue = ERR_PTR(-ENODEV); - - mutex_lock(&sec_id_lock); - info = sec_device_get(); - if (!info) - goto unlock; - - queue = sec_queue_alloc_start(info); - -unlock: - mutex_unlock(&sec_id_lock); - - return queue; -} - -/** - * sec_queue_stop_release() - free up a hw queue for reuse - * @queue: The queue we are done with. - * - * This will stop the current queue, terminanting any transactions - * that are inflight an return it to the pool of available hw queuess - */ -int sec_queue_stop_release(struct sec_queue *queue) -{ - struct device *dev = queue->dev_info->dev; - int ret; - - sec_queue_stop(queue); - - ret = sec_queue_free(queue); - if (ret) - dev_err(dev, "Releasing queue failed %d\n", ret); - - return ret; -} - -/** - * sec_queue_empty() - Is this hardware queue currently empty. - * @queue: The queue to test - * - * We need to know if we have an empty queue for some of the chaining modes - * as if it is not empty we may need to hold the message in a software queue - * until the hw queue is drained. - */ -bool sec_queue_empty(struct sec_queue *queue) -{ - struct sec_queue_ring_cmd *msg_ring = &queue->ring_cmd; - - return !atomic_read(&msg_ring->used); -} - -/** - * sec_queue_send() - queue up a single operation in the hw queue - * @queue: The queue in which to put the message - * @msg: The message - * @ctx: Context to be put in the shadow array and passed back to cb on result. - * - * This function will return -EAGAIN if the queue is currently full. - */ -int sec_queue_send(struct sec_queue *queue, struct sec_bd_info *msg, void *ctx) -{ - struct sec_queue_ring_cmd *msg_ring = &queue->ring_cmd; - void __iomem *base = queue->regs; - u32 write, read; - - mutex_lock(&msg_ring->lock); - read = readl(base + SEC_Q_RD_PTR_REG); - write = readl(base + SEC_Q_WR_PTR_REG); - if (write == read && atomic_read(&msg_ring->used) == SEC_QUEUE_LEN) { - mutex_unlock(&msg_ring->lock); - return -EAGAIN; - } - memcpy(msg_ring->vaddr + write, msg, sizeof(*msg)); - queue->shadow[write] = ctx; - write = (write + 1) % SEC_QUEUE_LEN; - - /* Ensure content updated before queue advance */ - wmb(); - writel(write, base + SEC_Q_WR_PTR_REG); - - atomic_inc(&msg_ring->used); - mutex_unlock(&msg_ring->lock); - - return 0; -} - -bool sec_queue_can_enqueue(struct sec_queue *queue, int num) -{ - struct sec_queue_ring_cmd *msg_ring = &queue->ring_cmd; - - return SEC_QUEUE_LEN - atomic_read(&msg_ring->used) >= num; -} - -static void sec_queue_hw_init(struct sec_queue *queue) -{ - sec_queue_ar_alloc(queue, SEC_QUEUE_AR_FROCE_NOALLOC); - sec_queue_aw_alloc(queue, SEC_QUEUE_AW_FROCE_NOALLOC); - sec_queue_ar_pkgattr(queue, 1); - sec_queue_aw_pkgattr(queue, 1); - - /* Enable out of order queue */ - sec_queue_reorder(queue, true); - - /* Interrupt after a single complete element */ - writel_relaxed(1, queue->regs + SEC_Q_PROC_NUM_CFG_REG); - - sec_queue_depth(queue, SEC_QUEUE_LEN - 1); - - sec_queue_cmdbase_addr(queue, queue->ring_cmd.paddr); - - sec_queue_outorder_addr(queue, queue->ring_cq.paddr); - - sec_queue_errbase_addr(queue, queue->ring_db.paddr); - - writel_relaxed(0x100, queue->regs + SEC_Q_OT_TH_REG); - - sec_queue_abn_irq_disable(queue); - sec_queue_irq_disable(queue); - writel_relaxed(SEC_Q_INIT_AND_STAT_CLEAR, queue->regs + SEC_Q_INIT_REG); -} - -static int sec_hw_init(struct sec_dev_info *info) -{ - struct iommu_domain *domain; - u32 sec_ipv4_mask = 0; - u32 sec_ipv6_mask[10] = {}; - int ret; - u32 i; - - domain = iommu_get_domain_for_dev(info->dev); - - /* - * Enable all available processing unit clocks. - * Only the first cluster is usable with translations. - */ - if (domain && (domain->type & __IOMMU_DOMAIN_PAGING)) - info->num_saas = 5; - - else - info->num_saas = 10; - - writel_relaxed(GENMASK(info->num_saas - 1, 0), - info->regs[SEC_SAA] + SEC_CLK_EN_REG); - - /* 32 bit little endian */ - sec_bd_endian_little(info); - - sec_cache_config(info); - - /* Data axi port write and read outstanding config as per datasheet */ - sec_data_axiwr_otsd_cfg(info, 0x7); - sec_data_axird_otsd_cfg(info, 0x7); - - /* Enable clock gating */ - sec_clk_gate_en(info, true); - - /* Set CNT_CYC register not read clear */ - sec_comm_cnt_cfg(info, false); - - /* Enable CNT_CYC */ - sec_commsnap_en(info, false); - - writel_relaxed((u32)~0, info->regs[SEC_SAA] + SEC_FSM_MAX_CNT_REG); - - ret = sec_ipv4_hashmask(info, sec_ipv4_mask); - if (ret) { - dev_err(info->dev, "Failed to set ipv4 hashmask %d\n", ret); - return -EIO; - } - - sec_ipv6_hashmask(info, sec_ipv6_mask); - - /* do not use debug bd */ - sec_set_dbg_bd_cfg(info, 0); - - if (domain && (domain->type & __IOMMU_DOMAIN_PAGING)) { - for (i = 0; i < SEC_Q_NUM; i++) { - sec_streamid(info, i); - /* Same QoS for all queues */ - writel_relaxed(0x3f, - info->regs[SEC_SAA] + - SEC_Q_WEIGHT_CFG_REG(i)); - } - } - - for (i = 0; i < info->num_saas; i++) { - sec_saa_getqm_en(info, i, 1); - sec_saa_int_mask(info, i, 0); - } - - return 0; -} - -static void sec_hw_exit(struct sec_dev_info *info) -{ - int i; - - for (i = 0; i < SEC_MAX_SAA_NUM; i++) { - sec_saa_int_mask(info, i, (u32)~0); - sec_saa_getqm_en(info, i, 0); - } -} - -static void sec_queue_base_init(struct sec_dev_info *info, - struct sec_queue *queue, int queue_id) -{ - queue->dev_info = info; - queue->queue_id = queue_id; - snprintf(queue->name, sizeof(queue->name), - "%s_%d", dev_name(info->dev), queue->queue_id); -} - -static int sec_map_io(struct sec_dev_info *info, struct platform_device *pdev) -{ - int i; - - for (i = 0; i < SEC_NUM_ADDR_REGIONS; i++) { - info->regs[i] = devm_platform_ioremap_resource(pdev, i); - if (IS_ERR(info->regs[i])) - return PTR_ERR(info->regs[i]); - } - - return 0; -} - -static int sec_base_init(struct sec_dev_info *info, - struct platform_device *pdev) -{ - int ret; - - ret = sec_map_io(info, pdev); - if (ret) - return ret; - - ret = sec_clk_en(info); - if (ret) - return ret; - - ret = sec_reset_whole_module(info); - if (ret) - goto sec_clk_disable; - - ret = sec_hw_init(info); - if (ret) - goto sec_clk_disable; - - return 0; - -sec_clk_disable: - sec_clk_dis(info); - - return ret; -} - -static void sec_base_exit(struct sec_dev_info *info) -{ - sec_hw_exit(info); - sec_clk_dis(info); -} - -#define SEC_Q_CMD_SIZE \ - round_up(SEC_QUEUE_LEN * sizeof(struct sec_bd_info), PAGE_SIZE) -#define SEC_Q_CQ_SIZE \ - round_up(SEC_QUEUE_LEN * sizeof(struct sec_out_bd_info), PAGE_SIZE) -#define SEC_Q_DB_SIZE \ - round_up(SEC_QUEUE_LEN * sizeof(struct sec_debug_bd_info), PAGE_SIZE) - -static int sec_queue_res_cfg(struct sec_queue *queue) -{ - struct device *dev = queue->dev_info->dev; - struct sec_queue_ring_cmd *ring_cmd = &queue->ring_cmd; - struct sec_queue_ring_cq *ring_cq = &queue->ring_cq; - struct sec_queue_ring_db *ring_db = &queue->ring_db; - int ret; - - ring_cmd->vaddr = dma_alloc_coherent(dev, SEC_Q_CMD_SIZE, - &ring_cmd->paddr, GFP_KERNEL); - if (!ring_cmd->vaddr) - return -ENOMEM; - - atomic_set(&ring_cmd->used, 0); - mutex_init(&ring_cmd->lock); - ring_cmd->callback = sec_alg_callback; - - ring_cq->vaddr = dma_alloc_coherent(dev, SEC_Q_CQ_SIZE, - &ring_cq->paddr, GFP_KERNEL); - if (!ring_cq->vaddr) { - ret = -ENOMEM; - goto err_free_ring_cmd; - } - - ring_db->vaddr = dma_alloc_coherent(dev, SEC_Q_DB_SIZE, - &ring_db->paddr, GFP_KERNEL); - if (!ring_db->vaddr) { - ret = -ENOMEM; - goto err_free_ring_cq; - } - queue->task_irq = platform_get_irq(to_platform_device(dev), - queue->queue_id * 2 + 1); - if (queue->task_irq < 0) { - ret = queue->task_irq; - goto err_free_ring_db; - } - - return 0; - -err_free_ring_db: - dma_free_coherent(dev, SEC_Q_DB_SIZE, queue->ring_db.vaddr, - queue->ring_db.paddr); -err_free_ring_cq: - dma_free_coherent(dev, SEC_Q_CQ_SIZE, queue->ring_cq.vaddr, - queue->ring_cq.paddr); -err_free_ring_cmd: - dma_free_coherent(dev, SEC_Q_CMD_SIZE, queue->ring_cmd.vaddr, - queue->ring_cmd.paddr); - - return ret; -} - -static void sec_queue_free_ring_pages(struct sec_queue *queue) -{ - struct device *dev = queue->dev_info->dev; - - dma_free_coherent(dev, SEC_Q_DB_SIZE, queue->ring_db.vaddr, - queue->ring_db.paddr); - dma_free_coherent(dev, SEC_Q_CQ_SIZE, queue->ring_cq.vaddr, - queue->ring_cq.paddr); - dma_free_coherent(dev, SEC_Q_CMD_SIZE, queue->ring_cmd.vaddr, - queue->ring_cmd.paddr); -} - -static int sec_queue_config(struct sec_dev_info *info, struct sec_queue *queue, - int queue_id) -{ - int ret; - - sec_queue_base_init(info, queue, queue_id); - - ret = sec_queue_res_cfg(queue); - if (ret) - return ret; - - ret = sec_queue_map_io(queue); - if (ret) { - dev_err(info->dev, "Queue map failed %d\n", ret); - sec_queue_free_ring_pages(queue); - return ret; - } - - sec_queue_hw_init(queue); - - return 0; -} - -static void sec_queue_unconfig(struct sec_dev_info *info, - struct sec_queue *queue) -{ - sec_queue_unmap_io(queue); - sec_queue_free_ring_pages(queue); -} - -static int sec_id_alloc(struct sec_dev_info *info) -{ - int ret = 0; - int i; - - mutex_lock(&sec_id_lock); - - for (i = 0; i < SEC_MAX_DEVICES; i++) - if (!sec_devices[i]) - break; - if (i == SEC_MAX_DEVICES) { - ret = -ENOMEM; - goto unlock; - } - info->sec_id = i; - sec_devices[info->sec_id] = info; - -unlock: - mutex_unlock(&sec_id_lock); - - return ret; -} - -static void sec_id_free(struct sec_dev_info *info) -{ - mutex_lock(&sec_id_lock); - sec_devices[info->sec_id] = NULL; - mutex_unlock(&sec_id_lock); -} - -static int sec_probe(struct platform_device *pdev) -{ - struct sec_dev_info *info; - struct device *dev = &pdev->dev; - int i, j; - int ret; - - ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); - if (ret) { - dev_err(dev, "Failed to set 64 bit dma mask %d", ret); - return -ENODEV; - } - - info = devm_kzalloc(dev, (sizeof(*info)), GFP_KERNEL); - if (!info) - return -ENOMEM; - - info->dev = dev; - mutex_init(&info->dev_lock); - - info->hw_sgl_pool = dmam_pool_create("sgl", dev, - sizeof(struct sec_hw_sgl), 64, 0); - if (!info->hw_sgl_pool) { - dev_err(dev, "Failed to create sec sgl dma pool\n"); - return -ENOMEM; - } - - ret = sec_base_init(info, pdev); - if (ret) { - dev_err(dev, "Base initialization fail! %d\n", ret); - return ret; - } - - for (i = 0; i < SEC_Q_NUM; i++) { - ret = sec_queue_config(info, &info->queues[i], i); - if (ret) - goto queues_unconfig; - - ret = sec_queue_irq_init(&info->queues[i]); - if (ret) { - sec_queue_unconfig(info, &info->queues[i]); - goto queues_unconfig; - } - } - - ret = sec_algs_register(); - if (ret) { - dev_err(dev, "Failed to register algorithms with crypto %d\n", - ret); - goto queues_unconfig; - } - - platform_set_drvdata(pdev, info); - - ret = sec_id_alloc(info); - if (ret) - goto algs_unregister; - - return 0; - -algs_unregister: - sec_algs_unregister(); -queues_unconfig: - for (j = i - 1; j >= 0; j--) { - sec_queue_irq_uninit(&info->queues[j]); - sec_queue_unconfig(info, &info->queues[j]); - } - sec_base_exit(info); - - return ret; -} - -static void sec_remove(struct platform_device *pdev) -{ - struct sec_dev_info *info = platform_get_drvdata(pdev); - int i; - - /* Unexpose as soon as possible, reuse during remove is fine */ - sec_id_free(info); - - sec_algs_unregister(); - - for (i = 0; i < SEC_Q_NUM; i++) { - sec_queue_irq_uninit(&info->queues[i]); - sec_queue_unconfig(info, &info->queues[i]); - } - - sec_base_exit(info); -} - -static const __maybe_unused struct of_device_id sec_match[] = { - { .compatible = "hisilicon,hip06-sec" }, - { .compatible = "hisilicon,hip07-sec" }, - {} -}; -MODULE_DEVICE_TABLE(of, sec_match); - -static const __maybe_unused struct acpi_device_id sec_acpi_match[] = { - { "HISI02C1", 0 }, - { } -}; -MODULE_DEVICE_TABLE(acpi, sec_acpi_match); - -static struct platform_driver sec_driver = { - .probe = sec_probe, - .remove = sec_remove, - .driver = { - .name = "hisi_sec_platform_driver", - .of_match_table = sec_match, - .acpi_match_table = ACPI_PTR(sec_acpi_match), - }, -}; -module_platform_driver(sec_driver); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("HiSilicon Security Accelerators"); -MODULE_AUTHOR("Zaibo Xu <xuzaibo@huawei.com"); -MODULE_AUTHOR("Jonathan Cameron <jonathan.cameron@huawei.com>");
diff --git a/drivers/crypto/hisilicon/sec/sec_drv.h b/drivers/crypto/hisilicon/sec/sec_drv.h deleted file mode 100644 index e2a50bf..0000000 --- a/drivers/crypto/hisilicon/sec/sec_drv.h +++ /dev/null
@@ -1,428 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -/* Copyright (c) 2016-2017 HiSilicon Limited. */ - -#ifndef _SEC_DRV_H_ -#define _SEC_DRV_H_ - -#include <crypto/algapi.h> -#include <linux/kfifo.h> - -#define SEC_MAX_SGE_NUM 64 -#define SEC_HW_RING_NUM 3 - -#define SEC_CMD_RING 0 -#define SEC_OUTORDER_RING 1 -#define SEC_DBG_RING 2 - -/* A reasonable length to balance memory use against flexibility */ -#define SEC_QUEUE_LEN 512 - -#define SEC_MAX_SGE_NUM 64 - -struct sec_bd_info { -#define SEC_BD_W0_T_LEN_M GENMASK(4, 0) -#define SEC_BD_W0_T_LEN_S 0 - -#define SEC_BD_W0_C_WIDTH_M GENMASK(6, 5) -#define SEC_BD_W0_C_WIDTH_S 5 -#define SEC_C_WIDTH_AES_128BIT 0 -#define SEC_C_WIDTH_AES_8BIT 1 -#define SEC_C_WIDTH_AES_1BIT 2 -#define SEC_C_WIDTH_DES_64BIT 0 -#define SEC_C_WIDTH_DES_8BIT 1 -#define SEC_C_WIDTH_DES_1BIT 2 - -#define SEC_BD_W0_C_MODE_M GENMASK(9, 7) -#define SEC_BD_W0_C_MODE_S 7 -#define SEC_C_MODE_ECB 0 -#define SEC_C_MODE_CBC 1 -#define SEC_C_MODE_CTR 4 -#define SEC_C_MODE_CCM 5 -#define SEC_C_MODE_GCM 6 -#define SEC_C_MODE_XTS 7 - -#define SEC_BD_W0_SEQ BIT(10) -#define SEC_BD_W0_DE BIT(11) -#define SEC_BD_W0_DAT_SKIP_M GENMASK(13, 12) -#define SEC_BD_W0_DAT_SKIP_S 12 -#define SEC_BD_W0_C_GRAN_SIZE_19_16_M GENMASK(17, 14) -#define SEC_BD_W0_C_GRAN_SIZE_19_16_S 14 - -#define SEC_BD_W0_CIPHER_M GENMASK(19, 18) -#define SEC_BD_W0_CIPHER_S 18 -#define SEC_CIPHER_NULL 0 -#define SEC_CIPHER_ENCRYPT 1 -#define SEC_CIPHER_DECRYPT 2 - -#define SEC_BD_W0_AUTH_M GENMASK(21, 20) -#define SEC_BD_W0_AUTH_S 20 -#define SEC_AUTH_NULL 0 -#define SEC_AUTH_MAC 1 -#define SEC_AUTH_VERIF 2 - -#define SEC_BD_W0_AI_GEN BIT(22) -#define SEC_BD_W0_CI_GEN BIT(23) -#define SEC_BD_W0_NO_HPAD BIT(24) -#define SEC_BD_W0_HM_M GENMASK(26, 25) -#define SEC_BD_W0_HM_S 25 -#define SEC_BD_W0_ICV_OR_SKEY_EN_M GENMASK(28, 27) -#define SEC_BD_W0_ICV_OR_SKEY_EN_S 27 - -/* Multi purpose field - gran size bits for send, flag for recv */ -#define SEC_BD_W0_FLAG_M GENMASK(30, 29) -#define SEC_BD_W0_C_GRAN_SIZE_21_20_M GENMASK(30, 29) -#define SEC_BD_W0_FLAG_S 29 -#define SEC_BD_W0_C_GRAN_SIZE_21_20_S 29 - -#define SEC_BD_W0_DONE BIT(31) - u32 w0; - -#define SEC_BD_W1_AUTH_GRAN_SIZE_M GENMASK(21, 0) -#define SEC_BD_W1_AUTH_GRAN_SIZE_S 0 -#define SEC_BD_W1_M_KEY_EN BIT(22) -#define SEC_BD_W1_BD_INVALID BIT(23) -#define SEC_BD_W1_ADDR_TYPE BIT(24) - -#define SEC_BD_W1_A_ALG_M GENMASK(28, 25) -#define SEC_BD_W1_A_ALG_S 25 -#define SEC_A_ALG_SHA1 0 -#define SEC_A_ALG_SHA256 1 -#define SEC_A_ALG_MD5 2 -#define SEC_A_ALG_SHA224 3 -#define SEC_A_ALG_HMAC_SHA1 8 -#define SEC_A_ALG_HMAC_SHA224 10 -#define SEC_A_ALG_HMAC_SHA256 11 -#define SEC_A_ALG_HMAC_MD5 12 -#define SEC_A_ALG_AES_XCBC 13 -#define SEC_A_ALG_AES_CMAC 14 - -#define SEC_BD_W1_C_ALG_M GENMASK(31, 29) -#define SEC_BD_W1_C_ALG_S 29 -#define SEC_C_ALG_DES 0 -#define SEC_C_ALG_3DES 1 -#define SEC_C_ALG_AES 2 - - u32 w1; - -#define SEC_BD_W2_C_GRAN_SIZE_15_0_M GENMASK(15, 0) -#define SEC_BD_W2_C_GRAN_SIZE_15_0_S 0 -#define SEC_BD_W2_GRAN_NUM_M GENMASK(31, 16) -#define SEC_BD_W2_GRAN_NUM_S 16 - u32 w2; - -#define SEC_BD_W3_AUTH_LEN_OFFSET_M GENMASK(9, 0) -#define SEC_BD_W3_AUTH_LEN_OFFSET_S 0 -#define SEC_BD_W3_CIPHER_LEN_OFFSET_M GENMASK(19, 10) -#define SEC_BD_W3_CIPHER_LEN_OFFSET_S 10 -#define SEC_BD_W3_MAC_LEN_M GENMASK(24, 20) -#define SEC_BD_W3_MAC_LEN_S 20 -#define SEC_BD_W3_A_KEY_LEN_M GENMASK(29, 25) -#define SEC_BD_W3_A_KEY_LEN_S 25 -#define SEC_BD_W3_C_KEY_LEN_M GENMASK(31, 30) -#define SEC_BD_W3_C_KEY_LEN_S 30 -#define SEC_KEY_LEN_AES_128 0 -#define SEC_KEY_LEN_AES_192 1 -#define SEC_KEY_LEN_AES_256 2 -#define SEC_KEY_LEN_DES 1 -#define SEC_KEY_LEN_3DES_3_KEY 1 -#define SEC_KEY_LEN_3DES_2_KEY 3 - u32 w3; - - /* W4,5 */ - union { - u32 authkey_addr_lo; - u32 authiv_addr_lo; - }; - union { - u32 authkey_addr_hi; - u32 authiv_addr_hi; - }; - - /* W6,7 */ - u32 cipher_key_addr_lo; - u32 cipher_key_addr_hi; - - /* W8,9 */ - u32 cipher_iv_addr_lo; - u32 cipher_iv_addr_hi; - - /* W10,11 */ - u32 data_addr_lo; - u32 data_addr_hi; - - /* W12,13 */ - u32 mac_addr_lo; - u32 mac_addr_hi; - - /* W14,15 */ - u32 cipher_destin_addr_lo; - u32 cipher_destin_addr_hi; -}; - -enum sec_mem_region { - SEC_COMMON = 0, - SEC_SAA, - SEC_NUM_ADDR_REGIONS -}; - -#define SEC_NAME_SIZE 64 -#define SEC_Q_NUM 16 - - -/** - * struct sec_queue_ring_cmd - store information about a SEC HW cmd ring - * @used: Local counter used to cheaply establish if the ring is empty. - * @lock: Protect against simultaneous adjusting of the read and write pointers. - * @vaddr: Virtual address for the ram pages used for the ring. - * @paddr: Physical address of the dma mapped region of ram used for the ring. - * @callback: Callback function called on a ring element completing. - */ -struct sec_queue_ring_cmd { - atomic_t used; - struct mutex lock; - struct sec_bd_info *vaddr; - dma_addr_t paddr; - void (*callback)(struct sec_bd_info *resp, void *ctx); -}; - -struct sec_debug_bd_info; -struct sec_queue_ring_db { - struct sec_debug_bd_info *vaddr; - dma_addr_t paddr; -}; - -struct sec_out_bd_info; -struct sec_queue_ring_cq { - struct sec_out_bd_info *vaddr; - dma_addr_t paddr; -}; - -struct sec_dev_info; - -enum sec_cipher_alg { - SEC_C_DES_ECB_64, - SEC_C_DES_CBC_64, - - SEC_C_3DES_ECB_192_3KEY, - SEC_C_3DES_ECB_192_2KEY, - - SEC_C_3DES_CBC_192_3KEY, - SEC_C_3DES_CBC_192_2KEY, - - SEC_C_AES_ECB_128, - SEC_C_AES_ECB_192, - SEC_C_AES_ECB_256, - - SEC_C_AES_CBC_128, - SEC_C_AES_CBC_192, - SEC_C_AES_CBC_256, - - SEC_C_AES_CTR_128, - SEC_C_AES_CTR_192, - SEC_C_AES_CTR_256, - - SEC_C_AES_XTS_128, - SEC_C_AES_XTS_256, - - SEC_C_NULL, -}; - -/** - * struct sec_alg_tfm_ctx - hardware specific tranformation context - * @cipher_alg: Cipher algorithm enabled include encryption mode. - * @key: Key storage if required. - * @pkey: DMA address for the key storage. - * @req_template: Request template to save time on setup. - * @queue: The hardware queue associated with this tfm context. - * @lock: Protect key and pkey to ensure they are consistent - * @auth_buf: Current context buffer for auth operations. - * @backlog: The backlog queue used for cases where our buffers aren't - * large enough. - */ -struct sec_alg_tfm_ctx { - enum sec_cipher_alg cipher_alg; - u8 *key; - dma_addr_t pkey; - struct sec_bd_info req_template; - struct sec_queue *queue; - struct mutex lock; - u8 *auth_buf; - struct list_head backlog; -}; - -/** - * struct sec_request - data associate with a single crypto request - * @elements: List of subparts of this request (hardware size restriction) - * @num_elements: The number of subparts (used as an optimization) - * @lock: Protect elements of this structure against concurrent change. - * @tfm_ctx: hardware specific context. - * @len_in: length of in sgl from upper layers - * @len_out: length of out sgl from upper layers - * @dma_iv: initialization vector - phsyical address - * @err: store used to track errors across subelements of this request. - * @req_base: pointer to base element of associate crypto context. - * This is needed to allow shared handling skcipher, ahash etc. - * @cb: completion callback. - * @backlog_head: list head to allow backlog maintenance. - * - * The hardware is limited in the maximum size of data that it can - * process from a single BD. Typically this is fairly large (32MB) - * but still requires the complexity of splitting the incoming - * skreq up into a number of elements complete with appropriate - * iv chaining. - */ -struct sec_request { - struct list_head elements; - int num_elements; - struct mutex lock; - struct sec_alg_tfm_ctx *tfm_ctx; - int len_in; - int len_out; - dma_addr_t dma_iv; - int err; - struct crypto_async_request *req_base; - void (*cb)(struct sec_bd_info *resp, struct crypto_async_request *req); - struct list_head backlog_head; -}; - -/** - * struct sec_request_el - A subpart of a request. - * @head: allow us to attach this to the list in the sec_request - * @req: hardware block descriptor corresponding to this request subpart - * @in: hardware sgl for input - virtual address - * @dma_in: hardware sgl for input - physical address - * @sgl_in: scatterlist for this request subpart - * @out: hardware sgl for output - virtual address - * @dma_out: hardware sgl for output - physical address - * @sgl_out: scatterlist for this request subpart - * @sec_req: The request which this subpart forms a part of - * @el_length: Number of bytes in this subpart. Needed to locate - * last ivsize chunk for iv chaining. - */ -struct sec_request_el { - struct list_head head; - struct sec_bd_info req; - struct sec_hw_sgl *in; - dma_addr_t dma_in; - struct scatterlist *sgl_in; - struct sec_hw_sgl *out; - dma_addr_t dma_out; - struct scatterlist *sgl_out; - struct sec_request *sec_req; - size_t el_length; -}; - -/** - * struct sec_queue - All the information about a HW queue - * @dev_info: The parent SEC device to which this queue belongs. - * @task_irq: Completion interrupt for the queue. - * @name: Human readable queue description also used as irq name. - * @ring: The several HW rings associated with one queue. - * @regs: The iomapped device registers - * @queue_id: Index of the queue used for naming and resource selection. - * @in_use: Flag to say if the queue is in use. - * @expected: The next expected element to finish assuming we were in order. - * @uprocessed: A bitmap to track which OoO elements are done but not handled. - * @softqueue: A software queue used when chaining requirements prevent direct - * use of the hardware queues. - * @havesoftqueue: A flag to say we have a queues - as we may need one for the - * current mode. - * @queuelock: Protect the soft queue from concurrent changes to avoid some - * potential loss of data races. - * @shadow: Pointers back to the shadow copy of the hardware ring element - * need because we can't store any context reference in the bd element. - */ -struct sec_queue { - struct sec_dev_info *dev_info; - int task_irq; - char name[SEC_NAME_SIZE]; - struct sec_queue_ring_cmd ring_cmd; - struct sec_queue_ring_cq ring_cq; - struct sec_queue_ring_db ring_db; - void __iomem *regs; - u32 queue_id; - bool in_use; - int expected; - - DECLARE_BITMAP(unprocessed, SEC_QUEUE_LEN); - DECLARE_KFIFO_PTR(softqueue, typeof(struct sec_request_el *)); - bool havesoftqueue; - spinlock_t queuelock; - void *shadow[SEC_QUEUE_LEN]; -}; - -/** - * struct sec_hw_sge: Track each of the 64 element SEC HW SGL entries - * @buf: The IOV dma address for this entry. - * @len: Length of this IOV. - * @pad: Reserved space. - */ -struct sec_hw_sge { - dma_addr_t buf; - unsigned int len; - unsigned int pad; -}; - -/** - * struct sec_hw_sgl: One hardware SGL entry. - * @next_sgl: The next entry if we need to chain dma address. Null if last. - * @entry_sum_in_chain: The full count of SGEs - only matters for first SGL. - * @entry_sum_in_sgl: The number of SGEs in this SGL element. - * @flag: Unused in skciphers. - * @serial_num: Unsued in skciphers. - * @cpuid: Currently unused. - * @data_bytes_in_sgl: Count of bytes from all SGEs in this SGL. - * @next: Virtual address used to stash the next sgl - useful in completion. - * @reserved: A reserved field not currently used. - * @sge_entries: The (up to) 64 Scatter Gather Entries, representing IOVs. - * @node: Currently unused. - */ -struct sec_hw_sgl { - dma_addr_t next_sgl; - u16 entry_sum_in_chain; - u16 entry_sum_in_sgl; - u32 flag; - u64 serial_num; - u32 cpuid; - u32 data_bytes_in_sgl; - struct sec_hw_sgl *next; - u64 reserved; - struct sec_hw_sge sge_entries[SEC_MAX_SGE_NUM]; - u8 node[16]; -}; - -struct dma_pool; - -/** - * struct sec_dev_info: The full SEC unit comprising queues and processors. - * @sec_id: Index used to track which SEC this is when more than one is present. - * @num_saas: The number of backed processors enabled. - * @regs: iomapped register regions shared by whole SEC unit. - * @dev_lock: Protects concurrent queue allocation / freeing for the SEC. - * @queues: The 16 queues that this SEC instance provides. - * @dev: Device pointer. - * @hw_sgl_pool: DMA pool used to mimise mapping for the scatter gather lists. - */ -struct sec_dev_info { - int sec_id; - int num_saas; - void __iomem *regs[SEC_NUM_ADDR_REGIONS]; - struct mutex dev_lock; - int queues_in_use; - struct sec_queue queues[SEC_Q_NUM]; - struct device *dev; - struct dma_pool *hw_sgl_pool; -}; - -int sec_queue_send(struct sec_queue *queue, struct sec_bd_info *msg, void *ctx); -bool sec_queue_can_enqueue(struct sec_queue *queue, int num); -int sec_queue_stop_release(struct sec_queue *queue); -struct sec_queue *sec_queue_alloc_start_safe(void); -bool sec_queue_empty(struct sec_queue *queue); - -/* Algorithm specific elements from sec_algs.c */ -void sec_alg_callback(struct sec_bd_info *resp, void *ctx); -int sec_algs_register(void); -void sec_algs_unregister(void); - -#endif /* _SEC_DRV_H_ */
diff --git a/drivers/crypto/hisilicon/sec2/sec_main.c b/drivers/crypto/hisilicon/sec2/sec_main.c index 03523cf..1e0412c 100644 --- a/drivers/crypto/hisilicon/sec2/sec_main.c +++ b/drivers/crypto/hisilicon/sec2/sec_main.c
@@ -1285,8 +1285,8 @@ static int sec_pre_store_cap_reg(struct hisi_qm *qm) i, qm->cap_ver); } - qm->cap_tables.dev_cap_table = sec_cap; qm->cap_tables.dev_cap_size = size; + qm->cap_tables.dev_cap_table = sec_cap; return 0; }
diff --git a/drivers/crypto/hisilicon/zip/dae_main.c b/drivers/crypto/hisilicon/zip/dae_main.c index 68aebd0..57ea836 100644 --- a/drivers/crypto/hisilicon/zip/dae_main.c +++ b/drivers/crypto/hisilicon/zip/dae_main.c
@@ -39,6 +39,8 @@ #define DAE_AM_RETURN_MASK 0x3 #define DAE_AXI_CFG_OFFSET 0x331000 #define DAE_AXI_SHUTDOWN_EN_MASK (BIT(0) | BIT(5)) +#define DAE_AUTO_CG_EN_OFFSET 0x331070 +#define DAE_AUTO_CG_EN_MASK (~(BIT_ULL(4) | BIT_ULL(18) | BIT_ULL(19))) struct hisi_dae_hw_error { u32 int_msk; @@ -61,6 +63,17 @@ static inline bool dae_is_support(struct hisi_qm *qm) return false; } +static void hisi_dae_set_clock_gating(struct hisi_qm *qm, bool enable) +{ + if (qm->ver < QM_HW_V5) + return; + + if (enable) + writeq(DAE_AUTO_CG_EN_MASK, qm->io_base + DAE_AUTO_CG_EN_OFFSET); + else + writeq(0, qm->io_base + DAE_AUTO_CG_EN_OFFSET); +} + int hisi_dae_set_user_domain(struct hisi_qm *qm) { u32 val; @@ -69,16 +82,22 @@ int hisi_dae_set_user_domain(struct hisi_qm *qm) if (!dae_is_support(qm)) return 0; + hisi_dae_set_clock_gating(qm, false); + val = readl(qm->io_base + DAE_MEM_START_OFFSET); val |= DAE_MEM_START_MASK; writel(val, qm->io_base + DAE_MEM_START_OFFSET); ret = readl_relaxed_poll_timeout(qm->io_base + DAE_MEM_DONE_OFFSET, val, val & DAE_MEM_DONE_MASK, DAE_REG_RD_INTVRL_US, DAE_REG_RD_TMOUT_US); - if (ret) + if (ret) { pci_err(qm->pdev, "failed to init dae memory!\n"); + return ret; + } - return ret; + hisi_dae_set_clock_gating(qm, true); + + return 0; } int hisi_dae_set_alg(struct hisi_qm *qm)
diff --git a/drivers/crypto/hisilicon/zip/zip_main.c b/drivers/crypto/hisilicon/zip/zip_main.c index 706a736..10091ad 100644 --- a/drivers/crypto/hisilicon/zip/zip_main.c +++ b/drivers/crypto/hisilicon/zip/zip_main.c
@@ -1400,8 +1400,8 @@ static int zip_pre_store_cap_reg(struct hisi_qm *qm) i, qm->cap_ver); } - qm->cap_tables.dev_cap_table = zip_cap; qm->cap_tables.dev_cap_size = size; + qm->cap_tables.dev_cap_table = zip_cap; return 0; }
diff --git a/drivers/crypto/inside-secure/eip93/eip93-aead.c b/drivers/crypto/inside-secure/eip93/eip93-aead.c index 2bbd0af..0b7a899 100644 --- a/drivers/crypto/inside-secure/eip93/eip93-aead.c +++ b/drivers/crypto/inside-secure/eip93/eip93-aead.c
@@ -92,7 +92,6 @@ static int eip93_aead_setkey(struct crypto_aead *ctfm, const u8 *key, struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); struct eip93_crypto_ctx *ctx = crypto_tfm_ctx(tfm); struct crypto_authenc_keys keys; - struct crypto_aes_ctx aes; struct sa_record *sa_record = ctx->sa_record; u32 nonce = 0; int ret; @@ -126,7 +125,7 @@ static int eip93_aead_setkey(struct crypto_aead *ctfm, const u8 *key, break; case EIP93_ALG_AES: - ret = aes_expandkey(&aes, keys.enckey, keys.enckeylen); + ret = aes_check_keylen(keys.enckeylen); if (ret) return ret;
diff --git a/drivers/crypto/inside-secure/eip93/eip93-regs.h b/drivers/crypto/inside-secure/eip93/eip93-regs.h index 96d28c6..1d726bc 100644 --- a/drivers/crypto/inside-secure/eip93/eip93-regs.h +++ b/drivers/crypto/inside-secure/eip93/eip93-regs.h
@@ -281,7 +281,7 @@ #define EIP93_SA_CMD_HASH_CRYPT_OFFSET GENMASK(23, 16) #define EIP93_SA_CMD_BYTE_OFFSET BIT(13) /* 0: CRYPT_OFFSET in 32bit word 1: CRYPT_OFFSET in 8bit bytes */ #define EIP93_SA_CMD_HMAC BIT(12) -#define EIP93_SA_CMD_SSL_MAC BIT(12) +#define EIP93_SA_CMD_SSL_MAC BIT(11) /* This mask can be either used for ARC4 or AES */ #define EIP93_SA_CMD_CHIPER_MODE GENMASK(9, 8) /* AES or DES operations */
diff --git a/drivers/crypto/inside-secure/safexcel_cipher.c b/drivers/crypto/inside-secure/safexcel_cipher.c index a8349b6..b031cb9 100644 --- a/drivers/crypto/inside-secure/safexcel_cipher.c +++ b/drivers/crypto/inside-secure/safexcel_cipher.c
@@ -375,7 +375,7 @@ static int safexcel_skcipher_aes_setkey(struct crypto_skcipher *ctfm, struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); struct safexcel_crypto_priv *priv = ctx->base.priv; - struct crypto_aes_ctx aes; + struct crypto_aes_ctx aes __cleanup(aes_zeroize_ctx); int ret, i; ret = aes_expandkey(&aes, key, len); @@ -396,7 +396,6 @@ static int safexcel_skcipher_aes_setkey(struct crypto_skcipher *ctfm, ctx->key_len = len; - memzero_explicit(&aes, sizeof(aes)); return 0; } @@ -407,7 +406,6 @@ static int safexcel_aead_setkey(struct crypto_aead *ctfm, const u8 *key, struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); struct safexcel_crypto_priv *priv = ctx->base.priv; struct crypto_authenc_keys keys; - struct crypto_aes_ctx aes; int err = -EINVAL, i; const char *alg; @@ -438,7 +436,7 @@ static int safexcel_aead_setkey(struct crypto_aead *ctfm, const u8 *key, goto badkey; break; case SAFEXCEL_AES: - err = aes_expandkey(&aes, keys.enckey, keys.enckeylen); + err = aes_check_keylen(keys.enckeylen); if (unlikely(err)) goto badkey; break; @@ -1362,7 +1360,7 @@ static int safexcel_skcipher_aesctr_setkey(struct crypto_skcipher *ctfm, struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); struct safexcel_crypto_priv *priv = ctx->base.priv; - struct crypto_aes_ctx aes; + struct crypto_aes_ctx aes __cleanup(aes_zeroize_ctx); int ret, i; unsigned int keylen; @@ -1388,7 +1386,6 @@ static int safexcel_skcipher_aesctr_setkey(struct crypto_skcipher *ctfm, ctx->key_len = keylen; - memzero_explicit(&aes, sizeof(aes)); return 0; } @@ -2542,7 +2539,7 @@ static int safexcel_skcipher_aesxts_setkey(struct crypto_skcipher *ctfm, struct crypto_tfm *tfm = crypto_skcipher_tfm(ctfm); struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); struct safexcel_crypto_priv *priv = ctx->base.priv; - struct crypto_aes_ctx aes; + struct crypto_aes_ctx aes __cleanup(aes_zeroize_ctx); int ret, i; unsigned int keylen; @@ -2590,7 +2587,6 @@ static int safexcel_skcipher_aesxts_setkey(struct crypto_skcipher *ctfm, ctx->key_len = keylen << 1; - memzero_explicit(&aes, sizeof(aes)); return 0; } @@ -2756,12 +2752,11 @@ static int safexcel_aead_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, struct crypto_tfm *tfm = crypto_aead_tfm(ctfm); struct safexcel_cipher_ctx *ctx = crypto_tfm_ctx(tfm); struct safexcel_crypto_priv *priv = ctx->base.priv; - struct crypto_aes_ctx aes; + struct crypto_aes_ctx aes __cleanup(aes_zeroize_ctx); int ret, i; ret = aes_expandkey(&aes, key, len); if (ret) { - memzero_explicit(&aes, sizeof(aes)); return ret; } @@ -2790,7 +2785,6 @@ static int safexcel_aead_ccm_setkey(struct crypto_aead *ctfm, const u8 *key, else ctx->hash_alg = CONTEXT_CONTROL_CRYPTO_ALG_XCBC128; - memzero_explicit(&aes, sizeof(aes)); return 0; }
diff --git a/drivers/crypto/inside-secure/safexcel_hash.c b/drivers/crypto/inside-secure/safexcel_hash.c index 3402e57..8f107da 100644 --- a/drivers/crypto/inside-secure/safexcel_hash.c +++ b/drivers/crypto/inside-secure/safexcel_hash.c
@@ -1905,7 +1905,7 @@ static int safexcel_cbcmac_setkey(struct crypto_ahash *tfm, const u8 *key, unsigned int len) { struct safexcel_ahash_ctx *ctx = crypto_tfm_ctx(crypto_ahash_tfm(tfm)); - struct crypto_aes_ctx aes; + struct crypto_aes_ctx aes __cleanup(aes_zeroize_ctx); int ret, i; ret = aes_expandkey(&aes, key, len); @@ -1928,7 +1928,6 @@ static int safexcel_cbcmac_setkey(struct crypto_ahash *tfm, const u8 *key, } ctx->cbcmac = true; - memzero_explicit(&aes, sizeof(aes)); return 0; } @@ -1993,6 +1992,7 @@ static int safexcel_xcbcmac_setkey(struct crypto_ahash *tfm, const u8 *key, ret = aes_prepareenckey(ctx->aes, (u8 *)key_tmp + 2 * AES_BLOCK_SIZE, AES_MIN_KEY_SIZE); + memzero_explicit(key_tmp, sizeof(key_tmp)); if (ret) return ret; @@ -2104,6 +2104,8 @@ static int safexcel_cmac_setkey(struct crypto_ahash *tfm, const u8 *key, } ctx->cbcmac = false; + memzero_explicit(consts, sizeof(consts)); + memzero_explicit(_const, sizeof(_const)); return 0; }
diff --git a/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c b/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c index fdda046..33e8e88 100644 --- a/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c +++ b/drivers/crypto/intel/ixp4xx/ixp4xx_crypto.c
@@ -707,8 +707,7 @@ static int register_chain_var(struct crypto_tfm *tfm, u8 xpad, u32 target, return -EAGAIN; } - memcpy(pad, key, key_len); - memset(pad + key_len, 0, HMAC_PAD_BLOCKLEN - key_len); + memcpy_and_pad(pad, HMAC_PAD_BLOCKLEN, key, key_len, 0); for (i = 0; i < HMAC_PAD_BLOCKLEN; i++) pad[i] ^= xpad;
diff --git a/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c b/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c index 19f9f73..d6f1f62 100644 --- a/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c +++ b/drivers/crypto/intel/qat/qat_420xx/adf_420xx_hw_data.c
@@ -443,7 +443,6 @@ void adf_init_hw_data_420xx(struct adf_hw_device_data *hw_data, u32 dev_id) hw_data->enable_error_correction = adf_gen4_enable_error_correction; hw_data->get_accel_mask = adf_gen4_get_accel_mask; hw_data->get_ae_mask = get_ae_mask; - hw_data->get_num_accels = adf_gen4_get_num_accels; hw_data->get_num_aes = adf_gen4_get_num_aes; hw_data->get_sram_bar_id = adf_gen4_get_sram_bar_id; hw_data->get_etr_bar_id = adf_gen4_get_etr_bar_id;
diff --git a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c index 49b425b..7d9dd44 100644 --- a/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c +++ b/drivers/crypto/intel/qat/qat_4xxx/adf_4xxx_hw_data.c
@@ -412,7 +412,6 @@ void adf_init_hw_data_4xxx(struct adf_hw_device_data *hw_data, u32 dev_id) hw_data->enable_error_correction = adf_gen4_enable_error_correction; hw_data->get_accel_mask = adf_gen4_get_accel_mask; hw_data->get_ae_mask = get_ae_mask; - hw_data->get_num_accels = adf_gen4_get_num_accels; hw_data->get_num_aes = adf_gen4_get_num_aes; hw_data->get_sram_bar_id = adf_gen4_get_sram_bar_id; hw_data->get_etr_bar_id = adf_gen4_get_etr_bar_id;
diff --git a/drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.c b/drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.c index 388087e..ca9bc5d 100644 --- a/drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.c +++ b/drivers/crypto/intel/qat/qat_6xxx/adf_6xxx_hw_data.c
@@ -326,11 +326,6 @@ static u32 get_accel_mask(struct adf_hw_device_data *self) return ADF_GEN6_ACCELERATORS_MASK; } -static u32 get_num_accels(struct adf_hw_device_data *self) -{ - return ADF_GEN6_MAX_ACCELERATORS; -} - static u32 get_num_aes(struct adf_hw_device_data *self) { return self ? hweight32(self->ae_mask) : 0; @@ -1023,7 +1018,6 @@ void adf_init_hw_data_6xxx(struct adf_hw_device_data *hw_data) hw_data->enable_error_correction = enable_error_correction; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; - hw_data->get_num_accels = get_num_accels; hw_data->get_num_aes = get_num_aes; hw_data->get_sram_bar_id = get_sram_bar_id; hw_data->get_etr_bar_id = get_etr_bar_id;
diff --git a/drivers/crypto/intel/qat/qat_c3xxx/adf_c3xxx_hw_data.c b/drivers/crypto/intel/qat/qat_c3xxx/adf_c3xxx_hw_data.c index 07f2c42..b9cc6c9 100644 --- a/drivers/crypto/intel/qat/qat_c3xxx/adf_c3xxx_hw_data.c +++ b/drivers/crypto/intel/qat/qat_c3xxx/adf_c3xxx_hw_data.c
@@ -129,7 +129,6 @@ void adf_init_hw_data_c3xxx(struct adf_hw_device_data *hw_data) hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; hw_data->get_accel_cap = adf_gen2_get_accel_cap; - hw_data->get_num_accels = adf_gen2_get_num_accels; hw_data->get_num_aes = adf_gen2_get_num_aes; hw_data->get_sram_bar_id = get_sram_bar_id; hw_data->get_etr_bar_id = get_etr_bar_id;
diff --git a/drivers/crypto/intel/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c b/drivers/crypto/intel/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c index db3c33f..8a5cce5 100644 --- a/drivers/crypto/intel/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c +++ b/drivers/crypto/intel/qat/qat_c3xxxvf/adf_c3xxxvf_hw_data.c
@@ -24,11 +24,6 @@ static u32 get_ae_mask(struct adf_hw_device_data *self) return ADF_C3XXXIOV_ACCELENGINES_MASK; } -static u32 get_num_accels(struct adf_hw_device_data *self) -{ - return ADF_C3XXXIOV_MAX_ACCELERATORS; -} - static u32 get_num_aes(struct adf_hw_device_data *self) { return ADF_C3XXXIOV_MAX_ACCELENGINES; @@ -80,7 +75,6 @@ void adf_init_hw_data_c3xxxiov(struct adf_hw_device_data *hw_data) hw_data->disable_iov = adf_vf2pf_notify_shutdown; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; - hw_data->get_num_accels = get_num_accels; hw_data->get_num_aes = get_num_aes; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id;
diff --git a/drivers/crypto/intel/qat/qat_c62x/adf_c62x_hw_data.c b/drivers/crypto/intel/qat/qat_c62x/adf_c62x_hw_data.c index 0b410b4..aed1c95 100644 --- a/drivers/crypto/intel/qat/qat_c62x/adf_c62x_hw_data.c +++ b/drivers/crypto/intel/qat/qat_c62x/adf_c62x_hw_data.c
@@ -131,7 +131,6 @@ void adf_init_hw_data_c62x(struct adf_hw_device_data *hw_data) hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; hw_data->get_accel_cap = adf_gen2_get_accel_cap; - hw_data->get_num_accels = adf_gen2_get_num_accels; hw_data->get_num_aes = adf_gen2_get_num_aes; hw_data->get_sram_bar_id = get_sram_bar_id; hw_data->get_etr_bar_id = get_etr_bar_id;
diff --git a/drivers/crypto/intel/qat/qat_c62xvf/adf_c62xvf_hw_data.c b/drivers/crypto/intel/qat/qat_c62xvf/adf_c62xvf_hw_data.c index 7f00035..ded32ea 100644 --- a/drivers/crypto/intel/qat/qat_c62xvf/adf_c62xvf_hw_data.c +++ b/drivers/crypto/intel/qat/qat_c62xvf/adf_c62xvf_hw_data.c
@@ -24,11 +24,6 @@ static u32 get_ae_mask(struct adf_hw_device_data *self) return ADF_C62XIOV_ACCELENGINES_MASK; } -static u32 get_num_accels(struct adf_hw_device_data *self) -{ - return ADF_C62XIOV_MAX_ACCELERATORS; -} - static u32 get_num_aes(struct adf_hw_device_data *self) { return ADF_C62XIOV_MAX_ACCELENGINES; @@ -80,7 +75,6 @@ void adf_init_hw_data_c62xiov(struct adf_hw_device_data *hw_data) hw_data->disable_iov = adf_vf2pf_notify_shutdown; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; - hw_data->get_num_accels = get_num_accels; hw_data->get_num_aes = get_num_aes; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id;
diff --git a/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h b/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h index a843801..b77f461 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h +++ b/drivers/crypto/intel/qat/qat_common/adf_accel_devices.h
@@ -279,7 +279,6 @@ struct adf_hw_device_data { u32 (*get_misc_bar_id)(struct adf_hw_device_data *self); u32 (*get_etr_bar_id)(struct adf_hw_device_data *self); u32 (*get_num_aes)(struct adf_hw_device_data *self); - u32 (*get_num_accels)(struct adf_hw_device_data *self); void (*get_arb_info)(struct arb_info *arb_csrs_info); void (*get_admin_info)(struct admin_info *admin_csrs_info); enum dev_sku_info (*get_sku)(struct adf_hw_device_data *self);
diff --git a/drivers/crypto/intel/qat/qat_common/adf_cfg.c b/drivers/crypto/intel/qat/qat_common/adf_cfg.c index b88febf..e2ef528 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_cfg.c +++ b/drivers/crypto/intel/qat/qat_common/adf_cfg.c
@@ -1,6 +1,5 @@ // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only) /* Copyright(c) 2014 - 2020 Intel Corporation */ -#include <linux/mutex.h> #include <linux/slab.h> #include <linux/string.h> #include <linux/list.h> @@ -9,13 +8,11 @@ #include "adf_cfg.h" #include "adf_common_drv.h" -static DEFINE_MUTEX(qat_cfg_read_lock); - static void *qat_dev_cfg_start(struct seq_file *sfile, loff_t *pos) { struct adf_cfg_device_data *dev_cfg = sfile->private; - mutex_lock(&qat_cfg_read_lock); + down_read(&dev_cfg->lock); return seq_list_start(&dev_cfg->sec_list, *pos); } @@ -43,7 +40,9 @@ static void *qat_dev_cfg_next(struct seq_file *sfile, void *v, loff_t *pos) static void qat_dev_cfg_stop(struct seq_file *sfile, void *v) { - mutex_unlock(&qat_cfg_read_lock); + struct adf_cfg_device_data *dev_cfg = sfile->private; + + up_read(&dev_cfg->lock); } static const struct seq_operations qat_dev_cfg_sops = { @@ -146,24 +145,6 @@ static void adf_cfg_keyval_add(struct adf_cfg_key_val *new, list_add_tail(&new->list, &sec->param_head); } -static void adf_cfg_keyval_remove(const char *key, struct adf_cfg_section *sec) -{ - struct list_head *head = &sec->param_head; - struct list_head *list_ptr, *tmp; - - list_for_each_prev_safe(list_ptr, tmp, head) { - struct adf_cfg_key_val *ptr = - list_entry(list_ptr, struct adf_cfg_key_val, list); - - if (strncmp(ptr->key, key, sizeof(ptr->key))) - continue; - - list_del(list_ptr); - kfree(ptr); - break; - } -} - static void adf_cfg_keyval_del_all(struct list_head *head) { struct list_head *list_ptr, *tmp; @@ -272,13 +253,9 @@ int adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev, enum adf_cfg_val_type type) { struct adf_cfg_device_data *cfg = accel_dev->cfg; - struct adf_cfg_key_val *key_val; - struct adf_cfg_section *section = adf_cfg_sec_find(accel_dev, - section_name); - char temp_val[ADF_CFG_MAX_VAL_LEN_IN_BYTES]; - - if (!section) - return -EFAULT; + struct adf_cfg_key_val *key_val, *existing; + struct adf_cfg_section *section; + int ret = 0; key_val = kzalloc_obj(*key_val); if (!key_val) @@ -299,7 +276,17 @@ int adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev, } key_val->type = type; - /* Add the key-value pair as below policy: + down_write(&cfg->lock); + + section = adf_cfg_sec_find(accel_dev, section_name); + if (!section) { + kfree(key_val); + ret = -ENOENT; + goto unlock; + } + + /* + * Add the key-value pair as below policy: * 1. if the key doesn't exist, add it; * 2. if the key already exists with a different value then update it * to the new value (the key is deleted and the newly created @@ -307,21 +294,21 @@ int adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev, * 3. if the key exists with the same value, then return without doing * anything (the newly created key_val is freed). */ - down_write(&cfg->lock); - if (!adf_cfg_key_val_get(accel_dev, section_name, key, temp_val)) { - if (strncmp(temp_val, key_val->val, sizeof(temp_val))) { - adf_cfg_keyval_remove(key, section); - } else { + existing = adf_cfg_key_value_find(section, key); + if (existing) { + if (!strncmp(existing->val, key_val->val, sizeof(existing->val))) { kfree(key_val); - goto out; + goto unlock; } + list_del(&existing->list); + kfree(existing); } adf_cfg_keyval_add(key_val, section); -out: +unlock: up_write(&cfg->lock); - return 0; + return ret; } EXPORT_SYMBOL_GPL(adf_cfg_add_key_value_param); @@ -339,21 +326,26 @@ EXPORT_SYMBOL_GPL(adf_cfg_add_key_value_param); int adf_cfg_section_add(struct adf_accel_dev *accel_dev, const char *name) { struct adf_cfg_device_data *cfg = accel_dev->cfg; - struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, name); + struct adf_cfg_section *sec; + int ret = 0; - if (sec) - return 0; + down_write(&cfg->lock); + + if (adf_cfg_sec_find(accel_dev, name)) + goto unlock; sec = kzalloc_obj(*sec); - if (!sec) - return -ENOMEM; + if (!sec) { + ret = -ENOMEM; + goto unlock; + } strscpy(sec->name, name); INIT_LIST_HEAD(&sec->param_head); - down_write(&cfg->lock); list_add_tail(&sec->list, &cfg->sec_list); +unlock: up_write(&cfg->lock); - return 0; + return ret; } EXPORT_SYMBOL_GPL(adf_cfg_section_add);
diff --git a/drivers/crypto/intel/qat/qat_common/adf_dev_mgr.c b/drivers/crypto/intel/qat/qat_common/adf_dev_mgr.c index 1618638..4e6d860 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_dev_mgr.c +++ b/drivers/crypto/intel/qat/qat_common/adf_dev_mgr.c
@@ -137,6 +137,13 @@ int adf_devmgr_add_dev(struct adf_accel_dev *accel_dev, mutex_lock(&table_lock); atomic_set(&accel_dev->ref_count, 0); + mutex_init(&accel_dev->state_lock); + /* + * The VF2PF lock is used to send messages to the PF outside of the + * device up/down cycle, so it must live as long as the accel device. + */ + if (accel_dev->is_vf) + mutex_init(&accel_dev->vf.vf2pf_lock); /* PF on host or VF on guest - optimized to remove redundant is_vf */ if (!accel_dev->is_vf || !pf) { @@ -210,7 +217,6 @@ int adf_devmgr_add_dev(struct adf_accel_dev *accel_dev, map->attached = true; list_add_tail(&map->list, &vfs_table); } - mutex_init(&accel_dev->state_lock); unlock: mutex_unlock(&table_lock); return ret; @@ -257,6 +263,8 @@ void adf_devmgr_rm_dev(struct adf_accel_dev *accel_dev, } } unlock: + if (accel_dev->is_vf) + mutex_destroy(&accel_dev->vf.vf2pf_lock); mutex_destroy(&accel_dev->state_lock); list_del(&accel_dev->list); mutex_unlock(&table_lock);
diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen2_hw_data.c b/drivers/crypto/intel/qat/qat_common/adf_gen2_hw_data.c index 6a505e9..bff89c8 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_gen2_hw_data.c +++ b/drivers/crypto/intel/qat/qat_common/adf_gen2_hw_data.c
@@ -7,15 +7,6 @@ #include "icp_qat_hw.h" #include <linux/pci.h> -u32 adf_gen2_get_num_accels(struct adf_hw_device_data *self) -{ - if (!self || !self->accel_mask) - return 0; - - return hweight16(self->accel_mask); -} -EXPORT_SYMBOL_GPL(adf_gen2_get_num_accels); - u32 adf_gen2_get_num_aes(struct adf_hw_device_data *self) { if (!self || !self->ae_mask)
diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen2_hw_data.h b/drivers/crypto/intel/qat/qat_common/adf_gen2_hw_data.h index 59bad36..3caeb1d 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_gen2_hw_data.h +++ b/drivers/crypto/intel/qat/qat_common/adf_gen2_hw_data.h
@@ -78,7 +78,6 @@ #define ADF_GEN2_SMIAPF1_MASK_OFFSET (0x3A000 + 0x30) #define ADF_GEN2_SMIA1_MASK 0x1 -u32 adf_gen2_get_num_accels(struct adf_hw_device_data *self); u32 adf_gen2_get_num_aes(struct adf_hw_device_data *self); void adf_gen2_enable_error_correction(struct adf_accel_dev *accel_dev); void adf_gen2_cfg_iov_thds(struct adf_accel_dev *accel_dev, bool enable,
diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c b/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c index f4a58f0..d9a0ed7 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c +++ b/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.c
@@ -21,12 +21,6 @@ u32 adf_gen4_get_accel_mask(struct adf_hw_device_data *self) } EXPORT_SYMBOL_GPL(adf_gen4_get_accel_mask); -u32 adf_gen4_get_num_accels(struct adf_hw_device_data *self) -{ - return ADF_GEN4_MAX_ACCELERATORS; -} -EXPORT_SYMBOL_GPL(adf_gen4_get_num_accels); - u32 adf_gen4_get_num_aes(struct adf_hw_device_data *self) { if (!self || !self->ae_mask)
diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.h b/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.h index cd26b67..46dfa23 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.h +++ b/drivers/crypto/intel/qat/qat_common/adf_gen4_hw_data.h
@@ -157,7 +157,6 @@ void adf_gen4_get_arb_info(struct arb_info *arb_info); u32 adf_gen4_get_etr_bar_id(struct adf_hw_device_data *self); u32 adf_gen4_get_heartbeat_clock(struct adf_hw_device_data *self); u32 adf_gen4_get_misc_bar_id(struct adf_hw_device_data *self); -u32 adf_gen4_get_num_accels(struct adf_hw_device_data *self); u32 adf_gen4_get_num_aes(struct adf_hw_device_data *self); enum dev_sku_info adf_gen4_get_sku(struct adf_hw_device_data *self); u32 adf_gen4_get_sram_bar_id(struct adf_hw_device_data *self);
diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen4_vf_mig.c b/drivers/crypto/intel/qat/qat_common/adf_gen4_vf_mig.c index bf2bae7..d8b961b 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_gen4_vf_mig.c +++ b/drivers/crypto/intel/qat/qat_common/adf_gen4_vf_mig.c
@@ -837,6 +837,9 @@ static int adf_gen4_vfmig_save_state(struct qat_mig_dev *mdev) return ret; } + memset(mdev->state + mdev->setup_size, 0, + mdev->state_size - mdev->setup_size); + adf_mstate_mgr_init(vfmig->mstate_mgr, mdev->state + mdev->setup_size, mdev->state_size - mdev->setup_size); if (!adf_mstate_preamble_add(vfmig->mstate_mgr)) @@ -934,6 +937,8 @@ static int adf_gen4_vfmig_save_setup(struct qat_mig_dev *mdev) if (mdev->setup_size) return 0; + memset(mdev->state, 0, mdev->state_size); + adf_mstate_mgr_init(vfmig->mstate_mgr, mdev->state, mdev->state_size); if (!adf_mstate_preamble_add(vfmig->mstate_mgr)) return -EINVAL;
diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.c b/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.c index 9672530..902c4b1 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.c +++ b/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.c
@@ -323,14 +323,26 @@ static void adf_handle_ti_cd_par_sts(struct adf_accel_dev *accel_dev, void __iom u32 ti_cd_par_sts; ti_cd_par_sts = ADF_CSR_RD(csr, ADF_GEN6_TI_CD_PAR_STS); - ti_cd_par_sts &= ADF_GEN6_TI_CD_PAR_STS_MASK; + ti_cd_par_sts &= ADF_GEN6_TI_CD_PAR_STS_TI_INT_ERR_DEVHALT_MASK; if (ti_cd_par_sts) { dev_err(&GET_DEV(accel_dev), "TI CD parity error: %#x\n", ti_cd_par_sts); - ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); ADF_CSR_WR(csr, ADF_GEN6_TI_CD_PAR_STS, ti_cd_par_sts); } } +static void adf_handle_ti_misc_cd_par_sts(struct adf_accel_dev *accel_dev, void __iomem *csr) +{ + u32 ti_misc_cd_par_sts; + + ti_misc_cd_par_sts = ADF_CSR_RD(csr, ADF_GEN6_TI_CD_PAR_STS); + ti_misc_cd_par_sts &= ADF_GEN6_TI_CD_PAR_STS_TI_MISC_MASK; + if (ti_misc_cd_par_sts) { + dev_err(&GET_DEV(accel_dev), "TI MISC CD parity error: %#x\n", ti_misc_cd_par_sts); + ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_UNCORR); + ADF_CSR_WR(csr, ADF_GEN6_TI_CD_PAR_STS, ti_misc_cd_par_sts); + } +} + static void adf_handle_ti_trnsb_par_sts(struct adf_accel_dev *accel_dev, void __iomem *csr) { u32 ti_trnsb_par_sts; @@ -367,7 +379,6 @@ static void adf_handle_ti_err(struct adf_accel_dev *accel_dev, void __iomem *csr adf_handle_ti_ci_par_sts(accel_dev, csr); adf_handle_ti_pullfub_par_sts(accel_dev, csr); adf_handle_ti_pushfub_par_sts(accel_dev, csr); - adf_handle_ti_cd_par_sts(accel_dev, csr); adf_handle_ti_trnsb_par_sts(accel_dev, csr); adf_handle_iosfp_cmd_parerr(accel_dev, csr); } @@ -591,6 +602,8 @@ static void adf_handle_timiscsts(struct adf_accel_dev *accel_dev, void __iomem * if (!(errsou & ADF_GEN6_ERRSOU3_TIMISCSTS_BIT)) return; + adf_handle_ti_misc_cd_par_sts(accel_dev, csr); + timiscsts = ADF_CSR_RD(csr, ADF_GEN6_TIMISCSTS); if (timiscsts) { dev_err(&GET_DEV(accel_dev), "Fatal error in transmit interface: %#x\n", @@ -730,6 +743,7 @@ static void adf_handle_ti_int_err_devhalt(struct adf_accel_dev *accel_dev, void if (!(errsou & ADF_GEN6_ERRSOU3_TI_INT_ERR_DEVHALT_BIT)) return; + adf_handle_ti_cd_par_sts(accel_dev, csr); dev_err(&GET_DEV(accel_dev), "DEVHALT due to a TI internal memory error\n"); ADF_RAS_ERR_CTR_INC(accel_dev->ras_errors, ADF_RAS_FATAL); }
diff --git a/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.h b/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.h index 66ced27..11f7b29 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.h +++ b/drivers/crypto/intel/qat/qat_common/adf_gen6_ras.h
@@ -170,23 +170,25 @@ struct adf_ras_ops; #define ADF_GEN6_TI_CD_PAR_ERR_MASK 0x500638 /* - * TI CD parity status mask + * TI CD parity status mask - TI_INT_ERR_DEVHALT bits * BIT(0) - BIT(15) - CtxMdRam[0:15]_sts parity status * BIT(16) - Leaf2ClusterRam_sts parity status * BIT(17) - BIT(18) - Ring2LeafRam[0:1]_sts parity status - * BIT(19) - VirtualQ_sts parity status - * BIT(20) - DtRdQ_sts parity status - * BIT(21) - DtWrQ_sts parity status - * BIT(22) - RiCmdQ_sts parity status - * BIT(23) - BypassQ_sts parity status - * BIT(24) - DtRdQ_sc_sts parity status - * BIT(25) - DtWrQ_sc_sts parity status */ -#define ADF_GEN6_TI_CD_PAR_STS_MASK \ +#define ADF_GEN6_TI_CD_PAR_STS_TI_INT_ERR_DEVHALT_MASK \ (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | \ BIT(7) | BIT(8) | BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | \ - BIT(14) | BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | \ - BIT(21) | BIT(22) | BIT(23) | BIT(24) | BIT(25)) + BIT(14) | BIT(15) | BIT(16) | BIT(17) | BIT(18)) + +/* + * TI CD parity status mask - TIMISCSTS bit + * BIT(19) - VirtualQ_sts parity status + */ +#define ADF_GEN6_TI_CD_PAR_STS_TI_MISC_MASK BIT(19) + +#define ADF_GEN6_TI_CD_PAR_STS_MASK \ + (ADF_GEN6_TI_CD_PAR_STS_TI_INT_ERR_DEVHALT_MASK | \ + ADF_GEN6_TI_CD_PAR_STS_TI_MISC_MASK) /* TI TRNSB parity status */ #define ADF_GEN6_TI_TRNSB_PAR_STS 0x500648
diff --git a/drivers/crypto/intel/qat/qat_common/adf_init.c b/drivers/crypto/intel/qat/qat_common/adf_init.c index 3e39c53..81cb5e6 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_init.c +++ b/drivers/crypto/intel/qat/qat_common/adf_init.c
@@ -260,13 +260,23 @@ static int adf_dev_start(struct adf_accel_dev *accel_dev) clear_bit(ADF_STATUS_STARTING, &accel_dev->status); set_bit(ADF_STATUS_STARTED, &accel_dev->status); - if (!list_empty(&accel_dev->crypto_list) && - (qat_algs_register() || qat_asym_algs_register())) { - dev_err(&GET_DEV(accel_dev), - "Failed to register crypto algs\n"); - set_bit(ADF_STATUS_STARTING, &accel_dev->status); - clear_bit(ADF_STATUS_STARTED, &accel_dev->status); - return -EFAULT; + if (!list_empty(&accel_dev->crypto_list)) { + ret = qat_algs_register(); + if (ret) { + dev_err(&GET_DEV(accel_dev), "Failed to register crypto algs\n"); + set_bit(ADF_STATUS_STARTING, &accel_dev->status); + clear_bit(ADF_STATUS_STARTED, &accel_dev->status); + return ret; + } + + ret = qat_asym_algs_register(); + if (ret) { + dev_err(&GET_DEV(accel_dev), "Failed to register crypto asym algs\n"); + qat_algs_unregister(); + set_bit(ADF_STATUS_STARTING, &accel_dev->status); + clear_bit(ADF_STATUS_STARTED, &accel_dev->status); + return ret; + } } set_bit(ADF_STATUS_CRYPTO_ALGS_REGISTERED, &accel_dev->status);
diff --git a/drivers/crypto/intel/qat/qat_common/adf_isr.c b/drivers/crypto/intel/qat/qat_common/adf_isr.c index 159e91a..0df4b39 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_isr.c +++ b/drivers/crypto/intel/qat/qat_common/adf_isr.c
@@ -70,6 +70,7 @@ void adf_enable_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 vf_mask) void adf_enable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 num_vfs) { void __iomem *pmisc_addr = adf_get_pmisc_base(accel_dev); + struct adf_pfvf_ops *pfvf_ops = GET_PFVF_OPS(accel_dev); unsigned long flags; u32 vf_mask; @@ -79,7 +80,19 @@ void adf_enable_all_vf2pf_interrupts(struct adf_accel_dev *accel_dev, u32 num_vf spin_lock_irqsave(&accel_dev->pf.vf2pf_ints_lock, flags); WRITE_ONCE(accel_dev->pf.vf2pf_disabled, false); - GET_PFVF_OPS(accel_dev)->enable_vf2pf_interrupts(pmisc_addr, vf_mask); + /* + * A VF2PF interrupt is only generated when a source transitions from + * masked to unmasked. A VF may write to its VF2PF CSR while the source + * is masked or while the MSI-X vectors are torn down, for example + * during a device reset, leaving the source latched with no interrupt + * pending. The FLR performed as part of a device reset returns the mask + * register to its default value, which leaves all the sources unmasked, + * so simply unmasking is not guaranteed to be a transition. Mask all the + * sources first, so that unmasking always generates an interrupt for + * the sources latched in the meantime. + */ + pfvf_ops->disable_all_vf2pf_interrupts(pmisc_addr); + pfvf_ops->enable_vf2pf_interrupts(pmisc_addr, vf_mask); spin_unlock_irqrestore(&accel_dev->pf.vf2pf_ints_lock, flags); }
diff --git a/drivers/crypto/intel/qat/qat_common/adf_sysfs_kpt.c b/drivers/crypto/intel/qat/qat_common/adf_sysfs_kpt.c index 1f733ae8..a0db98f 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_sysfs_kpt.c +++ b/drivers/crypto/intel/qat/qat_common/adf_sysfs_kpt.c
@@ -31,6 +31,7 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr, struct adf_hw_device_data *hw_data; struct adf_accel_dev *accel_dev; bool enable; + int svc; int ret; accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev)); @@ -38,14 +39,25 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr, return -EINVAL; if (adf_dev_started(accel_dev)) { - dev_info(dev, "Device qat_dev%d must be down before enabling KPT\n", + dev_info(dev, "Device qat_dev%d must be down before changing KPT state\n", accel_dev->accel_id); return -EINVAL; } - if (adf_get_service_enabled(accel_dev) != SVC_ASYM) { - dev_info(dev, "KPT can only be enabled when the asymmetric service is enabled\n"); - return -EINVAL; + ret = kstrtobool(buf, &enable); + if (ret) + return ret; + + if (enable) { + svc = adf_get_service_enabled(accel_dev); + if (svc < 0) + return svc; + + if (svc != SVC_ASYM) { + dev_info(dev, + "KPT can only be enabled when the asymmetric crypto service is enabled\n"); + return -EINVAL; + } } hw_data = GET_HW_DATA(accel_dev); @@ -59,10 +71,6 @@ static ssize_t enable_store(struct device *dev, struct device_attribute *attr, if (!hw_data->accel_capabilities_mask) return -EINVAL; - ret = kstrtobool(buf, &enable); - if (ret) - return ret; - user_data = GET_KPT_USER_DATA(accel_dev); user_data->enable = enable;
diff --git a/drivers/crypto/intel/qat/qat_common/adf_vf_isr.c b/drivers/crypto/intel/qat/qat_common/adf_vf_isr.c index 9ffaa56..1f28655 100644 --- a/drivers/crypto/intel/qat/qat_common/adf_vf_isr.c +++ b/drivers/crypto/intel/qat/qat_common/adf_vf_isr.c
@@ -118,7 +118,6 @@ static int adf_setup_pf2vf_bh(struct adf_accel_dev *accel_dev) tasklet_init(&accel_dev->vf.pf2vf_bh_tasklet, (void *)adf_pf2vf_bh_handler, (unsigned long)accel_dev); - mutex_init(&accel_dev->vf.vf2pf_lock); return 0; } @@ -126,7 +125,6 @@ static void adf_cleanup_pf2vf_bh(struct adf_accel_dev *accel_dev) { tasklet_disable(&accel_dev->vf.pf2vf_bh_tasklet); tasklet_kill(&accel_dev->vf.pf2vf_bh_tasklet); - mutex_destroy(&accel_dev->vf.vf2pf_lock); } static irqreturn_t adf_isr(int irq, void *privdata)
diff --git a/drivers/crypto/intel/qat/qat_common/qat_algs.c b/drivers/crypto/intel/qat/qat_common/qat_algs.c index 9166380..2ec1910 100644 --- a/drivers/crypto/intel/qat/qat_common/qat_algs.c +++ b/drivers/crypto/intel/qat/qat_common/qat_algs.c
@@ -388,7 +388,7 @@ static void qat_alg_skcipher_init_enc(struct qat_alg_skcipher_ctx *ctx, static void qat_alg_xts_reverse_key(const u8 *key_forward, unsigned int keylen, u8 *key_reverse) { - struct crypto_aes_ctx aes_expanded; + struct crypto_aes_ctx aes_expanded __cleanup(aes_zeroize_ctx); int nrounds; u8 *key; @@ -405,7 +405,6 @@ static void qat_alg_xts_reverse_key(const u8 *key_forward, unsigned int keylen, memcpy(key_reverse + AES_BLOCK_SIZE, key - AES_BLOCK_SIZE, AES_BLOCK_SIZE); } - memzero_explicit(&aes_expanded, sizeof(aes_expanded)); } static void qat_alg_skcipher_init_dec(struct qat_alg_skcipher_ctx *ctx, @@ -1320,19 +1319,22 @@ int qat_algs_register(void) ret = crypto_register_skciphers(qat_skciphers, ARRAY_SIZE(qat_skciphers)); if (ret) - goto unlock; + goto err_dec; ret = crypto_register_aeads(qat_aeads, ARRAY_SIZE(qat_aeads)); if (ret) - goto unreg_algs; + goto err_unreg_skciphers; + mutex_unlock(&algs_lock); + return 0; + +err_unreg_skciphers: + crypto_unregister_skciphers(qat_skciphers, ARRAY_SIZE(qat_skciphers)); +err_dec: + active_devs--; unlock: mutex_unlock(&algs_lock); return ret; - -unreg_algs: - crypto_unregister_skciphers(qat_skciphers, ARRAY_SIZE(qat_skciphers)); - goto unlock; } void qat_algs_unregister(void)
diff --git a/drivers/crypto/intel/qat/qat_common/qat_asym_algs.c b/drivers/crypto/intel/qat/qat_common/qat_asym_algs.c index 75c15c8..77d59e9 100644 --- a/drivers/crypto/intel/qat/qat_common/qat_asym_algs.c +++ b/drivers/crypto/intel/qat/qat_common/qat_asym_algs.c
@@ -535,8 +535,10 @@ static int qat_dh_init_tfm(struct crypto_kpp *tfm) return -EINVAL; ctx->ftfm = crypto_alloc_kpp(alg, 0, CRYPTO_ALG_NEED_FALLBACK); - if (IS_ERR(ctx->ftfm)) + if (IS_ERR(ctx->ftfm)) { + qat_crypto_put_instance(inst); return PTR_ERR(ctx->ftfm); + } crypto_kpp_set_flags(ctx->ftfm, crypto_kpp_get_flags(tfm)); @@ -987,7 +989,7 @@ static int qat_rsa_set_n(struct qat_rsa_ctx *ctx, const char *value, const char *ptr = value; int ret; - while (!*ptr && vlen) { + while (vlen && !*ptr) { ptr++; vlen--; } @@ -1018,7 +1020,7 @@ static int qat_rsa_set_e(struct qat_rsa_ctx *ctx, const char *value, struct device *dev = &GET_DEV(inst->accel_dev); const char *ptr = value; - while (!*ptr && vlen) { + while (vlen && !*ptr) { ptr++; vlen--; } @@ -1044,7 +1046,7 @@ static int qat_rsa_set_d(struct qat_rsa_ctx *ctx, const char *value, const char *ptr = value; int ret; - while (!*ptr && vlen) { + while (vlen && !*ptr) { ptr++; vlen--; } @@ -1067,7 +1069,7 @@ static int qat_rsa_set_d(struct qat_rsa_ctx *ctx, const char *value, static void qat_rsa_drop_leading_zeros(const char **ptr, unsigned int *len) { - while (!**ptr && *len) { + while (*len && !**ptr) { (*ptr)++; (*len)--; } @@ -1338,13 +1340,25 @@ int qat_asym_algs_register(void) int ret = 0; mutex_lock(&algs_lock); - if (++active_devs == 1) { - rsa.base.cra_flags = 0; - ret = crypto_register_akcipher(&rsa); - if (ret) - goto unlock; - ret = crypto_register_kpp(&dh); - } + if (++active_devs != 1) + goto unlock; + + rsa.base.cra_flags = 0; + ret = crypto_register_akcipher(&rsa); + if (ret) + goto err_dec; + + ret = crypto_register_kpp(&dh); + if (ret) + goto err_unreg_akcipher; + + mutex_unlock(&algs_lock); + return 0; + +err_unreg_akcipher: + crypto_unregister_akcipher(&rsa); +err_dec: + active_devs--; unlock: mutex_unlock(&algs_lock); return ret;
diff --git a/drivers/crypto/intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c b/drivers/crypto/intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c index 5b4bd0b..c318015 100644 --- a/drivers/crypto/intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c +++ b/drivers/crypto/intel/qat/qat_dh895xcc/adf_dh895xcc_hw_data.c
@@ -229,7 +229,6 @@ void adf_init_hw_data_dh895xcc(struct adf_hw_device_data *hw_data) hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; hw_data->get_accel_cap = get_accel_cap; - hw_data->get_num_accels = adf_gen2_get_num_accels; hw_data->get_num_aes = adf_gen2_get_num_aes; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id;
diff --git a/drivers/crypto/intel/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c b/drivers/crypto/intel/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c index 828456c..6fd5bb3 100644 --- a/drivers/crypto/intel/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c +++ b/drivers/crypto/intel/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c
@@ -24,11 +24,6 @@ static u32 get_ae_mask(struct adf_hw_device_data *self) return ADF_DH895XCCIOV_ACCELENGINES_MASK; } -static u32 get_num_accels(struct adf_hw_device_data *self) -{ - return ADF_DH895XCCIOV_MAX_ACCELERATORS; -} - static u32 get_num_aes(struct adf_hw_device_data *self) { return ADF_DH895XCCIOV_MAX_ACCELENGINES; @@ -80,7 +75,6 @@ void adf_init_hw_data_dh895xcciov(struct adf_hw_device_data *hw_data) hw_data->disable_iov = adf_vf2pf_notify_shutdown; hw_data->get_accel_mask = get_accel_mask; hw_data->get_ae_mask = get_ae_mask; - hw_data->get_num_accels = get_num_accels; hw_data->get_num_aes = get_num_aes; hw_data->get_etr_bar_id = get_etr_bar_id; hw_data->get_misc_bar_id = get_misc_bar_id;
diff --git a/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c b/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c index 096be42..2f088af 100644 --- a/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c +++ b/drivers/crypto/marvell/octeontx/otx_cptvf_algs.c
@@ -16,6 +16,7 @@ #include <crypto/sha1.h> #include <crypto/sha2.h> #include <crypto/xts.h> +#include <crypto/utils.h> #include <crypto/scatterwalk.h> #include <linux/sort.h> #include <linux/module.h> @@ -105,9 +106,9 @@ static inline int validate_hmac_cipher_null(struct otx_cpt_req_info *cpt_req) req = container_of(cpt_req->areq, struct aead_request, base); tfm = crypto_aead_reqtfm(req); rctx = aead_request_ctx_dma(req); - if (memcmp(rctx->fctx.hmac.s.hmac_calc, - rctx->fctx.hmac.s.hmac_recv, - crypto_aead_authsize(tfm)) != 0) + if (crypto_memneq(rctx->fctx.hmac.s.hmac_calc, + rctx->fctx.hmac.s.hmac_recv, + crypto_aead_authsize(tfm))) return -EBADMSG; return 0; @@ -792,8 +793,7 @@ static int aead_hmac_init(struct crypto_aead *cipher, ipad = ctx->ipad; opad = ctx->opad; - memcpy(ipad, ctx->key, authkeylen); - memset(ipad + authkeylen, 0, bs - authkeylen); + memcpy_and_pad(ipad, bs, ctx->key, authkeylen, 0); memcpy(opad, ipad, bs); for (icount = 0; icount < bs; icount++) {
diff --git a/drivers/crypto/marvell/octeontx/otx_cptvf_mbox.c b/drivers/crypto/marvell/octeontx/otx_cptvf_mbox.c index 90fdafb..38d1de2 100644 --- a/drivers/crypto/marvell/octeontx/otx_cptvf_mbox.c +++ b/drivers/crypto/marvell/octeontx/otx_cptvf_mbox.c
@@ -180,7 +180,7 @@ int otx_cptvf_send_vq_size_msg(struct otx_cptvf *cptvf) } /* - * Communicate VF group required to PF and get the VQ binded to that group + * Communicate VF group required to PF and get the VQ bound to that group */ int otx_cptvf_send_vf_to_grp_msg(struct otx_cptvf *cptvf, int group) { @@ -199,7 +199,7 @@ int otx_cptvf_send_vf_to_grp_msg(struct otx_cptvf *cptvf, int group) } /* - * Communicate VF group required to PF and get the VQ binded to that group + * Communicate VF group required to PF and get the VQ bound to that group */ int otx_cptvf_send_vf_priority_msg(struct otx_cptvf *cptvf) {
diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c b/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c index 8d9f394..9eb5dc0 100644 --- a/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c +++ b/drivers/crypto/marvell/octeontx2/otx2_cptvf_algs.c
@@ -11,6 +11,7 @@ #include <crypto/xts.h> #include <crypto/gcm.h> #include <crypto/scatterwalk.h> +#include <crypto/utils.h> #include <linux/sort.h> #include <linux/module.h> #include "otx2_cptvf.h" @@ -90,9 +91,9 @@ static inline int validate_hmac_cipher_null(struct otx2_cpt_req_info *cpt_req) req = container_of(cpt_req->areq, struct aead_request, base); tfm = crypto_aead_reqtfm(req); rctx = aead_request_ctx_dma(req); - if (memcmp(rctx->fctx.hmac.s.hmac_calc, - rctx->fctx.hmac.s.hmac_recv, - crypto_aead_authsize(tfm)) != 0) + if (crypto_memneq(rctx->fctx.hmac.s.hmac_calc, + rctx->fctx.hmac.s.hmac_recv, + crypto_aead_authsize(tfm))) return -EBADMSG; return 0; @@ -882,8 +883,7 @@ static int aead_hmac_init(struct crypto_aead *cipher, ipad = ctx->ipad; opad = ctx->opad; - memcpy(ipad, ctx->key, authkeylen); - memset(ipad + authkeylen, 0, bs - authkeylen); + memcpy_and_pad(ipad, bs, ctx->key, authkeylen, 0); memcpy(opad, ipad, bs); for (icount = 0; icount < bs; icount++) {
diff --git a/drivers/crypto/mxs-dcp.c b/drivers/crypto/mxs-dcp.c index c75a069..d104d95 100644 --- a/drivers/crypto/mxs-dcp.c +++ b/drivers/crypto/mxs-dcp.c
@@ -473,6 +473,9 @@ static int mxs_dcp_aes_enqueue(struct skcipher_request *req, int enc, int ecb) struct dcp_aes_req_ctx *rctx = skcipher_request_ctx(req); int ret; + if (!req->cryptlen) + return 0; + if (unlikely(actx->key_len != AES_KEYSIZE_128 && !actx->key_referenced)) return mxs_dcp_block_fallback(req, enc);
diff --git a/drivers/crypto/nx/nx-842.c b/drivers/crypto/nx/nx-842.c index a61208c..b4404a1 100644 --- a/drivers/crypto/nx/nx-842.c +++ b/drivers/crypto/nx/nx-842.c
@@ -421,6 +421,8 @@ static int decompress(struct nx842_crypto_ctx *ctx, slen -= spadding; + if (ignore > dlen) + return -EINVAL; dlen -= ignore; if (ignore) pr_debug("ignoring last %x bytes\n", ignore);
diff --git a/drivers/crypto/omap-des.c b/drivers/crypto/omap-des.c index 3b7104c..4b5a8d1 100644 --- a/drivers/crypto/omap-des.c +++ b/drivers/crypto/omap-des.c
@@ -1082,6 +1082,8 @@ static void omap_des_remove(struct platform_device *pdev) omap_des_unregister_algs(dd->pdata); + crypto_engine_exit(dd->engine); + cancel_work_sync(&dd->done_task); omap_des_dma_cleanup(dd); pm_runtime_disable(dd->dev);
diff --git a/drivers/crypto/omap-sham.c b/drivers/crypto/omap-sham.c index 6d2dd0b..5e73941 100644 --- a/drivers/crypto/omap-sham.c +++ b/drivers/crypto/omap-sham.c
@@ -1265,7 +1265,7 @@ static int omap_sham_finup(struct ahash_request *req) return err1; /* * final() has to be always called to cleanup resources - * even if udpate() failed, except EINPROGRESS + * even if update() failed, except EINPROGRESS */ err2 = omap_sham_final(req); @@ -1732,7 +1732,7 @@ static void omap_sham_done_task(struct work_struct *t) finish: dev_dbg(dd->dev, "update done: err: %d\n", err); - /* finish curent request */ + /* finish current request */ omap_sham_finish_req(dd->req, err); } @@ -2129,6 +2129,7 @@ static void omap_sham_remove(struct platform_device *pdev) list_del(&dd->list); spin_unlock_bh(&sham.lock); omap_sham_unregister_algs(dd->pdata); + crypto_engine_exit(dd->engine); cancel_work_sync(&dd->done_task); pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_disable(&pdev->dev);
diff --git a/drivers/crypto/padlock-aes.c b/drivers/crypto/padlock-aes.c index 1be549a..400a889 100644 --- a/drivers/crypto/padlock-aes.c +++ b/drivers/crypto/padlock-aes.c
@@ -109,7 +109,7 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, { struct aes_ctx *ctx = aes_ctx(tfm); const __le32 *key = (const __le32 *)in_key; - struct crypto_aes_ctx gen_aes; + struct crypto_aes_ctx gen_aes __cleanup(aes_zeroize_ctx); int cpu; if (key_len % 8) @@ -137,20 +137,18 @@ static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key, ctx->cword.decrypt.ksize = ctx->cword.encrypt.ksize; /* Don't generate extended keys if the hardware can do it. */ - if (aes_hw_extkey_available(key_len)) - goto ok; + if (!aes_hw_extkey_available(key_len)) { + ctx->D = ctx->d_data; + ctx->cword.encrypt.keygen = 1; + ctx->cword.decrypt.keygen = 1; - ctx->D = ctx->d_data; - ctx->cword.encrypt.keygen = 1; - ctx->cword.decrypt.keygen = 1; + if (aes_expandkey(&gen_aes, in_key, key_len)) + return -EINVAL; - if (aes_expandkey(&gen_aes, in_key, key_len)) - return -EINVAL; + memcpy(ctx->E, gen_aes.key_enc, AES_MAX_KEYLENGTH); + memcpy(ctx->D, gen_aes.key_dec, AES_MAX_KEYLENGTH); + } - memcpy(ctx->E, gen_aes.key_enc, AES_MAX_KEYLENGTH); - memcpy(ctx->D, gen_aes.key_dec, AES_MAX_KEYLENGTH); - -ok: for_each_online_cpu(cpu) if (&ctx->cword.encrypt == per_cpu(paes_last_cword, cpu) || &ctx->cword.decrypt == per_cpu(paes_last_cword, cpu))
diff --git a/drivers/crypto/qce/aead.c b/drivers/crypto/qce/aead.c index a9642c6..e0061bf 100644 --- a/drivers/crypto/qce/aead.c +++ b/drivers/crypto/qce/aead.c
@@ -379,7 +379,7 @@ static int qce_aead_create_ccm_nonce(struct qce_aead_reqctx *rctx, struct qce_ae /* * The crypto framework encodes cryptlen as unsigned int. Thus, even though - * spec allows for upto 8 bytes to encode msg_len only 4 bytes are needed. + * spec allows for up to 8 bytes to encode msg_len only 4 bytes are needed. */ if (msglen_size > 4) msglen_size = 4; @@ -769,14 +769,13 @@ static int qce_aead_register(struct qce_device *qce) for (i = 0; i < ARRAY_SIZE(aead_def); i++) { ret = qce_aead_register_one(&aead_def[i], qce); - if (ret) - goto err; + if (ret) { + qce_aead_unregister(qce); + return ret; + } } return 0; -err: - qce_aead_unregister(qce); - return ret; } const struct qce_algo_ops aead_ops = {
diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c index eb8a5b0..b67d749 100644 --- a/drivers/crypto/qce/sha.c +++ b/drivers/crypto/qce/sha.c
@@ -480,14 +480,13 @@ static int qce_ahash_register(struct qce_device *qce) for (i = 0; i < ARRAY_SIZE(ahash_def); i++) { ret = qce_ahash_register_one(&ahash_def[i], qce); - if (ret) - goto err; + if (ret) { + qce_ahash_unregister(qce); + return ret; + } } return 0; -err: - qce_ahash_unregister(qce); - return ret; } const struct qce_algo_ops ahash_ops = {
diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c index 4931b06..03a3cec 100644 --- a/drivers/crypto/qce/skcipher.c +++ b/drivers/crypto/qce/skcipher.c
@@ -416,14 +416,13 @@ static int qce_skcipher_register(struct qce_device *qce) for (i = 0; i < ARRAY_SIZE(skcipher_def); i++) { ret = qce_skcipher_register_one(&skcipher_def[i], qce); - if (ret) - goto err; + if (ret) { + qce_skcipher_unregister(qce); + return ret; + } } return 0; -err: - qce_skcipher_unregister(qce); - return ret; } const struct qce_algo_ops skcipher_ops = {
diff --git a/drivers/crypto/rockchip/rk3288_crypto.c b/drivers/crypto/rockchip/rk3288_crypto.c index 7cb1316..b2b629f 100644 --- a/drivers/crypto/rockchip/rk3288_crypto.c +++ b/drivers/crypto/rockchip/rk3288_crypto.c
@@ -163,7 +163,7 @@ static void rk_crypto_pm_exit(struct rk_crypto_info *rkdev) static irqreturn_t rk_crypto_irq_handle(int irq, void *dev_id) { - struct rk_crypto_info *dev = platform_get_drvdata(dev_id); + struct rk_crypto_info *dev = dev_id; u32 interrupt_status; interrupt_status = CRYPTO_READ(dev, RK_CRYPTO_INTSTS); @@ -363,7 +363,7 @@ static int rk_crypto_probe(struct platform_device *pdev) err = devm_request_irq(&pdev->dev, crypto_info->irq, rk_crypto_irq_handle, IRQF_SHARED, - "rk-crypto", pdev); + "rk-crypto", crypto_info); if (err) goto err_crypto;
diff --git a/drivers/crypto/s5p-sss.c b/drivers/crypto/s5p-sss.c index bdda7b3..a701027 100644 --- a/drivers/crypto/s5p-sss.c +++ b/drivers/crypto/s5p-sss.c
@@ -638,8 +638,7 @@ static int s5p_hash_rx(struct s5p_aes_dev *dev) static irqreturn_t s5p_aes_interrupt(int irq, void *dev_id) { - struct platform_device *pdev = dev_id; - struct s5p_aes_dev *dev = platform_get_drvdata(pdev); + struct s5p_aes_dev *dev = dev_id; struct skcipher_request *req; int err_dma_tx = 0; int err_dma_rx = 0; @@ -1446,7 +1445,7 @@ static void s5p_hash_tasklet_cb(unsigned long data) return; finish: - /* finish curent request */ + /* finish current request */ s5p_hash_finish_req(dd->hash_req, 0); /* If we are not busy, process next req */ @@ -2221,7 +2220,7 @@ static int s5p_aes_probe(struct platform_device *pdev) } err = devm_request_threaded_irq(dev, pdata->irq_fc, NULL, s5p_aes_interrupt, IRQF_ONESHOT, - pdev->name, pdev); + pdev->name, pdata); if (err < 0) { dev_warn(dev, "feed control interrupt is not available.\n"); goto err_irq;
diff --git a/drivers/crypto/sa2ul.c b/drivers/crypto/sa2ul.c index 9846cbe..4557eae 100644 --- a/drivers/crypto/sa2ul.c +++ b/drivers/crypto/sa2ul.c
@@ -125,9 +125,7 @@ struct sa_cmdl_cfg { * @mci_enc: Mode Control Instruction for Encryption algorithm * @mci_dec: Mode Control Instruction for Decryption * @inv_key: Whether the encryption algorithm demands key inversion - * @ctx: Pointer to the algorithm context * @keyed_mac: Whether the authentication algorithm has key - * @prep_iopad: Function pointer to generate intermediate ipad/opad */ struct algo_data { struct sa_eng_info enc_eng; @@ -141,10 +139,7 @@ struct algo_data { u8 *mci_enc; u8 *mci_dec; bool inv_key; - struct sa_tfm_ctx *ctx; bool keyed_mac; - void (*prep_iopad)(struct algo_data *algo, const u8 *key, - u16 key_sz, __be32 *ipad, __be32 *opad); }; /** @@ -381,92 +376,42 @@ static void sa_swiz_128(u8 *in, u16 len) } } -/* Prepare the ipad and opad from key as per SHA algorithm step 1*/ -static void prepare_kipad(u8 *k_ipad, const u8 *key, u16 key_sz) +static void sa_prepare_iopads(struct algo_data *data, const u8 *key, u16 key_sz, + __be32 *ipad, __be32 *opad) { - int i; + union { + struct hmac_sha1_key sha1; + struct hmac_sha256_key sha256; + } k; - for (i = 0; i < key_sz; i++) - k_ipad[i] = key[i] ^ 0x36; - - /* Instead of XOR with 0 */ - for (; i < SHA1_BLOCK_SIZE; i++) - k_ipad[i] = 0x36; -} - -static void prepare_kopad(u8 *k_opad, const u8 *key, u16 key_sz) -{ - int i; - - for (i = 0; i < key_sz; i++) - k_opad[i] = key[i] ^ 0x5c; - - /* Instead of XOR with 0 */ - for (; i < SHA1_BLOCK_SIZE; i++) - k_opad[i] = 0x5c; -} - -static void sa_export_shash(void *state, struct shash_desc *hash, - int digest_size, __be32 *out) -{ - struct sha1_state *sha1; - struct sha256_state *sha256; - u32 *result; - - switch (digest_size) { - case SHA1_DIGEST_SIZE: - sha1 = state; - result = sha1->state; + switch (data->aalg_id) { + case SA_AALG_ID_HMAC_SHA1: + hmac_sha1_preparekey(&k.sha1, key, key_sz); + cpu_to_be32_array(ipad, k.sha1.istate.h, + ARRAY_SIZE(k.sha1.istate.h)); + cpu_to_be32_array(opad, k.sha1.ostate.h, + ARRAY_SIZE(k.sha1.ostate.h)); break; - case SHA256_DIGEST_SIZE: - sha256 = state; - result = sha256->state; + case SA_AALG_ID_HMAC_SHA2_256: + hmac_sha256_preparekey(&k.sha256, key, key_sz); + cpu_to_be32_array(ipad, k.sha256.key.istate.h, + ARRAY_SIZE(k.sha256.key.istate.h)); + cpu_to_be32_array(opad, k.sha256.key.ostate.h, + ARRAY_SIZE(k.sha256.key.ostate.h)); break; default: - dev_err(sa_k3_dev, "%s: bad digest_size=%d\n", __func__, - digest_size); + dev_err(sa_k3_dev, "%s: bad aalg_id=%d\n", __func__, + data->aalg_id); return; } - crypto_shash_export(hash, state); - - cpu_to_be32_array(out, result, digest_size / 4); -} - -static void sa_prepare_iopads(struct algo_data *data, const u8 *key, - u16 key_sz, __be32 *ipad, __be32 *opad) -{ - SHASH_DESC_ON_STACK(shash, data->ctx->shash); - int block_size = crypto_shash_blocksize(data->ctx->shash); - int digest_size = crypto_shash_digestsize(data->ctx->shash); - union { - struct sha1_state sha1; - struct sha256_state sha256; - u8 k_pad[SHA1_BLOCK_SIZE]; - } sha; - - shash->tfm = data->ctx->shash; - - prepare_kipad(sha.k_pad, key, key_sz); - - crypto_shash_init(shash); - crypto_shash_update(shash, sha.k_pad, block_size); - sa_export_shash(&sha, shash, digest_size, ipad); - - prepare_kopad(sha.k_pad, key, key_sz); - - crypto_shash_init(shash); - crypto_shash_update(shash, sha.k_pad, block_size); - - sa_export_shash(&sha, shash, digest_size, opad); - - memzero_explicit(&sha, sizeof(sha)); + memzero_explicit(&k, sizeof(k)); } /* Derive the inverse key used in AES-CBC decryption operation */ static inline int sa_aes_inv_key(u8 *inv_key, const u8 *key, u16 key_sz) { - struct crypto_aes_ctx ctx; + struct crypto_aes_ctx ctx __cleanup(aes_zeroize_ctx); int key_pos; if (aes_expandkey(&ctx, key, key_sz)) { @@ -544,7 +489,7 @@ static void sa_set_sc_auth(struct algo_data *ad, const u8 *key, u16 key_sz, /* Copy the keys or ipad/opad */ if (ad->keyed_mac) - ad->prep_iopad(ad, key, key_sz, ipad, opad); + sa_prepare_iopads(ad, key, key_sz, ipad, opad); else { /* basic hash */ sc_buf[1] |= SA_BASIC_HASH; @@ -1443,7 +1388,6 @@ static int sa_sha_run(struct ahash_request *req) static int sa_sha_setup(struct sa_tfm_ctx *ctx, struct algo_data *ad) { - int bs = crypto_shash_blocksize(ctx->shash); int cmdl_len; struct sa_cmdl_cfg cfg; @@ -1451,7 +1395,6 @@ static int sa_sha_setup(struct sa_tfm_ctx *ctx, struct algo_data *ad) ad->auth_eng.eng_id = SA_ENG_ID_AM1; ad->auth_eng.sc_size = SA_CTX_AUTH_TYPE2_SZ; - memset(ctx->authkey, 0, bs); memset(&cfg, 0, sizeof(cfg)); cfg.aalg = ad->aalg_id; cfg.enc_eng_id = ad->enc_eng.eng_id; @@ -1494,12 +1437,6 @@ static int sa_sha_cra_init_alg(struct crypto_tfm *tfm, const char *alg_base) return ret; if (alg_base) { - ctx->shash = crypto_alloc_shash(alg_base, 0, 0); - if (IS_ERR(ctx->shash)) { - dev_err(sa_k3_dev, "base driver %s couldn't be loaded\n", - alg_base); - return PTR_ERR(ctx->shash); - } /* for fallback */ ctx->fallback.ahash = crypto_alloc_ahash(alg_base, 0, CRYPTO_ALG_ASYNC); @@ -1654,7 +1591,6 @@ static void sa_sha_cra_exit(struct crypto_tfm *tfm) if (crypto_tfm_alg_type(tfm) == CRYPTO_ALG_TYPE_AHASH) sa_free_ctx_info(&ctx->enc, data); - crypto_free_shash(ctx->shash); crypto_free_ahash(ctx->fallback.ahash); } @@ -1697,8 +1633,7 @@ static void sa_aead_dma_in_callback(void *data) aead_request_complete(req, err); } -static int sa_cra_init_aead(struct crypto_aead *tfm, const char *hash, - const char *fallback) +static int sa_cra_init_aead(struct crypto_aead *tfm, const char *fallback) { struct sa_tfm_ctx *ctx = crypto_aead_ctx(tfm); struct sa_crypto_data *data = dev_get_drvdata(sa_k3_dev); @@ -1707,12 +1642,6 @@ static int sa_cra_init_aead(struct crypto_aead *tfm, const char *hash, memzero_explicit(ctx, sizeof(*ctx)); ctx->dev_data = data; - ctx->shash = crypto_alloc_shash(hash, 0, CRYPTO_ALG_NEED_FALLBACK); - if (IS_ERR(ctx->shash)) { - dev_err(sa_k3_dev, "base driver %s couldn't be loaded\n", hash); - return PTR_ERR(ctx->shash); - } - ctx->fallback.aead = crypto_alloc_aead(fallback, 0, CRYPTO_ALG_NEED_FALLBACK); @@ -1744,14 +1673,12 @@ static int sa_cra_init_aead(struct crypto_aead *tfm, const char *hash, static int sa_cra_init_aead_sha1(struct crypto_aead *tfm) { - return sa_cra_init_aead(tfm, "sha1", - "authenc(hmac(sha1),cbc(aes))"); + return sa_cra_init_aead(tfm, "authenc(hmac(sha1),cbc(aes))"); } static int sa_cra_init_aead_sha256(struct crypto_aead *tfm) { - return sa_cra_init_aead(tfm, "sha256", - "authenc(hmac(sha256),cbc(aes))"); + return sa_cra_init_aead(tfm, "authenc(hmac(sha256),cbc(aes))"); } static void sa_exit_tfm_aead(struct crypto_aead *tfm) @@ -1759,7 +1686,6 @@ static void sa_exit_tfm_aead(struct crypto_aead *tfm) struct sa_tfm_ctx *ctx = crypto_aead_ctx(tfm); struct sa_crypto_data *data = dev_get_drvdata(sa_k3_dev); - crypto_free_shash(ctx->shash); crypto_free_aead(ctx->fallback.aead); sa_free_ctx_info(&ctx->enc, data); @@ -1785,7 +1711,6 @@ static int sa_aead_setkey(struct crypto_aead *authenc, if (key_idx >= 3) return -EINVAL; - ad->ctx = ctx; ad->enc_eng.eng_id = SA_ENG_ID_EM1; ad->enc_eng.sc_size = SA_CTX_ENC_TYPE1_SZ; ad->auth_eng.eng_id = SA_ENG_ID_AM1; @@ -1795,7 +1720,6 @@ static int sa_aead_setkey(struct crypto_aead *authenc, ad->inv_key = true; ad->keyed_mac = true; ad->ealg_id = SA_EALG_ID_AES_CBC; - ad->prep_iopad = sa_prepare_iopads; memset(&cfg, 0, sizeof(cfg)); cfg.enc = true;
diff --git a/drivers/crypto/sa2ul.h b/drivers/crypto/sa2ul.h index 12c17a6..211ef4e 100644 --- a/drivers/crypto/sa2ul.h +++ b/drivers/crypto/sa2ul.h
@@ -307,12 +307,9 @@ struct sa_tfm_ctx { struct sa_crypto_data *dev_data; struct sa_ctx_info enc; struct sa_ctx_info dec; - struct sa_ctx_info auth; int keylen; int iv_idx; u32 key[AES_KEYSIZE_256 / sizeof(u32)]; - u8 authkey[SHA512_BLOCK_SIZE]; - struct crypto_shash *shash; /* for fallback */ union { struct crypto_skcipher *skcipher;
diff --git a/drivers/crypto/starfive/jh7110-cryp.c b/drivers/crypto/starfive/jh7110-cryp.c index 842f76b..8562903 100644 --- a/drivers/crypto/starfive/jh7110-cryp.c +++ b/drivers/crypto/starfive/jh7110-cryp.c
@@ -120,9 +120,17 @@ static int starfive_cryp_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(cryp->rst), "Error getting hardware reset line\n"); - clk_prepare_enable(cryp->hclk); - clk_prepare_enable(cryp->ahb); - reset_control_deassert(cryp->rst); + ret = clk_prepare_enable(cryp->hclk); + if (ret) + return ret; + + ret = clk_prepare_enable(cryp->ahb); + if (ret) + goto disable_hclk; + + ret = reset_control_deassert(cryp->rst); + if (ret) + goto disable_ahb; spin_lock(&dev_list.lock); list_add(&cryp->list, &dev_list.dev_list); @@ -170,9 +178,11 @@ static int starfive_cryp_probe(struct platform_device *pdev) list_del(&cryp->list); spin_unlock(&dev_list.lock); - clk_disable_unprepare(cryp->hclk); - clk_disable_unprepare(cryp->ahb); reset_control_assert(cryp->rst); +disable_ahb: + clk_disable_unprepare(cryp->ahb); +disable_hclk: + clk_disable_unprepare(cryp->hclk); return ret; }
diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c index fa96b6b..c7d9ce2 100644 --- a/drivers/crypto/talitos.c +++ b/drivers/crypto/talitos.c
@@ -751,8 +751,7 @@ static void talitos_error(struct device *dev, u32 isr, u32 isr_lo) #define DEF_TALITOS1_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \ static irqreturn_t talitos1_interrupt_##name(int irq, void *data) \ { \ - struct device *dev = data; \ - struct talitos_private *priv = dev_get_drvdata(dev); \ + struct talitos_private *priv = data; \ u32 isr, isr_lo; \ unsigned long flags; \ \ @@ -765,7 +764,7 @@ static irqreturn_t talitos1_interrupt_##name(int irq, void *data) \ \ if (unlikely(isr & ch_err_mask || isr_lo & TALITOS1_IMR_LO_INIT)) { \ spin_unlock_irqrestore(&priv->reg_lock, flags); \ - talitos_error(dev, isr & ch_err_mask, isr_lo); \ + talitos_error(priv->dev, isr & ch_err_mask, isr_lo); \ } \ else { \ if (likely(isr & ch_done_mask)) { \ @@ -786,8 +785,7 @@ DEF_TALITOS1_INTERRUPT(4ch, TALITOS1_ISR_4CHDONE, TALITOS1_ISR_4CHERR, 0) #define DEF_TALITOS2_INTERRUPT(name, ch_done_mask, ch_err_mask, tlet) \ static irqreturn_t talitos2_interrupt_##name(int irq, void *data) \ { \ - struct device *dev = data; \ - struct talitos_private *priv = dev_get_drvdata(dev); \ + struct talitos_private *priv = data; \ u32 isr, isr_lo; \ unsigned long flags; \ \ @@ -800,7 +798,7 @@ static irqreturn_t talitos2_interrupt_##name(int irq, void *data) \ \ if (unlikely(isr & ch_err_mask || isr_lo)) { \ spin_unlock_irqrestore(&priv->reg_lock, flags); \ - talitos_error(dev, isr & ch_err_mask, isr_lo); \ + talitos_error(priv->dev, isr & ch_err_mask, isr_lo); \ } \ else { \ if (likely(isr & ch_done_mask)) { \ @@ -3242,7 +3240,7 @@ static void talitos_remove(struct platform_device *ofdev) for (i = 0; i < 2; i++) if (priv->irq[i] > 0) - free_irq(priv->irq[i], dev); + free_irq(priv->irq[i], priv); tasklet_kill(&priv->done_task[0]); if (priv->irq[1] > 0) @@ -3355,35 +3353,27 @@ static int talitos_probe_irq(struct platform_device *ofdev) int err; bool is_sec1 = has_ftr_sec1(priv); - priv->irq[0] = platform_get_irq(ofdev, 0); - if (priv->irq[0] < 0) - return priv->irq[0]; - if (is_sec1) { err = request_irq(priv->irq[0], talitos1_interrupt_4ch, 0, - dev_driver_string(dev), dev); + dev_driver_string(dev), priv); goto primary_out; } - priv->irq[1] = platform_get_irq_optional(ofdev, 1); - if (priv->irq[1] == -EPROBE_DEFER) - return priv->irq[1]; - - /* get the primary irq line */ + /* single (or primary) irq line */ if (priv->irq[1] < 0) { err = request_irq(priv->irq[0], talitos2_interrupt_4ch, 0, - dev_driver_string(dev), dev); + dev_driver_string(dev), priv); goto primary_out; } err = request_irq(priv->irq[0], talitos2_interrupt_ch0_2, 0, - dev_driver_string(dev), dev); + dev_driver_string(dev), priv); if (err) goto primary_out; - /* get the secondary irq line */ + /* secondary irq line */ err = request_irq(priv->irq[1], talitos2_interrupt_ch1_3, 0, - dev_driver_string(dev), dev); + dev_driver_string(dev), priv); if (err) { dev_err(dev, "failed to request secondary irq\n"); priv->irq[1] = 0; @@ -3394,7 +3384,9 @@ static int talitos_probe_irq(struct platform_device *ofdev) primary_out: if (err) { dev_err(dev, "failed to request primary irq\n"); + /* neither line is requested, keep remove() from freeing them */ priv->irq[0] = 0; + priv->irq[1] = 0; } return err; @@ -3406,12 +3398,27 @@ static int talitos_probe(struct platform_device *ofdev) struct device_node *np = ofdev->dev.of_node; struct talitos_private *priv; unsigned int num_channels; + void __iomem *reg; int i, err; int stride; + int irq0; + int irq1; if (of_property_read_u32(np, "fsl,num-channels", &num_channels)) return -EINVAL; + irq0 = platform_get_irq(ofdev, 0); + if (irq0 < 0) + return irq0; + + irq1 = platform_get_irq_optional(ofdev, 1); + if (irq1 == -EPROBE_DEFER) + return irq1; + + reg = devm_platform_ioremap_resource(ofdev, 0); + if (IS_ERR(reg)) + return PTR_ERR(reg); + priv = devm_kzalloc(dev, struct_size(priv, chan, num_channels), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -3422,16 +3429,12 @@ static int talitos_probe(struct platform_device *ofdev) dev_set_drvdata(dev, priv); + priv->dev = dev; priv->ofdev = ofdev; spin_lock_init(&priv->reg_lock); - priv->reg = devm_platform_ioremap_resource(ofdev, 0); - if (IS_ERR(priv->reg)) { - dev_err(dev, "failed to of_iomap\n"); - err = PTR_ERR(priv->reg); - goto err_out; - } + priv->reg = reg; /* get SEC version capabilities from device tree */ of_property_read_u32(np, "fsl,channel-fifo-len", &priv->chfifo_len); @@ -3482,9 +3485,7 @@ static int talitos_probe(struct platform_device *ofdev) stride = TALITOS2_CH_STRIDE; } - err = talitos_probe_irq(ofdev); - if (err) - goto err_out; + priv->irq[0] = irq0; if (has_ftr_sec1(priv)) { if (priv->num_channels == 1) @@ -3494,6 +3495,7 @@ static int talitos_probe(struct platform_device *ofdev) tasklet_init(&priv->done_task[0], talitos1_done_4ch, (unsigned long)dev); } else { + priv->irq[1] = irq1; if (priv->irq[1] > 0) { tasklet_init(&priv->done_task[0], talitos2_done_ch0_2, (unsigned long)dev); @@ -3525,7 +3527,7 @@ static int talitos_probe(struct platform_device *ofdev) if (!priv->chan[i].fifo) { dev_err(dev, "failed to allocate request fifo %d\n", i); err = -ENOMEM; - goto err_out; + goto err_noirq; } atomic_set(&priv->chan[i].submit_count, @@ -3538,9 +3540,14 @@ static int talitos_probe(struct platform_device *ofdev) err = init_device(dev); if (err) { dev_err(dev, "failed to initialize device\n"); - goto err_out; + goto err_noirq; } + /* enable interrupts once the channel fifos and tasklets are set up */ + err = talitos_probe_irq(ofdev); + if (err) + goto err_out; + /* register the RNG, if available */ if (hw_supports(dev, DESC_HDR_SEL0_RNG)) { err = talitos_register_rng(dev); @@ -3598,6 +3605,10 @@ static int talitos_probe(struct platform_device *ofdev) return 0; +err_noirq: + /* the irq numbers are known, but the lines are not requested yet */ + priv->irq[0] = 0; + priv->irq[1] = 0; err_out: talitos_remove(ofdev);
diff --git a/drivers/crypto/xilinx/zynqmp-aes-gcm.c b/drivers/crypto/xilinx/zynqmp-aes-gcm.c index d54c268..d9bd6dc 100644 --- a/drivers/crypto/xilinx/zynqmp-aes-gcm.c +++ b/drivers/crypto/xilinx/zynqmp-aes-gcm.c
@@ -230,10 +230,8 @@ static int zynqmp_aes_aead_cipher(struct aead_request *req) } freemem: - memzero_explicit(kbuf, dma_size); - kfree(kbuf); - memzero_explicit(dmabuf, sizeof(struct zynqmp_aead_hw_req) + GCM_AES_IV_SIZE); - kfree(dmabuf); + kfree_sensitive(kbuf); + kfree_sensitive(dmabuf); return ret; } @@ -364,11 +362,9 @@ static int versal_aes_aead_cipher(struct aead_request *req) if (unlikely(dma_addr_hw_req)) dma_unmap_single(dev, dma_addr_hw_req, dmabuf_size, DMA_BIDIRECTIONAL); buf2_free: - memzero_explicit(dmabuf, dmabuf_size); - kfree(dmabuf); + kfree_sensitive(dmabuf); buf1_free: - memzero_explicit(kbuf, kbuf_size); - kfree(kbuf); + kfree_sensitive(kbuf); err: return ret; } @@ -766,7 +762,7 @@ static void xilinx_aes_aead_exit(struct crypto_aead *aead) struct xilinx_aead_tfm_ctx *tfm_ctx = crypto_tfm_ctx(tfm); dma_unmap_single(tfm_ctx->dev, tfm_ctx->key_dma_addr, AES_KEYSIZE_256, DMA_TO_DEVICE); - kfree(tfm_ctx->key); + kfree_sensitive(tfm_ctx->key); if (tfm_ctx->fbk_cipher) { crypto_free_aead(tfm_ctx->fbk_cipher); tfm_ctx->fbk_cipher = NULL;
diff --git a/drivers/crypto/xilinx/zynqmp-sha.c b/drivers/crypto/xilinx/zynqmp-sha.c index 5813017..cd051e1 100644 --- a/drivers/crypto/xilinx/zynqmp-sha.c +++ b/drivers/crypto/xilinx/zynqmp-sha.c
@@ -59,7 +59,7 @@ static int zynqmp_sha_init_tfm(struct crypto_shash *hash) return PTR_ERR(fallback_tfm); if (crypto_shash_descsize(hash) < - crypto_shash_statesize(tfm_ctx->fbk_tfm)) { + crypto_shash_statesize(fallback_tfm)) { crypto_free_shash(fallback_tfm); return -EINVAL; }
diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index e060edb..2519719 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c
@@ -9,14 +9,15 @@ #include <linux/types.h> #include <linux/module.h> -#include <linux/of.h> +#include <linux/property.h> #include <linux/kernel.h> #include <linux/slab.h> +#include <linux/string.h> #include <linux/device.h> #include "common.h" -#define SCMI_UEVENT_MODALIAS_FMT "%s:%02x:%s" +#define SCMI_UEVENT_MODALIAS_FMT SCMI_MODULE_PREFIX "%02x:%s" BLOCKING_NOTIFIER_HEAD(scmi_requested_devices_nh); EXPORT_SYMBOL_GPL(scmi_requested_devices_nh); @@ -185,7 +186,7 @@ static int scmi_protocol_table_register(const struct scmi_device_id *id_table) const struct scmi_device_id *entry; int ret; - for (entry = id_table; entry->name; entry++) { + for (entry = id_table; entry->name[0]; entry++) { ret = scmi_protocol_device_request(entry); if (ret) goto err_unrequest; @@ -205,7 +206,7 @@ scmi_protocol_table_unregister(const struct scmi_device_id *id_table) { const struct scmi_device_id *entry; - for (entry = id_table; entry->name; entry++) + for (entry = id_table; entry->name[0]; entry++) scmi_protocol_device_unrequest(entry); } @@ -219,10 +220,10 @@ static int __scmi_dev_match_by_id_table(struct scmi_device *scmi_dev, const struct scmi_device_id *id_table, bool skip_transport) { - if (!id_table || !id_table->name) + if (!id_table || !id_table->name[0]) return 0; - for (; id_table->protocol_id && id_table->name; id_table++) + for (; id_table->protocol_id && id_table->name[0]; id_table++) if (id_table->protocol_id == scmi_dev->protocol_id && !(skip_transport && scmi_device_is_transport(scmi_dev)) && !strcmp(id_table->name, scmi_dev->name)) @@ -266,7 +267,7 @@ scmi_child_dev_find_get(struct device *parent, int prot_id, const char *name) struct device *dev; id_table[0].protocol_id = prot_id; - id_table[0].name = name; + strscpy(id_table[0].name, name, sizeof(id_table[0].name)); dev = device_find_child(parent, &id_table, scmi_match_by_id_table); if (!dev) @@ -300,8 +301,7 @@ static int scmi_device_uevent(const struct device *dev, struct kobj_uevent_env * const struct scmi_device *scmi_dev = to_scmi_dev(dev); return add_uevent_var(env, "MODALIAS=" SCMI_UEVENT_MODALIAS_FMT, - dev_name(&scmi_dev->dev), scmi_dev->protocol_id, - scmi_dev->name); + scmi_dev->protocol_id, scmi_dev->name); } static ssize_t modalias_show(struct device *dev, @@ -309,9 +309,8 @@ static ssize_t modalias_show(struct device *dev, { struct scmi_device *scmi_dev = to_scmi_dev(dev); - return sysfs_emit(buf, SCMI_UEVENT_MODALIAS_FMT, - dev_name(&scmi_dev->dev), scmi_dev->protocol_id, - scmi_dev->name); + return sysfs_emit(buf, SCMI_UEVENT_MODALIAS_FMT "\n", + scmi_dev->protocol_id, scmi_dev->name); } static DEVICE_ATTR_RO(modalias); @@ -429,17 +428,16 @@ static void scmi_device_release(struct device *dev) struct scmi_device *scmi_dev = to_scmi_dev(dev); scmi_device_release_resources(scmi_dev); - of_node_put(dev->of_node); + fwnode_handle_put(dev_fwnode(dev)); kfree_const(scmi_dev->name); kfree(scmi_dev); } static void __scmi_device_destroy(struct scmi_device *scmi_dev) { - pr_debug("(%pOF) Destroying SCMI device '%s' for protocol 0x%x (%s)\n", - scmi_dev->dev.parent->of_node, - dev_name(&scmi_dev->dev), scmi_dev->protocol_id, - scmi_dev->name); + pr_debug("(%pfwf) Destroying SCMI device '%s' for protocol 0x%x (%s)\n", + dev_fwnode(&scmi_dev->dev), dev_name(&scmi_dev->dev), + scmi_dev->protocol_id, scmi_dev->name); device_del(&scmi_dev->dev); scmi_device_release_resources(scmi_dev); @@ -447,7 +445,7 @@ static void __scmi_device_destroy(struct scmi_device *scmi_dev) } static struct scmi_device * -__scmi_device_create(struct device_node *np, struct device *parent, +__scmi_device_create(struct fwnode_handle *fwnode, struct device *parent, int protocol, const char *name) { int id, retval; @@ -458,7 +456,7 @@ __scmi_device_create(struct device_node *np, struct device *parent, * If the same protocol/name device already exist under the same parent * (i.e. SCMI instance) just return the existent device. * This avoids any race between the SCMI driver, creating devices for - * each DT defined protocol at probe time, and the concurrent + * each fwnode defined protocol at probe time, and the concurrent * registration of SCMI drivers. */ scmi_dev = scmi_child_dev_find_get(parent, protocol, name); @@ -495,7 +493,7 @@ __scmi_device_create(struct device_node *np, struct device *parent, scmi_dev->id = id; scmi_dev->dev.parent = parent; - device_set_node(&scmi_dev->dev, of_fwnode_handle(of_node_get(np))); + device_set_node(&scmi_dev->dev, fwnode_handle_get(fwnode)); scmi_dev->dev.bus = &scmi_bus_type; scmi_dev->dev.release = scmi_device_release; dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id); @@ -504,8 +502,8 @@ __scmi_device_create(struct device_node *np, struct device *parent, if (retval) goto put_dev; - pr_debug("(%pOF) Created SCMI device '%s' for protocol 0x%x (%s)\n", - parent->of_node, dev_name(&scmi_dev->dev), protocol, name); + pr_debug("(%pfwf) Created SCMI device '%s' - protocol 0x%x (%s)\n", + fwnode, dev_name(&scmi_dev->dev), protocol, name); return scmi_dev; put_dev: @@ -521,23 +519,51 @@ __scmi_device_create(struct device_node *np, struct device *parent, } static struct scmi_device * -_scmi_device_create(struct device_node *np, struct device *parent, +_scmi_device_create(struct fwnode_handle *fwnode, struct device *parent, int protocol, const char *name) { struct scmi_device *sdev; - sdev = __scmi_device_create(np, parent, protocol, name); + sdev = __scmi_device_create(fwnode, parent, protocol, name); if (!sdev) - pr_err("(%pOF) Failed to create device for protocol 0x%x (%s)\n", - parent->of_node, protocol, name); + pr_err("(%pfwf) Failed to create device - protocol 0x%x (%s)\n", + fwnode, protocol, name); return sdev; } +/* Standard protocols table */ +static const struct scmi_device_id scmi_std_id_table[] = { + { SCMI_PROTOCOL_POWER, "genpd" }, + { SCMI_PROTOCOL_SYSTEM, "syspower" }, + { SCMI_PROTOCOL_PERF, "perf" }, + { SCMI_PROTOCOL_PERF, "cpufreq" }, + { SCMI_PROTOCOL_CLOCK, "clocks" }, + { SCMI_PROTOCOL_SENSOR, "hwmon" }, + { SCMI_PROTOCOL_SENSOR, "iiodev" }, + { SCMI_PROTOCOL_RESET, "reset" }, + { SCMI_PROTOCOL_VOLTAGE, "regulator" }, + { SCMI_PROTOCOL_POWERCAP, "powercap" }, + { SCMI_PROTOCOL_PINCTRL, "pinctrl" }, + { SCMI_PROTOCOL_PINCTRL, "pinctrl-imx" }, + { }, +}; + +static bool scmi_device_id_in_std_id_table(const struct scmi_device_id *id) +{ + for (int i = 0; scmi_std_id_table[i].name[0]; i++) { + if (scmi_std_id_table[i].protocol_id == id->protocol_id && + !strcmp(scmi_std_id_table[i].name, id->name)) + return true; + } + + return false; +} + /** * scmi_device_create - A method to create one or more SCMI devices * - * @np: A reference to the device node to use for the new device(s) + * @fwnode: A reference to the device node to use for the new device(s) * @parent: The parent device to use identifying a specific SCMI instance * @protocol: The SCMI protocol to be associated with this device * @name: The requested-name of the device to be created; this is optional @@ -557,30 +583,47 @@ _scmi_device_create(struct device_node *np, struct device *parent, * could have been potentially created for a whole protocol, unless no * device was found to have been requested for that specific protocol. */ -struct scmi_device *scmi_device_create(struct device_node *np, +struct scmi_device *scmi_device_create(struct fwnode_handle *fwnode, struct device *parent, int protocol, const char *name) { struct list_head *phead; struct scmi_requested_dev *rdev; - struct scmi_device *scmi_dev = NULL; + struct scmi_device *sdev, *scmi_dev = NULL; if (name) - return _scmi_device_create(np, parent, protocol, name); + return _scmi_device_create(fwnode, parent, protocol, name); + + /* + * Always create devices for standard protocols, even if the device-ids + * have not been registered into scmi_requested_devices yet. This allows + * auto-loading of SCMI protocol driver modules for standard protocols. + */ + for (int i = 0; scmi_std_id_table[i].name[0]; i++) { + if (scmi_std_id_table[i].protocol_id != protocol) + continue; + + sdev = _scmi_device_create(fwnode, parent, protocol, + scmi_std_id_table[i].name); + if (sdev) + scmi_dev = sdev; + } mutex_lock(&scmi_requested_devices_mtx); phead = idr_find(&scmi_requested_devices, protocol); /* Nothing to do. */ if (!phead) { mutex_unlock(&scmi_requested_devices_mtx); - return NULL; + return scmi_dev; } /* Walk the list of requested devices for protocol and create them */ list_for_each_entry(rdev, phead, node) { - struct scmi_device *sdev; + /* Standard proto matches already have their dev created above */ + if (scmi_device_id_in_std_id_table(rdev->id_table)) + continue; - sdev = _scmi_device_create(np, parent, + sdev = _scmi_device_create(fwnode, parent, rdev->id_table->protocol_id, rdev->id_table->name); if (sdev)
diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index fe8c22c..af5b025 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h
@@ -9,6 +9,7 @@ #ifndef _SCMI_COMMON_H #define _SCMI_COMMON_H +#include <linux/acpi.h> #include <linux/bitfield.h> #include <linux/completion.h> #include <linux/device.h> @@ -152,7 +153,7 @@ extern const struct bus_type scmi_bus_type; #define SCMI_BUS_NOTIFY_DEVICE_UNREQUEST 1 extern struct blocking_notifier_head scmi_requested_devices_nh; -struct scmi_device *scmi_device_create(struct device_node *np, +struct scmi_device *scmi_device_create(struct fwnode_handle *fwnode, struct device *parent, int protocol, const char *name); void scmi_device_destroy(struct device *parent, int protocol, const char *name); @@ -206,7 +207,8 @@ struct scmi_chan_info { * @poll_done: Callback to poll transfer status */ struct scmi_transport_ops { - bool (*chan_available)(struct device_node *of_node, int idx); + bool (*chan_available)(struct fwnode_handle *fwnode, int prot_id, + int idx); int (*chan_setup)(struct scmi_chan_info *cinfo, struct device *dev, bool tx); int (*chan_free)(int id, void *p, void *data); @@ -232,7 +234,7 @@ struct scmi_transport_ops { * be pending simultaneously in the system. May be overridden by the * get_max_msg op. * @max_msg_size: Maximum size of data payload per message that can be handled. - * @atomic_threshold: Optional system wide DT-configured threshold, expressed + * @atomic_threshold: Optional system wide fwnode-configured threshold, expressed * in microseconds, for atomic operations. * Only SCMI synchronous commands reported by the platform * to have an execution latency lesser-equal to the threshold @@ -240,7 +242,8 @@ struct scmi_transport_ops { * decision is finally left up to the SCMI drivers. * @no_completion_irq: Flag to indicate that this transport has no completion * interrupt and has to be polled. This is similar to the - * force_polling below, except this is set via DT property. + * force_polling below, except this is set via fwnode + * property. * @force_polling: Flag to force this whole transport to use SCMI core polling * mechanism instead of completion interrupts even if available. * @sync_cmds_completed_on_ret: Flag to indicate that the transport assures @@ -284,6 +287,28 @@ static inline bool is_polling_enabled(struct scmi_chan_info *cinfo, is_transport_polling_capable(desc); } +/** + * scmi_xfer_async_response_arm - Arm the delayed response completion + * + * @xfer: A reference to the xfer to arm + * @async_done: The completion to signal upon reception of a delayed response, + * or NULL to disarm @xfer. + */ +static inline void scmi_xfer_async_response_arm(struct scmi_xfer *xfer, + struct completion *async_done) +{ + unsigned long flags; + + spin_lock_irqsave(&xfer->lock, flags); + xfer->async_done = async_done; + spin_unlock_irqrestore(&xfer->lock, flags); +} + +static inline void scmi_xfer_async_response_disarm(struct scmi_xfer *xfer) +{ + scmi_xfer_async_response_arm(xfer, NULL); +} + void scmi_xfer_raw_put(const struct scmi_handle *handle, struct scmi_xfer *xfer); struct scmi_xfer *scmi_xfer_raw_get(const struct scmi_handle *handle); @@ -465,6 +490,17 @@ struct scmi_transport_core_operations { const struct scmi_message_operations *msg; }; +struct scmi_dsd_info { + u32 protocol_id; + const char *const property_name; +}; + +static const struct scmi_dsd_info scmi_dsd_info_list[] __maybe_unused = { + { SCMI_PROTOCOL_BASE, "arm-arml0001-transport-pcc" }, + { SCMI_PROTOCOL_POWERCAP, "arm-arml0001-protocol-pcap" }, + { SCMI_PROTOCOL_TELEMETRY, "arm-arml0001-protocol-telemetry" }, +}; + /** * struct scmi_transport_handle - Transport instance handle * @supplier_get: A helper to retrieve the device descriptor, identifying the @@ -615,7 +651,8 @@ struct scmi_transport_supplier __supplier = { \ .th.supplier_put = scmi_transport_supplier_put, \ } -#define DEFINE_SCMI_TRANSPORT_DRIVER(__tag, __drv, __desc, __match, __core_ops)\ +#define __DEFINE_SCMI_TRANSPORT_DRIVER(__tag, __drv, __desc, __of_match, \ + __acpi_match, __core_ops) \ static void __tag##_dev_free(void *data) \ { \ struct platform_device *spdev = data; \ @@ -649,7 +686,10 @@ static int __tag##_probe(struct platform_device *pdev) \ goto err_mem; \ } \ \ - device_set_of_node_from_dev(&spdev->dev, dev); \ + if (dev_of_node(dev)) \ + platform_device_set_of_node_from_dev(spdev, dev); \ + else \ + platform_device_set_fwnode(spdev, dev_fwnode(dev)); \ \ strans.supplier = supplier; \ memcpy(&strans.desc, &(__desc), sizeof(strans.desc)); \ @@ -678,11 +718,18 @@ err_mem: \ static struct platform_driver __drv = { \ .driver = { \ .name = #__tag "_transport", \ - .of_match_table = __match, \ + .of_match_table = __of_match, \ + .acpi_match_table = ACPI_PTR(__acpi_match), \ }, \ .probe = __tag##_probe, \ } +#define DEFINE_SCMI_TRANSPORT_DRIVER(__tag, __drv, __desc, __match, __core_ops)\ + __DEFINE_SCMI_TRANSPORT_DRIVER(__tag, __drv, __desc, __match, NULL, __core_ops) + +#define DEFINE_SCMI_ACPI_TRANSPORT_DRIVER(__tag, __drv, __desc, __match, __core_ops)\ + __DEFINE_SCMI_TRANSPORT_DRIVER(__tag, __drv, __desc, NULL, __match, __core_ops) + void scmi_notification_instance_data_set(const struct scmi_handle *handle, void *priv); void *scmi_notification_instance_data_get(const struct scmi_handle *handle);
diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index a666ad3..1e6f69b 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c
@@ -16,6 +16,7 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt +#include <linux/acpi.h> #include <linux/bitmap.h> #include <linux/cleanup.h> #include <linux/debugfs.h> @@ -30,7 +31,7 @@ #include <linux/hashtable.h> #include <linux/list.h> #include <linux/module.h> -#include <linux/of.h> +#include <linux/property.h> #include <linux/platform_device.h> #include <linux/processor.h> #include <linux/rcupdate.h> @@ -102,7 +103,7 @@ struct scmi_xfers_info { * initialization code to identify this instance. * * Each protocol is initialized independently once for each SCMI platform in - * which is defined by DT and implemented by the SCMI server fw. + * which is defined by fwnode and implemented by the SCMI server fw. */ struct scmi_protocol_instance { const struct scmi_handle *handle; @@ -137,8 +138,9 @@ struct scmi_protocol_instance { * @protocols_imp: List of protocols implemented, currently maximum of * scmi_base_info.num_protocols elements allocated by the * base protocol - * @active_protocols: IDR storing device_nodes for protocols actually defined - * in the DT and confirmed as implemented by fw. + * @active_protocols: IDR storing fwnodes for protocols actually defined + * in the firmware description and confirmed as implemented + * by fw. * @notify_priv: Pointer to private data structure specific to notifications. * @node: List head * @users: Number of users of this instance @@ -416,19 +418,19 @@ EXPORT_SYMBOL_GPL(scmi_protocol_unregister); * scmi_create_protocol_devices - Create devices for all pending requests for * this SCMI instance. * - * @np: The device node describing the protocol + * @fwnode: The firmware node describing the protocol * @info: The SCMI instance descriptor * @prot_id: The protocol ID * @name: The optional name of the device to be created: if not provided this * call will lead to the creation of all the devices currently requested * for the specified protocol. */ -static void scmi_create_protocol_devices(struct device_node *np, +static void scmi_create_protocol_devices(struct fwnode_handle *fwnode, struct scmi_info *info, int prot_id, const char *name) { mutex_lock(&info->devreq_mtx); - scmi_device_create(np, info->dev, prot_id, name); + scmi_device_create(fwnode, info->dev, prot_id, name); mutex_unlock(&info->devreq_mtx); } @@ -718,6 +720,7 @@ static struct scmi_xfer *scmi_xfer_get(const struct scmi_handle *handle, refcount_set(&xfer->users, 1); atomic_set(&xfer->busy, SCMI_XFER_FREE); + xfer->async_done = NULL; spin_unlock_irqrestore(&minfo->xfer_lock, flags); return xfer; @@ -752,9 +755,10 @@ struct scmi_xfer *scmi_xfer_raw_get(const struct scmi_handle *handle) * @protocol_id: Identifier of the protocol * * Note that in a regular SCMI stack, usually, a protocol has to be defined in - * the DT to have an associated channel and be usable; but in Raw mode any - * protocol in range is allowed, re-using the Base channel, so as to enable - * fuzzing on any protocol without the need of a fully compiled DT. + * the firmware description to have an associated channel and be usable; but in + * Raw mode any protocol in range is allowed, re-using the Base channel, so as + * to enable fuzzing on any protocol without the need of a fully compiled + * firmware description. * * Return: A reference to the channel to use, or an ERR_PTR */ @@ -768,7 +772,7 @@ scmi_xfer_raw_channel_get(const struct scmi_handle *handle, u8 protocol_id) if (!cinfo) { if (protocol_id == SCMI_PROTOCOL_BASE) return ERR_PTR(-EINVAL); - /* Use Base channel for protocols not defined for DT */ + /* Use Base channel for protocols not defined for fwnode */ cinfo = idr_find(&info->tx_idr, SCMI_PROTOCOL_BASE); if (!cinfo) return ERR_PTR(-EINVAL); @@ -1064,6 +1068,29 @@ static inline void scmi_xfer_command_release(struct scmi_info *info, __scmi_xfer_put(&info->tx_minfo, xfer); } +/** + * scmi_xfer_async_response_complete - Signal a received delayed response + * + * @xfer: A reference to the xfer whose delayed response was received + * + * Return: True if a completion was still armed on @xfer and has been + * signalled, false if a waiter has already disarmed it due to + * timeout or other error. + */ +static bool scmi_xfer_async_response_complete(struct scmi_xfer *xfer) +{ + unsigned long flags; + struct completion *async_done; + + spin_lock_irqsave(&xfer->lock, flags); + async_done = xfer->async_done; + if (async_done) + complete(async_done); + spin_unlock_irqrestore(&xfer->lock, flags); + + return !!async_done; +} + static inline void scmi_clear_channel(struct scmi_info *info, struct scmi_chan_info *cinfo) { @@ -1167,8 +1194,12 @@ static void scmi_handle_response(struct scmi_chan_info *cinfo, if (xfer->hdr.type == MSG_TYPE_DELAYED_RESP) { scmi_clear_channel(info, cinfo); - complete(xfer->async_done); - scmi_inc_count(info->dbg, DELAYED_RESPONSE_OK); + if (scmi_xfer_async_response_complete(xfer)) + scmi_inc_count(info->dbg, DELAYED_RESPONSE_OK); + else + dev_err(cinfo->dev, + "Delayed Response for %d (protocol 0x%X msg 0x%X) received after waiter was disarmed, dropping\n", + xfer->hdr.seq, xfer->hdr.protocol_id, xfer->hdr.id); } else { complete(&xfer->done); scmi_inc_count(info->dbg, RESPONSE_OK); @@ -1510,7 +1541,7 @@ static int do_xfer_with_response(const struct scmi_protocol_handle *ph, int ret, timeout = msecs_to_jiffies(SCMI_MAX_RESPONSE_TIMEOUT); DECLARE_COMPLETION_ONSTACK(async_response); - xfer->async_done = &async_response; + scmi_xfer_async_response_arm(xfer, &async_response); /* * Delayed responses should not be polled, so an async command should @@ -1522,7 +1553,7 @@ static int do_xfer_with_response(const struct scmi_protocol_handle *ph, ret = do_xfer(ph, xfer); if (!ret) { - if (!wait_for_completion_timeout(xfer->async_done, timeout)) { + if (!wait_for_completion_timeout(&async_response, timeout)) { dev_err(ph->dev, "timed out in delayed resp(caller: %pS)\n", (void *)_RET_IP_); @@ -1532,7 +1563,7 @@ static int do_xfer_with_response(const struct scmi_protocol_handle *ph, } } - xfer->async_done = NULL; + scmi_xfer_async_response_disarm(xfer); return ret; } @@ -2749,7 +2780,7 @@ static int scmi_xfer_info_init(struct scmi_info *sinfo) return ret; } -static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node, +static int scmi_chan_setup(struct scmi_info *info, struct fwnode_handle *fwnode, int prot_id, bool tx) { int ret, idx; @@ -2765,7 +2796,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node, if (idr_find(idr, prot_id)) return -EEXIST; - if (!info->desc->ops->chan_available(of_node, idx)) { + if (!info->desc->ops->chan_available(fwnode, prot_id, idx)) { cinfo = idr_find(idr, SCMI_PROTOCOL_BASE); if (unlikely(!cinfo)) /* Possible only if platform has no Rx */ return -EINVAL; @@ -2785,7 +2816,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node, snprintf(name, sizeof(name), SCMI_TRANSPORT_DEVNAME_PREFIX "_%s_%02X", idx ? "rx" : "tx", prot_id); /* Create a uniquely named, dedicated transport device for this chan */ - tdev = scmi_device_create(of_node, info->dev, prot_id, name); + tdev = scmi_device_create(fwnode, info->dev, prot_id, name); if (!tdev) { dev_err(info->dev, "failed to create transport device (%s)\n", name); @@ -2831,14 +2862,14 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node, } static inline int -scmi_txrx_setup(struct scmi_info *info, struct device_node *of_node, +scmi_txrx_setup(struct scmi_info *info, struct fwnode_handle *fwnode, int prot_id) { - int ret = scmi_chan_setup(info, of_node, prot_id, true); + int ret = scmi_chan_setup(info, fwnode, prot_id, true); if (!ret) { /* Rx is optional, report only memory errors */ - ret = scmi_chan_setup(info, of_node, prot_id, false); + ret = scmi_chan_setup(info, fwnode, prot_id, false); if (ret && ret != -ENOMEM) ret = 0; } @@ -2855,44 +2886,57 @@ scmi_txrx_setup(struct scmi_info *info, struct device_node *of_node, * * @info: The SCMI instance descriptor. * - * Initialize all the channels found described in the DT against the underlying - * configured transport using custom defined dedicated devices instead of - * borrowing devices from the SCMI drivers; this way channels are initialized + * Initialize all the channels found described in the fwnode against the + * underlying configured transport using custom defined dedicated devices instead + * of borrowing devices from the SCMI drivers; this way channels are initialized * upfront during core SCMI stack probing and are no more coupled with SCMI * devices used by SCMI drivers. * * Note that, even though a pair of TX/RX channels is associated to each - * protocol defined in the DT, a distinct freshly initialized channel is - * created only if the DT node for the protocol at hand describes a dedicated + * protocol defined in the fwnode, a distinct freshly initialized channel is + * created only if the fwnode for the protocol at hand describes a dedicated * channel: in all the other cases the common BASE protocol channel is reused. * * Return: 0 on Success */ static int scmi_channels_setup(struct scmi_info *info) { - int ret; - struct device_node *top_np = info->dev->of_node; + int ret, idx; + struct fwnode_handle *fwnode = dev_fwnode(info->dev); /* Initialize a common generic channel at first */ - ret = scmi_txrx_setup(info, top_np, SCMI_PROTOCOL_BASE); + ret = scmi_txrx_setup(info, fwnode, SCMI_PROTOCOL_BASE); if (ret) return ret; - for_each_available_child_of_node_scoped(top_np, child) { - u32 prot_id; + if (!is_acpi_node(fwnode)) { + fwnode_for_each_available_child_node_scoped(fwnode, child) { + u32 prot_id; - if (of_property_read_u32(child, "reg", &prot_id)) - continue; + if (fwnode_property_read_u32(child, "reg", &prot_id)) + continue; - if (!FIELD_FIT(MSG_PROTOCOL_ID_MASK, prot_id)) { - dev_err(info->dev, - "Out of range protocol %d\n", prot_id); - continue; + if (!FIELD_FIT(MSG_PROTOCOL_ID_MASK, prot_id)) { + dev_err(info->dev, + "Out of range protocol %d\n", prot_id); + continue; + } + + ret = scmi_txrx_setup(info, child, prot_id); + if (ret) + return ret; } + } else { + for (idx = 0; idx < ARRAY_SIZE(scmi_dsd_info_list); idx++) { + int prot_id = scmi_dsd_info_list[idx].protocol_id; - ret = scmi_txrx_setup(info, child, prot_id); - if (ret) - return ret; + if (prot_id == SCMI_PROTOCOL_BASE) + continue; + + ret = scmi_txrx_setup(info, fwnode, prot_id); + if (ret) + return ret; + } } return 0; @@ -2969,14 +3013,14 @@ static int scmi_bus_notifier(struct notifier_block *nb, static int scmi_device_request_notifier(struct notifier_block *nb, unsigned long action, void *data) { - struct device_node *np; + struct fwnode_handle *fwnode; struct scmi_device_id *id_table = data; struct scmi_info *info = req_nb_to_scmi_info(nb); rcu_read_lock(); - np = idr_find(&info->active_protocols, id_table->protocol_id); + fwnode = idr_find(&info->active_protocols, id_table->protocol_id); rcu_read_unlock(); - if (!np) + if (!fwnode) return NOTIFY_DONE; dev_dbg(info->dev, "%sRequested device (%s) for protocol 0x%x\n", @@ -2985,7 +3029,7 @@ static int scmi_device_request_notifier(struct notifier_block *nb, switch (action) { case SCMI_BUS_NOTIFY_DEVICE_REQUEST: - scmi_create_protocol_devices(np, info, id_table->protocol_id, + scmi_create_protocol_devices(fwnode, info, id_table->protocol_id, id_table->name); break; case SCMI_BUS_NOTIFY_DEVICE_UNREQUEST: @@ -3061,6 +3105,15 @@ static void scmi_debugfs_common_cleanup(void *d) kfree(dbg->type); } +static const char *scmi_acpi_device_hid(struct acpi_device *adev) +{ +#ifdef CONFIG_ACPI + return adev ? acpi_device_hid(adev) : "unknown"; +#else + return "unknown"; +#endif +} + static struct scmi_debug_info *scmi_debugfs_common_setup(struct scmi_info *info) { char top_dir[16]; @@ -3072,13 +3125,16 @@ static struct scmi_debug_info *scmi_debugfs_common_setup(struct scmi_info *info) if (!dbg) return NULL; - dbg->name = kstrdup(of_node_full_name(info->dev->of_node), GFP_KERNEL); + dbg->name = kstrdup(fwnode_get_name(dev_fwnode(info->dev)), GFP_KERNEL); if (!dbg->name) { devm_kfree(info->dev, dbg); return NULL; } - of_property_read_string(info->dev->of_node, "compatible", &c_ptr); + if (fwnode_property_read_string(dev_fwnode(info->dev), "compatible", + &c_ptr)) + c_ptr = scmi_acpi_device_hid(ACPI_COMPANION(info->dev)); + dbg->type = kstrdup(c_ptr, GFP_KERNEL); if (!dbg->type) { kfree(dbg->name); @@ -3184,23 +3240,23 @@ static const struct scmi_desc *scmi_transport_setup(struct device *dev) dev_info(dev, "Using %s\n", dev_driver_string(trans->supplier)); - ret = of_property_read_u32(dev->of_node, "arm,max-rx-timeout-ms", - &trans->desc.max_rx_timeout_ms); + ret = fwnode_property_read_u32(dev_fwnode(dev), "arm,max-rx-timeout-ms", + &trans->desc.max_rx_timeout_ms); if (ret && ret != -EINVAL) - dev_err(dev, "Malformed arm,max-rx-timeout-ms DT property.\n"); + dev_err(dev, "Malformed arm,max-rx-timeout-ms property.\n"); - ret = of_property_read_u32(dev->of_node, "arm,max-msg-size", - &trans->desc.max_msg_size); + ret = fwnode_property_read_u32(dev_fwnode(dev), "arm,max-msg-size", + &trans->desc.max_msg_size); if (ret && ret != -EINVAL) - dev_err(dev, "Malformed arm,max-msg-size DT property.\n"); + dev_err(dev, "Malformed arm,max-msg-size property.\n"); - ret = of_property_read_u32(dev->of_node, "arm,max-msg", - &trans->desc.max_msg); + ret = fwnode_property_read_u32(dev_fwnode(dev), "arm,max-msg", + &trans->desc.max_msg); if (ret && ret != -EINVAL) - dev_err(dev, "Malformed arm,max-msg DT property.\n"); + dev_err(dev, "Malformed arm,max-msg property.\n"); - trans->desc.no_completion_irq = of_property_read_bool(dev->of_node, - "arm,no-completion-irq"); + trans->desc.no_completion_irq = + fwnode_property_read_bool(dev_fwnode(dev), "arm,no-completion-irq"); dev_info(dev, "SCMI max-rx-timeout: %dms / max-msg-size: %dbytes / max-msg: %d\n", @@ -3208,8 +3264,8 @@ static const struct scmi_desc *scmi_transport_setup(struct device *dev) trans->desc.max_msg); /* System wide atomic threshold for atomic ops .. if any */ - if (!of_property_read_u32(dev->of_node, "atomic-threshold-us", - &trans->desc.atomic_threshold)) + if (!fwnode_property_read_u32(dev_fwnode(dev), "atomic-threshold-us", + &trans->desc.atomic_threshold)) dev_info(dev, "SCMI System wide atomic threshold set to %u us\n", trans->desc.atomic_threshold); @@ -3229,16 +3285,52 @@ static void scmi_enable_matching_quirks(struct scmi_info *info) rev->sub_vendor_id, rev->impl_ver); } -static int scmi_probe(struct platform_device *pdev) +static void scmi_device_check_create(struct fwnode_handle *fwnode, int prot_id, + struct scmi_info *info, bool report_missing) { int ret; + struct device *dev = info->dev; + struct scmi_handle *handle = &info->handle; + + if (!FIELD_FIT(MSG_PROTOCOL_ID_MASK, prot_id)) { + dev_err(dev, "Out of range protocol %d\n", prot_id); + return; + } + + if (!scmi_is_protocol_implemented(handle, prot_id)) { + if (!report_missing) + return; + + dev_err(dev, "SCMI protocol %d not implemented\n", prot_id); + return; + } + + /* + * Save this valid fwnode protocol descriptor amongst + * @active_protocols for this SCMI instance. + */ + ret = idr_alloc(&info->active_protocols, fwnode, + prot_id, prot_id + 1, GFP_KERNEL); + if (ret != prot_id) { + dev_err(dev, "SCMI protocol %d already activated. Skip\n", + prot_id); + return; + } + + scmi_create_protocol_devices(fwnode_handle_get(fwnode), info, prot_id, + NULL); +} + +static int scmi_probe(struct platform_device *pdev) +{ + int ret, idx; char *err_str = "probe failure\n"; struct scmi_handle *handle; const struct scmi_desc *desc; struct scmi_info *info; bool coex = IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX); struct device *dev = &pdev->dev; - struct device_node *child, *np = dev->of_node; + struct fwnode_handle *child; desc = scmi_transport_setup(dev); if (!desc) { @@ -3277,7 +3369,7 @@ static int scmi_probe(struct platform_device *pdev) handle->devm_protocol_put = scmi_devm_protocol_put; handle->is_transport_atomic = scmi_is_transport_atomic; - /* Setup all channels described in the DT at first */ + /* Setup all channels described in the fwnode at first */ ret = scmi_channels_setup(info); if (ret) { err_str = "failed to setup channels\n"; @@ -3352,37 +3444,25 @@ static int scmi_probe(struct platform_device *pdev) scmi_enable_matching_quirks(info); - for_each_available_child_of_node(np, child) { - u32 prot_id; + if (!is_acpi_node(dev_fwnode(dev))) { + fwnode_for_each_available_child_node(dev_fwnode(dev), child) { + u32 prot_id; - if (of_property_read_u32(child, "reg", &prot_id)) - continue; + if (fwnode_property_read_u32(child, "reg", &prot_id)) + continue; - if (!FIELD_FIT(MSG_PROTOCOL_ID_MASK, prot_id)) { - dev_err(dev, "Out of range protocol %d\n", prot_id); - continue; + scmi_device_check_create(child, prot_id, info, true); } + } else { + for (idx = 0; idx < ARRAY_SIZE(scmi_dsd_info_list); idx++) { + int prot_id = scmi_dsd_info_list[idx].protocol_id; - if (!scmi_is_protocol_implemented(handle, prot_id)) { - dev_err(dev, "SCMI protocol %d not implemented\n", - prot_id); - continue; + if (prot_id == SCMI_PROTOCOL_BASE) + continue; + + scmi_device_check_create(dev_fwnode(dev), prot_id, + info, false); } - - /* - * Save this valid DT protocol descriptor amongst - * @active_protocols for this SCMI instance/ - */ - ret = idr_alloc(&info->active_protocols, child, - prot_id, prot_id + 1, GFP_KERNEL); - if (ret != prot_id) { - dev_err(dev, "SCMI protocol %d already activated. Skip\n", - prot_id); - continue; - } - - of_node_get(child); - scmi_create_protocol_devices(child, info, prot_id, NULL); } return 0; @@ -3409,7 +3489,7 @@ static void scmi_remove(struct platform_device *pdev) { int id; struct scmi_info *info = platform_get_drvdata(pdev); - struct device_node *child; + struct fwnode_handle *child; if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) scmi_raw_mode_cleanup(info->raw); @@ -3434,7 +3514,7 @@ static void scmi_remove(struct platform_device *pdev) mutex_unlock(&info->protocols_mtx); idr_for_each_entry(&info->active_protocols, child, id) - of_node_put(child); + fwnode_handle_put(child); idr_destroy(&info->active_protocols); bus_unregister_notifier(&scmi_bus_type, &info->bus_nb);
diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h index 15ad516..85831590 100644 --- a/drivers/firmware/arm_scmi/protocols.h +++ b/drivers/firmware/arm_scmi/protocols.h
@@ -100,7 +100,10 @@ struct scmi_msg_hdr { * message. If request-ACK protocol is used, we can reuse the same * buffer for the rx path as we use for the tx path. * @done: command message transmit completion event - * @async_done: pointer to delayed response message received event completion + * @async_done: pointer to delayed response message received event completion, + * or NULL when no delayed response is expected. Protected by + * @lock, since the completion is owned by the waiter and can + * vanish once the wait times out. * @pending: True for xfers added to @pending_xfers hashtable * @node: An hlist_node reference used to store this xfer, alternatively, on * the free list @free_xfers or in the @pending_xfers hashtable @@ -121,7 +124,7 @@ struct scmi_msg_hdr { * - SCMI_XFER_SENT_OK -> SCMI_XFER_DRESP_OK * (Missing synchronous response is assumed OK and ignored) * @flags: Optional flags associated to this xfer. - * @lock: A spinlock to protect state and busy fields. + * @lock: A spinlock to protect state, busy and async_done fields. * @priv: A pointer for transport private usage. */ struct scmi_xfer { @@ -147,7 +150,7 @@ struct scmi_xfer { #define SCMI_XFER_IS_CHAN_SET(x) \ ((x)->flags & SCMI_XFER_FLAG_CHAN_SET) int flags; - /* A lock to protect state and busy fields */ + /* A lock to protect state, busy and async_done fields */ spinlock_t lock; void *priv; };
diff --git a/drivers/firmware/arm_scmi/raw_mode.c b/drivers/firmware/arm_scmi/raw_mode.c index 1f6e516..f01bf2f 100644 --- a/drivers/firmware/arm_scmi/raw_mode.c +++ b/drivers/firmware/arm_scmi/raw_mode.c
@@ -198,6 +198,8 @@ struct scmi_raw_mode_info { * @async_response: A completion to be, optionally, used for async waits: it * will be setup by @scmi_do_xfer_raw_start, if needed, to be * pointed at by xfer->async_done. + * @async: True if @async_response was armed on @xfer, i.e. if a delayed + * response has to be waited for. * @node: A list node. */ struct scmi_xfer_raw_waiter { @@ -205,6 +207,7 @@ struct scmi_xfer_raw_waiter { struct scmi_chan_info *cinfo; struct scmi_xfer *xfer; struct completion async_response; + bool async; struct list_head node; }; @@ -346,9 +349,10 @@ scmi_xfer_raw_waiter_get(struct scmi_raw_mode_info *raw, struct scmi_xfer *xfer, if (async) { reinit_completion(&rw->async_response); - xfer->async_done = &rw->async_response; + scmi_xfer_async_response_arm(xfer, &rw->async_response); } + rw->async = async; rw->cinfo = cinfo; rw->xfer = xfer; } @@ -361,8 +365,16 @@ static void scmi_xfer_raw_waiter_put(struct scmi_raw_mode_info *raw, struct scmi_xfer_raw_waiter *rw) { if (rw->xfer) { - rw->xfer->async_done = NULL; + /* + * Disarm the delayed response before this waiter, and its + * embedded completion, can be picked up again for a new + * transaction: a delayed response received late, after the + * related wait timed out, must not signal a completion which + * has been in the meantime re-armed on a different xfer. + */ + scmi_xfer_async_response_disarm(rw->xfer); rw->xfer = NULL; + rw->async = false; } mutex_lock(&raw->free_mtx); @@ -479,18 +491,23 @@ static void scmi_xfer_raw_worker(struct work_struct *work) ret, scmi_inflight_count(raw->handle)); /* Wait also for an async delayed response if needed */ - if (!ret && xfer->async_done) { + if (!ret && rw->async) { unsigned long tmo = msecs_to_jiffies(SCMI_MAX_RESPONSE_TIMEOUT); - if (!wait_for_completion_timeout(xfer->async_done, tmo)) + if (!wait_for_completion_timeout(&rw->async_response, tmo)) dev_err(dev, "timed out in RAW delayed resp - HDR:%08X\n", pack_scmi_header(&xfer->hdr)); } - /* Release waiter and xfer */ - scmi_xfer_raw_put(raw->handle, xfer); + /* + * Release the waiter first: this disarms the delayed response + * while we still hold a reference on the xfer, so that the xfer + * cannot be recycled by a new transaction while it still points + * at this waiter's completion. + */ scmi_xfer_raw_waiter_put(raw, rw); + scmi_xfer_raw_put(raw->handle, xfer); } while (1); } @@ -694,6 +711,7 @@ static int scmi_raw_message_send(struct scmi_raw_mode_info *raw, } else { dev_err(raw->handle->dev, "Failed to send RAW message - Polling NOT supported\n"); + scmi_xfer_raw_put(raw->handle, xfer); return -EINVAL; } }
diff --git a/drivers/firmware/arm_scmi/reset.c b/drivers/firmware/arm_scmi/reset.c index 4bc5c24..2cdddc2 100644 --- a/drivers/firmware/arm_scmi/reset.c +++ b/drivers/firmware/arm_scmi/reset.c
@@ -60,8 +60,7 @@ struct scmi_reset_issued_notify_payld { struct reset_dom_info { bool async_reset; bool reset_notify; - u32 latency_us; - char name[SCMI_MAX_STR_SIZE]; + struct scmi_reset_domain_info info; }; struct scmi_reset_info { @@ -134,10 +133,10 @@ scmi_reset_domain_attributes_get(const struct scmi_protocol_handle *ph, if (pinfo->notify_reset_cmd) dom_info->reset_notify = SUPPORTS_NOTIFY_RESET(attributes); - dom_info->latency_us = le32_to_cpu(attr->latency); - if (dom_info->latency_us == U32_MAX) - dom_info->latency_us = 0; - strscpy(dom_info->name, attr->name, SCMI_SHORT_NAME_MAX_SIZE); + dom_info->info.latency_us = le32_to_cpu(attr->latency); + if (dom_info->info.latency_us == U32_MAX) + dom_info->info.latency_us = 0; + strscpy(dom_info->info.name, attr->name, SCMI_SHORT_NAME_MAX_SIZE); } ph->xops->xfer_put(ph, t); @@ -149,7 +148,7 @@ scmi_reset_domain_attributes_get(const struct scmi_protocol_handle *ph, if (!ret && PROTOCOL_REV_MAJOR(ph->version) >= 0x3 && SUPPORTS_EXTENDED_NAMES(attributes)) ph->hops->extended_name_get(ph, RESET_DOMAIN_NAME_GET, domain, - NULL, dom_info->name, + NULL, dom_info->info.name, SCMI_MAX_STR_SIZE); return ret; @@ -162,28 +161,16 @@ static int scmi_reset_num_domains_get(const struct scmi_protocol_handle *ph) return pi->num_domains; } -static const char * -scmi_reset_name_get(const struct scmi_protocol_handle *ph, u32 domain) +static const struct scmi_reset_domain_info * +scmi_reset_info_get(const struct scmi_protocol_handle *ph, u32 domain) { struct reset_dom_info *dom_info; dom_info = scmi_reset_domain_lookup(ph, domain); if (IS_ERR(dom_info)) - return "unknown"; + return NULL; - return dom_info->name; -} - -static int scmi_reset_latency_get(const struct scmi_protocol_handle *ph, - u32 domain) -{ - struct reset_dom_info *dom_info; - - dom_info = scmi_reset_domain_lookup(ph, domain); - if (IS_ERR(dom_info)) - return PTR_ERR(dom_info); - - return dom_info->latency_us; + return &dom_info->info; } static int scmi_domain_reset(const struct scmi_protocol_handle *ph, u32 domain, @@ -241,8 +228,7 @@ scmi_reset_domain_deassert(const struct scmi_protocol_handle *ph, u32 domain) static const struct scmi_reset_proto_ops reset_proto_ops = { .num_domains_get = scmi_reset_num_domains_get, - .name_get = scmi_reset_name_get, - .latency_get = scmi_reset_latency_get, + .info_get = scmi_reset_info_get, .reset = scmi_reset_domain_reset, .assert = scmi_reset_domain_assert, .deassert = scmi_reset_domain_deassert,
diff --git a/drivers/firmware/arm_scmi/transports/Kconfig b/drivers/firmware/arm_scmi/transports/Kconfig index 57eccf3..0e34fbf 100644 --- a/drivers/firmware/arm_scmi/transports/Kconfig +++ b/drivers/firmware/arm_scmi/transports/Kconfig
@@ -77,6 +77,18 @@ This driver can also be built as a module. If so, the module will be called scmi_transport_optee. +config ARM_SCMI_TRANSPORT_PCC + tristate "SCMI transport based on ACPI PCC" + depends on PCC + select ARM_SCMI_HAVE_TRANSPORT + help + This enables the ACPI PCC mailbox based transport for SCMI. + + If you want the ARM SCMI PROTOCOL stack to include support for a + transport based on ACPI PCC mailboxes, answer Y. + This driver can also be built as a module. If so, the module + will be called scmi_transport_pcc. + config ARM_SCMI_TRANSPORT_VIRTIO tristate "SCMI transport based on VirtIO" depends on VIRTIO
diff --git a/drivers/firmware/arm_scmi/transports/Makefile b/drivers/firmware/arm_scmi/transports/Makefile index 3ba3d3b..e7c4b8d 100644 --- a/drivers/firmware/arm_scmi/transports/Makefile +++ b/drivers/firmware/arm_scmi/transports/Makefile
@@ -7,6 +7,8 @@ obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += scmi_transport_mailbox.o scmi_transport_optee-objs := optee.o obj-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += scmi_transport_optee.o +scmi_transport_pcc-objs := pcc.o +obj-$(CONFIG_ARM_SCMI_TRANSPORT_PCC) += scmi_transport_pcc.o scmi_transport_virtio-objs := virtio.o obj-$(CONFIG_ARM_SCMI_TRANSPORT_VIRTIO) += scmi_transport_virtio.o
diff --git a/drivers/firmware/arm_scmi/transports/mailbox.c b/drivers/firmware/arm_scmi/transports/mailbox.c index 308736c..56af2cb 100644 --- a/drivers/firmware/arm_scmi/transports/mailbox.c +++ b/drivers/firmware/arm_scmi/transports/mailbox.c
@@ -77,9 +77,14 @@ static void rx_callback(struct mbox_client *cl, void *m) core->shmem->read_header(smbox->shmem), NULL); } -static bool mailbox_chan_available(struct device_node *of_node, int idx) +static bool +mailbox_chan_available(struct fwnode_handle *fwnode, int prot_id, int idx) { int num_mb; + struct device_node *of_node = to_of_node(fwnode); + + if (!of_node) + return false; /* * Just check if bidirrectional channels are involved, and check the
diff --git a/drivers/firmware/arm_scmi/transports/optee.c b/drivers/firmware/arm_scmi/transports/optee.c index dbe32e1..6022f74 100644 --- a/drivers/firmware/arm_scmi/transports/optee.c +++ b/drivers/firmware/arm_scmi/transports/optee.c
@@ -314,9 +314,14 @@ static int invoke_process_msg_channel(struct scmi_optee_channel *channel, size_t return 0; } -static bool scmi_optee_chan_available(struct device_node *of_node, int idx) +static bool +scmi_optee_chan_available(struct fwnode_handle *fwnode, int prot_id, int idx) { u32 channel_id; + struct device_node *of_node = to_of_node(fwnode); + + if (!of_node) + return false; return !of_property_read_u32_index(of_node, "linaro,optee-channel-id", idx, &channel_id);
diff --git a/drivers/firmware/arm_scmi/transports/pcc.c b/drivers/firmware/arm_scmi/transports/pcc.c new file mode 100644 index 0000000..86d4a09 --- /dev/null +++ b/drivers/firmware/arm_scmi/transports/pcc.c
@@ -0,0 +1,875 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * System Control and Management Interface (SCMI) Message ACPI PCC + * Transport Driver + * + * This transport uses ACPI PCC (PCCT Type 3/4) subspaces via the Linux + * PCC mailbox controller to exchange SCMI messages over the standard + * SCMI Shared Memory Transport (SMT) layout. + * + * PCC subspace selection is conveyed via ACPI SCMI namespace device. + * described in ACPI for System Control and Management Interface Platform + * Design Document[1] + * + * [1] https://support.arm.com/documentation/111115/latest + * + * Copyright (C) 2026 + */ + +#include <linux/acpi.h> +#include <linux/cleanup.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/hashtable.h> +#include <linux/io.h> +#include <linux/limits.h> +#include <linux/list.h> +#include <linux/mailbox_client.h> +#include <linux/mutex.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/types.h> +#include <acpi/pcc.h> + +#include "../common.h" + +#define SCMI_TRANSPORT_PACKAGE_MAX_VERSION (1) +#define SCMI_PROTOCOL_PACKAGE_MAX_VERSION (1) +#define SCMI_TRANSPORT_SHARED_CHANNEL BIT_ULL(0) +#define SCMI_TRANSPORT_P2A_CHANNEL BIT_ULL(1) +#define SCMI_TRANSPORT_FLAGS_MASK (SCMI_TRANSPORT_SHARED_CHANNEL | \ + SCMI_TRANSPORT_P2A_CHANNEL) + +#define SCMI_DSD_GUID_ENTRY_COUNT 2 +#define SCMI_PROTOCOL_MAX_TRANSPORTS 2 + +enum scmi_dsd_property_index { + SCMI_DSD_PROPERTY_NAME, + SCMI_DSD_PROPERTY_VALUE, + SCMI_DSD_PROPERTY_COUNT, +}; + +enum scmi_pcc_transport_index { + SCMI_PCC_TRANSPORT_REVISION, + SCMI_PCC_TRANSPORT_COUNT, + SCMI_PCC_TRANSPORT_DESCRIPTORS, +}; + +enum scmi_pcc_descriptor_index { + SCMI_PCC_DESCRIPTOR_PCCT_INDEX, + SCMI_PCC_DESCRIPTOR_TRANSPORT_UID, + SCMI_PCC_DESCRIPTOR_FLAGS, + SCMI_PCC_DESCRIPTOR_COUNT, +}; + +enum scmi_protocol_property_index { + SCMI_PROTOCOL_PROPERTY_REVISION, + SCMI_PROTOCOL_PROPERTY_TRANSPORTS, + SCMI_PROTOCOL_PROPERTY_ASSOCIATIONS, + SCMI_PROTOCOL_PROPERTY_COUNT, +}; + +enum scmi_protocol_transport_index { + SCMI_PROTOCOL_TRANSPORT_UID, + SCMI_PROTOCOL_TRANSPORT_FLAGS, + SCMI_PROTOCOL_TRANSPORT_COUNT, +}; + +/* + * SCMI specification requires all parameters, message headers, return + * arguments or any protocol data to be expressed in little endian + * format only. + */ +struct pcc_shared_mem { + struct acpi_pcct_ext_pcc_shared_memory header; + u8 msg_payload[]; +}; + +#define SCMI_PCC_MSG_HEADER_SIZE sizeof(u32) +#define SCMI_PCC_STATUS_SIZE sizeof(u32) +#define SCMI_PCC_RESPONSE_OVERHEAD (SCMI_PCC_MSG_HEADER_SIZE + \ + SCMI_PCC_STATUS_SIZE) +#define SCMI_PCC_SHMEM_OVERHEAD (sizeof(struct pcc_shared_mem) + \ + SCMI_PCC_STATUS_SIZE) + +/** + * struct scmi_pcc - Structure representing a SCMI mailbox transport + * + * @cl: Mailbox Client + * @pchan: Transmit/Receive PCC/mailbox channel + * @cinfo: SCMI channel info + */ +struct scmi_pcc { + struct mbox_client cl; + struct pcc_mbox_chan *pchan; + struct scmi_chan_info *cinfo; +}; + +struct pcc_transport { + u64 uid; + u64 flags; + u32 pcc_ss_id; + u32 protocol_id; + struct hlist_node hnode; +}; + +struct pcc_transport_map { + struct fwnode_handle *fwnode; + struct device *dev; + struct list_head node; + DECLARE_HASHTABLE(table, ilog2(MAX_PCC_SUBSPACES / 8)); +}; + +#define client_to_scmi_pcc(c) container_of(c, struct scmi_pcc, cl) + +static struct scmi_transport_core_operations *core; +static LIST_HEAD(pcc_transport_maps); +static DEFINE_MUTEX(pcc_transport_maps_lock); + +static void acpi_scmi_clear_transport_map(struct pcc_transport_map *map) +{ + struct pcc_transport *p; + struct hlist_node *tmp; + int idx; + + hash_for_each_safe(map->table, idx, tmp, p, hnode) { + hash_del(&p->hnode); + kfree(p); + } +} + +static void acpi_scmi_destroy_transport_map(struct pcc_transport_map *map) +{ + acpi_scmi_clear_transport_map(map); + if (map->fwnode) + fwnode_handle_put(map->fwnode); + kfree(map); +} + +static void pcc_transport_map_release(void *data) +{ + struct pcc_transport_map *map = data; + + guard(mutex)(&pcc_transport_maps_lock); + list_del(&map->node); + acpi_scmi_destroy_transport_map(map); +} + +static void acpi_scmi_clear_transport_maps(void) +{ + struct pcc_transport_map *map, *tmp; + + guard(mutex)(&pcc_transport_maps_lock); + list_for_each_entry_safe(map, tmp, &pcc_transport_maps, node) { + list_del(&map->node); + acpi_scmi_destroy_transport_map(map); + } +} + +static const union acpi_object * +acpi_scmi_pkg_elements(const union acpi_object *obj, unsigned int count) +{ + if (obj->type != ACPI_TYPE_PACKAGE || obj->package.count != count) + return NULL; + + return obj->package.elements; +} + +static int +acpi_scmi_pkg_u64(const union acpi_object *pkg, unsigned int idx, u64 *val) +{ + const union acpi_object *elem = &pkg->package.elements[idx]; + + if (elem->type != ACPI_TYPE_INTEGER) + return -EINVAL; + + *val = elem->integer.value; + + return 0; +} + +static int acpi_scmi_property(const union acpi_object *properties, + unsigned int idx, const char **name, + const union acpi_object **value) +{ + const union acpi_object *property; + const union acpi_object *elems; + + property = &properties->package.elements[idx]; + elems = acpi_scmi_pkg_elements(property, SCMI_DSD_PROPERTY_COUNT); + if (!elems) + return -EINVAL; + if (elems[SCMI_DSD_PROPERTY_NAME].type != ACPI_TYPE_STRING || + !elems[SCMI_DSD_PROPERTY_NAME].string.pointer) + return -EINVAL; + + *name = elems[SCMI_DSD_PROPERTY_NAME].string.pointer; + *value = &elems[SCMI_DSD_PROPERTY_VALUE]; + + return 0; +} + +static int +acpi_scmi_dsd_parse_transport_package(struct pcc_transport_map *map, + const union acpi_object *obj) +{ + u64 revision, pkg_cnt; + bool common_a2p = false, common_p2a = false; + + if (obj->type != ACPI_TYPE_PACKAGE || + obj->package.count < SCMI_PCC_TRANSPORT_DESCRIPTORS || + acpi_scmi_pkg_u64(obj, SCMI_PCC_TRANSPORT_REVISION, &revision) || + acpi_scmi_pkg_u64(obj, SCMI_PCC_TRANSPORT_COUNT, &pkg_cnt)) + return -EINVAL; + if (revision != SCMI_TRANSPORT_PACKAGE_MAX_VERSION) + return -EINVAL; + if (pkg_cnt != obj->package.count - SCMI_PCC_TRANSPORT_DESCRIPTORS) + return -EINVAL; + + for (u32 idx = 0; idx < pkg_cnt; idx++) { + struct pcc_transport *p, *tmp; + union acpi_object *pack; + u64 pcc_ss_id, uid, flags; + + pack = &obj->package.elements[idx + + SCMI_PCC_TRANSPORT_DESCRIPTORS]; + if (!acpi_scmi_pkg_elements(pack, SCMI_PCC_DESCRIPTOR_COUNT)) { + pr_info("Invalid transport properties pkg %u\n", idx); + return -EINVAL; + } + if (acpi_scmi_pkg_u64(pack, SCMI_PCC_DESCRIPTOR_PCCT_INDEX, + &pcc_ss_id) || + acpi_scmi_pkg_u64(pack, SCMI_PCC_DESCRIPTOR_TRANSPORT_UID, + &uid) || + acpi_scmi_pkg_u64(pack, SCMI_PCC_DESCRIPTOR_FLAGS, &flags)) + return -EINVAL; + if (pcc_ss_id > INT_MAX || + flags & ~SCMI_TRANSPORT_FLAGS_MASK) + return -EINVAL; + + hash_for_each_possible(map->table, tmp, hnode, uid) { + if (tmp->uid == uid) { + pr_info("Duplicate UID %llu\n", uid); + return -EEXIST; + } + } + + if (flags & SCMI_TRANSPORT_SHARED_CHANNEL) { + if (flags & SCMI_TRANSPORT_P2A_CHANNEL) { + if (common_p2a) + return -EINVAL; + common_p2a = true; + } else { + if (common_a2p) + return -EINVAL; + common_a2p = true; + } + } + + p = kzalloc(sizeof(*p), GFP_KERNEL); + if (!p) + return -ENOMEM; + + p->uid = uid; + p->pcc_ss_id = pcc_ss_id; + p->flags = flags; + if (p->flags & SCMI_TRANSPORT_SHARED_CHANNEL) + p->protocol_id = SCMI_PROTOCOL_BASE; + + hash_add(map->table, &p->hnode, uid); + } + + if (!common_a2p) + return -EINVAL; + + return 0; +} + +static int +acpi_scmi_dsd_parse_protocol_subpackage(struct pcc_transport_map *map, + const union acpi_object *obj, + int prot_id) +{ + struct pcc_transport *p; + unsigned int pkg_cnt = obj->package.count; + bool found, tx_found = false, rx_found = false; + u64 uid; + + if (pkg_cnt > SCMI_PROTOCOL_MAX_TRANSPORTS) { + pr_warn("Found %u protocol channels, at most %u allowed\n", + pkg_cnt, SCMI_PROTOCOL_MAX_TRANSPORTS); + return -EINVAL; + } + + for (u32 idx = 0; idx < pkg_cnt; idx++) { + union acpi_object *pack = &obj->package.elements[idx]; + u64 flags; + + if (!acpi_scmi_pkg_elements(pack, SCMI_PROTOCOL_TRANSPORT_COUNT) || + acpi_scmi_pkg_u64(pack, SCMI_PROTOCOL_TRANSPORT_UID, &uid) || + acpi_scmi_pkg_u64(pack, SCMI_PROTOCOL_TRANSPORT_FLAGS, + &flags)) + return -EINVAL; + if (flags) + return -EINVAL; + + found = false; + hash_for_each_possible(map->table, p, hnode, uid) { + if (p->uid != uid) + continue; + + found = true; + if (p->flags & SCMI_TRANSPORT_SHARED_CHANNEL) { + pr_info("Protocol package references common PCC subspace %u\n", + p->pcc_ss_id); + return -EINVAL; + } + if (p->protocol_id && p->protocol_id != prot_id) + return -EINVAL; + + if (p->flags & SCMI_TRANSPORT_P2A_CHANNEL) { + if (rx_found) + return -EINVAL; + rx_found = true; + } else { + if (tx_found) + return -EINVAL; + tx_found = true; + } + p->protocol_id = prot_id; + break; + } + + if (!found) + return -ENOENT; + } + + return 0; +} + +static int +acpi_scmi_dsd_parse_protocol_package(struct pcc_transport_map *map, + const union acpi_object *obj, int prot_id) +{ + const union acpi_object *elems; + const union acpi_object *pack; + u64 revision; + int ret; + + elems = acpi_scmi_pkg_elements(obj, SCMI_PROTOCOL_PROPERTY_COUNT); + if (!elems || + acpi_scmi_pkg_u64(obj, SCMI_PROTOCOL_PROPERTY_REVISION, &revision)) + return -EINVAL; + + pack = &elems[SCMI_PROTOCOL_PROPERTY_TRANSPORTS]; + + if (revision != SCMI_PROTOCOL_PACKAGE_MAX_VERSION) + return -EINVAL; + + if (pack->type != ACPI_TYPE_PACKAGE) { + pr_info("Invalid protocol transport package\n"); + return -EINVAL; + } + + /* + * Document 111115A v1.0, Sections 2.2.2.1 and 2.2.3 permit an empty + * protocol transport package when common transport channels exist. + */ + if (pack->package.count != 0) { + ret = acpi_scmi_dsd_parse_protocol_subpackage(map, pack, prot_id); + if (ret) + return ret; + } + + pack = &elems[SCMI_PROTOCOL_PROPERTY_ASSOCIATIONS]; + if (pack->type != ACPI_TYPE_PACKAGE) { + pr_info("Invalid protocol transport association package\n"); + return -EINVAL; + } + + if (pack->package.count != 0) { + pr_info("Non-empty association package not supported\n"); + return -EINVAL; + } + + return 0; +} + +/* ACPI SCMI _DSD UUID: "84a2d1c6-86b6-4199-8dac-9c17449d5e03" */ +static const guid_t acpi_scmi_uuid = GUID_INIT(0x84a2d1c6, 0x86b6, 0x4199, + 0x8d, 0xac, 0x9c, 0x17, + 0x44, 0x9d, 0x5e, 0x03); + +static int acpi_scmi_lookup_protocol_id(const char *name) +{ + for (size_t i = 0; i < ARRAY_SIZE(scmi_dsd_info_list); i++) { + if (!strcmp(name, scmi_dsd_info_list[i].property_name)) + return scmi_dsd_info_list[i].protocol_id; + } + return -ENOENT; +} + +static int acpi_scmi_parse_properties(struct pcc_transport_map *map, + const union acpi_object *properties) +{ + bool transport_found = false; + + if (properties->type != ACPI_TYPE_PACKAGE) + return -EINVAL; + + /* + * Protocol properties reference TransportUIDs declared by the transport + * property. Parse the transport first because _DSD property ordering is + * not defined. + */ + for (u32 i = 0; i < properties->package.count; i++) { + const union acpi_object *v; + const char *name; + int prot_id, ret; + + ret = acpi_scmi_property(properties, i, &name, &v); + if (ret) + return ret; + + prot_id = acpi_scmi_lookup_protocol_id(name); + if (prot_id < 0) + continue; + if (prot_id != SCMI_PROTOCOL_BASE) + continue; + if (v->type != ACPI_TYPE_PACKAGE) + return -EINVAL; + if (transport_found) + return -EEXIST; + + ret = acpi_scmi_dsd_parse_transport_package(map, v); + if (ret) + return ret; + transport_found = true; + } + + if (!transport_found) + return -ENOENT; + + for (u32 i = 0; i < properties->package.count; i++) { + const union acpi_object *v; + const char *name; + int prot_id, ret; + + ret = acpi_scmi_property(properties, i, &name, &v); + if (ret) + return ret; + + prot_id = acpi_scmi_lookup_protocol_id(name); + if (prot_id < 0 || prot_id == SCMI_PROTOCOL_BASE) + continue; + if (v->type != ACPI_TYPE_PACKAGE) + return -EINVAL; + + ret = acpi_scmi_dsd_parse_protocol_package(map, v, prot_id); + if (ret) + return ret; + } + + return 0; +} + +static int acpi_scmi_namespace_fwnode_parse(struct fwnode_handle *fwnode, + struct pcc_transport_map *map) +{ + struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_device *adev = to_acpi_device_node(fwnode); + union acpi_object *desc; + acpi_status status; + int ret = -ENOENT; + + if (!adev || !adev->handle) + return -EINVAL; + + status = acpi_evaluate_object_typed(adev->handle, "_DSD", NULL, &buf, + ACPI_TYPE_PACKAGE); + if (ACPI_FAILURE(status)) + return -EINVAL; + + desc = buf.pointer; + if (desc->package.count % SCMI_DSD_GUID_ENTRY_COUNT) { + ret = -EINVAL; + goto out_free; + } + + /* Look for the device properties GUID. */ + for (u32 i = 0; i < desc->package.count; + i += SCMI_DSD_GUID_ENTRY_COUNT) { + const union acpi_object *guid; + const union acpi_object *properties; + + guid = &desc->package.elements[i]; + properties = &desc->package.elements[i + 1]; + + /* + * The first element must be a GUID and the second one must be + * a package. + */ + if (guid->type != ACPI_TYPE_BUFFER || + guid->buffer.length != UUID_SIZE || + properties->type != ACPI_TYPE_PACKAGE) + continue; + + if (!guid_equal((guid_t *)guid->buffer.pointer, + &acpi_scmi_uuid)) + continue; + + ret = acpi_scmi_parse_properties(map, properties); + break; + } + +out_free: + ACPI_FREE(buf.pointer); + return ret; +} + +static bool +pcc_transport_map_has_ss_id(struct pcc_transport_map *map, u32 pcc_ss_id) +{ + struct pcc_transport *p; + int idx; + + hash_for_each(map->table, idx, p, hnode) { + if (p->pcc_ss_id == pcc_ss_id) + return true; + } + + return false; +} + +static int pcc_transport_map_validate(struct pcc_transport_map *map) +{ + struct pcc_transport_map *iter; + struct pcc_transport *p; + int idx; + + list_for_each_entry(iter, &pcc_transport_maps, node) { + hash_for_each(map->table, idx, p, hnode) { + if (pcc_transport_map_has_ss_id(iter, p->pcc_ss_id)) + return -EEXIST; + } + } + + return 0; +} + +static +struct pcc_transport_map *pcc_transport_map_find(struct fwnode_handle *fwnode) +{ + struct pcc_transport_map *map; + + list_for_each_entry(map, &pcc_transport_maps, node) { + if (map->fwnode == fwnode) + return map; + } + + return NULL; +} + +static +struct pcc_transport_map *pcc_transport_map_get(struct fwnode_handle *fwnode) +{ + struct pcc_transport_map *map; + int ret; + + map = pcc_transport_map_find(fwnode); + if (map) + return map; + + map = kzalloc_obj(*map, GFP_KERNEL); + if (!map) + return ERR_PTR(-ENOMEM); + + hash_init(map->table); + ret = acpi_scmi_namespace_fwnode_parse(fwnode, map); + if (ret) + goto err_free_map; + + ret = pcc_transport_map_validate(map); + if (ret) + goto err_free_map; + + map->fwnode = fwnode_handle_get(fwnode); + list_add_tail(&map->node, &pcc_transport_maps); + + return map; + +err_free_map: + acpi_scmi_clear_transport_map(map); + kfree(map); + return ERR_PTR(ret); +} + +static int pcc_transport_map_manage(struct pcc_transport_map *map, + struct device *dev) +{ + int ret; + + if (!dev || map->dev == dev) + return 0; + if (map->dev) + return -EBUSY; + + /* + * Release the cached map after the SCMI remove path tears down channels. + */ + ret = devm_add_action(dev, pcc_transport_map_release, map); + if (ret) + return ret; + + map->dev = dev; + + return 0; +} + +static int pcc_lookup_ss_id(struct pcc_transport_map *map, u32 prot_id, bool tx) +{ + struct pcc_transport *p; + int idx; + + hash_for_each(map->table, idx, p, hnode) { + if (p->protocol_id != prot_id) + continue; + + if ((!tx && (p->flags & SCMI_TRANSPORT_P2A_CHANNEL)) || + (tx && !(p->flags & SCMI_TRANSPORT_P2A_CHANNEL))) + return p->pcc_ss_id; + } + + return -ENOENT; +} + +static int pcc_get_ss_id(struct fwnode_handle *fwnode, u32 prot_id, bool tx, + struct device *dev) +{ + struct pcc_transport_map *map; + int ret; + + if (!fwnode) + return -EINVAL; + + guard(mutex)(&pcc_transport_maps_lock); + map = pcc_transport_map_get(fwnode); + if (IS_ERR(map)) + return PTR_ERR(map); + + ret = pcc_transport_map_manage(map, dev); + if (ret) + return ret; + + return pcc_lookup_ss_id(map, prot_id, tx); +} + +static bool +pcc_chan_available(struct fwnode_handle *fwnode, int prot_id, int idx) +{ + return pcc_get_ss_id(fwnode, prot_id, !idx, NULL) >= 0; +} + +static void tx_prepare(struct mbox_client *cl, void *m) +{ + struct scmi_pcc *smbox = client_to_scmi_pcc(cl); + struct pcc_shared_mem __iomem *shmem = smbox->pchan->shmem; + struct scmi_xfer *xfer = m; + + /* + * PCC take cares not to call tx_prepare until last transmit is done. + * Request platform interrupt notification if available. + */ + if (xfer->tx.buf) + memcpy_toio(shmem->msg_payload, xfer->tx.buf, xfer->tx.len); + iowrite32(SCMI_PCC_MSG_HEADER_SIZE + xfer->tx.len, + &shmem->header.length); + iowrite32(pack_scmi_header(&xfer->hdr), &shmem->header.command); + iowrite32(smbox->pchan->mchan->mbox->txdone_irq ? + PCC_CMD_COMPLETION_NOTIFY : 0, &shmem->header.flags); +} + +static void rx_callback(struct mbox_client *cl, void *m) +{ + struct scmi_pcc *smbox = client_to_scmi_pcc(cl); + struct pcc_shared_mem __iomem *shmem = smbox->pchan->shmem; + + core->rx_callback(smbox->cinfo, ioread32(&shmem->header.command), NULL); +} + +static int pcc_chan_validate_shmem(struct scmi_chan_info *cinfo, + struct scmi_pcc *smbox, int ss_id) +{ + struct pcc_shared_mem __iomem *shmem = smbox->pchan->shmem; + u32 valid_signature = ss_id + PCC_SIGNATURE; + + if (smbox->pchan->shmem_size < SCMI_PCC_SHMEM_OVERHEAD || + smbox->pchan->shmem_size - SCMI_PCC_SHMEM_OVERHEAD < + cinfo->max_msg_size) { + dev_err(cinfo->dev, "misconfigured SCMI PCC shared memory\n"); + return -ENOSPC; + } + + if (ioread32(&shmem->header.signature) != valid_signature) { + dev_err(cinfo->dev, "invalid PCC shared memory signature\n"); + return -EINVAL; + } + + return 0; +} + +static int pcc_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, + bool tx) +{ + const char *desc = tx ? "Tx" : "Rx"; + struct device *cdev = cinfo->dev; + struct scmi_pcc *smbox; + struct mbox_client *cl; + int ret, ss_id; + + smbox = devm_kzalloc(dev, sizeof(*smbox), GFP_KERNEL); + if (!smbox) + return -ENOMEM; + + cl = &smbox->cl; + cl->dev = cdev; + cl->tx_prepare = tx ? tx_prepare : NULL; + cl->rx_callback = rx_callback; + cl->tx_block = false; + + ss_id = pcc_get_ss_id(dev_fwnode(cinfo->dev), cinfo->id, tx, dev); + if (ss_id < 0) + return ss_id; + + smbox->pchan = pcc_mbox_request_channel(cl, ss_id); + if (IS_ERR(smbox->pchan)) { + ret = PTR_ERR(smbox->pchan); + if (ret != -EPROBE_DEFER) + dev_err(cdev, + "failed to request SCMI %s mailbox\n", desc); + return ret; + } + + ret = pcc_chan_validate_shmem(cinfo, smbox, ss_id); + if (ret) { + pcc_mbox_free_channel(smbox->pchan); + return ret; + } + + cinfo->transport_info = smbox; + smbox->cinfo = cinfo; + + return 0; +} + +static int pcc_chan_free(int id, void *p, void *data) +{ + struct scmi_chan_info *cinfo = p; + struct scmi_pcc *smbox = cinfo->transport_info; + + if (!smbox || IS_ERR_OR_NULL(smbox->pchan)) + return 0; + + pcc_mbox_free_channel(smbox->pchan); + cinfo->transport_info = NULL; + smbox->pchan = NULL; + smbox->cinfo = NULL; + + return 0; +} + +static int +pcc_send_message(struct scmi_chan_info *cinfo, struct scmi_xfer *xfer) +{ + struct scmi_pcc *smbox = cinfo->transport_info; + int ret; + + /* + * The mailbox layer has its own queue. However the mailbox queue + * confuses the per message SCMI timeouts since the clock starts when + * the message is submitted into the mailbox queue. So when multiple + * messages are queued up the clock starts on all messages instead of + * only the one inflight. + */ + ret = mbox_send_message(smbox->pchan->mchan, xfer); + /* mbox_send_message returns non-negative value on success */ + if (ret < 0) + return ret; + + return 0; +} + +static void pcc_fetch_response(struct scmi_chan_info *cinfo, + struct scmi_xfer *xfer) +{ + struct scmi_pcc *smbox = cinfo->transport_info; + struct pcc_shared_mem __iomem *shmem = smbox->pchan->shmem; + size_t len = ioread32(&shmem->header.length); + size_t payload_len; + + xfer->hdr.status = ioread32(shmem->msg_payload); + payload_len = len > SCMI_PCC_RESPONSE_OVERHEAD ? + len - SCMI_PCC_RESPONSE_OVERHEAD : 0; + xfer->rx.len = min(xfer->rx.len, payload_len); + + /* msg_payload starts after the header, so skip only the status here. */ + memcpy_fromio(xfer->rx.buf, shmem->msg_payload + SCMI_PCC_STATUS_SIZE, + xfer->rx.len); +} + +static void pcc_fetch_notification(struct scmi_chan_info *cinfo, size_t max_len, + struct scmi_xfer *xfer) +{ + struct scmi_pcc *smbox = cinfo->transport_info; + struct pcc_shared_mem __iomem *shmem = smbox->pchan->shmem; + size_t len = ioread32(&shmem->header.length); + size_t payload_len; + + payload_len = len > SCMI_PCC_MSG_HEADER_SIZE ? + len - SCMI_PCC_MSG_HEADER_SIZE : 0; + xfer->rx.len = min(max_len, payload_len); + memcpy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len); +} + +static const struct scmi_transport_ops scmi_pcc_ops = { + .chan_available = pcc_chan_available, + .chan_setup = pcc_chan_setup, + .chan_free = pcc_chan_free, + .send_message = pcc_send_message, + .fetch_response = pcc_fetch_response, + .fetch_notification = pcc_fetch_notification, +}; + +static struct scmi_desc scmi_pcc_desc = { + .ops = &scmi_pcc_ops, + .max_rx_timeout_ms = 30, + .max_msg = MBOX_TX_QUEUE_LEN, + .max_msg_size = SCMI_SHMEM_MAX_PAYLOAD_SIZE, +}; + +static const struct acpi_device_id scmi_acpi_ids[] = { + { .id = "ARML0001" }, + { } +}; + +MODULE_DEVICE_TABLE(acpi, scmi_acpi_ids); + +DEFINE_SCMI_ACPI_TRANSPORT_DRIVER(scmi_pcc, scmi_pcc_driver, + scmi_pcc_desc, scmi_acpi_ids, core); + +static int __init scmi_pcc_init(void) +{ + return platform_driver_register(&scmi_pcc_driver); +} + +static void __exit scmi_pcc_exit(void) +{ + platform_driver_unregister(&scmi_pcc_driver); + acpi_scmi_clear_transport_maps(); +} +module_init(scmi_pcc_init); +module_exit(scmi_pcc_exit); + +MODULE_AUTHOR("Sudeep Holla <sudeep.holla@kernel.org>"); +MODULE_DESCRIPTION("SCMI ACPI PCC Transport driver"); +MODULE_LICENSE("GPL");
diff --git a/drivers/firmware/arm_scmi/transports/smc.c b/drivers/firmware/arm_scmi/transports/smc.c index 1fce3cc..7fb2736 100644 --- a/drivers/firmware/arm_scmi/transports/smc.c +++ b/drivers/firmware/arm_scmi/transports/smc.c
@@ -84,10 +84,16 @@ static irqreturn_t smc_msg_done_isr(int irq, void *data) return IRQ_HANDLED; } -static bool smc_chan_available(struct device_node *of_node, int idx) +static bool +smc_chan_available(struct fwnode_handle *fwnode, int prot_id, int idx) { + struct device_node *of_node = to_of_node(fwnode); + + if (!of_node) + return false; + struct device_node *np __free(device_node) = - of_parse_phandle(of_node, "shmem", 0); + of_parse_phandle(of_node, "shmem", 0); if (!np) return false;
diff --git a/drivers/firmware/arm_scmi/transports/virtio.c b/drivers/firmware/arm_scmi/transports/virtio.c index 3282d82..3d608c8 100644 --- a/drivers/firmware/arm_scmi/transports/virtio.c +++ b/drivers/firmware/arm_scmi/transports/virtio.c
@@ -375,7 +375,8 @@ static unsigned int virtio_get_max_msg(struct scmi_chan_info *base_cinfo) return vioch->max_msg; } -static bool virtio_chan_available(struct device_node *of_node, int idx) +static bool +virtio_chan_available(struct fwnode_handle *fwnode, int prot_id, int idx) { struct scmi_vio_channel *channels, *vioch = NULL;
diff --git a/drivers/firmware/imx/imx-dsp.c b/drivers/firmware/imx/imx-dsp.c index ed79e82..7e3f45d 100644 --- a/drivers/firmware/imx/imx-dsp.c +++ b/drivers/firmware/imx/imx-dsp.c
@@ -99,8 +99,10 @@ static int imx_dsp_setup_channels(struct imx_dsp_ipc *dsp_ipc) else chan_name = kasprintf(GFP_KERNEL, "rxdb%d", i - 2); - if (!chan_name) - return -ENOMEM; + if (!chan_name) { + ret = -ENOMEM; + goto out; + } dsp_chan = &dsp_ipc->chans[i]; dsp_chan->name = chan_name;
diff --git a/drivers/firmware/microchip/mpfs-auto-update.c b/drivers/firmware/microchip/mpfs-auto-update.c index 1211fd8..b97d34b 100644 --- a/drivers/firmware/microchip/mpfs-auto-update.c +++ b/drivers/firmware/microchip/mpfs-auto-update.c
@@ -156,7 +156,7 @@ static int mpfs_auto_update_verify_image(struct fw_upload *fw_uploader) { struct mpfs_auto_update_priv *priv = fw_uploader->dd_handle; u32 *response_msg __free(kfree) = - kzalloc(AUTO_UPDATE_FEATURE_RESP_SIZE * sizeof(*response_msg), GFP_KERNEL); + kzalloc_objs(*response_msg, AUTO_UPDATE_FEATURE_RESP_SIZE); struct mpfs_mss_response *response __free(kfree) = kzalloc_obj(struct mpfs_mss_response); struct mpfs_mss_msg *message __free(kfree) = @@ -358,7 +358,7 @@ static const struct fw_upload_ops mpfs_auto_update_ops = { static int mpfs_auto_update_available(struct mpfs_auto_update_priv *priv) { u32 *response_msg __free(kfree) = - kzalloc(AUTO_UPDATE_FEATURE_RESP_SIZE * sizeof(*response_msg), GFP_KERNEL); + kzalloc_objs(*response_msg, AUTO_UPDATE_FEATURE_RESP_SIZE); struct mpfs_mss_response *response __free(kfree) = kzalloc_obj(struct mpfs_mss_response); struct mpfs_mss_msg *message __free(kfree) =
diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig index 95b968d..3ad22f8 100644 --- a/drivers/firmware/qcom/Kconfig +++ b/drivers/firmware/qcom/Kconfig
@@ -7,7 +7,7 @@ menu "Qualcomm firmware drivers" config QCOM_PAS - tristate "Qualcomm generic PAS interface driver" + tristate "Qualcomm generic PAS interface driver" if COMPILE_TEST help Enable the generic Peripheral Authentication Service (PAS) provided by the firmware. It acts as the common layer with different TZ @@ -16,6 +16,7 @@ config QCOM_PAS_TEE tristate "Qualcomm PAS TEE interface driver" + depends on ARCH_QCOM || COMPILE_TEST select QCOM_PAS depends on TEE depends on !CPU_BIG_ENDIAN @@ -25,7 +26,7 @@ by the firmware TEE implementation as the backend. config QCOM_SCM - tristate "Qualcomm PAS SCM interface driver" + tristate "Qualcomm PAS SCM interface driver" if ARCH_QCOM || COMPILE_TEST select QCOM_PAS select QCOM_TZMEM default y if ARCH_QCOM
diff --git a/drivers/firmware/qcom/qcom_scm-legacy.c b/drivers/firmware/qcom/qcom_scm-legacy.c index 029e6d1..fe751ee 100644 --- a/drivers/firmware/qcom/qcom_scm-legacy.c +++ b/drivers/firmware/qcom/qcom_scm-legacy.c
@@ -219,7 +219,7 @@ int scm_legacy_call(struct device *dev, const struct qcom_scm_desc *desc, * @res: SCM call return values * * This shall only be used with commands that are guaranteed to be - * uninterruptable, atomic and SMP safe. + * uninterruptible, atomic and SMP safe. */ int scm_legacy_call_atomic(struct device *unused, const struct qcom_scm_desc *desc,
diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 3eaa4c9..43e250f 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c
@@ -576,26 +576,6 @@ static void qcom_scm_set_download_mode(struct qcom_scm *scm, u32 dload_mode) writel_relaxed(minidump_dest, scm->minidump_sram); } -struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev, - u32 pas_id, - phys_addr_t mem_phys, - size_t mem_size) -{ - struct qcom_pas_context *ctx; - - ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL); - if (!ctx) - return ERR_PTR(-ENOMEM); - - ctx->dev = dev; - ctx->pas_id = pas_id; - ctx->mem_phys = mem_phys; - ctx->mem_size = mem_size; - - return (struct qcom_scm_pas_context *)ctx; -} -EXPORT_SYMBOL_GPL(devm_qcom_scm_pas_context_alloc); - static int __qcom_scm_pas_init_image(struct device *dev, u32 pas_id, dma_addr_t mdata_phys, struct qcom_scm_res *res) @@ -653,9 +633,9 @@ static int qcom_scm_pas_prep_and_init_image(struct device *dev, return ret ? : res.result[0]; } -static int __qcom_scm_pas_init_image2(struct device *dev, u32 pas_id, - const void *metadata, size_t size, - struct qcom_pas_context *ctx) +static int qcom_scm_pas_init_image(struct device *dev, u32 pas_id, + const void *metadata, size_t size, + struct qcom_pas_context *ctx) { struct qcom_scm_res res; dma_addr_t mdata_phys; @@ -695,16 +675,8 @@ static int __qcom_scm_pas_init_image2(struct device *dev, u32 pas_id, return ret ? : res.result[0]; } -int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size, - struct qcom_scm_pas_context *ctx) -{ - return __qcom_scm_pas_init_image2(__scm->dev, pas_id, metadata, size, - (struct qcom_pas_context *)ctx); -} -EXPORT_SYMBOL_GPL(qcom_scm_pas_init_image); - -static void __qcom_scm_pas_metadata_release(struct device *dev, - struct qcom_pas_context *ctx) +static void qcom_scm_pas_metadata_release(struct device *dev, + struct qcom_pas_context *ctx) { if (ctx->use_tzmem) qcom_tzmem_free(ctx->ptr); @@ -714,15 +686,8 @@ static void __qcom_scm_pas_metadata_release(struct device *dev, ctx->ptr = NULL; } -void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx) -{ - __qcom_scm_pas_metadata_release(__scm->dev, - (struct qcom_pas_context *)ctx); -} -EXPORT_SYMBOL_GPL(qcom_scm_pas_metadata_release); - -static int __qcom_scm_pas_mem_setup(struct device *dev, u32 pas_id, - phys_addr_t addr, phys_addr_t size) +static int qcom_scm_pas_mem_setup(struct device *dev, u32 pas_id, + phys_addr_t addr, phys_addr_t size) { int ret; struct qcom_scm_desc desc = { @@ -753,12 +718,6 @@ static int __qcom_scm_pas_mem_setup(struct device *dev, u32 pas_id, return ret ? : res.result[0]; } -int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size) -{ - return __qcom_scm_pas_mem_setup(__scm->dev, pas_id, addr, size); -} -EXPORT_SYMBOL_GPL(qcom_scm_pas_mem_setup); - static void *__qcom_scm_pas_get_rsc_table(struct device *dev, u32 pas_id, void *input_rt_tzm, size_t input_rt_size, @@ -812,11 +771,10 @@ static void *__qcom_scm_pas_get_rsc_table(struct device *dev, u32 pas_id, return ret ? ERR_PTR(ret) : output_rt_tzm; } -static void *__qcom_scm_pas_get_rsc_table2(struct device *dev, - struct qcom_pas_context *ctx, - void *input_rt, - size_t input_rt_size, - size_t *output_rt_size) +static void *qcom_scm_pas_get_rsc_table(struct device *dev, + struct qcom_pas_context *ctx, + void *input_rt, size_t input_rt_size, + size_t *output_rt_size) { struct resource_table empty_rsc = {}; size_t size = SZ_16K; @@ -854,17 +812,27 @@ static void *__qcom_scm_pas_get_rsc_table2(struct device *dev, output_rt_tzm = __qcom_scm_pas_get_rsc_table(dev, ctx->pas_id, input_rt_tzm, input_rt_size, &size); - if (PTR_ERR(output_rt_tzm) == -EOVERFLOW) - /* Try again with the size requested by the TZ */ + if (PTR_ERR(output_rt_tzm) == -EOVERFLOW) { + /* Try again with a page-aligned size requested by the TZ. */ + size = PAGE_ALIGN(size); output_rt_tzm = __qcom_scm_pas_get_rsc_table(dev, ctx->pas_id, input_rt_tzm, input_rt_size, &size); + } if (IS_ERR(output_rt_tzm)) { ret = PTR_ERR(output_rt_tzm); goto free_input_rt; } + *output_rt_size = size; + + /* A zero-sized table means that TrustZone has no resource table. */ + if (!size) { + tbl_ptr = NULL; + goto free_output_rt; + } + tbl_ptr = kmemdup(output_rt_tzm, size, GFP_KERNEL); if (!tbl_ptr) { qcom_tzmem_free(output_rt_tzm); @@ -872,7 +840,7 @@ static void *__qcom_scm_pas_get_rsc_table2(struct device *dev, goto free_input_rt; } - *output_rt_size = size; +free_output_rt: qcom_tzmem_free(output_rt_tzm); free_input_rt: @@ -887,19 +855,7 @@ static void *__qcom_scm_pas_get_rsc_table2(struct device *dev, return ret ? ERR_PTR(ret) : tbl_ptr; } -struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *ctx, - void *input_rt, - size_t input_rt_size, - size_t *output_rt_size) -{ - return __qcom_scm_pas_get_rsc_table2(__scm->dev, - (struct qcom_pas_context *)ctx, - input_rt, input_rt_size, - output_rt_size); -} -EXPORT_SYMBOL_GPL(qcom_scm_pas_get_rsc_table); - -static int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 pas_id) +static int qcom_scm_pas_auth_and_reset(struct device *dev, u32 pas_id) { int ret; struct qcom_scm_desc desc = { @@ -928,14 +884,8 @@ static int __qcom_scm_pas_auth_and_reset(struct device *dev, u32 pas_id) return ret ? : res.result[0]; } -int qcom_scm_pas_auth_and_reset(u32 pas_id) -{ - return __qcom_scm_pas_auth_and_reset(__scm->dev, pas_id); -} -EXPORT_SYMBOL_GPL(qcom_scm_pas_auth_and_reset); - -static int __qcom_scm_pas_prepare_and_auth_reset(struct device *dev, - struct qcom_pas_context *ctx) +static int qcom_scm_pas_prepare_and_auth_reset(struct device *dev, + struct qcom_pas_context *ctx) { u64 handle; int ret; @@ -946,7 +896,7 @@ static int __qcom_scm_pas_prepare_and_auth_reset(struct device *dev, * memory region and then invokes a call to TrustZone to authenticate. */ if (!ctx->use_tzmem) - return __qcom_scm_pas_auth_and_reset(dev, ctx->pas_id); + return qcom_scm_pas_auth_and_reset(dev, ctx->pas_id); /* * When Linux runs @ EL2 Linux must create the shmbridge itself and then @@ -956,21 +906,14 @@ static int __qcom_scm_pas_prepare_and_auth_reset(struct device *dev, if (ret) return ret; - ret = __qcom_scm_pas_auth_and_reset(dev, ctx->pas_id); + ret = qcom_scm_pas_auth_and_reset(dev, ctx->pas_id); qcom_tzmem_shm_bridge_delete(handle); return ret; } -int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx) -{ - return __qcom_scm_pas_prepare_and_auth_reset(__scm->dev, - (struct qcom_pas_context *)ctx); -} -EXPORT_SYMBOL_GPL(qcom_scm_pas_prepare_and_auth_reset); - -static int __qcom_scm_pas_set_remote_state(struct device *dev, u32 state, - u32 pas_id) +static int qcom_scm_pas_set_remote_state(struct device *dev, u32 state, + u32 pas_id) { struct qcom_scm_desc desc = { .svc = QCOM_SCM_SVC_BOOT, @@ -988,13 +931,7 @@ static int __qcom_scm_pas_set_remote_state(struct device *dev, u32 state, return ret ? : res.result[0]; } -int qcom_scm_set_remote_state(u32 state, u32 id) -{ - return __qcom_scm_pas_set_remote_state(__scm->dev, state, id); -} -EXPORT_SYMBOL_GPL(qcom_scm_set_remote_state); - -static int __qcom_scm_pas_shutdown(struct device *dev, u32 pas_id) +static int qcom_scm_pas_shutdown(struct device *dev, u32 pas_id) { int ret; struct qcom_scm_desc desc = { @@ -1023,13 +960,7 @@ static int __qcom_scm_pas_shutdown(struct device *dev, u32 pas_id) return ret ? : res.result[0]; } -int qcom_scm_pas_shutdown(u32 pas_id) -{ - return __qcom_scm_pas_shutdown(__scm->dev, pas_id); -} -EXPORT_SYMBOL_GPL(qcom_scm_pas_shutdown); - -static bool __qcom_scm_pas_supported(struct device *dev, u32 pas_id) +static bool qcom_scm_pas_supported(struct device *dev, u32 pas_id) { int ret; struct qcom_scm_desc desc = { @@ -1050,23 +981,17 @@ static bool __qcom_scm_pas_supported(struct device *dev, u32 pas_id) return ret ? false : !!res.result[0]; } -bool qcom_scm_pas_supported(u32 pas_id) -{ - return __qcom_scm_pas_supported(__scm->dev, pas_id); -} -EXPORT_SYMBOL_GPL(qcom_scm_pas_supported); - static struct qcom_pas_ops qcom_pas_ops_scm = { .drv_name = "qcom_scm", - .supported = __qcom_scm_pas_supported, - .init_image = __qcom_scm_pas_init_image2, - .mem_setup = __qcom_scm_pas_mem_setup, - .get_rsc_table = __qcom_scm_pas_get_rsc_table2, - .auth_and_reset = __qcom_scm_pas_auth_and_reset, - .prepare_and_auth_reset = __qcom_scm_pas_prepare_and_auth_reset, - .set_remote_state = __qcom_scm_pas_set_remote_state, - .shutdown = __qcom_scm_pas_shutdown, - .metadata_release = __qcom_scm_pas_metadata_release, + .supported = qcom_scm_pas_supported, + .init_image = qcom_scm_pas_init_image, + .mem_setup = qcom_scm_pas_mem_setup, + .get_rsc_table = qcom_scm_pas_get_rsc_table, + .auth_and_reset = qcom_scm_pas_auth_and_reset, + .prepare_and_auth_reset = qcom_scm_pas_prepare_and_auth_reset, + .set_remote_state = qcom_scm_pas_set_remote_state, + .shutdown = qcom_scm_pas_shutdown, + .metadata_release = qcom_scm_pas_metadata_release, }; /** @@ -2302,6 +2227,7 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_send); static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = { { .compatible = "asus,vivobook-s15" }, { .compatible = "asus,vivobook-s15-x1p4" }, + { .compatible = "asus,zenbook-a14-ux3407na" }, { .compatible = "asus,zenbook-a14-ux3407qa" }, { .compatible = "asus,zenbook-a14-ux3407ra" }, { .compatible = "asus,zenbook-a16-ux3607oa" }, @@ -2311,14 +2237,17 @@ static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = { { .compatible = "ecs,liva-qc710" }, { .compatible = "honor,magicbook-art-14-snapdragon" }, { .compatible = "hp,elitebook-ultra-g1q" }, + { .compatible = "hp,elitebook-x-g2q" }, { .compatible = "hp,omnibook-x14" }, { .compatible = "huawei,gaokun3" }, { .compatible = "lenovo,flex-5g" }, { .compatible = "lenovo,ideacentre-mini-01q8x10" }, { .compatible = "lenovo,thinkbook-16" }, { .compatible = "lenovo,thinkpad-t14s" }, + { .compatible = "lenovo,thinkpad-t14s-gen7" }, { .compatible = "lenovo,thinkpad-x13s", }, { .compatible = "lenovo,yoga-slim7x" }, + { .compatible = "lenovo,yoga-slim7x-gen11" }, { .compatible = "medion,sprchrgd14s1" }, { .compatible = "microsoft,arcata", }, { .compatible = "microsoft,surface-pro-12in", }, @@ -2327,7 +2256,9 @@ static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = { { .compatible = "microsoft,romulus13", }, { .compatible = "microsoft,romulus15", }, { .compatible = "qcom,glymur-crd" }, + { .compatible = "qcom,glymur-qcb" }, { .compatible = "qcom,hamoa-iot-evk" }, + { .compatible = "qcom,kalambo-crd" }, { .compatible = "qcom,mahua-crd" }, { .compatible = "qcom,purwa-iot-evk" }, { .compatible = "qcom,sc8180x-primus" }, @@ -2844,17 +2775,15 @@ static int qcom_scm_probe(struct platform_device *pdev) if (ret) return ret; - ret = of_reserved_mem_device_init(scm->dev); + ret = devm_of_reserved_mem_device_init(scm->dev); if (ret && ret != -ENODEV) return dev_err_probe(scm->dev, ret, "Failed to setup the reserved memory region for TZ mem\n"); ret = qcom_tzmem_enable(scm->dev); - if (ret) { - ret = dev_err_probe(scm->dev, ret, - "Failed to enable the TrustZone memory allocator\n"); - goto err_rmem; - } + if (ret) + return dev_err_probe(scm->dev, ret, + "Failed to enable the TrustZone memory allocator\n"); memset(&pool_config, 0, sizeof(pool_config)); pool_config.initial_size = 0; @@ -2862,11 +2791,9 @@ static int qcom_scm_probe(struct platform_device *pdev) pool_config.max_size = SZ_256K; scm->mempool = devm_qcom_tzmem_pool_new(scm->dev, &pool_config); - if (IS_ERR(scm->mempool)) { - ret = dev_err_probe(scm->dev, PTR_ERR(scm->mempool), - "Failed to create the SCM memory pool\n"); - goto err_rmem; - } + if (IS_ERR(scm->mempool)) + return dev_err_probe(scm->dev, PTR_ERR(scm->mempool), + "Failed to create the SCM memory pool\n"); ret = qcom_scm_query_waitq_count(scm); scm->wq_cnt = ret < 0 ? QCOM_SCM_DEFAULT_WAITQ_COUNT : ret; @@ -2942,10 +2869,6 @@ static int qcom_scm_probe(struct platform_device *pdev) qcom_scm_gunyah_wdt_init(scm); return 0; - -err_rmem: - of_reserved_mem_device_release(scm->dev); - return ret; } static void qcom_scm_shutdown(struct platform_device *pdev)
diff --git a/drivers/firmware/qcom/qcom_tzmem.c b/drivers/firmware/qcom/qcom_tzmem.c index 322fa92..e1d944d 100644 --- a/drivers/firmware/qcom/qcom_tzmem.c +++ b/drivers/firmware/qcom/qcom_tzmem.c
@@ -82,6 +82,7 @@ static const char *const qcom_tzmem_blacklist[] = { "qcom,sc8180x", "qcom,sdm670", /* failure in GPU firmware loading */ "qcom,sdm845", /* reset in rmtfs memory assignment */ + "qcom,sm7125", /* hang in rmtfs memory assignment */ "qcom,sm7150", /* reset in rmtfs memory assignment */ "qcom,sm8150", /* reset in rmtfs memory assignment */ NULL @@ -516,7 +517,7 @@ int qcom_tzmem_enable(struct device *dev) static int result; qcom_tzmem_dev = dev; - DO_ONCE(qcom_tzmem_do_init, &result); + DO_ONCE_SLEEPABLE(qcom_tzmem_do_init, &result); return result; } EXPORT_SYMBOL_GPL(qcom_tzmem_enable);
diff --git a/drivers/firmware/ti_sci.c b/drivers/firmware/ti_sci.c index 33d7c4a..5fa63ff 100644 --- a/drivers/firmware/ti_sci.c +++ b/drivers/firmware/ti_sci.c
@@ -4050,7 +4050,7 @@ static const struct ti_sci_desc ti_sci_pmmc_k2g_desc = { .default_host_id = 2, /* Conservative duration */ .max_rx_timeout_ms = 1000, - /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */ + /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle up to 128 messages! */ .max_msgs = 20, .max_msg_size = 64, }; @@ -4060,7 +4060,7 @@ static const struct ti_sci_desc ti_sci_pmmc_am654_desc = { .default_host_id = 12, /* Conservative duration */ .max_rx_timeout_ms = 10000, - /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle upto 128 messages! */ + /* Limited by MBOX_TX_QUEUE_LEN. K2G can handle up to 128 messages! */ .max_msgs = 20, .max_msg_size = 60, }; @@ -4132,7 +4132,7 @@ static int ti_sci_probe(struct platform_device *pdev) /* Pre-initialize the buffer pointer to pre-allocated buffers */ for (i = 0, xfer = minfo->xfer_block; i < desc->max_msgs; i++, xfer++) { - xfer->xfer_buf = devm_kcalloc(dev, 1, desc->max_msg_size, + xfer->xfer_buf = devm_kzalloc(dev, desc->max_msg_size, GFP_KERNEL); if (!xfer->xfer_buf) return -ENOMEM;
diff --git a/drivers/firmware/xilinx/zynqmp-ufs.c b/drivers/firmware/xilinx/zynqmp-ufs.c index 85da8a8..81ccf61 100644 --- a/drivers/firmware/xilinx/zynqmp-ufs.c +++ b/drivers/firmware/xilinx/zynqmp-ufs.c
@@ -5,6 +5,7 @@ * Copyright (C) 2025 Advanced Micro Devices, Inc. */ +#include <linux/delay.h> #include <linux/firmware/xlnx-zynqmp.h> #include <linux/module.h> @@ -33,7 +34,7 @@ * * Return: Returns 0 on success or error value on failure. */ -int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready) +static int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready) { u32 regval; int ret; @@ -53,7 +54,6 @@ int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready) return ret; } -EXPORT_SYMBOL_GPL(zynqmp_pm_is_mphy_tx_rx_config_ready); /** * zynqmp_pm_is_sram_init_done - check SRAM initialization @@ -61,7 +61,7 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_is_mphy_tx_rx_config_ready); * * Return: Returns 0 on success or error value on failure. */ -int zynqmp_pm_is_sram_init_done(bool *is_done) +static int zynqmp_pm_is_sram_init_done(bool *is_done) { u32 regval; int ret; @@ -81,7 +81,69 @@ int zynqmp_pm_is_sram_init_done(bool *is_done) return ret; } -EXPORT_SYMBOL_GPL(zynqmp_pm_is_sram_init_done); + +/** + * zynqmp_pm_wait_mphy_tx_rx_config_ready - wait for M-PHY TX-RX config ready + * @timeout_us: Caller-supplied timeout budget in microseconds + * + * Poll the M-PHY TX-RX configuration-ready status until it settles or the + * timeout elapses. The poll loop is EEMI-specific (legacy firmware only offers + * the per-read status primitive), so it lives here in the firmware driver + * rather than in the UFS controller driver; an SCMI-based backend can instead + * offload the wait to the platform in a single call. The timeout budget is + * owned by the caller (UFS driver), keeping the policy with the consumer. + * + * Return: Returns 0 once ready, -ETIMEDOUT on timeout, or error value. + */ +int zynqmp_pm_wait_mphy_tx_rx_config_ready(u32 timeout_us) +{ + bool is_ready; + int ret; + + while (timeout_us--) { + ret = zynqmp_pm_is_mphy_tx_rx_config_ready(&is_ready); + if (ret) + return ret; + + if (!is_ready) + return 0; + + usleep_range(1, 5); + } + + return -ETIMEDOUT; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_wait_mphy_tx_rx_config_ready); + +/** + * zynqmp_pm_wait_sram_init_done - wait for SRAM initialization to complete + * @timeout_us: Caller-supplied timeout budget in microseconds + * + * Poll the SRAM initialization-done status until it is set or the timeout + * elapses. As with the M-PHY wait, the poll loop is EEMI-specific and kept in + * the firmware driver so the UFS controller driver stays backend-agnostic. + * + * Return: Returns 0 once done, -ETIMEDOUT on timeout, or error value. + */ +int zynqmp_pm_wait_sram_init_done(u32 timeout_us) +{ + bool is_done; + int ret; + + while (timeout_us--) { + ret = zynqmp_pm_is_sram_init_done(&is_done); + if (ret) + return ret; + + if (is_done) + return 0; + + usleep_range(1, 5); + } + + return -ETIMEDOUT; +} +EXPORT_SYMBOL_GPL(zynqmp_pm_wait_sram_init_done); /** * zynqmp_pm_set_sram_bypass - Set SRAM bypass Control
diff --git a/drivers/firmware/xilinx/zynqmp.c b/drivers/firmware/xilinx/zynqmp.c index fe65074..d76660c 100644 --- a/drivers/firmware/xilinx/zynqmp.c +++ b/drivers/firmware/xilinx/zynqmp.c
@@ -1527,7 +1527,6 @@ EXPORT_SYMBOL_GPL(zynqmp_pm_request_wake); */ int zynqmp_pm_start_rpu(const u32 node, const u64 bootaddr) { - enum rpu_boot_mem bootmem; int ret; /* @@ -1536,22 +1535,55 @@ int zynqmp_pm_start_rpu(const u32 node, const u64 bootaddr) * starts at the base-address and subsequent vectors are on 4-byte * boundaries. * + * The Cortex-R5 cores can boot from TCM and OCM memories. * Exception vectors can start either from 0x0000_0000 (LOVEC) or * from 0xFFFF_0000 (HIVEC) which is mapped in the OCM (On-Chip Memory) * * Usually firmware will put Exception vectors at LOVEC. * + * The Cortex-R52 cores can boot from DDR and TCM. + * That means vector table can be at address 0x0 or at any DDR address + * that is in the 32-bit address range. Note that booting from DDR + * address 0x0 is not supported and the user must always assume that if + * 0x0 address is passed, then it will be TCM boot. + * * It is not recommend that you change the exception vector. * Changing the EVP to HIVEC will result in increased interrupt latency * and jitter. Also, if the OCM is secured and the Cortex-R5F processor * is non-secured, then the Cortex-R5F processor cannot access the * HIVEC exception vectors in the OCM. */ - bootmem = (bootaddr >= 0xFFFC0000) ? - PM_RPU_BOOTMEM_HIVEC : PM_RPU_BOOTMEM_LOVEC; + if (upper_32_bits(bootaddr)) { + pr_err("invalid bootaddr = 0x%llx\n", bootaddr); + return -EINVAL; + } - pr_debug("RPU boot addr 0x%llx from %s.", bootaddr, - bootmem == PM_RPU_BOOTMEM_HIVEC ? "OCM" : "TCM"); + /* + * New platforms can boot from DDR and require the DDR address + * to be configured explicitly. If the correct version of the + * IOCTL_RPU_BOOT_ADDR_CONFIG ioctl is not supported, do not + * treat it as a failure. If a DDR address is passed on other + * platforms, the PM request wake EEMI call will still fail and + * the RPU won't boot. + */ + ret = zynqmp_pm_is_function_supported(PM_IOCTL, + IOCTL_RPU_BOOT_ADDR_CONFIG); + if (!ret) { + /* config ddr boot address */ + ret = zynqmp_pm_invoke_fn(PM_IOCTL, NULL, 3, + node, + IOCTL_RPU_BOOT_ADDR_CONFIG, + bootaddr); + if (ret < 0) { + pr_err("failed to set RPU Boot address 0x%llx\n", + bootaddr); + return ret; + } + } else if (ret != -EOPNOTSUPP && ret != -ENODATA) { + pr_err("ioctl rpu boot addr config ver check failed %d\n", + ret); + return ret; + } /* Request node before starting RPU core if new version of API is supported */ if (zynqmp_pm_feature(PM_REQUEST_NODE) > PM_API_VERSION_1) { @@ -1565,7 +1597,7 @@ int zynqmp_pm_start_rpu(const u32 node, const u64 bootaddr) } ret = zynqmp_pm_request_wake(node, true, - bootmem, ZYNQMP_PM_REQUEST_ACK_NO); + bootaddr, ZYNQMP_PM_REQUEST_ACK_NO); if (ret) pr_err("failed to start RPU = 0x%x\n", node); return ret;
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index a48586b..0e38657 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig
@@ -204,6 +204,27 @@ Select this option to enable GPIO driver for Atheros AR71XX/AR724X/AR913X SoC devices. +config GPIO_AXIADO_SGPIO + tristate "Axiado AX3005 SGPIO support" + depends on ARCH_AXIADO || COMPILE_TEST + select GPIOLIB_IRQCHIP + select GPIO_REGMAP + select REGMAP_MMIO + help + Enable support for the Axiado AX3005 Serial GPIO (SGPIO) + controller. + + The SGPIO controller provides a serialized interface for + controlling multiple GPIO signals over a limited number of + physical lines. Each signal is exposed as one input and one + output line, and input lines can raise interrupts. + + This driver integrates with the Linux GPIO subsystem and + exposes the controller as a standard GPIO provider. + + To compile this driver as a module, choose M here: the module + will be called gpio-axiado-sgpio. + config GPIO_RASPBERRYPI_EXP tristate "Raspberry Pi 3 GPIO Expander" default RASPBERRYPI_FIRMWARE @@ -1385,6 +1406,18 @@ be configured to GPO on the ROHM PMIC. The pin configuration is done on OTP at manufacturing. +config GPIO_BD73800 + tristate "ROHM BD73800 GPIO support" + depends on MFD_ROHM_BD71828 + select GPIO_REGMAP + help + Support for GPIOs on ROHM BD73800 PMIC. There can be up to 4 + GPI or GPO pins available on the PMIC in total. The purpose of + the pins is decided at the device manufacturing by OTP + configuration and can't be reconfigured later. Enable this + if your PMIC has pins set as GPIs or GPOs and if you wish to + control the pins via the GPIO framework. + config GPIO_BD9571MWV tristate "ROHM BD9571 GPIO support" depends on MFD_BD9571MWV @@ -1818,6 +1851,18 @@ menu "Auxiliary Bus GPIO drivers" depends on AUXILIARY_BUS +config GPIO_AD7768 + tristate "Analog Devices AD7768 GPIO support" + depends on AD7768 + depends on GPIOLIB + select GPIO_REGMAP + help + Say yes here to expose the AD7768 utility pins as GPIOs when the + device tree node is marked as a GPIO controller. + + To compile this driver as a module, choose M here: the module will be + called gpio-ad7768. + config GPIO_LTC4283 tristate "Analog Devices LTC4283 GPIO support" depends on SENSORS_LTC4283
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index dc9e6d6..f0ab389 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile
@@ -27,6 +27,7 @@ obj-$(CONFIG_GPIO_104_IDIO_16) += gpio-104-idio-16.o obj-$(CONFIG_GPIO_74X164) += gpio-74x164.o obj-$(CONFIG_GPIO_74XX_MMIO) += gpio-74xx-mmio.o +obj-$(CONFIG_GPIO_AD7768) += gpio-ad7768.o obj-$(CONFIG_GPIO_ADNP) += gpio-adnp.o obj-$(CONFIG_GPIO_ADP5520) += gpio-adp5520.o obj-$(CONFIG_GPIO_ADP5585) += gpio-adp5585.o @@ -40,11 +41,13 @@ obj-$(CONFIG_GPIO_ASPEED) += gpio-aspeed.o obj-$(CONFIG_GPIO_ASPEED_SGPIO) += gpio-aspeed-sgpio.o obj-$(CONFIG_GPIO_ATH79) += gpio-ath79.o +obj-$(CONFIG_GPIO_AXIADO_SGPIO) += gpio-axiado-sgpio.o obj-$(CONFIG_GPIO_BCM_KONA) += gpio-bcm-kona.o obj-$(CONFIG_GPIO_BCM_XGS_IPROC) += gpio-xgs-iproc.o obj-$(CONFIG_GPIO_BD71815) += gpio-bd71815.o obj-$(CONFIG_GPIO_BD71828) += gpio-bd71828.o obj-$(CONFIG_GPIO_BD72720) += gpio-bd72720.o +obj-$(CONFIG_GPIO_BD73800) += gpio-bd73800.o obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o obj-$(CONFIG_GPIO_BLZP1600) += gpio-blzp1600.o obj-$(CONFIG_GPIO_BRCMSTB) += gpio-brcmstb.o
diff --git a/drivers/gpio/gpio-ad7768.c b/drivers/gpio/gpio-ad7768.c new file mode 100644 index 0000000..c37e1ac --- /dev/null +++ b/drivers/gpio/gpio-ad7768.c
@@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Analog Devices AD7768 GPIO auxiliary driver + * + * Copyright 2026 Analog Devices Inc. + */ + +#include <linux/auxiliary_bus.h> +#include <linux/bitops.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/gpio/driver.h> +#include <linux/gpio/regmap.h> +#include <linux/module.h> +#include <linux/pm_runtime.h> +#include <linux/property.h> +#include <linux/regmap.h> + +#define AD7768_REG_GPIO_CONTROL 0x0E +#define AD7768_GPIO_UGPIO_ENABLE BIT(7) + +#define AD7768_REG_GPIO_WRITE 0x0F +#define AD7768_REG_GPIO_READ 0x10 + +#define AD7768_NUM_GPIOS 5 +#define AD7768_FILTER_GPIO 4 + +static int ad7768_gpio_init_valid_mask(struct gpio_chip *gc, + unsigned long *valid_mask, + unsigned int ngpios) +{ + if (ngpios > AD7768_FILTER_GPIO && + fwnode_property_match_string(gc->fwnode, "clock-names", "mclk") < 0) + __clear_bit(AD7768_FILTER_GPIO, valid_mask); + + return 0; +} + +static int ad7768_gpio_reg_mask_xlate(struct gpio_regmap *gpio, + enum gpio_regmap_operation op, + unsigned int base, unsigned int offset, + unsigned int *reg, unsigned int *mask) +{ + struct regmap *regmap = gpio_regmap_get_drvdata(gpio); + int ret; + + *reg = base; + *mask = BIT(offset); + + if (op != GPIO_REGMAP_GET_OP) + return 0; + + /* + * AD7768 has separate input-state and output-latch registers. For an + * output line, report the programmed value from the output latch; + * input lines continue to use the input-state register. + */ + ret = regmap_test_bits(regmap, AD7768_REG_GPIO_CONTROL, *mask); + if (ret < 0) + return ret; + if (ret) + *reg = AD7768_REG_GPIO_WRITE; + + return 0; +} + +static int ad7768_gpio_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) +{ + struct gpio_regmap_config config; + struct device *dev = &adev->dev; + struct device *parent = dev->parent; + struct regmap *map; + int ret; + + map = dev_get_regmap(parent, NULL); + if (!map) + return -ENODEV; + + PM_RUNTIME_ACQUIRE_AUTOSUSPEND(parent, pm); + ret = PM_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + + ret = regmap_set_bits(map, AD7768_REG_GPIO_CONTROL, AD7768_GPIO_UGPIO_ENABLE); + if (ret) + return ret; + + config = (struct gpio_regmap_config) { + .parent = dev, + .regmap = map, + .label = dev_name(parent), + .ngpio = AD7768_NUM_GPIOS, + .reg_dat_base = AD7768_REG_GPIO_READ, + .reg_set_base = AD7768_REG_GPIO_WRITE, + .reg_dir_out_base = AD7768_REG_GPIO_CONTROL, + .pm_dev = parent, + .fwnode = dev_fwnode(parent), + .reg_mask_xlate = ad7768_gpio_reg_mask_xlate, + .init_valid_mask = ad7768_gpio_init_valid_mask, + .drvdata = map, + }; + + return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &config)); +} + +static const struct auxiliary_device_id ad7768_gpio_ids[] = { + { .name = "ad7768.gpio" }, + { } +}; +MODULE_DEVICE_TABLE(auxiliary, ad7768_gpio_ids); + +static struct auxiliary_driver ad7768_gpio_driver = { + .probe = ad7768_gpio_probe, + .id_table = ad7768_gpio_ids, +}; +module_auxiliary_driver(ad7768_gpio_driver); + +MODULE_AUTHOR("Janani Sunil <janani.sunil@analog.com>"); +MODULE_DESCRIPTION("Analog Devices AD7768 GPIO auxiliary driver"); +MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-adp5585.c b/drivers/gpio/gpio-adp5585.c index 6f10fc6..7c04a7e 100644 --- a/drivers/gpio/gpio-adp5585.c +++ b/drivers/gpio/gpio-adp5585.c
@@ -390,16 +390,6 @@ static const struct irq_chip adp5585_irq_chip = { GPIOCHIP_IRQ_RESOURCE_HELPERS, }; -static void adp5585_gpio_unreg_notifier(void *data) -{ - struct adp5585_gpio_dev *adp5585_gpio = data; - struct device *dev = adp5585_gpio->gpio_chip.parent; - struct adp5585_dev *adp5585 = dev_get_drvdata(dev->parent); - - blocking_notifier_chain_unregister(&adp5585->event_notifier, - &adp5585_gpio->nb); -} - static int adp5585_gpio_probe(struct platform_device *pdev) { struct adp5585_dev *adp5585 = dev_get_drvdata(pdev->dev.parent); @@ -450,13 +440,9 @@ static int adp5585_gpio_probe(struct platform_device *pdev) girq->threaded = true; adp5585_gpio->nb.notifier_call = adp5585_gpio_key_event; - ret = blocking_notifier_chain_register(&adp5585->event_notifier, - &adp5585_gpio->nb); - if (ret) - return ret; - - ret = devm_add_action_or_reset(dev, adp5585_gpio_unreg_notifier, - adp5585_gpio); + ret = devm_blocking_notifier_chain_register(dev, + &adp5585->event_notifier, + &adp5585_gpio->nb); if (ret) return ret; }
diff --git a/drivers/gpio/gpio-altera.c b/drivers/gpio/gpio-altera.c index 532e336..a6ac935 100644 --- a/drivers/gpio/gpio-altera.c +++ b/drivers/gpio/gpio-altera.c
@@ -220,8 +220,11 @@ static int altera_gpio_probe(struct platform_device *pdev) return -ENOMEM; mapped_irq = platform_get_irq_optional(pdev, 0); - if (mapped_irq < 0) + if (mapped_irq < 0) { + if (mapped_irq != -ENXIO) + return mapped_irq; goto skip_irq; + } if (device_property_read_u32(dev, "altr,interrupt-type", ®)) { dev_err(&pdev->dev,
diff --git a/drivers/gpio/gpio-axiado-sgpio.c b/drivers/gpio/gpio-axiado-sgpio.c new file mode 100644 index 0000000..b57a507 --- /dev/null +++ b/drivers/gpio/gpio-axiado-sgpio.c
@@ -0,0 +1,736 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (c) 2022-2026 Axiado Corporation + */ + +#include <linux/bitfield.h> +#include <linux/bitmap.h> +#include <linux/bitops.h> +#include <linux/bits.h> +#include <linux/clk.h> +#include <linux/device.h> +#include <linux/err.h> +#include <linux/gpio/driver.h> +#include <linux/gpio/regmap.h> +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/irqdesc.h> +#include <linux/irqdomain.h> +#include <linux/math.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/property.h> +#include <linux/regmap.h> +#include <linux/types.h> + +struct axiado_sgpio_reg_offsets { + u32 mux_0; + u32 preset_0; + u32 count_0; + u32 pos_0; + + u32 mux_1; + u32 ld; + u32 ld_ss; + + u32 preset_1; + u32 count_1; + u32 pos_1; + + u32 mux_2; + u32 dout; + u32 dout_ss; + + u32 preset_2; + u32 count_2; + u32 pos_2; + + u32 mux_3; + u32 preset_3; + u32 count_3; + u32 pos_3; + + u32 mux_4; + u32 oe; + u32 oe_ss; + + u32 preset_4; + u32 count_4; + u32 pos_4; + + u32 mask; + u32 ctrl_en; + u32 ctrl_en_pos; + + u32 din_ss; + u32 status; +}; + +static const struct axiado_sgpio_reg_offsets axiado_sgpio_offsets = { + .mux_0 = 0x000, + .preset_0 = 0x1dc, + .count_0 = 0x1f0, + .pos_0 = 0x204, + + .mux_1 = 0x004, + .ld = 0x014, + .ld_ss = 0x0d8, + + .preset_1 = 0x1e0, + .count_1 = 0x1f4, + .pos_1 = 0x208, + + .mux_2 = 0x008, + .dout = 0x054, + .dout_ss = 0x158, + + .preset_2 = 0x1e4, + .count_2 = 0x1f8, + .pos_2 = 0x20c, + + .mux_3 = 0x00c, + .preset_3 = 0x1e8, + .count_3 = 0x1fc, + .pos_3 = 0x210, + + .mux_4 = 0x010, + .oe = 0x0d4, + .oe_ss = 0x1d8, + + .preset_4 = 0x1ec, + .count_4 = 0x200, + .pos_4 = 0x214, + + .mask = 0x224, + .ctrl_en = 0x218, + .ctrl_en_pos = 0x21c, + + .din_ss = 0x198, + .status = 0x228, +}; + +/* Number of SGPIO positions held by one bank register. */ +#define SGPIO_BANK_SIZE 32 +#define SGPIO_MAX_SIGNALS 512 +#define SGPIO_NUM_BANKS 16 + +/* + * Slice mux encodings taken from the AX3005 SGPIO programming sequence. + */ +#define SGPIO_MUX_CLK 0x306 +#define SGPIO_MUX_DATA 0x30c +#define SGPIO_MUX_DIN 0x14c +#define SGPIO_MUX_OE 0x10c + +/* A POS register holds the first and the last position driven by the slice. */ +#define SGPIO_POS_FIRST GENMASK(31, 16) +#define SGPIO_POS_LAST GENMASK(15, 0) +#define SGPIO_POS(pos) (FIELD_PREP(SGPIO_POS_FIRST, (pos)) | \ + FIELD_PREP(SGPIO_POS_LAST, (pos))) + +/* The clock and output enable slices always cover a full bank. */ +#define SGPIO_POS_FULL_BANK SGPIO_POS(SGPIO_BANK_SIZE - 1) + +/* The enable and interrupt registers hold one bit per slice. */ +#define SGPIO_SLICE_MASK GENMASK(15, 0) + +/* + * Interrupt sources enabled by the programming sequence. Bit 13 is left + * masked, the remaining slice events are all reported. + */ +#define SGPIO_IRQ_ENABLE 0xdfff + +/* The upper half of the status register reports one bit per data bank. */ +#define SGPIO_STATUS_EXCHANGE GENMASK(31, 16) + +struct axiado_sgpio { + u32 preset_value; + u32 count_value; + u32 pos_reg; + /* Last sampled input word of each bank, for edge detection. */ + u32 *din_shadow; + unsigned long *irq_unmasked; + unsigned long *irq_rising; + unsigned long *irq_falling; + u32 nsignals; + u32 din_bank_shift; + unsigned long *dir_out; + struct gpio_regmap *gpio; + struct irq_domain *domain; + struct regmap *regmap; + const struct axiado_sgpio_reg_offsets *regs; +}; + +/* + * Tell lockdep that these interrupts are in a different category than the + * parent they are handled from, so that the nested handling is not reported + * as recursion. + */ +static struct lock_class_key axiado_sgpio_irq_lock_class; +static struct lock_class_key axiado_sgpio_irq_request_class; + +/* + * Each SGPIO signal is exposed as two GPIO lines: an even line for the serial + * input and the following odd line for the serial output. Signal n therefore + * lives in bit (n % 32) of bank (n / 32) of either the input or the output + * register. + */ +static int axiado_sgpio_reg_mask_xlate(struct gpio_regmap *gpio, + enum gpio_regmap_operation op, + unsigned int base, unsigned int offset, + unsigned int *reg, unsigned int *mask) +{ + struct axiado_sgpio *sgpio = gpio_regmap_get_drvdata(gpio); + unsigned int signal = offset / 2; + unsigned int bank = signal / SGPIO_BANK_SIZE; + + /* + * An output line lives in the output register for both reads and + * writes, so the register follows from the line rather than from the + * operation. The AX3005 input banks are right aligned, hence the + * shift. + */ + if (offset % 2) + base = sgpio->regs->dout_ss; + else + bank += sgpio->din_bank_shift; + + *reg = base + bank * sizeof(u32); + *mask = BIT(signal % SGPIO_BANK_SIZE); + + return 0; +} + +static irqreturn_t axiado_sgpio_irq_handler(int irq, void *arg) +{ + struct axiado_sgpio *sgpio = arg; + unsigned int nbanks = DIV_ROUND_UP(sgpio->nsignals, SGPIO_BANK_SIZE); + u32 status, new_value, changed_value; + unsigned int bit, reg_ptr, i; + int ret; + + /* Read-on-clear (ACK) parent cause */ + ret = regmap_read(sgpio->regmap, sgpio->regs->status, &status); + if (ret) + return IRQ_NONE; + + /* Nothing pending: the interrupt came from somebody else. */ + if (!status) + return IRQ_NONE; + + status = FIELD_GET(SGPIO_STATUS_EXCHANGE, status); + + reg_ptr = sgpio->din_bank_shift; + + for (i = 0; i < nbanks; i++, reg_ptr++) { + if (status & BIT(reg_ptr)) { + ret = regmap_read(sgpio->regmap, + sgpio->regs->din_ss + reg_ptr * sizeof(u32), + &new_value); + if (ret) + continue; + + /* + * Track every signal so that the shadow always holds + * the last sampled level, then report only the ones + * whose interrupt is unmasked. Transitions of a masked + * signal are dropped rather than delivered later, the + * hardware has no per signal latch to replay them + * from. Only this handler touches the shadow and it is + * not reentrant. + */ + changed_value = sgpio->din_shadow[i] ^ new_value; + sgpio->din_shadow[i] = new_value; + changed_value &= bitmap_read(sgpio->irq_unmasked, + i * SGPIO_BANK_SIZE, + SGPIO_BANK_SIZE); + + while (changed_value) { + unsigned int child_irq; + irq_hw_number_t hwirq; + unsigned int position; + bool rising; + + bit = __ffs(changed_value); + changed_value &= ~BIT(bit); + + position = i * SGPIO_BANK_SIZE + bit; + hwirq = position * 2; + + rising = !!(new_value & BIT(bit)); + + if (!test_bit(position, rising ? sgpio->irq_rising + : sgpio->irq_falling)) + continue; + + child_irq = irq_find_mapping(sgpio->domain, hwirq); + if (child_irq) + handle_nested_irq(child_irq); + } + } + } + + return IRQ_HANDLED; +} + +static int axiado_sgpio_hw_init(struct axiado_sgpio *sgpio) +{ + const struct axiado_sgpio_reg_offsets *regs = sgpio->regs; + unsigned int nbanks = DIV_ROUND_UP(sgpio->nsignals, SGPIO_BANK_SIZE); + unsigned int last_bank = (sgpio->nsignals - 1) / SGPIO_BANK_SIZE; + unsigned int last_bit = (sgpio->nsignals - 1) % SGPIO_BANK_SIZE; + unsigned int i; + int ret; + + /* Slice A0 is the shift clock, slice B1 the data load. */ + const struct reg_sequence pre_load[] = { + { regs->mask, 0 }, + { regs->mux_0, SGPIO_MUX_CLK }, + { regs->preset_0, sgpio->preset_value }, + { regs->count_0, sgpio->count_value }, + { regs->pos_0, SGPIO_POS_FULL_BANK }, + { regs->mux_1, SGPIO_MUX_DATA }, + }; + /* Slice C2 is the data output. */ + const struct reg_sequence pre_dout[] = { + { regs->preset_1, sgpio->preset_value }, + { regs->count_1, sgpio->count_value }, + { regs->pos_1, sgpio->pos_reg }, + { regs->mux_2, SGPIO_MUX_DATA }, + }; + /* Slice D3 is the data input, slice E4 the output enable. */ + const struct reg_sequence post_dout[] = { + { regs->preset_2, sgpio->preset_value }, + { regs->count_2, sgpio->count_value }, + { regs->pos_2, sgpio->pos_reg }, + { regs->mux_3, SGPIO_MUX_DIN }, + { regs->preset_3, sgpio->preset_value }, + { regs->count_3, sgpio->count_value }, + { regs->pos_3, sgpio->pos_reg }, + { regs->mux_4, SGPIO_MUX_OE }, + { regs->oe, GENMASK(31, 0) }, + { regs->oe_ss, GENMASK(31, 0) }, + { regs->preset_4, sgpio->preset_value }, + { regs->count_4, sgpio->count_value }, + { regs->pos_4, SGPIO_POS_FULL_BANK }, + { regs->ctrl_en, SGPIO_SLICE_MASK }, + { regs->ctrl_en_pos, SGPIO_SLICE_MASK }, + }; + + ret = regmap_multi_reg_write(sgpio->regmap, pre_load, + ARRAY_SIZE(pre_load)); + if (ret) + return ret; + + /* + * Latch the signals that are present. Only the last bank may be + * partially populated; a last bit of zero still describes one signal. + */ + for (i = 0; i < nbanks; i++) { + u32 val = i < last_bank ? GENMASK(SGPIO_BANK_SIZE - 1, 0) : + GENMASK(last_bit, 0); + + ret = regmap_write(sgpio->regmap, regs->ld + i * 4, val); + if (ret) + return ret; + + ret = regmap_write(sgpio->regmap, regs->ld_ss + i * 4, val); + if (ret) + return ret; + } + + ret = regmap_multi_reg_write(sgpio->regmap, pre_dout, + ARRAY_SIZE(pre_dout)); + if (ret) + return ret; + + /* All outputs start out driving zero. */ + for (i = 0; i < nbanks; i++) { + ret = regmap_write(sgpio->regmap, regs->dout + i * 4, 0); + if (ret) + return ret; + + ret = regmap_write(sgpio->regmap, regs->dout_ss + i * 4, 0); + if (ret) + return ret; + } + + return regmap_multi_reg_write(sgpio->regmap, post_dout, + ARRAY_SIZE(post_dout)); +} + +static int axiado_sgpio_irq_enable(struct axiado_sgpio *sgpio) +{ + return regmap_write(sgpio->regmap, sgpio->regs->mask, + SGPIO_IRQ_ENABLE); +} + +static void axiado_sgpio_disable(void *data) +{ + struct axiado_sgpio *sgpio = data; + + /* Mask the interrupts and stop the shift engine. */ + regmap_write(sgpio->regmap, sgpio->regs->mask, 0); + regmap_write(sgpio->regmap, sgpio->regs->ctrl_en, 0); +} + +static int axiado_sgpio_set_irq_type(struct irq_data *d, unsigned int type) +{ + struct axiado_sgpio *sgpio = irq_data_get_irq_chip_data(d); + irq_hw_number_t hwirq = irqd_to_hwirq(d); + unsigned int position; + + /* Only even GPIO offsets represent SGPIO inputs. */ + if (hwirq & 1) + return -EINVAL; + + position = hwirq / 2; + if (position >= sgpio->nsignals) + return -EINVAL; + + type &= IRQ_TYPE_SENSE_MASK; + + switch (type) { + case IRQ_TYPE_EDGE_BOTH: + case IRQ_TYPE_EDGE_RISING: + case IRQ_TYPE_EDGE_FALLING: + break; + default: + return -EINVAL; + } + + assign_bit(position, sgpio->irq_rising, type & IRQ_TYPE_EDGE_RISING); + assign_bit(position, sgpio->irq_falling, type & IRQ_TYPE_EDGE_FALLING); + + return 0; +} + +static void axiado_sgpio_mask_irq(struct irq_data *d) +{ + struct axiado_sgpio *sgpio = irq_data_get_irq_chip_data(d); + irq_hw_number_t hwirq = irqd_to_hwirq(d); + + clear_bit(hwirq / 2, sgpio->irq_unmasked); + gpio_regmap_disable_irq(sgpio->gpio, hwirq); +} + +static void axiado_sgpio_unmask_irq(struct irq_data *d) +{ + struct axiado_sgpio *sgpio = irq_data_get_irq_chip_data(d); + irq_hw_number_t hwirq = irqd_to_hwirq(d); + + gpio_regmap_enable_irq(sgpio->gpio, hwirq); + set_bit(hwirq / 2, sgpio->irq_unmasked); +} + +static int axiado_sgpio_irq_request_resources(struct irq_data *d) +{ + struct axiado_sgpio *sgpio = irq_data_get_irq_chip_data(d); + + return gpio_regmap_reqres_irq(sgpio->gpio, d->hwirq); +} + +static void axiado_sgpio_irq_release_resources(struct irq_data *d) +{ + struct axiado_sgpio *sgpio = irq_data_get_irq_chip_data(d); + + gpio_regmap_relres_irq(sgpio->gpio, d->hwirq); +} + +static const struct irq_chip axiado_sgpio_irqchip = { + .name = "axiado-sgpio", + .irq_mask = axiado_sgpio_mask_irq, + .irq_unmask = axiado_sgpio_unmask_irq, + .irq_set_type = axiado_sgpio_set_irq_type, + .flags = IRQCHIP_IMMUTABLE | IRQCHIP_MASK_ON_SUSPEND, + .irq_request_resources = axiado_sgpio_irq_request_resources, + .irq_release_resources = axiado_sgpio_irq_release_resources, +}; + +static int axiado_sgpio_irq_map(struct irq_domain *domain, unsigned int virq, + irq_hw_number_t hwirq) +{ + struct axiado_sgpio *sgpio = domain->host_data; + + /* Only even offsets represent input GPIOs. */ + if (hwirq % 2) + return -EINVAL; + + irq_set_chip_data(virq, sgpio); + irq_set_lockdep_class(virq, &axiado_sgpio_irq_lock_class, + &axiado_sgpio_irq_request_class); + irq_set_chip_and_handler(virq, &axiado_sgpio_irqchip, handle_simple_irq); + irq_set_nested_thread(virq, true); + irq_set_noprobe(virq); + + return 0; +} + +static const struct irq_domain_ops axiado_sgpio_domain_ops = { + .map = axiado_sgpio_irq_map, + .xlate = irq_domain_xlate_twocell, +}; + +static int axiado_sgpio_init_input_cache(struct axiado_sgpio *sgpio) +{ + unsigned int num_banks = DIV_ROUND_UP(sgpio->nsignals, + SGPIO_BANK_SIZE); + unsigned int reg_ptr = sgpio->din_bank_shift; + unsigned int i; + int ret; + + for (i = 0; i < num_banks; i++, reg_ptr++) { + ret = regmap_read(sgpio->regmap, + sgpio->regs->din_ss + reg_ptr * sizeof(u32), + &sgpio->din_shadow[i]); + if (ret) + return ret; + } + + return 0; +} + +static bool axiado_sgpio_dout_reg(const struct axiado_sgpio *sgpio, + unsigned int reg) +{ + unsigned int span = SGPIO_NUM_BANKS * sizeof(u32); + + return reg >= sgpio->regs->dout_ss && + reg < sgpio->regs->dout_ss + span; +} + +static bool axiado_sgpio_readable_reg(struct device *dev, unsigned int reg) +{ + const struct axiado_sgpio *sgpio = dev_get_drvdata(dev); + + /* The status register is the last one of the block. */ + if (reg > sgpio->regs->status) + return false; + + /* + * The output shadow feeds the shift register and cannot be read back, + * the driven value is kept in the register cache instead. + */ + return !axiado_sgpio_dout_reg(sgpio, reg); +} + +static bool axiado_sgpio_volatile_reg(struct device *dev, unsigned int reg) +{ + const struct axiado_sgpio *sgpio = dev_get_drvdata(dev); + + /* + * Everything but the output shadow is live hardware state: shifted in + * data, running counters and the interrupt status. Caching any of it + * would hand out stale values, so the cache holds the output banks + * alone. + */ + return !axiado_sgpio_dout_reg(sgpio, reg); +} + +static bool axiado_sgpio_precious_reg(struct device *dev, unsigned int reg) +{ + const struct axiado_sgpio *sgpio = dev_get_drvdata(dev); + + /* Reading the status register acknowledges the interrupts. */ + return reg == sgpio->regs->status; +} + +static const struct regmap_config axiado_sgpio_regmap_config = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, + .readable_reg = axiado_sgpio_readable_reg, + .volatile_reg = axiado_sgpio_volatile_reg, + .precious_reg = axiado_sgpio_precious_reg, + .cache_type = REGCACHE_MAPLE, +}; + +static int axiado_sgpio_probe(struct platform_device *pdev) +{ + struct gpio_regmap_config config = { }; + struct irq_domain_info d_info = { }; + struct axiado_sgpio *sgpio; + unsigned int ngpio, i; + unsigned long apb_freq; + struct clk *apb_clk; + void __iomem *base; + u32 sgpio_freq; + int irq, rc; + + sgpio = devm_kzalloc(&pdev->dev, sizeof(*sgpio), GFP_KERNEL); + if (!sgpio) + return -ENOMEM; + + /* The regmap callbacks below need both of these. */ + platform_set_drvdata(pdev, sgpio); + + sgpio->regs = &axiado_sgpio_offsets; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + sgpio->regmap = devm_regmap_init_mmio(&pdev->dev, base, + &axiado_sgpio_regmap_config); + if (IS_ERR(sgpio->regmap)) + return dev_err_probe(&pdev->dev, PTR_ERR(sgpio->regmap), + "Failed to init regmap\n"); + + rc = device_property_read_u32(&pdev->dev, "ngpios", &ngpio); + if (rc) + return dev_err_probe(&pdev->dev, rc, + "Failed to read ngpios property\n"); + + /* + * Each SGPIO signal is exposed as one input and one output line, so + * the number of lines is twice the number of signals. + */ + if (!ngpio || ngpio % 2 || ngpio > SGPIO_MAX_SIGNALS * 2) + return dev_err_probe(&pdev->dev, -EINVAL, + "Invalid ngpios value: %u (even, max %u)\n", + ngpio, SGPIO_MAX_SIGNALS * 2); + + sgpio->nsignals = ngpio / 2; + + sgpio->din_shadow = devm_kcalloc(&pdev->dev, + DIV_ROUND_UP(sgpio->nsignals, + SGPIO_BANK_SIZE), + sizeof(*sgpio->din_shadow), GFP_KERNEL); + sgpio->irq_unmasked = devm_bitmap_zalloc(&pdev->dev, sgpio->nsignals, + GFP_KERNEL); + sgpio->irq_rising = devm_bitmap_zalloc(&pdev->dev, sgpio->nsignals, + GFP_KERNEL); + sgpio->irq_falling = devm_bitmap_zalloc(&pdev->dev, sgpio->nsignals, + GFP_KERNEL); + if (!sgpio->din_shadow || !sgpio->irq_unmasked || + !sgpio->irq_rising || !sgpio->irq_falling) + return -ENOMEM; + + apb_clk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(apb_clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(apb_clk), + "Failed to get and enable APB clock\n"); + + rc = device_property_read_u32(&pdev->dev, "bus-frequency", + &sgpio_freq); + if (rc) + return dev_err_probe(&pdev->dev, rc, + "Failed to read bus-frequency\n"); + + apb_freq = clk_get_rate(apb_clk); + + if (!apb_freq || !sgpio_freq || sgpio_freq > apb_freq) + return dev_err_probe(&pdev->dev, -EINVAL, + "Invalid SGPIO bus frequency\n"); + + sgpio->preset_value = (apb_freq / sgpio_freq) - 1; + sgpio->count_value = sgpio->preset_value; + + sgpio->pos_reg = SGPIO_POS(sgpio->nsignals - 1); + + sgpio->din_bank_shift = SGPIO_NUM_BANKS - + DIV_ROUND_UP(sgpio->nsignals, SGPIO_BANK_SIZE); + + /* + * From here on the hardware may be running, so the shutdown action has + * to be in place before the first register is programmed. It only ever + * writes zeroes, which is harmless if initialisation never got that + * far, and it runs before the APB clock is disabled because that was + * requested earlier. + */ + rc = devm_add_action_or_reset(&pdev->dev, axiado_sgpio_disable, sgpio); + if (rc) + return rc; + + rc = axiado_sgpio_hw_init(sgpio); + if (rc) + return dev_err_probe(&pdev->dev, rc, + "Failed to initialize hardware\n"); + + rc = axiado_sgpio_init_input_cache(sgpio); + if (rc) + return dev_err_probe(&pdev->dev, rc, + "Failed to initialize input cache\n"); + + sgpio->dir_out = devm_bitmap_zalloc(&pdev->dev, ngpio, GFP_KERNEL); + if (!sgpio->dir_out) + return -ENOMEM; + + /* Even lines are the serial inputs, odd lines the serial outputs. */ + for (i = 1; i < ngpio; i += 2) + __set_bit(i, sgpio->dir_out); + + d_info.fwnode = dev_fwnode(&pdev->dev); + d_info.size = ngpio; + d_info.hwirq_max = ngpio; + d_info.ops = &axiado_sgpio_domain_ops; + d_info.host_data = sgpio; + + sgpio->domain = devm_irq_domain_instantiate(&pdev->dev, &d_info); + if (IS_ERR(sgpio->domain)) + return PTR_ERR(sgpio->domain); + + config.parent = &pdev->dev; + config.regmap = sgpio->regmap; + config.ngpio = ngpio; + config.reg_dat_base = GPIO_REGMAP_ADDR(sgpio->regs->din_ss); + config.reg_set_base = GPIO_REGMAP_ADDR(sgpio->regs->dout_ss); + config.reg_mask_xlate = axiado_sgpio_reg_mask_xlate; + config.fixed_direction_output = sgpio->dir_out; + config.irq_domain = sgpio->domain; + config.drvdata = sgpio; + + sgpio->gpio = devm_gpio_regmap_register(&pdev->dev, &config); + if (IS_ERR(sgpio->gpio)) + return dev_err_probe(&pdev->dev, PTR_ERR(sgpio->gpio), + "Could not register gpiochip\n"); + + irq = platform_get_irq(pdev, 0); + if (irq < 0) + return irq; + + rc = devm_request_threaded_irq(&pdev->dev, irq, NULL, axiado_sgpio_irq_handler, + IRQF_ONESHOT, dev_name(&pdev->dev), sgpio); + if (rc) + return dev_err_probe(&pdev->dev, rc, "Failed to request IRQ\n"); + + rc = axiado_sgpio_irq_enable(sgpio); + if (rc) + return dev_err_probe(&pdev->dev, rc, + "Failed to enable interrupts\n"); + + return 0; +} + +static void axiado_sgpio_remove(struct platform_device *pdev) +{ + struct axiado_sgpio *sgpio = platform_get_drvdata(pdev); + + /* + * Runs before the devres unwind, so the interrupts are masked while the + * parent interrupt is still requested. The shift engine is stopped by + * axiado_sgpio_disable(), registered before the hardware was programmed + * so that it also covers failures during probe. + */ + regmap_write(sgpio->regmap, sgpio->regs->mask, 0); +} + +static const struct of_device_id axiado_sgpio_of_match[] = { + { .compatible = "axiado,ax3005-sgpio" }, + { } +}; +MODULE_DEVICE_TABLE(of, axiado_sgpio_of_match); + +static struct platform_driver axiado_sgpio_driver = { + .driver = { + .name = KBUILD_MODNAME, + .of_match_table = axiado_sgpio_of_match, + }, + .probe = axiado_sgpio_probe, + .remove = axiado_sgpio_remove, +}; +module_platform_driver(axiado_sgpio_driver); + +MODULE_DESCRIPTION("Axiado AX3005 Serial GPIO Driver"); +MODULE_AUTHOR("Axiado Corporation"); +MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-bd73800.c b/drivers/gpio/gpio-bd73800.c new file mode 100644 index 0000000..2be2a88 --- /dev/null +++ b/drivers/gpio/gpio-bd73800.c
@@ -0,0 +1,209 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Support to GPIOs on ROHM BD73800 + * Copyright 2024 ROHM Semiconductors. + * Author: Matti Vaittinen <mazziesaccount@gmail.com> + */ + +#include <linux/bitmap.h> +#include <linux/bitops.h> +#include <linux/gpio/driver.h> +#include <linux/gpio/regmap.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/mfd/rohm-bd73800.h> + +#define BD73800_GPIO_MAX_PINS 4 +/* + * The BD73800 has several "one time programmable" (OTP) configurations which + * can be set at manufacturing phase. Some of these options allow using + * individual pins as GPI or GPO (not both at the same time). The OTP + * configuration can't be read at run-time, so drivers rely on device-tree to + * advertise the OTP programmed in manufacturing. + * + * The pins which can be used as GPIO are: + * GPIO1, CLKOUT (GPIO2), FAULT_B, EXTEN_OUT. + * + * The OTP options 2 and 3 state for all the pins: + * - OTP2: GPI (also IRQ source) + * - OTP3: GPO (NOTE: This is actually 2 different OTP options. Either a + * register controllable output or a power-sequence controlled output. + * The "gpo" referred here means only the register controllable output.) + * The datasheet refers to this as: "<pin> output is controlled by + * GPIO<N>_OUT or power on/off sequencer to control external VRs. ON/OFF + * sequence timing is configurable." + * + * The data-sheet further says that the GPI/GPO is not a default OTP + * configuration for any of the pins. Hence the GPIO driver defaults to a pin + * not being a GPI or GPO, but requires the pin to be explicitly marked as a + * GPI or GPO in the device-tree. + * + * DT properties: + * "rohm,pin-gpio1", "rohm,pin-clkout", "rohm,pin-fault_b", "rohm,pin-exten" + * can be set to one of the values "gpi" or "gpo" to enable them to be used as + * GPIO. + * + * The amount of GPIO lines the chip exposes to the user-space (chip.ngpio) is + * always the same, regardless of the OTP variant in use. The lines which are + * not usable as GPIO on a given OTP variant are marked invalid via the GPIO + * valid_mask. This way the user-space always sees a constant amount of GPIO + * lines, where numbering (relative to the chip's base) stays also the same. + * Users can then use the valid_mask to find out which of the lines are usable. + */ + +struct bd73800_gpio { + /* dev points to the platform device for devm and prints */ + struct device *dev; + struct regmap *regmap; + /* Pins which have been OTP configured as GPI or GPO */ + DECLARE_BITMAP(valid_mask, BD73800_GPIO_MAX_PINS); + /* Subset of valid_mask - pins which have been OTP configured as GPO */ + DECLARE_BITMAP(output_mask, BD73800_GPIO_MAX_PINS); +}; + +static const char * const bd73800_gpio_properties[BD73800_GPIO_MAX_PINS] = { + "rohm,pin-gpio1", + "rohm,pin-clkout", + "rohm,pin-fault_b", + "rohm,pin-exten" +}; + +static int bd73800_gpio_get_pins(struct bd73800_gpio *data) +{ + struct device *parent = data->dev->parent; + const char *val; + int i, ret; + + for (i = 0; i < BD73800_GPIO_MAX_PINS; i++) { + ret = device_property_read_string(parent, + bd73800_gpio_properties[i], + &val); + if (ret) { + if (ret == -EINVAL) + continue; + + return dev_err_probe(data->dev, ret, + "pin %d (%s), bad configuration\n", i, + bd73800_gpio_properties[i]); + } + + if (!strcmp(val, "gpi")) { + __set_bit(i, data->valid_mask); + } else if (!strcmp(val, "gpo")) { + __set_bit(i, data->valid_mask); + __set_bit(i, data->output_mask); + } else { + dev_warn(data->dev, + "pin %d (%s), unknown value '%s' ignored\n", i, + bd73800_gpio_properties[i], val); + } + } + + return 0; +} + +static int bd73800_gpio_init_valid_mask(struct gpio_chip *gc, + unsigned long *valid_mask, + unsigned int ngpios) +{ + struct gpio_regmap *gpio = gpiochip_get_data(gc); + struct bd73800_gpio *data = gpio_regmap_get_drvdata(gpio); + + bitmap_copy(valid_mask, data->valid_mask, ngpios); + + return 0; +} + +/* + * The used register depends on OTP: + * - If OTP has set pin as GPO, only the GPO_OUT register is valid. + * - If OTP has set pin as GPI, only the INT_5_SRC register is valid. + */ +static int bd73800_gpio_reg_mask_xlate(struct gpio_regmap *gpio, + enum gpio_regmap_operation op, + unsigned int base, unsigned int offset, + unsigned int *reg, unsigned int *mask) +{ + struct bd73800_gpio *data = gpio_regmap_get_drvdata(gpio); + bool is_output = test_bit(offset, data->output_mask); + + if (is_output) + *reg = BD73800_REG_GPO_OUT; + else + *reg = base; + + *mask = BIT(offset); + + return 0; +} + +static int gpo_bd73800_probe(struct platform_device *pdev) +{ + struct gpio_regmap_config config = { }; + struct bd73800_gpio *data; + struct device *parent, *dev; + int ret; + + dev = &pdev->dev; + /* The device-tree and regmap come from MFD => use parent for that */ + parent = dev->parent; + + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->dev = dev; + data->regmap = dev_get_regmap(parent, NULL); + if (!data->regmap) + return dev_err_probe(dev, -ENODEV, "no parent regmap\n"); + + ret = bd73800_gpio_get_pins(data); + if (ret) + return ret; + + if (bitmap_empty(data->valid_mask, BD73800_GPIO_MAX_PINS)) { + /* + * The BD73800 may or may not have pins allocated for GPIO + * depending on the OTP used at manufacturing. + * If there are no pins, then we have nothing to do. + */ + dev_dbg(dev, "no GPIO pins\n"); + return -ENODEV; + } + + config.parent = parent; + config.regmap = data->regmap; + config.label = "bd73800"; + config.ngpio = BD73800_GPIO_MAX_PINS; + config.reg_dat_base = BD73800_REG_INT_5_SRC; + config.reg_set_base = BD73800_REG_GPO_OUT; + config.reg_mask_xlate = bd73800_gpio_reg_mask_xlate; + config.init_valid_mask = bd73800_gpio_init_valid_mask; + /* All pins that are valid GPIO lines also have a fixed direction */ + config.fixed_direction_mask = data->valid_mask; + config.fixed_direction_output = data->output_mask; + config.drvdata = data; + + return PTR_ERR_OR_ZERO(devm_gpio_regmap_register(dev, &config)); +} + +static const struct platform_device_id bd73800_gpio_id[] = { + { "bd73800-gpio" }, + { }, +}; +MODULE_DEVICE_TABLE(platform, bd73800_gpio_id); + +static struct platform_driver gpo_bd73800_driver = { + .driver = { + .name = "bd73800-gpio", + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + }, + .probe = gpo_bd73800_probe, + .id_table = bd73800_gpio_id, +}; +module_platform_driver(gpo_bd73800_driver); + +MODULE_AUTHOR("Matti Vaittinen <mazziesaccount@gmail.com>"); +MODULE_DESCRIPTION("GPIO interface for BD73800"); +MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-crystalcove.c b/drivers/gpio/gpio-crystalcove.c index 0fb5c06..ab7fab5 100644 --- a/drivers/gpio/gpio-crystalcove.c +++ b/drivers/gpio/gpio-crystalcove.c
@@ -396,3 +396,4 @@ module_platform_driver(crystalcove_gpio_driver); MODULE_AUTHOR("Yang, Bin <bin.yang@intel.com>"); MODULE_DESCRIPTION("Intel Crystal Cove GPIO Driver"); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:crystal_cove_gpio");
diff --git a/drivers/gpio/gpio-dln2.c b/drivers/gpio/gpio-dln2.c index 4670ffd..aef4345 100644 --- a/drivers/gpio/gpio-dln2.c +++ b/drivers/gpio/gpio-dln2.c
@@ -243,10 +243,8 @@ static int dln2_gpio_set_direction(struct gpio_chip *chip, unsigned offset, if (ret < 0) return ret; - if (dir == DLN2_GPIO_DIRECTION_OUT) - set_bit(offset, dln2->output_enabled); - else - clear_bit(offset, dln2->output_enabled); + assign_bit(offset, dln2->output_enabled, + dir == DLN2_GPIO_DIRECTION_OUT); return ret; }
diff --git a/drivers/gpio/gpio-eic-sprd.c b/drivers/gpio/gpio-eic-sprd.c index 3b7ebcf..86eb962 100644 --- a/drivers/gpio/gpio-eic-sprd.c +++ b/drivers/gpio/gpio-eic-sprd.c
@@ -601,13 +601,6 @@ static const struct irq_chip sprd_eic_irq = { GPIOCHIP_IRQ_RESOURCE_HELPERS, }; -static void sprd_eic_unregister_notifier(void *data) -{ - struct notifier_block *nb = data; - - atomic_notifier_chain_unregister(&sprd_eic_irq_notifier, nb); -} - static int sprd_eic_probe(struct platform_device *pdev) { const struct sprd_eic_variant_data *pdata; @@ -690,14 +683,8 @@ static int sprd_eic_probe(struct platform_device *pdev) } sprd_eic->irq_nb.notifier_call = sprd_eic_irq_notify; - ret = atomic_notifier_chain_register(&sprd_eic_irq_notifier, - &sprd_eic->irq_nb); - if (ret) - return dev_err_probe(dev, ret, - "Failed to register with the interrupt notifier"); - - return devm_add_action_or_reset(dev, sprd_eic_unregister_notifier, - &sprd_eic->irq_nb); + return devm_atomic_notifier_chain_register(dev, &sprd_eic_irq_notifier, + &sprd_eic->irq_nb); } static const struct of_device_id sprd_eic_of_match[] = {
diff --git a/drivers/gpio/gpio-it87.c b/drivers/gpio/gpio-it87.c index 2ad3c23..6993251 100644 --- a/drivers/gpio/gpio-it87.c +++ b/drivers/gpio/gpio-it87.c
@@ -362,7 +362,7 @@ static int __init it87_gpio_init(void) */ labels = kcalloc(it87_gpio->chip.ngpio, sizeof("it87_gpXY"), GFP_KERNEL); - labels_table = kcalloc(it87_gpio->chip.ngpio, sizeof(const char *), + labels_table = kcalloc(it87_gpio->chip.ngpio, sizeof(*labels_table), GFP_KERNEL); if (!labels || !labels_table) {
diff --git a/drivers/gpio/gpio-mlxbf2.c b/drivers/gpio/gpio-mlxbf2.c index 4e2f338..4e5c5d1 100644 --- a/drivers/gpio/gpio-mlxbf2.c +++ b/drivers/gpio/gpio-mlxbf2.c
@@ -394,7 +394,9 @@ mlxbf2_gpio_probe(struct platform_device *pdev) gc->owner = THIS_MODULE; irq = platform_get_irq_optional(pdev, 0); - if (irq >= 0) { + if (irq < 0 && irq != -ENXIO) + return irq; + if (irq > 0) { girq = &gs->chip.gc.irq; gpio_irq_chip_set_chip(girq, &mlxbf2_gpio_irq_chip); girq->handler = handle_simple_irq;
diff --git a/drivers/gpio/gpio-mlxbf3.c b/drivers/gpio/gpio-mlxbf3.c index 5663266..929f64c5 100644 --- a/drivers/gpio/gpio-mlxbf3.c +++ b/drivers/gpio/gpio-mlxbf3.c
@@ -231,7 +231,9 @@ static int mlxbf3_gpio_probe(struct platform_device *pdev) gc->add_pin_ranges = mlxbf3_gpio_add_pin_ranges; irq = platform_get_irq_optional(pdev, 0); - if (irq >= 0) { + if (irq < 0 && irq != -ENXIO) + return irq; + if (irq > 0) { girq = &gs->chip.gc.irq; gpio_irq_chip_set_chip(girq, &gpio_mlxbf3_irqchip); girq->default_type = IRQ_TYPE_NONE;
diff --git a/drivers/gpio/gpio-mmio.c b/drivers/gpio/gpio-mmio.c index e9c531e..0709ffa 100644 --- a/drivers/gpio/gpio-mmio.c +++ b/drivers/gpio/gpio-mmio.c
@@ -49,6 +49,7 @@ o ` ~~~~\___/~~~~ ` controller in FPGA is ,.` #include <linux/log2.h> #include <linux/module.h> #include <linux/pinctrl/consumer.h> +#include <linux/pinctrl/pinconf-generic.h> #include <linux/platform_device.h> #include <linux/property.h> #include <linux/spinlock.h> @@ -354,6 +355,11 @@ static int gpio_mmio_dir_return(struct gpio_chip *gc, unsigned int gpio, if (!chip->pinctrl) return 0; +#ifdef CONFIG_PINCTRL + if (list_empty(&gc->gpiodev->pin_ranges)) + return 0; +#endif + if (dir_out) return pinctrl_gpio_direction_output(gc, gpio); else @@ -367,7 +373,17 @@ static int gpio_mmio_dir_in_err(struct gpio_chip *gc, unsigned int gpio) static int gpio_mmio_simple_dir_in(struct gpio_chip *gc, unsigned int gpio) { - return gpio_mmio_dir_return(gc, gpio, false); + struct gpio_generic_chip *chip = to_gpio_generic_chip(gc); + int ret; + + ret = gpio_mmio_dir_return(gc, gpio, false); + if (ret) + return ret; + + guard(raw_spinlock_irqsave)(&chip->lock); + chip->sdir &= ~gpio_mmio_line2mask(gc, gpio); + + return 0; } static int gpio_mmio_dir_out_err(struct gpio_chip *gc, unsigned int gpio, @@ -379,9 +395,19 @@ static int gpio_mmio_dir_out_err(struct gpio_chip *gc, unsigned int gpio, static int gpio_mmio_simple_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) { + struct gpio_generic_chip *chip = to_gpio_generic_chip(gc); + int ret; + gc->set(gc, gpio, val); - return gpio_mmio_dir_return(gc, gpio, true); + ret = gpio_mmio_dir_return(gc, gpio, true); + if (ret) + return ret; + + guard(raw_spinlock_irqsave)(&chip->lock); + chip->sdir |= gpio_mmio_line2mask(gc, gpio); + + return 0; } static int gpio_mmio_dir_in(struct gpio_chip *gc, unsigned int gpio) @@ -596,20 +622,51 @@ static int gpio_mmio_setup_direction(struct gpio_generic_chip *chip, gc->direction_input = gpio_mmio_dir_in_err; else gc->direction_input = gpio_mmio_simple_dir_in; + + if (cfg->flags & GPIO_GENERIC_PINCTRL_BACKEND) { + chip->dir_unreadable = true; + gc->get_direction = gpio_mmio_get_dir; + gc->get_config = gpiochip_generic_get_config; + } } return 0; } +static void gpio_mmio_seed_dir_from_pinctrl(struct gpio_chip *gc, + unsigned int gpio) +{ + struct gpio_generic_chip *chip = to_gpio_generic_chip(gc); + unsigned long config; + + if (!gc->get_config || chip->reg_dir_out || chip->reg_dir_in) + return; + + config = pinconf_to_config_packed(PIN_CONFIG_OUTPUT_ENABLE, 0); + if (gc->get_config(gc, gpio, &config)) + return; + + guard(raw_spinlock_irqsave)(&chip->lock); + if (config) + chip->sdir |= gpio_mmio_line2mask(gc, gpio); + else + chip->sdir &= ~gpio_mmio_line2mask(gc, gpio); +} + static int gpio_mmio_request(struct gpio_chip *gc, unsigned int gpio_pin) { struct gpio_generic_chip *chip = to_gpio_generic_chip(gc); + int ret; if (gpio_pin >= gc->ngpio) return -EINVAL; - if (chip->pinctrl) - return gpiochip_generic_request(gc, gpio_pin); + if (chip->pinctrl) { + ret = gpiochip_generic_request(gc, gpio_pin); + if (ret) + return ret; + gpio_mmio_seed_dir_from_pinctrl(gc, gpio_pin); + } return 0; }
diff --git a/drivers/gpio/gpio-mvebu.c b/drivers/gpio/gpio-mvebu.c index a279624..267e6d5 100644 --- a/drivers/gpio/gpio-mvebu.c +++ b/drivers/gpio/gpio-mvebu.c
@@ -599,6 +599,21 @@ static void mvebu_gpio_irq_handler(struct irq_desc *desc) } static const struct regmap_config mvebu_gpio_regmap_config = { + .name = "gpio", + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, +}; + +static const struct regmap_config mvebu_gpio_percpu_regmap_config = { + .name = "percpu", + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, +}; + +static const struct regmap_config mvebu_pwm_regmap_config = { + .name = "pwm", .reg_bits = 32, .reg_stride = 4, .val_bits = 32, @@ -868,7 +883,7 @@ static int mvebu_pwm_probe(struct platform_device *pdev, return PTR_ERR(base); mvpwm->regs = devm_regmap_init_mmio(&pdev->dev, base, - &mvebu_gpio_regmap_config); + &mvebu_pwm_regmap_config); if (IS_ERR(mvpwm->regs)) return PTR_ERR(mvpwm->regs); @@ -1135,7 +1150,7 @@ static int mvebu_gpio_probe_raw(struct platform_device *pdev, mvchip->percpu_regs = devm_regmap_init_mmio(&pdev->dev, base, - &mvebu_gpio_regmap_config); + &mvebu_gpio_percpu_regmap_config); if (IS_ERR(mvchip->percpu_regs)) return PTR_ERR(mvchip->percpu_regs); }
diff --git a/drivers/gpio/gpio-omap.c b/drivers/gpio/gpio-omap.c index 005420b..a9b9a3d 100644 --- a/drivers/gpio/gpio-omap.c +++ b/drivers/gpio/gpio-omap.c
@@ -1032,8 +1032,6 @@ static void omap_gpio_mod_init(struct gpio_bank *bank) static int omap_gpio_chip_init(struct gpio_bank *bank, struct device *pm_dev) { struct gpio_irq_chip *irq; - static int gpio; - const char *label; int ret; /* @@ -1055,11 +1053,7 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct device *pm_dev) if (bank->regs->wkup_en) bank->chip.parent = &omap_mpuio_device.dev; } else { - label = devm_kasprintf(bank->chip.parent, GFP_KERNEL, "gpio-%d-%d", - gpio, gpio + bank->width - 1); - if (!label) - return -ENOMEM; - bank->chip.label = label; + bank->chip.label = dev_name(bank->chip.parent); } bank->chip.base = -1; bank->chip.ngpio = bank->width; @@ -1086,9 +1080,6 @@ static int omap_gpio_chip_init(struct gpio_bank *bank, struct device *pm_dev) if (ret) gpiochip_remove(&bank->chip); - if (!bank->is_mpuio) - gpio += bank->width; - return ret; }
diff --git a/drivers/gpio/gpio-pcf857x.c b/drivers/gpio/gpio-pcf857x.c index c1f5e10..1ba6a09 100644 --- a/drivers/gpio/gpio-pcf857x.c +++ b/drivers/gpio/gpio-pcf857x.c
@@ -71,8 +71,9 @@ MODULE_DEVICE_TABLE(of, pcf857x_of_table); struct pcf857x { struct gpio_chip chip; struct i2c_client *client; - struct mutex lock; /* protect 'out' */ + struct mutex lock; /* protect 'out' and 'dir' */ unsigned int out; /* software latch */ + unsigned int dir; /* direction latch (1 = input) */ unsigned int status; /* current status */ unsigned int irq_enabled; /* enabled irqs */ @@ -126,12 +127,21 @@ static int pcf857x_input(struct gpio_chip *chip, unsigned int offset) mutex_lock(&gpio->lock); gpio->out |= (1 << offset); + gpio->dir |= (1 << offset); status = gpio->write(gpio->client, gpio->out); mutex_unlock(&gpio->lock); return status; } +static int pcf857x_get_direction(struct gpio_chip *chip, unsigned int offset) +{ + struct pcf857x *gpio = gpiochip_get_data(chip); + + return (gpio->dir & (1 << offset)) ? GPIO_LINE_DIRECTION_IN + : GPIO_LINE_DIRECTION_OUT; +} + static int pcf857x_get(struct gpio_chip *chip, unsigned int offset) { struct pcf857x *gpio = gpiochip_get_data(chip); @@ -167,6 +177,7 @@ static int pcf857x_output(struct gpio_chip *chip, unsigned int offset, int value gpio->out |= bit; else gpio->out &= ~bit; + gpio->dir &= ~bit; status = gpio->write(gpio->client, gpio->out); mutex_unlock(&gpio->lock); @@ -187,6 +198,7 @@ static int pcf857x_set_multiple(struct gpio_chip *chip, unsigned long *mask, mutex_lock(&gpio->lock); gpio->out &= ~*mask; gpio->out |= *bits & *mask; + gpio->dir &= ~*mask; status = gpio->write(gpio->client, gpio->out); mutex_unlock(&gpio->lock); @@ -301,6 +313,7 @@ static int pcf857x_probe(struct i2c_client *client) gpio->chip.set_multiple = pcf857x_set_multiple; gpio->chip.direction_input = pcf857x_input; gpio->chip.direction_output = pcf857x_output; + gpio->chip.get_direction = pcf857x_get_direction; gpio->chip.ngpio = (uintptr_t)i2c_get_match_data(client); reset_gpio = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH); @@ -396,6 +409,7 @@ static int pcf857x_probe(struct i2c_client *client) * reset state. Otherwise it flags pins to be driven low. */ gpio->out = ~n_latch; + gpio->dir = ~n_latch; gpio->status = gpio->read(gpio->client); /* Enable irqchip if we have an interrupt */
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 2b5da97..3ff21e8 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c
@@ -268,7 +268,7 @@ static int pxa_gpio_direction_input(struct gpio_chip *chip, unsigned offset) spin_lock_irqsave(&gpio_lock, flags); value = readl_relaxed(base + GPDR_OFFSET); - if (__gpio_is_inverted(chip->base + offset)) + if (__gpio_is_inverted(offset)) value |= mask; else value &= ~mask; @@ -297,7 +297,7 @@ static int pxa_gpio_direction_output(struct gpio_chip *chip, spin_lock_irqsave(&gpio_lock, flags); tmp = readl_relaxed(base + GPDR_OFFSET); - if (__gpio_is_inverted(chip->base + offset)) + if (__gpio_is_inverted(offset)) tmp &= ~mask; else tmp |= mask;
diff --git a/drivers/gpio/gpio-rcar.c b/drivers/gpio/gpio-rcar.c index 09bebde..54dc47d 100644 --- a/drivers/gpio/gpio-rcar.c +++ b/drivers/gpio/gpio-rcar.c
@@ -36,6 +36,7 @@ struct gpio_rcar_info { bool has_both_edge_trigger; bool has_always_in; bool has_inen; + const u8 *offsetmap; }; struct gpio_rcar_priv { @@ -49,34 +50,68 @@ struct gpio_rcar_priv { struct gpio_rcar_bank_info bank_info; }; -#define IOINTSEL 0x00 /* General IO/Interrupt Switching Register */ -#define INOUTSEL 0x04 /* General Input/Output Switching Register */ -#define OUTDT 0x08 /* General Output Register */ -#define INDT 0x0c /* General Input Register */ -#define INTDT 0x10 /* Interrupt Display Register */ -#define INTCLR 0x14 /* Interrupt Clear Register */ -#define INTMSK 0x18 /* Interrupt Mask Register */ -#define MSKCLR 0x1c /* Interrupt Mask Clear Register */ -#define POSNEG 0x20 /* Positive/Negative Logic Select Register */ -#define EDGLEVEL 0x24 /* Edge/level Select Register */ -#define OUTDTSEL 0x40 /* Output Data Select Register */ -#define BOTHEDGE 0x4c /* One Edge/Both Edge Select Register */ -#define INEN 0x50 /* General Input Enable Register */ +enum gpio_rcar_reg { + IOINTSEL, /* General IO/Interrupt Switching Register */ + INOUTSEL, /* General Input/Output Switching Register */ + OUTDT, /* General Output Register */ + INDT, /* General Input Register */ + INTDT, /* Interrupt Display Register */ + INTCLR, /* Interrupt Clear Register */ + INTMSK, /* Interrupt Mask Register */ + MSKCLR, /* Interrupt Mask Clear Register */ + POSNEG, /* Positive/Negative Logic Select Register */ + EDGLEVEL, /* Edge/level Select Register */ + OUTDTSEL, /* Output Data Select Register */ + BOTHEDGE, /* One Edge/Both Edge Select Register */ + INEN, /* General Input Enable Register */ +}; + +static const u8 gpio_rcar_offsetmap_gen1[] = { + [IOINTSEL] = 0x00, + [INOUTSEL] = 0x04, + [OUTDT] = 0x08, + [INDT] = 0x0c, + [INTDT] = 0x10, + [INTCLR] = 0x14, + [INTMSK] = 0x18, + [MSKCLR] = 0x1c, + [POSNEG] = 0x20, + [EDGLEVEL] = 0x24, + [OUTDTSEL] = 0x40, + [BOTHEDGE] = 0x4c, + [INEN] = 0x50, +}; + +static const u8 gpio_rcar_offsetmap_gen5[] = { + [IOINTSEL] = 0x00, + [INOUTSEL] = 0x04, + [OUTDT] = 0x08, + [INDT] = 0x1c, + [INTDT] = 0x80, + [INTCLR] = 0x84, + [INTMSK] = 0x88, + [MSKCLR] = 0x8c, + [POSNEG] = 0x90, + [EDGLEVEL] = 0x94, + [OUTDTSEL] = 0x0c, + [BOTHEDGE] = 0xbc, + [INEN] = 0x18, +}; #define RCAR_MAX_GPIO_PER_BANK 32 -static inline u32 gpio_rcar_read(struct gpio_rcar_priv *p, int offs) +static inline u32 gpio_rcar_read(struct gpio_rcar_priv *p, enum gpio_rcar_reg offs) { - return ioread32(p->base + offs); + return ioread32(p->base + p->info.offsetmap[offs]); } -static inline void gpio_rcar_write(struct gpio_rcar_priv *p, int offs, +static inline void gpio_rcar_write(struct gpio_rcar_priv *p, enum gpio_rcar_reg offs, u32 value) { - iowrite32(value, p->base + offs); + iowrite32(value, p->base + p->info.offsetmap[offs]); } -static void gpio_rcar_modify_bit(struct gpio_rcar_priv *p, int offs, +static void gpio_rcar_modify_bit(struct gpio_rcar_priv *p, enum gpio_rcar_reg offs, int bit, bool value) { u32 tmp = gpio_rcar_read(p, offs); @@ -399,6 +434,7 @@ static const struct gpio_rcar_info gpio_rcar_info_gen1 = { .has_both_edge_trigger = false, .has_always_in = false, .has_inen = false, + .offsetmap = gpio_rcar_offsetmap_gen1, }; static const struct gpio_rcar_info gpio_rcar_info_gen2 = { @@ -406,6 +442,7 @@ static const struct gpio_rcar_info gpio_rcar_info_gen2 = { .has_both_edge_trigger = true, .has_always_in = false, .has_inen = false, + .offsetmap = gpio_rcar_offsetmap_gen1, }; static const struct gpio_rcar_info gpio_rcar_info_gen3 = { @@ -413,6 +450,7 @@ static const struct gpio_rcar_info gpio_rcar_info_gen3 = { .has_both_edge_trigger = true, .has_always_in = true, .has_inen = false, + .offsetmap = gpio_rcar_offsetmap_gen1, }; static const struct gpio_rcar_info gpio_rcar_info_gen4 = { @@ -420,6 +458,15 @@ static const struct gpio_rcar_info gpio_rcar_info_gen4 = { .has_both_edge_trigger = true, .has_always_in = true, .has_inen = true, + .offsetmap = gpio_rcar_offsetmap_gen1, +}; + +static const struct gpio_rcar_info gpio_rcar_info_gen5 = { + .has_outdtsel = true, + .has_both_edge_trigger = true, + .has_always_in = true, + .has_inen = true, + .offsetmap = gpio_rcar_offsetmap_gen5, }; static const struct of_device_id gpio_rcar_of_table[] = { @@ -439,6 +486,9 @@ static const struct of_device_id gpio_rcar_of_table[] = { .compatible = "renesas,rcar-gen4-gpio", .data = &gpio_rcar_info_gen4, }, { + .compatible = "renesas,rcar-gen5-gpio", + .data = &gpio_rcar_info_gen5, + }, { .compatible = "renesas,gpio-rcar", .data = &gpio_rcar_info_gen1, }, {
diff --git a/drivers/gpio/gpio-realtek-otto.c b/drivers/gpio/gpio-realtek-otto.c index 4a606ba..5d98ad5 100644 --- a/drivers/gpio/gpio-realtek-otto.c +++ b/drivers/gpio/gpio-realtek-otto.c
@@ -176,10 +176,10 @@ static void realtek_gpio_update_line_imr(struct realtek_gpio_ctrl *ctrl, unsigne u32 reg_val; reg += 4 * (line_shift / 32); - reg_val = ioread32(reg); + reg_val = __raw_readl(reg); reg_val &= ~(REALTEK_GPIO_IMR_LINE_MASK << shift); reg_val |= (irq_type & irq_mask & REALTEK_GPIO_IMR_LINE_MASK) << shift; - iowrite32(reg_val, reg); + __raw_writel(reg_val, reg); } static void realtek_gpio_irq_ack(struct irq_data *data) @@ -393,18 +393,29 @@ static int realtek_gpio_probe(struct platform_device *pdev) raw_spin_lock_init(&ctrl->lock); + gen_gc_flags = GPIO_GENERIC_PINCTRL_BACKEND; + if (dev_flags & GPIO_PORTS_REVERSED) { - gen_gc_flags = 0; ctrl->bank_read = realtek_gpio_bank_read; ctrl->bank_write = realtek_gpio_bank_write; ctrl->line_imr_pos = realtek_gpio_line_imr_pos; } else { - gen_gc_flags = GPIO_GENERIC_BIG_ENDIAN_BYTE_ORDER; + gen_gc_flags |= GPIO_GENERIC_BIG_ENDIAN_BYTE_ORDER; ctrl->bank_read = realtek_gpio_bank_read_swapped; ctrl->bank_write = realtek_gpio_bank_write_swapped; ctrl->line_imr_pos = realtek_gpio_line_imr_pos_swapped; } + if (device_property_read_bool(dev, "little-endian")) { + gen_gc_flags = 0; + ctrl->bank_read = realtek_gpio_bank_read; + ctrl->bank_write = realtek_gpio_bank_write; + } else if (device_is_big_endian(dev)) { + gen_gc_flags = GPIO_GENERIC_BIG_ENDIAN_BYTE_ORDER; + ctrl->bank_read = realtek_gpio_bank_read_swapped; + ctrl->bank_write = realtek_gpio_bank_write_swapped; + } + config = (struct gpio_generic_chip_config) { .dev = dev, .sz = 4, @@ -423,6 +434,8 @@ static int realtek_gpio_probe(struct platform_device *pdev) ctrl->chip.gc.owner = THIS_MODULE; irq = platform_get_irq_optional(pdev, 0); + if (irq < 0 && irq != -ENXIO) + return irq; if (!(dev_flags & GPIO_INTERRUPTS_DISABLED) && irq > 0) { girq = &ctrl->chip.gc.irq; gpio_irq_chip_set_chip(girq, &realtek_gpio_irq_chip);
diff --git a/drivers/gpio/gpio-regmap.c b/drivers/gpio/gpio-regmap.c index fb21396..2f5f45b 100644 --- a/drivers/gpio/gpio-regmap.c +++ b/drivers/gpio/gpio-regmap.c
@@ -6,11 +6,13 @@ */ #include <linux/bits.h> +#include <linux/cleanup.h> #include <linux/compiler_attributes.h> #include <linux/device.h> #include <linux/err.h> #include <linux/io.h> #include <linux/module.h> +#include <linux/pm_runtime.h> #include <linux/regmap.h> #include <linux/slab.h> #include <linux/types.h> @@ -23,6 +25,8 @@ struct gpio_regmap { struct device *parent; struct regmap *regmap; + struct device *pm_dev; + struct gpio_chip gpio_chip; int reg_stride; @@ -79,6 +83,33 @@ static int gpio_regmap_simple_xlate(struct gpio_regmap *gpio, return 0; } +static int gpio_regmap_runtime_get(struct gpio_regmap *gpio) +{ + if (!gpio->pm_dev) + return 0; + + return pm_runtime_get_active(gpio->pm_dev, RPM_TRANSPARENT); +} + +static void gpio_regmap_runtime_put(struct gpio_regmap *gpio) +{ + if (!gpio->pm_dev) + return; + + pm_runtime_put_autosuspend(gpio->pm_dev); +} + +DEFINE_GUARD(gpio_regmap_runtime, struct gpio_regmap *, + gpio_regmap_runtime_get(_T), gpio_regmap_runtime_put(_T)) +DEFINE_GUARD_COND(gpio_regmap_runtime, _try, + gpio_regmap_runtime_get(_T), _RET == 0) + +#define GPIO_REGMAP_RUNTIME_ACQUIRE(_gpio, _var) \ + ACQUIRE(gpio_regmap_runtime_try, _var)(_gpio) + +#define GPIO_REGMAP_RUNTIME_ACQUIRE_ERR(_var_ptr) \ + ACQUIRE_ERR(gpio_regmap_runtime, _var_ptr) + static int gpio_regmap_get(struct gpio_chip *chip, unsigned int offset) { struct gpio_regmap *gpio = gpiochip_get_data(chip); @@ -91,15 +122,21 @@ static int gpio_regmap_get(struct gpio_chip *chip, unsigned int offset) else base = gpio_regmap_addr(gpio->reg_set_base); - ret = gpio->reg_mask_xlate(gpio, GPIO_REGMAP_GET_OP, base, offset, ®, &mask); + GPIO_REGMAP_RUNTIME_ACQUIRE(gpio, pm); + ret = GPIO_REGMAP_RUNTIME_ACQUIRE_ERR(&pm); if (ret) return ret; + ret = gpio->reg_mask_xlate(gpio, GPIO_REGMAP_GET_OP, base, offset, + ®, &mask); + if (ret) + return ret; + + if (gpio->reg_dat_base != gpio->reg_set_base) + return regmap_test_bits(gpio->regmap, reg, mask); + /* ensure we don't spoil any register cache with pin input values */ - if (gpio->reg_dat_base == gpio->reg_set_base) - ret = regmap_read_bypassed(gpio->regmap, reg, &val); - else - ret = regmap_read(gpio->regmap, reg, &val); + ret = regmap_read_bypassed(gpio->regmap, reg, &val); if (ret) return ret; @@ -114,7 +151,13 @@ static int gpio_regmap_set(struct gpio_chip *chip, unsigned int offset, unsigned int reg, mask, mask_val; int ret; - ret = gpio->reg_mask_xlate(gpio, GPIO_REGMAP_SET_OP, base, offset, ®, &mask); + GPIO_REGMAP_RUNTIME_ACQUIRE(gpio, pm); + ret = GPIO_REGMAP_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + + ret = gpio->reg_mask_xlate(gpio, GPIO_REGMAP_SET_OP, base, offset, + ®, &mask); if (ret) return ret; @@ -146,6 +189,11 @@ static int gpio_regmap_set_with_clear(struct gpio_chip *chip, unsigned int base, reg, mask, value = 0; int ret; + GPIO_REGMAP_RUNTIME_ACQUIRE(gpio, pm); + ret = GPIO_REGMAP_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + if (val) base = gpio_regmap_addr(gpio->reg_set_base); else @@ -183,7 +231,7 @@ static int gpio_regmap_get_direction(struct gpio_chip *chip, unsigned int offset) { struct gpio_regmap *gpio = gpiochip_get_data(chip); - unsigned int base, val, reg, mask; + unsigned int base, reg, mask; int invert, ret; if (gpio_regmap_fixed_direction(gpio, offset)) { @@ -208,18 +256,24 @@ static int gpio_regmap_get_direction(struct gpio_chip *chip, return -ENOTSUPP; } - ret = gpio->reg_mask_xlate(gpio, GPIO_REGMAP_GET_DIR_OP, base, offset, ®, &mask); + GPIO_REGMAP_RUNTIME_ACQUIRE(gpio, pm); + ret = GPIO_REGMAP_RUNTIME_ACQUIRE_ERR(&pm); if (ret) return ret; - ret = regmap_read(gpio->regmap, reg, &val); + ret = gpio->reg_mask_xlate(gpio, GPIO_REGMAP_GET_DIR_OP, base, offset, + ®, &mask); if (ret) return ret; - if (!!(val & mask) ^ invert) + ret = regmap_test_bits(gpio->regmap, reg, mask); + if (ret < 0) + return ret; + + if (ret ^ invert) return GPIO_LINE_DIRECTION_OUT; - else - return GPIO_LINE_DIRECTION_IN; + + return GPIO_LINE_DIRECTION_IN; } static int gpio_regmap_try_direction_fixed(struct gpio_regmap *gpio, @@ -262,7 +316,13 @@ static int gpio_regmap_set_direction(struct gpio_chip *chip, return -ENOTSUPP; } - ret = gpio->reg_mask_xlate(gpio, GPIO_REGMAP_SET_DIR_OP, base, offset, ®, &mask); + GPIO_REGMAP_RUNTIME_ACQUIRE(gpio, pm); + ret = GPIO_REGMAP_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + + ret = gpio->reg_mask_xlate(gpio, GPIO_REGMAP_SET_DIR_OP, base, offset, + ®, &mask); if (ret) return ret; @@ -293,6 +353,11 @@ static int gpio_regmap_direction_output(struct gpio_chip *chip, struct gpio_regmap *gpio = gpiochip_get_data(chip); int ret; + GPIO_REGMAP_RUNTIME_ACQUIRE(gpio, pm); + ret = GPIO_REGMAP_RUNTIME_ACQUIRE_ERR(&pm); + if (ret) + return ret; + /* * First check if this is gonna work on a fixed direction line, * if it doesn't (i.e. this is a fixed input line), then do not @@ -304,7 +369,9 @@ static int gpio_regmap_direction_output(struct gpio_chip *chip, return ret; } - gpio_regmap_set(chip, offset, value); + ret = gpio_regmap_set(chip, offset, value); + if (ret) + return ret; return gpio_regmap_set_direction(chip, offset, true); } @@ -399,6 +466,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config gpio->reg_clr_base = config->reg_clr_base; gpio->reg_dir_in_base = config->reg_dir_in_base; gpio->reg_dir_out_base = config->reg_dir_out_base; + gpio->pm_dev = config->pm_dev; chip = &gpio->gpio_chip; chip->parent = config->parent; @@ -406,7 +474,7 @@ struct gpio_regmap *gpio_regmap_register(const struct gpio_regmap_config *config chip->base = -1; chip->names = config->names; chip->label = config->label ?: dev_name(config->parent); - chip->can_sleep = regmap_might_sleep(config->regmap); + chip->can_sleep = config->pm_dev || regmap_might_sleep(config->regmap); chip->init_valid_mask = config->init_valid_mask; chip->request = gpiochip_generic_request;
diff --git a/drivers/gpio/gpio-rtd1625.c b/drivers/gpio/gpio-rtd1625.c index 483e44c..bebd1b8 100644 --- a/drivers/gpio/gpio-rtd1625.c +++ b/drivers/gpio/gpio-rtd1625.c
@@ -107,10 +107,11 @@ static int rtd1625_reg_mask_xlate(struct gpio_regmap *gpio, enum gpio_regmap_ope unsigned int base, unsigned int offset, unsigned int *reg, unsigned int *mask) { - /* Each GPIO has its own dedicated 32-bit register */ struct rtd1625_gpio *data = gpio_regmap_get_drvdata(gpio); - int val = 0, ret = 0; + /* Each GPIO has its own dedicated 32-bit register */ *reg = base + offset * 4; + unsigned int val; + int ret; switch (op) { case GPIO_REGMAP_SET_OP: @@ -220,11 +221,11 @@ static void rtd1625_gpio_irq_handle(struct irq_desc *desc) { unsigned int (*get_reg_offset)(struct rtd1625_gpio *gpio, unsigned int offset); struct rtd1625_gpio *data = irq_desc_get_handler_data(desc); + struct device *dev = regmap_get_device(data->regmap); struct irq_chip *chip = irq_desc_get_chip(desc); unsigned int irq = irq_desc_get_irq(desc); struct irq_domain *domain = data->domain; - unsigned int reg_offset, i, j, val; - irq_hw_number_t hwirq; + unsigned int reg_offset, j, val; unsigned long status; u32 irq_type; int ret; @@ -240,11 +241,12 @@ static void rtd1625_gpio_irq_handle(struct irq_desc *desc) chained_irq_enter(chip, desc); - for (i = 0; i < data->info->num_gpios; i += 32) { + for (unsigned int i = 0; i < data->info->num_gpios; i += 32) { reg_offset = get_reg_offset(data, i); ret = regmap_read(data->regmap, reg_offset, &val); if (ret) { - pr_err_ratelimited("Failed to read IRQ status for GPIO %u: %d\n", i, ret); + dev_err_ratelimited(dev, "Failed to read IRQ status for GPIO %u: %d\n", + i, ret); continue; } @@ -261,12 +263,14 @@ static void rtd1625_gpio_irq_handle(struct irq_desc *desc) if (irq != data->irqs[RTD1625_IRQ_LEVEL]) { ret = regmap_write(data->regmap, reg_offset, status); if (ret) - pr_err_ratelimited("Failed to clear edge IRQ for GPIO %u: %d\n", - i, ret); + dev_err_ratelimited(dev, + "Failed to clear edge IRQ for GPIO %u: %d\n", + i, ret); } for_each_set_bit(j, &status, 32) { - hwirq = i + j; + irq_hw_number_t hwirq = i + j; + irq_type = irq_get_trigger_type(irq_find_mapping(domain, hwirq)); /* @@ -486,7 +490,6 @@ static int rtd1625_gpio_setup_irq(struct platform_device *pdev, struct rtd1625_g return irq; num_irqs = (data->info->irq_type_support & IRQ_TYPE_LEVEL_MASK) ? 3 : 2; - for (unsigned int i = 0; i < num_irqs; i++) { irq = platform_get_irq(pdev, i); if (irq < 0) @@ -612,8 +615,7 @@ static const struct rtd1625_gpio_info rtd1625_iso_gpio_info = { static const struct rtd1625_gpio_info rtd1625_isom_gpio_info = { .num_gpios = 4, - .irq_type_support = IRQ_TYPE_EDGE_BOTH | IRQ_TYPE_LEVEL_LOW | - IRQ_TYPE_LEVEL_HIGH, + .irq_type_support = IRQ_TYPE_DEFAULT, .base_offset = 0x20, .gpa_offset = 0x00, .gpda_offset = 0x04,
diff --git a/drivers/gpio/gpio-siox.c b/drivers/gpio/gpio-siox.c index 958034b9..d60680a 100644 --- a/drivers/gpio/gpio-siox.c +++ b/drivers/gpio/gpio-siox.c
@@ -148,11 +148,11 @@ static int gpio_siox_get(struct gpio_chip *chip, unsigned int offset) if (offset >= 12) { unsigned int bitpos = 19 - offset; - ret = ddata->setdata[0] & (1 << bitpos); + ret = !!(ddata->setdata[0] & (1 << bitpos)); } else { unsigned int bitpos = 11 - offset; - ret = ddata->getdata[bitpos / 8] & (1 << (bitpos % 8)); + ret = !!(ddata->getdata[bitpos / 8] & (1 << (bitpos % 8))); } mutex_unlock(&ddata->lock);
diff --git a/drivers/gpio/gpio-sloppy-logic-analyzer.c b/drivers/gpio/gpio-sloppy-logic-analyzer.c index 044d81e..0717649 100644 --- a/drivers/gpio/gpio-sloppy-logic-analyzer.c +++ b/drivers/gpio/gpio-sloppy-logic-analyzer.c
@@ -299,8 +299,8 @@ static int gpio_la_poll_probe(struct platform_device *pdev) debugfs_create_blob("meta_data", 0400, priv->debug_dir, &priv->meta); debugfs_create_ulong("delay_ns", 0600, priv->debug_dir, &priv->delay_ns); debugfs_create_ulong("delay_ns_acquisition", 0400, priv->debug_dir, &priv->acq_delay); - debugfs_create_file_unsafe("buf_size", 0600, priv->debug_dir, priv, &fops_buf_size); - debugfs_create_file_unsafe("capture", 0200, priv->debug_dir, priv, &fops_capture); + debugfs_create_file("buf_size", 0600, priv->debug_dir, priv, &fops_buf_size); + debugfs_create_file("capture", 0200, priv->debug_dir, priv, &fops_capture); debugfs_create_file("trigger", 0200, priv->debug_dir, priv, &fops_trigger); return 0;
diff --git a/drivers/gpio/gpio-tegra186.c b/drivers/gpio/gpio-tegra186.c index d9a2ded..34e084c 100644 --- a/drivers/gpio/gpio-tegra186.c +++ b/drivers/gpio/gpio-tegra186.c
@@ -1419,6 +1419,71 @@ static const struct tegra_gpio_soc tegra264_uphy_soc = { .has_vm_support = true, }; +static const struct tegra_gpio_port tegra268_main_ports[] = { + TEGRA264_MAIN_GPIO_PORT(F, 3, 0, 8), + TEGRA264_MAIN_GPIO_PORT(G, 3, 1, 5), + TEGRA264_MAIN_GPIO_PORT(H, 1, 0, 8), + TEGRA264_MAIN_GPIO_PORT(J, 1, 1, 8), + TEGRA264_MAIN_GPIO_PORT(K, 1, 2, 8), + TEGRA264_MAIN_GPIO_PORT(L, 1, 3, 8), + TEGRA264_MAIN_GPIO_PORT(M, 1, 4, 2), + TEGRA264_MAIN_GPIO_PORT(P, 2, 0, 8), + TEGRA264_MAIN_GPIO_PORT(Q, 2, 1, 8), + TEGRA264_MAIN_GPIO_PORT(R, 2, 2, 8), + TEGRA264_MAIN_GPIO_PORT(S, 2, 3, 2), + TEGRA264_MAIN_GPIO_PORT(T, 0, 0, 7), + TEGRA264_MAIN_GPIO_PORT(U, 0, 1, 8), + TEGRA264_MAIN_GPIO_PORT(V, 0, 2, 8), + TEGRA264_MAIN_GPIO_PORT(W, 0, 3, 8), + TEGRA264_MAIN_GPIO_PORT(Y, 0, 5, 8), + TEGRA264_MAIN_GPIO_PORT(Z, 0, 6, 8), + TEGRA264_MAIN_GPIO_PORT(AL, 0, 4, 3), +}; + +static const struct tegra_gpio_soc tegra268_main_soc = { + .num_ports = ARRAY_SIZE(tegra268_main_ports), + .ports = tegra268_main_ports, + .name = "tegra268-gpio", + .instance = 0, + .num_irqs_per_bank = 8, + .has_vm_support = true, +}; + +static const struct tegra_gpio_port tegra268_aon_ports[] = { + TEGRA264_AON_GPIO_PORT(AA, 0, 0, 8), + TEGRA264_AON_GPIO_PORT(BB, 0, 1, 2), + TEGRA264_AON_GPIO_PORT(CC, 0, 2, 8), + TEGRA264_AON_GPIO_PORT(DD, 0, 3, 8), + TEGRA264_AON_GPIO_PORT(EE, 0, 4, 2) +}; + +static const struct tegra_gpio_soc tegra268_aon_soc = { + .num_ports = ARRAY_SIZE(tegra268_aon_ports), + .ports = tegra268_aon_ports, + .name = "tegra268-gpio-aon", + .instance = 1, + .num_irqs_per_bank = 8, + .has_gte = true, + .has_vm_support = true, +}; + +static const struct tegra_gpio_port tegra268_uphy_ports[] = { + TEGRA264_UPHY_GPIO_PORT(A, 0, 0, 6), + TEGRA264_UPHY_GPIO_PORT(B, 0, 1, 8), + TEGRA264_UPHY_GPIO_PORT(C, 0, 2, 3), + TEGRA264_UPHY_GPIO_PORT(D, 1, 0, 6), + TEGRA264_UPHY_GPIO_PORT(E, 1, 1, 4), +}; + +static const struct tegra_gpio_soc tegra268_uphy_soc = { + .num_ports = ARRAY_SIZE(tegra268_uphy_ports), + .ports = tegra268_uphy_ports, + .name = "tegra268-gpio-uphy", + .instance = 2, + .num_irqs_per_bank = 8, + .has_vm_support = true, +}; + #define TEGRA256_MAIN_GPIO_PORT(_name, _bank, _port, _pins) \ TEGRA_GPIO_PORT(TEGRA256_MAIN, _name, _bank, _port, _pins) @@ -1529,6 +1594,15 @@ static const struct of_device_id tegra186_gpio_of_match[] = { .compatible = "nvidia,tegra264-gpio-uphy", .data = &tegra264_uphy_soc }, { + .compatible = "nvidia,tegra268-gpio", + .data = &tegra268_main_soc + }, { + .compatible = "nvidia,tegra268-gpio-aon", + .data = &tegra268_aon_soc + }, { + .compatible = "nvidia,tegra268-gpio-uphy", + .data = &tegra268_uphy_soc + }, { /* sentinel */ } };
diff --git a/drivers/gpio/gpiolib-acpi-core.c b/drivers/gpio/gpiolib-acpi-core.c index 220f0ac..f94f456 100644 --- a/drivers/gpio/gpiolib-acpi-core.c +++ b/drivers/gpio/gpiolib-acpi-core.c
@@ -116,7 +116,8 @@ static int acpi_gpiochip_find(struct gpio_chip *gc, const void *data) /** * acpi_get_gpiod() - Translate ACPI GPIO pin to GPIO descriptor usable with GPIO API - * @path: ACPI GPIO controller full path name, (e.g. "\\_SB.GPO1") + * @parent: parent ACPI handle to resolve relative path + * @path: ACPI GPIO controller path name, (e.g. "\\_SB.GPO1" or "^GP01") * @pin: ACPI GPIO pin number (0-based, controller-relative) * * Returns: @@ -128,12 +129,12 @@ static int acpi_gpiochip_find(struct gpio_chip *gc, const void *data) * controller does not have GPIO chip registered at the moment. This is to * support probe deferral. */ -static struct gpio_desc *acpi_get_gpiod(char *path, unsigned int pin) +static struct gpio_desc *acpi_get_gpiod(acpi_handle parent, char *path, unsigned int pin) { acpi_handle handle; acpi_status status; - status = acpi_get_handle(NULL, path, &handle); + status = acpi_get_handle(parent, path, &handle); if (ACPI_FAILURE(status)) return ERR_PTR(-ENODEV); @@ -733,7 +734,8 @@ static int acpi_populate_gpio_lookup(struct acpi_resource *ares, void *data) if (info->quirks & ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER) desc = gpio_to_desc(agpio->pin_table[pin_index]); else - desc = acpi_get_gpiod(agpio->resource_source.string_ptr, + desc = acpi_get_gpiod(acpi_device_handle(info->adev), + agpio->resource_source.string_ptr, agpio->pin_table[pin_index]); lookup->desc = desc; info->pin_config = agpio->pin_config;
diff --git a/drivers/gpio/gpiolib-acpi-quirks.c b/drivers/gpio/gpiolib-acpi-quirks.c index a0116f0..9a52387 100644 --- a/drivers/gpio/gpiolib-acpi-quirks.c +++ b/drivers/gpio/gpiolib-acpi-quirks.c
@@ -345,6 +345,22 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = { }, { /* + * GPIO 11 is the power enable of the internal USB camera. + * The firmware drives it high but also lists it in _AEI with + * an empty handler. Requesting it as an input turns the camera + * off, so it never enumerates. + * Found in BIOS V1.14 + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Acer"), + DMI_MATCH(DMI_PRODUCT_FAMILY, "Acer Nitro V 16S AI"), + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .ignore_interrupt = "AMDI0030:00@11", + }, + }, + { + /* * Wakeup only works when keyboard backlight is turned off * https://gitlab.freedesktop.org/drm/amd/-/issues/4169 */ @@ -392,6 +408,32 @@ static const struct dmi_system_id gpiolib_acpi_quirks[] __initconst = { .ignore_wake = "VEN_0488:00@355", }, }, + { + /* + * Spurious wakeups from GPP3 PCIe bridge interrupt + * Found in BIOS UX425UA.301 + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "ZenBook UX425UA_UM425UA"), + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .ignore_wake = "AMDI0030:00@24", + }, + }, + { + /* + * Lenovo IdeaPad Slim 3 15ABR8: the touchscreen wake IRQ fires as soon + * as the system enters suspend, causing an immediate spurious resume. + */ + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), + DMI_MATCH(DMI_PRODUCT_NAME, "82XM"), + }, + .driver_data = &(struct acpi_gpiolib_dmi_quirk) { + .ignore_wake = "GTCH7503:00@10", + }, + }, {} /* Terminating entry */ };
diff --git a/drivers/gpio/gpiolib-cdev.c b/drivers/gpio/gpiolib-cdev.c index a127e6e..a30564d 100644 --- a/drivers/gpio/gpiolib-cdev.c +++ b/drivers/gpio/gpiolib-cdev.c
@@ -715,6 +715,8 @@ static int hte_edge_setup(struct line *line, u64 eflags) line->desc); ret = hte_ts_get(NULL, hdesc, 0); + if (ret == -ENODEV) + return -EOPNOTSUPP; if (ret) return ret;
diff --git a/drivers/gpio/gpiolib-kunit.c b/drivers/gpio/gpiolib-kunit.c index 6a2c8b3..f005854 100644 --- a/drivers/gpio/gpiolib-kunit.c +++ b/drivers/gpio/gpiolib-kunit.c
@@ -566,13 +566,6 @@ static int gpio_unbind_notify(struct notifier_block *nb, unsigned long action, return NOTIFY_OK; } -static void gpio_unbind_unregister_notifier(void *data) -{ - struct notifier_block *nb = data; - - blocking_notifier_chain_unregister(&gpio_unbind_notifier, nb); -} - static int gpio_unbind_consumer_probe(struct platform_device *pdev) { struct gpio_unbind_consumer_drvdata *data; @@ -590,11 +583,8 @@ static int gpio_unbind_consumer_probe(struct platform_device *pdev) return PTR_ERR(data->desc); data->nb.notifier_call = gpio_unbind_notify; - ret = blocking_notifier_chain_register(&gpio_unbind_notifier, &data->nb); - if (ret) - return ret; - - ret = devm_add_action_or_reset(dev, gpio_unbind_unregister_notifier, &data->nb); + ret = devm_blocking_notifier_chain_register(dev, &gpio_unbind_notifier, + &data->nb); if (ret) return ret;
diff --git a/drivers/gpio/gpiolib.c b/drivers/gpio/gpiolib.c index c0394c7..c880686 100644 --- a/drivers/gpio/gpiolib.c +++ b/drivers/gpio/gpiolib.c
@@ -2447,6 +2447,27 @@ int gpiochip_generic_config(struct gpio_chip *gc, unsigned int offset, } EXPORT_SYMBOL_GPL(gpiochip_generic_config); +/** + * gpiochip_generic_get_config() - read back the configuration of a pin + * @gc: the gpiochip owning the GPIO + * @offset: the offset of the GPIO to query + * @config: the packed parameter to query, replaced by its bare argument + * + * Returns: + * 0 on success, or negative errno on failure. + */ +int gpiochip_generic_get_config(struct gpio_chip *gc, unsigned int offset, + unsigned long *config) +{ +#ifdef CONFIG_PINCTRL + if (list_empty(&gc->gpiodev->pin_ranges)) + return -ENOTSUPP; +#endif + + return pinctrl_gpio_get_config(gc, offset, config); +} +EXPORT_SYMBOL_GPL(gpiochip_generic_get_config); + #ifdef CONFIG_PINCTRL /**
diff --git a/drivers/hid/Kconfig b/drivers/hid/Kconfig index c43e824..2481bc0 100644 --- a/drivers/hid/Kconfig +++ b/drivers/hid/Kconfig
@@ -527,15 +527,6 @@ - MousePen i608X tablet - EasyPen M610X tablet -config HID_KYSONA - tristate "Kysona devices" - depends on USB_HID - help - Support for Kysona mice. - - Say Y here if you have a Kysona M600 mouse - and want to be able to read its battery capacity. - config HID_UCLOGIC tristate "UC-Logic" depends on USB_HID @@ -867,12 +858,16 @@ tristate "Nintendo Joy-Con, NSO, and Pro Controller support" depends on NEW_LEDS depends on LEDS_CLASS + depends on USB_HID select POWER_SUPPLY help - Adds support for the Nintendo Switch Joy-Cons, NSO, Pro Controller. - All controllers support bluetooth, and the Pro Controller also supports - its USB mode. This also includes support for the Nintendo Switch Online - Controllers which include the NES, Genesis, SNES, and N64 controllers. + Adds support for the Nintendo Switch Joy-Cons, NSO, Pro Controller, as + well as Nintendo Switch 2 Joy-Cons, Pro Controller, and NSO GameCube + controllers. All Switch controllers support bluetooth, and the Pro + Controller also supports its USB mode. This also includes support for + the Nintendo Switch Online Controllers which include the NES, Genesis, + SNES, and N64 controllers. Switch 2 controllers currently only support + USB mode. To compile this driver as a module, choose M here: the module will be called hid-nintendo. @@ -882,10 +877,21 @@ depends on HID_NINTENDO select INPUT_FF_MEMLESS help - Say Y here if you have a Nintendo Switch controller and want to enable - force feedback support for it. This works for both joy-cons, the pro - controller, and the NSO N64 controller. For the pro controller, both - rumble motors can be controlled individually. + Say Y here if you have a Nintendo Switch or Switch 2 controller and want + to enable force feedback support for it. This works for Joy-Cons, the Pro + Controllers, and the NSO N64 and GameCube controller. For the Pro + Controller, both rumble motors can be controlled individually. + +config NINTENDO_SWITCH2_USB + tristate "Wired Nintendo Switch 2 controller support" + depends on HID_NINTENDO + depends on USB + help + Say Y here if you want to enable support for wired Nintendo Switch 2 + controllers. + + To compile this driver as a module, choose M here: the + module will be called hid-nintendo-switch2-usb. config HID_NTI tristate "NTI keyboard adapters" @@ -1359,6 +1365,18 @@ Supports Moza Racing, Cammus, VRS, FFBeast and more. +config HID_PULSAR + tristate "Pulsar gaming mouse support" + depends on USB_HID + select POWER_SUPPLY + help + Support for Pulsar gaming mice (X2 V2, X2H, X2A, Xlite V3) + connected via 1kHz/4kHz USB dongle or wired. + Provides battery level, voltage, and charging status + monitoring via the power supply framework. + + Additional supported devices: Kysona M600, ATK VXE R1 SE+ + config HID_WACOM tristate "Wacom Intuos/Graphire tablet support (USB)" depends on USB_HID
diff --git a/drivers/hid/Makefile b/drivers/hid/Makefile index 48a863b..43a8eb0 100644 --- a/drivers/hid/Makefile +++ b/drivers/hid/Makefile
@@ -74,7 +74,6 @@ obj-$(CONFIG_HID_KENSINGTON) += hid-kensington.o obj-$(CONFIG_HID_KEYTOUCH) += hid-keytouch.o obj-$(CONFIG_HID_KYE) += hid-kye.o -obj-$(CONFIG_HID_KYSONA) += hid-kysona.o obj-$(CONFIG_HID_LCPOWER) += hid-lcpower.o obj-$(CONFIG_HID_LENOVO) += hid-lenovo.o obj-$(CONFIG_HID_LENOVO_GO) += hid-lenovo-go.o @@ -96,6 +95,7 @@ obj-$(CONFIG_HID_MSI) += hid-msi.o obj-$(CONFIG_HID_MULTITOUCH) += hid-multitouch.o obj-$(CONFIG_HID_NINTENDO) += hid-nintendo.o +obj-$(CONFIG_NINTENDO_SWITCH2_USB) += hid-nintendo-switch2-usb.o obj-$(CONFIG_HID_NTI) += hid-nti.o obj-$(CONFIG_HID_NTRIG) += hid-ntrig.o obj-$(CONFIG_HID_NVIDIA_SHIELD) += hid-nvidia-shield.o @@ -117,6 +117,7 @@ obj-$(CONFIG_HID_PLANTRONICS) += hid-plantronics.o obj-$(CONFIG_HID_PLAYSTATION) += hid-playstation.o obj-$(CONFIG_HID_PRIMAX) += hid-primax.o +obj-$(CONFIG_HID_PULSAR) += hid-pulsar.o obj-$(CONFIG_HID_PXRC) += hid-pxrc.o obj-$(CONFIG_HID_RAKK) += hid-rakk.o obj-$(CONFIG_HID_RAPOO) += hid-rapoo.o
diff --git a/drivers/hid/amd-sfh-hid/Makefile b/drivers/hid/amd-sfh-hid/Makefile index 106514b..a0e4113 100644 --- a/drivers/hid/amd-sfh-hid/Makefile +++ b/drivers/hid/amd-sfh-hid/Makefile
@@ -8,6 +8,7 @@ amd_sfh-objs := amd_sfh_hid.o amd_sfh-objs += amd_sfh_client.o amd_sfh-objs += amd_sfh_pcie.o +amd_sfh-objs += amd_sfh_sysfs.o amd_sfh-objs += hid_descriptor/amd_sfh_hid_desc.o amd_sfh-objs += sfh1_1/amd_sfh_init.o amd_sfh-objs += sfh1_1/amd_sfh_interface.o
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_client.c b/drivers/hid/amd-sfh-hid/amd_sfh_client.c index ae6add0..a68b275 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_client.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_client.c
@@ -95,7 +95,7 @@ void amd_sfh_work(struct work_struct *work) cli_data->feature_report[current_index]); if (report_size) hid_input_report(cli_data->hid_sensor_hubs[current_index], - cli_data->report_type[current_index], + node_type, cli_data->feature_report[current_index], report_size, 0); else pr_err("AMDSFH: Invalid report size\n"); @@ -104,7 +104,7 @@ void amd_sfh_work(struct work_struct *work) report_size = mp2_ops->get_in_rep(current_index, sensor_index, report_id, in_data); if (report_size) hid_input_report(cli_data->hid_sensor_hubs[current_index], - cli_data->report_type[current_index], + node_type, in_data->input_report[current_index], report_size, 0); else pr_err("AMDSFH: Invalid report size\n");
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_common.h b/drivers/hid/amd-sfh-hid/amd_sfh_common.h index 3d29119..e8cc7f1 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_common.h +++ b/drivers/hid/amd-sfh-hid/amd_sfh_common.h
@@ -18,6 +18,7 @@ #define PCI_DEVICE_ID_AMD_MP2 0x15E4 #define PCI_DEVICE_ID_AMD_MP2_1_1 0x164A +#define PCI_DEVICE_ID_AMD_MP2_1_2 0x1152 /* The BAR 2 size must cover the highest register offset (0x10958) */ #define AMD_SFH_MIN_BAR_SIZE SZ_128K @@ -43,6 +44,7 @@ enum cmd_id { enum amd_mp2_version { MP2_VER_V2 = 1, MP2_VER_1_1 = 2, + MP2_VER_1_2 = 3, }; struct amd_mp2_sensor_info {
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c index 061a635..b3cb13b 100644 --- a/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c +++ b/drivers/hid/amd-sfh-hid/amd_sfh_pcie.c
@@ -20,9 +20,9 @@ #include <linux/iopoll.h> #include <linux/module.h> #include <linux/slab.h> -#include <linux/string_choices.h> #include "amd_sfh_pcie.h" +#include "amd_sfh_sysfs.h" #include "sfh1_1/amd_sfh_init.h" #define DRIVER_NAME "pcie_mp2_amd" @@ -41,6 +41,8 @@ module_param_named(sensor_mask, sensor_mask_override, int, 0444); MODULE_PARM_DESC(sensor_mask, "override the detected sensors mask"); static bool intr_disable = true; +module_param_named(intr_disable, intr_disable, bool, 0444); +MODULE_PARM_DESC(intr_disable, "override the interrupt disable sensor bit"); static int amd_sfh_wait_response_v2(struct amd_mp2_dev *mp2, u8 sid, u32 sensor_sts) { @@ -313,6 +315,13 @@ static const struct dmi_system_id dmi_sfh_table[] = { DMI_MATCH(DMI_PRODUCT_NAME, "HP ProBook x360 435 G7"), }, }, + { + .callback = mp2_disable_intr, + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), + DMI_MATCH(DMI_PRODUCT_NAME, "VivoBook_ASUSLaptop TP420UA_TM420UA"), + }, + }, {} }; @@ -331,57 +340,6 @@ static const struct dmi_system_id dmi_nodevs[] = { { } }; -static ssize_t hpd_show(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct amd_mp2_dev *mp2 = dev_get_drvdata(dev); - - return sysfs_emit(buf, "%s\n", str_enabled_disabled(mp2->dev_en.is_hpd_enabled)); -} - -static ssize_t hpd_store(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - struct amd_mp2_dev *mp2 = dev_get_drvdata(dev); - bool enabled; - int ret; - - ret = kstrtobool(buf, &enabled); - if (ret) - return ret; - - mp2->sfh1_1_ops->toggle_hpd(mp2, enabled); - - return count; -} -static DEVICE_ATTR_RW(hpd); - -static umode_t sfh_attr_is_visible(struct kobject *kobj, struct attribute *attr, int idx) -{ - struct device *dev = kobj_to_dev(kobj); - struct amd_mp2_dev *mp2 = dev_get_drvdata(dev); - - if (!mp2->sfh1_1_ops || !mp2->dev_en.is_hpd_present) - return 0; - - return attr->mode; -} - -static struct attribute *sfh_attrs[] = { - &dev_attr_hpd.attr, - NULL, -}; - -static struct attribute_group sfh_attr_group = { - .attrs = sfh_attrs, - .is_visible = sfh_attr_is_visible, -}; - -static const struct attribute_group *amd_sfh_groups[] = { - &sfh_attr_group, - NULL, -}; - static DEFINE_IDA(sfh_tm_ida); static void amd_sfh_maybe_register_tm(struct amd_mp2_dev *mp2) @@ -439,7 +397,7 @@ static void sfh1_1_init_work(struct work_struct *work) amd_sfh_clear_intr(mp2); mp2->init_done = 1; - rc = sysfs_update_group(&mp2->pdev->dev.kobj, &sfh_attr_group); + rc = amd_sfh_update_sysfs(mp2); if (rc) dev_warn(&mp2->pdev->dev, "failed to update sysfs group\n"); @@ -598,6 +556,7 @@ static SIMPLE_DEV_PM_OPS(amd_mp2_pm_ops, amd_mp2_pci_suspend, static const struct pci_device_id amd_mp2_pci_tbl[] = { { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_MP2) }, { PCI_DEVICE_DATA(AMD, MP2_1_1, MP2_VER_1_1) }, + { PCI_DEVICE_DATA(AMD, MP2_1_2, MP2_VER_1_2) }, { } }; MODULE_DEVICE_TABLE(pci, amd_mp2_pci_tbl);
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_sysfs.c b/drivers/hid/amd-sfh-hid/amd_sfh_sysfs.c new file mode 100644 index 0000000..8af4df0 --- /dev/null +++ b/drivers/hid/amd-sfh-hid/amd_sfh_sysfs.c
@@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * AMD SFH sysfs attributes + * + * Copyright (c) 2026, Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com> + */ +#include <linux/device.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/string_choices.h> +#include <linux/sysfs.h> + +#include "amd_sfh_common.h" +#include "amd_sfh_sysfs.h" +#include "sfh1_1/amd_sfh_init.h" +#include "sfh1_1/amd_sfh_interface.h" + +static ssize_t hpd_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct amd_mp2_dev *mp2 = dev_get_drvdata(dev); + + return sysfs_emit(buf, "%s\n", str_enabled_disabled(mp2->dev_en.is_hpd_enabled)); +} + +static ssize_t hpd_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct amd_mp2_dev *mp2 = dev_get_drvdata(dev); + bool enabled; + int ret; + + ret = kstrtobool(buf, &enabled); + if (ret) + return ret; + + mp2->sfh1_1_ops->toggle_hpd(mp2, enabled); + + return count; +} +static DEVICE_ATTR_RW(hpd); + +/* Operating-mode telemetry reported by the SRA sensor, exposed read-only. */ +static int amd_sfh_read_op_mode(struct amd_mp2_dev *mp2, struct sfh_op_mode *mode) +{ + struct sfh_accel_data accel_data; + void __iomem *sensoraddr; + + if (!mp2->sfh1_1_ops || !mp2->dev_en.is_sra_present) + return -ENODEV; + + if (mp2->mp2_ver >= MP2_VER_1_2) { + sensoraddr = mp2->vsbase + + (SRA_IDX * SENSOR_DATA_MEM_SIZE_DEFAULT) + + OFFSET_SENSOR_DATA_DEFAULT; + memcpy_fromio(&accel_data, sensoraddr, sizeof(struct sfh_accel_data)); + mode->val = accel_data.c2p3_data; + } else { + mode->val = readl(mp2->mmio + amd_get_c2p_val(mp2, 3)); + } + + return 0; +} + +#define SFH_OP_MODE_ATTR(_name, _field) \ +static ssize_t _name##_show(struct device *dev, \ + struct device_attribute *attr, char *buf) \ +{ \ + struct amd_mp2_dev *mp2 = dev_get_drvdata(dev); \ + struct sfh_op_mode mode; \ + int ret; \ + \ + ret = amd_sfh_read_op_mode(mp2, &mode); \ + if (ret) \ + return ret; \ + \ + return sysfs_emit(buf, "%u\n", mode.op_mode._field); \ +} \ +static DEVICE_ATTR_RO(_name) + +SFH_OP_MODE_ATTR(in_bag_state, inbagstate); +SFH_OP_MODE_ATTR(out_bag_state, outbagstate); +SFH_OP_MODE_ATTR(on_table_state, ontablestate); +SFH_OP_MODE_ATTR(hinge_angle, angle); +SFH_OP_MODE_ATTR(lid_status, lidstatus); +SFH_OP_MODE_ATTR(device_mode, devicemode); + +static umode_t sfh_attr_is_visible(struct kobject *kobj, struct attribute *attr, int idx) +{ + struct device *dev = kobj_to_dev(kobj); + struct amd_mp2_dev *mp2 = dev_get_drvdata(dev); + + if (!mp2->sfh1_1_ops) + return 0; + + if (attr == &dev_attr_hpd.attr) { + if (!mp2->dev_en.is_hpd_present) + return 0; + } else if (!mp2->dev_en.is_sra_present) { + /* operating-mode telemetry requires the SRA sensor */ + return 0; + } + + return attr->mode; +} + +static struct attribute *sfh_attrs[] = { + &dev_attr_hpd.attr, + &dev_attr_in_bag_state.attr, + &dev_attr_out_bag_state.attr, + &dev_attr_on_table_state.attr, + &dev_attr_hinge_angle.attr, + &dev_attr_lid_status.attr, + &dev_attr_device_mode.attr, + NULL, +}; + +static struct attribute_group sfh_attr_group = { + .attrs = sfh_attrs, + .is_visible = sfh_attr_is_visible, +}; + +const struct attribute_group *amd_sfh_groups[] = { + &sfh_attr_group, + NULL, +}; + +int amd_sfh_update_sysfs(struct amd_mp2_dev *mp2) +{ + return sysfs_update_group(&mp2->pdev->dev.kobj, &sfh_attr_group); +}
diff --git a/drivers/hid/amd-sfh-hid/amd_sfh_sysfs.h b/drivers/hid/amd-sfh-hid/amd_sfh_sysfs.h new file mode 100644 index 0000000..941b995 --- /dev/null +++ b/drivers/hid/amd-sfh-hid/amd_sfh_sysfs.h
@@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * AMD SFH sysfs attributes + * + * Copyright (c) 2026, Advanced Micro Devices, Inc. + * All Rights Reserved. + * + * Author: Basavaraj Natikar <Basavaraj.Natikar@amd.com> + */ +#ifndef AMD_SFH_SYSFS_H +#define AMD_SFH_SYSFS_H + +#include "amd_sfh_common.h" + +extern const struct attribute_group *amd_sfh_groups[]; + +int amd_sfh_update_sysfs(struct amd_mp2_dev *mp2); + +#endif
diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h index 882434b..230fb69 100644 --- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h +++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_desc.h
@@ -48,8 +48,6 @@ struct accel3_input_report { int in_accel_x_value; int in_accel_y_value; int in_accel_z_value; - /* include if required to support the "shake" event */ - u8 in_accel_shake_detection; } __packed; struct gyro_feature_report {
diff --git a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h index 67ec2d6..64cff84 100644 --- a/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h +++ b/drivers/hid/amd-sfh-hid/hid_descriptor/amd_sfh_hid_report_desc.h
@@ -169,13 +169,6 @@ static const u8 accel3_report_descriptor[] = { 0x95, 1, /* HID report count (1) */ 0x55, 0x0E, /* HID unit exponent(0x0E) */ 0X81, 0x02, /* HID Input (Data_Arr_Abs) */ - -0x0A, 0x51, 0x04, /* HID usage sensor data motion state */ -0x15, 0, /* HID logical Min_8(0) False = Still*/ -0x25, 1, /* HID logical Min_8(1) True = In motion */ -0x75, 8, /* HID report size(8) */ -0x95, 1, /* HID report count (1) */ -0X81, 0x02, /* HID Input (Data_Arr_Abs) */ 0xC0 /* HID end collection */ };
diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c index c8916af..b81a97d 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_desc.c
@@ -187,6 +187,7 @@ static u8 get_input_rep(u8 current_index, int sensor_idx, int report_id, struct sfh_gyro_data gyro_data; struct sfh_mag_data mag_data; struct sfh_als_data als_data; + struct sfh_hpd_data hpd_data; struct hpd_status hpdstatus; struct sfh_base_info binfo; void __iomem *sensoraddr; @@ -251,8 +252,16 @@ static u8 get_input_rep(u8 current_index, int sensor_idx, int report_id, break; case HPD_IDX: get_common_inputs(&hpd_input.common_property, report_id); - hpdstatus.val = readl(mp2->mmio + amd_get_c2p_val(mp2, 4)); - hpd_input.human_presence = hpdstatus.shpd.presence; + if (mp2->mp2_ver >= MP2_VER_1_2) { + sensoraddr = mp2->vsbase + + (HPD_IDX * SENSOR_DATA_MEM_SIZE_DEFAULT) + + OFFSET_SENSOR_DATA_DEFAULT; + memcpy_fromio(&hpd_data, sensoraddr, sizeof(struct sfh_hpd_data)); + hpd_input.human_presence = hpd_data.status.shpd.presence; + } else { + hpdstatus.val = readl(mp2->mmio + amd_get_c2p_val(mp2, 4)); + hpd_input.human_presence = hpdstatus.shpd.presence; + } report_size = sizeof(hpd_input); memcpy(input_report, &hpd_input, sizeof(hpd_input)); break;
diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c index 60c185a..bc0adb7 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.c
@@ -98,6 +98,25 @@ void sfh_interface_init(struct amd_mp2_dev *mp2) emp2 = mp2; } +static unsigned int amd_sfh_read_c2p3(struct amd_mp2_dev *mp2) +{ + struct sfh_accel_data accel_data; + void __iomem *sensoraddr; + u32 val; + + if (mp2->mp2_ver >= MP2_VER_1_2) { + sensoraddr = mp2->vsbase + + (SRA_IDX * SENSOR_DATA_MEM_SIZE_DEFAULT) + + OFFSET_SENSOR_DATA_DEFAULT; + memcpy_fromio(&accel_data, sensoraddr, sizeof(struct sfh_accel_data)); + val = accel_data.c2p3_data; + } else { + val = readl(mp2->mmio + amd_get_c2p_val(mp2, 3)); + } + + return val; +} + static int amd_sfh_op_mode_info(u32 *op_mode) { struct sfh_op_mode mode; @@ -114,7 +133,7 @@ static int amd_sfh_op_mode_info(u32 *op_mode) if (!present) return -ENODEV; - mode.val = readl(emp2->mmio + amd_get_c2p_val(emp2, 3)); + mode.val = amd_sfh_read_c2p3(emp2); dev_dbg(&emp2->pdev->dev, "op-mode: %s (mode=%u)\n", mode.op_mode.mode == SFH_MODE_TABLET ? "tablet" : "laptop", mode.op_mode.mode); @@ -133,7 +152,7 @@ static int amd_sfh_mode_info(u32 *platform_type, u32 *laptop_placement) if (!emp2 || !emp2->dev_en.is_sra_present) return -ENODEV; - mode.val = readl(emp2->mmio + amd_get_c2p_val(emp2, 3)); + mode.val = amd_sfh_read_c2p3(emp2); *platform_type = mode.op_mode.devicemode; @@ -160,7 +179,9 @@ static int amd_sfh_mode_info(u32 *platform_type, u32 *laptop_placement) static int amd_sfh_hpd_info(u8 *user_present) { + struct sfh_hpd_data hpd_data; struct hpd_status hpdstatus; + void __iomem *sensoraddr; if (!user_present) return -EINVAL; @@ -168,8 +189,16 @@ static int amd_sfh_hpd_info(u8 *user_present) if (!emp2 || !emp2->dev_en.is_hpd_present || !emp2->dev_en.is_hpd_enabled) return -ENODEV; - hpdstatus.val = readl(emp2->mmio + amd_get_c2p_val(emp2, 4)); - *user_present = hpdstatus.shpd.presence; + if (emp2->mp2_ver >= MP2_VER_1_2) { + sensoraddr = emp2->vsbase + + (HPD_IDX * SENSOR_DATA_MEM_SIZE_DEFAULT) + + OFFSET_SENSOR_DATA_DEFAULT; + memcpy_fromio(&hpd_data, sensoraddr, sizeof(struct sfh_hpd_data)); + *user_present = hpd_data.status.shpd.presence; + } else { + hpdstatus.val = readl(emp2->mmio + amd_get_c2p_val(emp2, 4)); + *user_present = hpdstatus.shpd.presence; + } return 0; }
diff --git a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h index 56258c4..eaa90c6 100644 --- a/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h +++ b/drivers/hid/amd-sfh-hid/sfh1_1/amd_sfh_interface.h
@@ -130,6 +130,7 @@ struct sfh_accel_data { struct sfh_common_data commondata; struct sfh_float32 acceldata; u32 accelstatus; + u32 c2p3_data; }; struct sfh_gyro_data { @@ -165,6 +166,12 @@ struct hpd_status { }; }; +struct sfh_hpd_data { + struct sfh_common_data commondata; + u32 reserved; + struct hpd_status status; +}; + struct sfh_op_mode { union { u32 val;
diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c index f6134c5..5b32fb8 100644 --- a/drivers/hid/hid-apple.c +++ b/drivers/hid/hid-apple.c
@@ -30,7 +30,7 @@ #include "hid-ids.h" #define APPLE_RDESC_JIS BIT(0) -/* BIT(1) reserved, was: APPLE_IGNORE_MOUSE */ +#define APPLE_IGNORE_MOUSE BIT(1) #define APPLE_HAS_FN BIT(2) /* BIT(3) reserved, was: APPLE_HIDDEV */ #define APPLE_ISO_TILDE_QUIRK BIT(4) @@ -373,6 +373,9 @@ static const struct apple_non_apple_keyboard non_apple_keyboards[] = { { "2.4G Wireless Receiver" }, /* EPOMAKER TH87 dongle */ { "Thock TKL Wireless" }, /* ENDORFY THOCK TKL BT mode */ { "USB Dongle" }, /* ENDORFY THOCK TKL dongle */ + { "HFD GS3104T PRO" }, /* GANSS GS3104T PRO USB mode */ + { "GS3104T-PRO 2.4G" }, /* GANSS GS3104T PRO 2.4G dongle */ + { "GS3104T PRO" }, /* GANSS GS3104T PRO Bluetooth */ }; static bool apple_is_non_apple_keyboard(struct hid_device *hdev) @@ -957,6 +960,9 @@ static int apple_probe(struct hid_device *hdev, struct apple_sc *asc; int ret; + if (quirks & APPLE_IGNORE_MOUSE && hdev->type == HID_TYPE_USBMOUSE) + return -ENODEV; + asc = devm_kzalloc(&hdev->dev, sizeof(*asc), GFP_KERNEL); if (asc == NULL) { hid_err(hdev, "can't alloc apple descriptor\n"); @@ -1182,27 +1188,31 @@ static const struct hid_device_id apple_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRING9_JIS), .driver_data = APPLE_HAS_FN | APPLE_RDESC_JIS }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J140K), - .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK }, + .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | + APPLE_IGNORE_MOUSE }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J132), .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | - APPLE_DISABLE_FKEYS }, + APPLE_DISABLE_FKEYS | APPLE_IGNORE_MOUSE }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680), .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | - APPLE_DISABLE_FKEYS }, + APPLE_DISABLE_FKEYS | APPLE_IGNORE_MOUSE }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J680_ALT), .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | - APPLE_DISABLE_FKEYS }, + APPLE_DISABLE_FKEYS | APPLE_IGNORE_MOUSE }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J213), .driver_data = APPLE_HAS_FN | APPLE_BACKLIGHT_CTL | APPLE_ISO_TILDE_QUIRK | - APPLE_DISABLE_FKEYS }, + APPLE_DISABLE_FKEYS | APPLE_IGNORE_MOUSE }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J214K), - .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS }, + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS | + APPLE_IGNORE_MOUSE }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J223), - .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS }, + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS | + APPLE_IGNORE_MOUSE }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J230K), - .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK }, + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_IGNORE_MOUSE }, { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_WELLSPRINGT2_J152F), - .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS }, + .driver_data = APPLE_HAS_FN | APPLE_ISO_TILDE_QUIRK | APPLE_DISABLE_FKEYS | + APPLE_IGNORE_MOUSE }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ANSI), .driver_data = APPLE_NUMLOCK_EMULATION | APPLE_HAS_FN }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, USB_DEVICE_ID_APPLE_ALU_WIRELESS_2009_ISO),
diff --git a/drivers/hid/hid-appletb-kbd.c b/drivers/hid/hid-appletb-kbd.c index 5cc2706..3cc3a13b 100644 --- a/drivers/hid/hid-appletb-kbd.c +++ b/drivers/hid/hid-appletb-kbd.c
@@ -56,6 +56,12 @@ static int appletb_tb_idle_timeout = 15; module_param_named(idle_timeout, appletb_tb_idle_timeout, int, 0644); MODULE_PARM_DESC(idle_timeout, "Idle timeout in sec"); +static int appletb_tb_double_press_switch_time; +module_param_named(double_press_switch_time, + appletb_tb_double_press_switch_time, int, 0644); +MODULE_PARM_DESC(double_press_switch_time, + "Fn double-press interval in ms (0 disables layer switching)"); + struct appletb_kbd { struct hid_field *mode_field; struct input_handler inp_handler; @@ -68,6 +74,7 @@ struct appletb_kbd { bool has_turned_off; u8 saved_mode; u8 current_mode; + unsigned long last_fn_press; }; static const struct key_entry appletb_kbd_keymap[] = { @@ -87,29 +94,37 @@ static const struct key_entry appletb_kbd_keymap[] = { { KE_END, 0 } }; -static int appletb_kbd_set_mode(struct appletb_kbd *kbd, u8 mode) +static int appletb_kbd_set_mode_active(struct appletb_kbd *kbd, u8 mode) { struct hid_report *report = kbd->mode_field->report; struct hid_device *hdev = report->device; int ret; + ret = hid_set_field(kbd->mode_field, 0, mode); + if (ret) { + hid_err(hdev, "Failed to set mode field to %u (%pe)\n", mode, ERR_PTR(ret)); + return ret; + } + + hid_hw_request(hdev, report, HID_REQ_SET_REPORT); + + kbd->current_mode = mode; + return 0; +} + +static int appletb_kbd_set_mode(struct appletb_kbd *kbd, u8 mode) +{ + struct hid_device *hdev = kbd->mode_field->report->device; + int ret; + ret = hid_hw_power(hdev, PM_HINT_FULLON); if (ret) { hid_err(hdev, "Device didn't resume (%pe)\n", ERR_PTR(ret)); return ret; } - ret = hid_set_field(kbd->mode_field, 0, mode); - if (ret) { - hid_err(hdev, "Failed to set mode field to %u (%pe)\n", mode, ERR_PTR(ret)); - goto power_normal; - } + ret = appletb_kbd_set_mode_active(kbd, mode); - hid_hw_request(hdev, report, HID_REQ_SET_REPORT); - - kbd->current_mode = mode; - -power_normal: hid_hw_power(hdev, PM_HINT_NORMAL); return ret; @@ -243,6 +258,18 @@ static int appletb_kbd_hid_event(struct hid_device *hdev, struct hid_field *fiel return kbd->current_mode == APPLETB_KBD_MODE_OFF; } +static u8 appletb_switch_mode(u8 mode) +{ + switch (mode) { + case APPLETB_KBD_MODE_SPCL: + return APPLETB_KBD_MODE_FN; + case APPLETB_KBD_MODE_FN: + return APPLETB_KBD_MODE_SPCL; + default: + return mode; + } +} + static void appletb_kbd_inp_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) { @@ -250,15 +277,36 @@ static void appletb_kbd_inp_event(struct input_handle *handle, unsigned int type reset_inactivity_timer(kbd); - if (type == EV_KEY && code == KEY_FN && appletb_tb_fn_toggle && - (kbd->current_mode == APPLETB_KBD_MODE_SPCL || - kbd->current_mode == APPLETB_KBD_MODE_FN)) { + if (type == EV_KEY && code == KEY_FN && + (kbd->current_mode == APPLETB_KBD_MODE_SPCL || + kbd->current_mode == APPLETB_KBD_MODE_FN)) { if (value == 1) { - kbd->saved_mode = kbd->current_mode; - appletb_kbd_set_mode(kbd, kbd->current_mode == APPLETB_KBD_MODE_SPCL - ? APPLETB_KBD_MODE_FN : APPLETB_KBD_MODE_SPCL); + if (appletb_tb_double_press_switch_time > 0) { + unsigned long now = jiffies; + + if (time_before(now, kbd->last_fn_press + + msecs_to_jiffies(appletb_tb_double_press_switch_time))) { + appletb_tb_def_mode = + appletb_switch_mode(appletb_tb_def_mode); + + appletb_kbd_set_mode(kbd, appletb_tb_def_mode); + + kbd->saved_mode = appletb_tb_def_mode; + kbd->last_fn_press = 0; + + return; + } + + kbd->last_fn_press = now; + } + if (appletb_tb_fn_toggle) { + kbd->saved_mode = kbd->current_mode; + + appletb_kbd_set_mode(kbd, appletb_switch_mode(kbd->current_mode)); + } } else if (value == 0) { - if (kbd->saved_mode != kbd->current_mode) + if (appletb_tb_fn_toggle && + kbd->saved_mode != kbd->current_mode) appletb_kbd_set_mode(kbd, kbd->saved_mode); } } @@ -487,18 +535,19 @@ static int appletb_kbd_suspend(struct hid_device *hdev, pm_message_t msg) struct appletb_kbd *kbd = hid_get_drvdata(hdev); kbd->saved_mode = kbd->current_mode; - appletb_kbd_set_mode(kbd, APPLETB_KBD_MODE_OFF); - return 0; + /* This callback already runs as part of a USB PM transition. Taking a + * nested runtime-PM reference would wait for that transition to complete + * and deadlock the USB PM state machine. + */ + return appletb_kbd_set_mode_active(kbd, APPLETB_KBD_MODE_OFF); } static int appletb_kbd_resume(struct hid_device *hdev) { struct appletb_kbd *kbd = hid_get_drvdata(hdev); - appletb_kbd_set_mode(kbd, kbd->saved_mode); - - return 0; + return appletb_kbd_set_mode_active(kbd, kbd->saved_mode); } static const struct hid_device_id appletb_kbd_hid_ids[] = {
diff --git a/drivers/hid/hid-asus.c b/drivers/hid/hid-asus.c index c38a2b3..f6aa1be 100644 --- a/drivers/hid/hid-asus.c +++ b/drivers/hid/hid-asus.c
@@ -51,6 +51,8 @@ MODULE_DESCRIPTION("Asus HID Keyboard and TouchPad"); #define FEATURE_KBD_LED_REPORT_ID1 0x5d #define FEATURE_KBD_LED_REPORT_ID2 0x5e +#define ROG_XGM_REPORT_SIZE 300 + #define ROG_ALLY_REPORT_SIZE 64 #define ROG_ALLY_X_MIN_MCU 313 #define ROG_ALLY_MIN_MCU 319 @@ -144,6 +146,11 @@ struct asus_worker { bool removed; }; +struct asus_xgm_led { + struct led_classdev cdev; + struct hid_device *hdev; +}; + struct asus_touchpad_info { int max_x; int max_y; @@ -170,6 +177,7 @@ struct asus_drvdata { unsigned long battery_next_query; struct asus_hid_listener listener; bool fn_lock; + struct asus_xgm_led *xgm_led; }; static int asus_report_battery(struct asus_drvdata *, u8 *, int); @@ -765,9 +773,14 @@ static void asus_work(struct work_struct *work) struct asus_work_action *action = NULL; unsigned long flags; - /* Save the action to be performed and clear the flag */ + /* + * Dequeue the next action, if any. Once teardown has begun .removed + * is set and asus_worker_stop() drains the queue: leave the queued + * actions alone, they are dropped instead of being executed against + * a device that is being removed. + */ spin_lock_irqsave(&worker->lock, flags); - if (!list_empty(&worker->actions)) { + if (!worker->removed && !list_empty(&worker->actions)) { action = list_first_entry(&worker->actions, struct asus_work_action, node); list_del(&action->node); @@ -817,6 +830,25 @@ static int asus_worker_create(struct hid_device *hdev, struct asus_drvdata *drvd return 0; } +/** + * asus_worker_stop - quiesce the worker + * @worker: the worker to quiesce + * + * Once this function returns no more actions can be queued and no instance + * of asus_work() is running or pending. + * + * Callers must do this before hid_hw_stop(): actions are executed while the + * device is fully operational, since they send raw requests to it and, in + * the fan-key fallback path, re-inject raw reports into the HID core. After + * hid_hw_stop() the transport is gone (usbhid_stop() frees the URBs and the + * I/O buffers) and the input devices have been unregistered. + * + * The quiescing is race free because every site that queues an action holds + * worker->lock across the .removed check, the list insertion and + * schedule_work(): anything scheduled before .removed is set here is caught + * by the cancel_work_sync() below, anything after it is discarded by + * asus_worker_schedule(). + */ static void asus_worker_stop(struct asus_worker *worker) { struct asus_work_action *action, *tmp; @@ -1137,6 +1169,26 @@ static int asus_battery_probe(struct hid_device *hdev) return ret; } +static int asus_xgm_led_set(struct led_classdev *led_cdev, enum led_brightness value) +{ + const u8 buf[ROG_XGM_REPORT_SIZE] = { + FEATURE_KBD_LED_REPORT_ID2, 0xC5, (value) ? 0x50 : 0x00 + }; + struct asus_xgm_led *xgm = container_of(led_cdev, struct asus_xgm_led, cdev); + int ret; + + ret = asus_kbd_set_report(xgm->hdev, buf, ROG_XGM_REPORT_SIZE); + if (ret < 0) { + hid_err(xgm->hdev, "Unable to set XG mobile led state: %d\n", ret); + return ret; + } else if (ret != ROG_XGM_REPORT_SIZE) { + hid_err(xgm->hdev, "Unexpected partial transfer to XG mobile: %d\n", ret); + return -EIO; + } + + return 0; +} + static int asus_input_configured(struct hid_device *hdev, struct hid_input *hi) { struct input_dev *input = hi->input; @@ -1360,6 +1412,71 @@ static int asus_start_multitouch(struct hid_device *hdev) return 0; } +/* + * Initialize the reports of the device. + * + * Failures are intentionally not fatal: asus_kbd_init() tolerates a wrong + * handshake until this is verified to work for all devices, so a failure + * is only reported and the initialization of the remaining reports is + * still attempted. + */ +static void asus_initialize_reports(struct hid_device *hdev) +{ + int ret; + + for (int r = 0; r < ARRAY_SIZE(asus_report_id_init); r++) { + if (asus_has_report_id(hdev, asus_report_id_init[r])) { + ret = asus_kbd_init(hdev, asus_report_id_init[r]); + if (ret < 0) + hid_warn(hdev, "Failed to initialize 0x%x: %d.\n", + asus_report_id_init[r], ret); + } + } +} + +static int asus_xgm_init(struct hid_device *hdev, struct asus_drvdata *drvdata) +{ + const char *name; + int ret; + + drvdata->xgm_led = devm_kzalloc(&hdev->dev, sizeof(*drvdata->xgm_led), GFP_KERNEL); + if (drvdata->xgm_led == NULL) + return -ENOMEM; + + name = devm_kasprintf(&hdev->dev, GFP_KERNEL, "asus:xgm-%s:led", + strlen(hdev->uniq) ? hdev->uniq : dev_name(&hdev->dev)); + + if (name == NULL) { + ret = -ENOMEM; + goto asus_xgm_init_err; + } + + drvdata->xgm_led->hdev = hdev; + drvdata->xgm_led->cdev.name = name; + drvdata->xgm_led->cdev.brightness = 1; + drvdata->xgm_led->cdev.max_brightness = 1; + drvdata->xgm_led->cdev.brightness_set_blocking = asus_xgm_led_set; + drvdata->xgm_led->cdev.flags = LED_CORE_SUSPENDRESUME; + + /* LED state is arbitrary on boot, set a default */ + ret = asus_xgm_led_set(&drvdata->xgm_led->cdev, drvdata->xgm_led->cdev.brightness); + if (ret) { + hid_err(hdev, "Asus failed to set xgm led: %d\n", ret); + goto asus_xgm_init_err; + } + + ret = devm_led_classdev_register(&hdev->dev, &drvdata->xgm_led->cdev); + if (ret) { + hid_err(hdev, "Asus failed to register xgm led: %d\n", ret); + goto asus_xgm_init_err; + } + + return 0; +asus_xgm_init_err: + drvdata->xgm_led = NULL; + return ret; +} + static int __maybe_unused asus_resume(struct hid_device *hdev) { struct asus_drvdata *drvdata = hid_get_drvdata(hdev); @@ -1379,6 +1496,9 @@ static int __maybe_unused asus_reset_resume(struct hid_device *hdev) { struct asus_drvdata *drvdata = hid_get_drvdata(hdev); + if (!drvdata->tp) + asus_initialize_reports(hdev); + if (drvdata->tp) return asus_start_multitouch(hdev); @@ -1493,12 +1613,16 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) return ret; } - for (int r = 0; r < ARRAY_SIZE(asus_report_id_init); r++) { - if (asus_has_report_id(hdev, asus_report_id_init[r])) { - ret = asus_kbd_init(hdev, asus_report_id_init[r]); - if (ret < 0) - hid_warn(hdev, "Failed to initialize 0x%x: %d.\n", - asus_report_id_init[r], ret); + if (!drvdata->tp) + asus_initialize_reports(hdev); + + if (asus_has_report_id(hdev, FEATURE_KBD_REPORT_ID) && + ((hdev->product == USB_DEVICE_ID_ASUSTEK_XGM_2022) || + (hdev->product == USB_DEVICE_ID_ASUSTEK_XGM_2023))) { + ret = asus_xgm_init(hdev, drvdata); + if (ret) { + hid_err(hdev, "Failed to initialize xg mobile: %d\n", ret); + goto err_stop_hw; } } @@ -1539,6 +1663,9 @@ static int asus_probe(struct hid_device *hdev, const struct hid_device_id *id) if (drvdata->listener.brightness_set) asus_hid_unregister_listener(&drvdata->listener); + if (drvdata->xgm_led) + devm_led_classdev_unregister(&hdev->dev, &drvdata->xgm_led->cdev); + asus_worker_stop(drvdata->worker); hid_hw_stop(hdev); return ret; @@ -1551,6 +1678,9 @@ static void asus_remove(struct hid_device *hdev) if (drvdata->listener.brightness_set) asus_hid_unregister_listener(&drvdata->listener); + if (drvdata->xgm_led) + devm_led_classdev_unregister(&hdev->dev, &drvdata->xgm_led->cdev); + asus_worker_stop(drvdata->worker); hid_hw_stop(hdev); } @@ -1733,6 +1863,8 @@ static const struct hid_device_id asus_devices[] = { QUIRK_USE_KBD_BACKLIGHT | QUIRK_ROG_NKEY_KEYBOARD }, { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD) }, + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, + USB_VENDOR_ID_ASUSTEK, USB_DEVICE_ID_ASUSTEK_T302CHI_KEYBOARD) }, { } }; MODULE_DEVICE_TABLE(hid, asus_devices);
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index a3ff051..a71ddaa 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c
@@ -71,8 +71,8 @@ static u32 s32ton(__s32 value, unsigned int n) if (!value || !n) return 0; - if (n > 32) - n = 32; + if (n >= 32) + return (u32) value; a = value >> (n - 1); if (a && a != -1)
diff --git a/drivers/hid/hid-cougar.c b/drivers/hid/hid-cougar.c index ad027c4..7156658 100644 --- a/drivers/hid/hid-cougar.c +++ b/drivers/hid/hid-cougar.c
@@ -270,6 +270,9 @@ static int cougar_raw_event(struct hid_device *hdev, struct hid_report *report, if (!shared->enabled || !shared->input) return -EPERM; + if (size <= COUGAR_FIELD_ACTION) + return -EPERM; + code = data[COUGAR_FIELD_CODE]; action = data[COUGAR_FIELD_ACTION]; for (i = 0; cougar_mapping[i][0]; i++) {
diff --git a/drivers/hid/hid-cp2112.c b/drivers/hid/hid-cp2112.c index 04379db..6b938f7 100644 --- a/drivers/hid/hid-cp2112.c +++ b/drivers/hid/hid-cp2112.c
@@ -1430,6 +1430,9 @@ static int cp2112_raw_event(struct hid_device *hdev, struct hid_report *report, switch (data[0]) { case CP2112_TRANSFER_STATUS_RESPONSE: + if (size < sizeof(*xfer)) + return 0; + hid_dbg(hdev, "xfer status: %02x %02x %04x %04x\n", xfer->status0, xfer->status1, be16_to_cpu(xfer->retries), be16_to_cpu(xfer->length)); @@ -1463,11 +1466,16 @@ static int cp2112_raw_event(struct hid_device *hdev, struct hid_report *report, atomic_set(&dev->xfer_avail, 1); break; case CP2112_DATA_READ_RESPONSE: + if (size < 3) + return 0; + hid_dbg(hdev, "read response: %02x %02x\n", data[1], data[2]); dev->read_length = data[2]; if (dev->read_length > sizeof(dev->read_data)) dev->read_length = sizeof(dev->read_data); + if (dev->read_length > size - 3) + return 0; memcpy(dev->read_data, &data[3], dev->read_length); atomic_set(&dev->read_avail, 1); @@ -1494,4 +1502,3 @@ module_hid_driver(cp2112_driver); MODULE_DESCRIPTION("Silicon Labs HID USB to SMBus master bridge"); MODULE_AUTHOR("David Barksdale <dbarksdale@uplogix.com>"); MODULE_LICENSE("GPL"); -
diff --git a/drivers/hid/hid-elo.c b/drivers/hid/hid-elo.c index b8f5f3e..86e8729 100644 --- a/drivers/hid/hid-elo.c +++ b/drivers/hid/hid-elo.c
@@ -85,6 +85,9 @@ static int elo_raw_event(struct hid_device *hdev, struct hid_report *report, if (!(hdev->claimed & HID_CLAIMED_INPUT) || list_empty(&hdev->inputs)) return 0; + if (size < ELO_SMARTSET_PACKET_SIZE) + return 0; + hidinput = list_first_entry(&hdev->inputs, struct hid_input, list); switch (report->id) {
diff --git a/drivers/hid/hid-google-hammer.c b/drivers/hid/hid-google-hammer.c index c99c3c0..847b1dd 100644 --- a/drivers/hid/hid-google-hammer.c +++ b/drivers/hid/hid-google-hammer.c
@@ -268,7 +268,7 @@ static void cbas_ec_remove(struct platform_device *pdev) #ifdef CONFIG_ACPI static const struct acpi_device_id cbas_ec_acpi_ids[] = { - { "GOOG000B", 0 }, + { .id = "GOOG000B" }, { } }; MODULE_DEVICE_TABLE(acpi, cbas_ec_acpi_ids);
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index cb7f16d..91319aa 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h
@@ -218,6 +218,7 @@ #define USB_DEVICE_ID_ASUSTEK_T100TAF_KEYBOARD 0x1807 #define USB_DEVICE_ID_ASUSTEK_T100CHI_KEYBOARD 0x8502 #define USB_DEVICE_ID_ASUSTEK_T101HA_KEYBOARD 0x183d +#define USB_DEVICE_ID_ASUSTEK_T302CHI_KEYBOARD 0x182f #define USB_DEVICE_ID_ASUSTEK_T304_KEYBOARD 0x184a #define USB_DEVICE_ID_ASUSTEK_I2C_KEYBOARD 0x8585 #define USB_DEVICE_ID_ASUSTEK_I2C_ZENBOOK_KEYBOARD 0x4b42 @@ -252,6 +253,12 @@ #define USB_VENDOR_ID_ATMEL_V_USB 0x16c0 #define USB_DEVICE_ID_ATMEL_V_USB 0x05df +#define USB_VENDOR_ID_ATK 0x3554 +#define USB_DEVICE_ID_ATK_VXE_R1_SE_WIRED 0xF58F + +#define USB_VENDOR_ID_ATK_ALT 0x373B +#define USB_DEVICE_ID_ATK_VXE_R1_SE_DONGLE 0x1085 + #define USB_VENDOR_ID_AUREAL 0x0755 #define USB_DEVICE_ID_AUREAL_W01RN 0x2626 @@ -747,6 +754,7 @@ #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A081 0xa081 #define USB_DEVICE_ID_HOLTEK_ALT_MOUSE_A0C2 0xa0c2 #define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096 0xa096 +#define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A292 0xa292 #define USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293 0xa293 #define USB_VENDOR_ID_IMATION 0x0718 @@ -822,6 +830,7 @@ #define USB_VENDOR_ID_KYSONA 0x3554 #define USB_DEVICE_ID_KYSONA_M600_DONGLE 0xF57C +#define USB_DEVICE_ID_KYSONA_M600V2_DONGLE 0xf5d5 #define USB_DEVICE_ID_KYSONA_M600_WIRED 0xF57D #define USB_VENDOR_ID_LABTEC 0x1020 @@ -1118,6 +1127,10 @@ #define USB_DEVICE_ID_NINTENDO_SNESCON 0x2017 #define USB_DEVICE_ID_NINTENDO_GENCON 0x201e #define USB_DEVICE_ID_NINTENDO_N64CON 0x2019 +#define USB_DEVICE_ID_NINTENDO_NS2_JOYCONR 0x2066 +#define USB_DEVICE_ID_NINTENDO_NS2_JOYCONL 0x2067 +#define USB_DEVICE_ID_NINTENDO_NS2_PROCON 0x2069 +#define USB_DEVICE_ID_NINTENDO_NS2_GCCON 0x2073 #define USB_VENDOR_ID_NOVATEK 0x0603 #define USB_DEVICE_ID_NOVATEK_PCT 0x0600 @@ -1169,6 +1182,7 @@ #define USB_DEVICE_ID_PDP_PS4_JAGUAR 0x0173 #define USB_DEVICE_ID_PDP_PS4_RIFFMASTER 0x024a #define USB_DEVICE_ID_PDP_PS5_RIFFMASTER 0x0249 +#define USB_DEVICE_ID_PDP_SWITCH_AFTERGLOW 0x018c #define USB_VENDOR_ID_PLANTRONICS 0x047f #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3210_SERIES 0xc055 @@ -1221,6 +1235,11 @@ #define USB_VENDOR_ID_PRODIGE 0x05af #define USB_DEVICE_ID_PRODIGE_CORDLESS 0x3062 +#define USB_VENDOR_ID_PULSAR 0x3554 +#define USB_DEVICE_ID_PULSAR_WIRED 0xf507 +#define USB_DEVICE_ID_PULSAR_1KHZ 0xf508 +#define USB_DEVICE_ID_PULSAR_4KHZ 0xf509 + #define I2C_VENDOR_ID_QTEC 0x6243 #define USB_VENDOR_ID_QUANTA 0x0408 @@ -1633,6 +1652,9 @@ #define USB_VENDOR_ID_YEALINK 0x6993 #define USB_DEVICE_ID_YEALINK_P1K_P4K_B2K 0xb001 +#define USB_VENDOR_ID_YJXCHIP 0xa8a5 +#define USB_DEVICE_ID_YJXCHIP_MOUSE 0x2255 + #define USB_VENDOR_ID_ZEROPLUS 0x0c12 #define USB_VENDOR_ID_ZYDACRON 0x13EC
diff --git a/drivers/hid/hid-kysona.c b/drivers/hid/hid-kysona.c deleted file mode 100644 index ccbd838..0000000 --- a/drivers/hid/hid-kysona.c +++ /dev/null
@@ -1,292 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * USB HID driver for Kysona - * Kysona M600 mice. - * - * Copyright (c) 2024 Lode Willems <me@lodewillems.com> - */ - -#include <linux/device.h> -#include <linux/hid.h> -#include <linux/usb.h> - -#include "hid-ids.h" - -#define BATTERY_TIMEOUT_MS 5000 - -#define ONLINE_REPORT_ID 3 -#define BATTERY_REPORT_ID 4 - -struct kysona_drvdata { - struct hid_device *hdev; - bool online; - - struct power_supply_desc battery_desc; - struct power_supply *battery; - u8 battery_capacity; - bool battery_charging; - u16 battery_voltage; - struct delayed_work battery_work; -}; - -static enum power_supply_property kysona_battery_props[] = { - POWER_SUPPLY_PROP_STATUS, - POWER_SUPPLY_PROP_PRESENT, - POWER_SUPPLY_PROP_CAPACITY, - POWER_SUPPLY_PROP_SCOPE, - POWER_SUPPLY_PROP_MODEL_NAME, - POWER_SUPPLY_PROP_VOLTAGE_NOW, - POWER_SUPPLY_PROP_ONLINE -}; - -static int kysona_battery_get_property(struct power_supply *psy, - enum power_supply_property psp, - union power_supply_propval *val) -{ - struct kysona_drvdata *drv_data = power_supply_get_drvdata(psy); - int ret = 0; - - switch (psp) { - case POWER_SUPPLY_PROP_PRESENT: - val->intval = 1; - break; - case POWER_SUPPLY_PROP_ONLINE: - val->intval = drv_data->online; - break; - case POWER_SUPPLY_PROP_STATUS: - if (drv_data->online) - val->intval = drv_data->battery_charging ? - POWER_SUPPLY_STATUS_CHARGING : - POWER_SUPPLY_STATUS_DISCHARGING; - else - val->intval = POWER_SUPPLY_STATUS_UNKNOWN; - break; - case POWER_SUPPLY_PROP_SCOPE: - val->intval = POWER_SUPPLY_SCOPE_DEVICE; - break; - case POWER_SUPPLY_PROP_CAPACITY: - val->intval = drv_data->battery_capacity; - break; - case POWER_SUPPLY_PROP_VOLTAGE_NOW: - /* hardware reports voltage in mV. sysfs expects uV */ - val->intval = drv_data->battery_voltage * 1000; - break; - case POWER_SUPPLY_PROP_MODEL_NAME: - val->strval = drv_data->hdev->name; - break; - default: - ret = -EINVAL; - break; - } - return ret; -} - -static const char kysona_online_request[] = { - 0x08, ONLINE_REPORT_ID, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4a -}; - -static const char kysona_battery_request[] = { - 0x08, BATTERY_REPORT_ID, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49 -}; - -static int kysona_m600_fetch_online(struct hid_device *hdev) -{ - u8 *write_buf; - int ret; - - /* Request online information */ - write_buf = kmemdup(kysona_online_request, sizeof(kysona_online_request), GFP_KERNEL); - if (!write_buf) - return -ENOMEM; - - ret = hid_hw_raw_request(hdev, kysona_online_request[0], - write_buf, sizeof(kysona_online_request), - HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); - if (ret < (int)sizeof(kysona_online_request)) { - hid_err(hdev, "hid_hw_raw_request() failed with %d\n", ret); - ret = -ENODATA; - } - kfree(write_buf); - return ret; -} - -static void kysona_fetch_online(struct hid_device *hdev) -{ - int ret = kysona_m600_fetch_online(hdev); - - if (ret < 0) - hid_dbg(hdev, - "Online query failed (err: %d)\n", ret); -} - -static int kysona_m600_fetch_battery(struct hid_device *hdev) -{ - u8 *write_buf; - int ret; - - /* Request battery information */ - write_buf = kmemdup(kysona_battery_request, sizeof(kysona_battery_request), GFP_KERNEL); - if (!write_buf) - return -ENOMEM; - - ret = hid_hw_raw_request(hdev, kysona_battery_request[0], - write_buf, sizeof(kysona_battery_request), - HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); - if (ret < (int)sizeof(kysona_battery_request)) { - hid_err(hdev, "hid_hw_raw_request() failed with %d\n", ret); - ret = -ENODATA; - } - kfree(write_buf); - return ret; -} - -static void kysona_fetch_battery(struct hid_device *hdev) -{ - int ret = kysona_m600_fetch_battery(hdev); - - if (ret < 0) - hid_dbg(hdev, - "Battery query failed (err: %d)\n", ret); -} - -static void kysona_battery_timer_tick(struct work_struct *work) -{ - struct kysona_drvdata *drv_data = container_of(work, - struct kysona_drvdata, battery_work.work); - struct hid_device *hdev = drv_data->hdev; - - kysona_fetch_online(hdev); - kysona_fetch_battery(hdev); - schedule_delayed_work(&drv_data->battery_work, - msecs_to_jiffies(BATTERY_TIMEOUT_MS)); -} - -static int kysona_battery_probe(struct hid_device *hdev) -{ - struct kysona_drvdata *drv_data = hid_get_drvdata(hdev); - struct power_supply_config pscfg = { .drv_data = drv_data }; - int ret = 0; - - drv_data->online = false; - drv_data->battery_capacity = 100; - drv_data->battery_voltage = 4200; - - drv_data->battery_desc.properties = kysona_battery_props; - drv_data->battery_desc.num_properties = ARRAY_SIZE(kysona_battery_props); - drv_data->battery_desc.get_property = kysona_battery_get_property; - drv_data->battery_desc.type = POWER_SUPPLY_TYPE_BATTERY; - drv_data->battery_desc.use_for_apm = 0; - drv_data->battery_desc.name = devm_kasprintf(&hdev->dev, GFP_KERNEL, - "kysona-%s-battery", - strlen(hdev->uniq) ? - hdev->uniq : dev_name(&hdev->dev)); - if (!drv_data->battery_desc.name) - return -ENOMEM; - - drv_data->battery = devm_power_supply_register(&hdev->dev, - &drv_data->battery_desc, &pscfg); - if (IS_ERR(drv_data->battery)) { - ret = PTR_ERR(drv_data->battery); - drv_data->battery = NULL; - hid_err(hdev, "Unable to register battery device\n"); - return ret; - } - - power_supply_powers(drv_data->battery, &hdev->dev); - - INIT_DELAYED_WORK(&drv_data->battery_work, kysona_battery_timer_tick); - kysona_fetch_online(hdev); - kysona_fetch_battery(hdev); - schedule_delayed_work(&drv_data->battery_work, - msecs_to_jiffies(BATTERY_TIMEOUT_MS)); - - return ret; -} - -static int kysona_probe(struct hid_device *hdev, const struct hid_device_id *id) -{ - int ret; - struct kysona_drvdata *drv_data; - struct usb_interface *usbif; - - if (!hid_is_usb(hdev)) - return -EINVAL; - - usbif = to_usb_interface(hdev->dev.parent); - - drv_data = devm_kzalloc(&hdev->dev, sizeof(*drv_data), GFP_KERNEL); - if (!drv_data) - return -ENOMEM; - - hid_set_drvdata(hdev, drv_data); - drv_data->hdev = hdev; - - ret = hid_parse(hdev); - if (ret) - return ret; - - ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); - if (ret) - return ret; - - if (usbif->cur_altsetting->desc.bInterfaceNumber == 1) { - if (kysona_battery_probe(hdev) < 0) - hid_err(hdev, "Kysona hid battery_probe failed: %d\n", ret); - } - - return 0; -} - -static int kysona_raw_event(struct hid_device *hdev, - struct hid_report *report, u8 *data, int size) -{ - struct kysona_drvdata *drv_data = hid_get_drvdata(hdev); - - if (size == sizeof(kysona_online_request) && - data[0] == 8 && data[1] == ONLINE_REPORT_ID) { - drv_data->online = data[6]; - } - - if (size == sizeof(kysona_battery_request) && - data[0] == 8 && data[1] == BATTERY_REPORT_ID) { - drv_data->battery_capacity = data[6]; - drv_data->battery_charging = data[7]; - drv_data->battery_voltage = (data[8] << 8) | data[9]; - } - - return 0; -} - -static void kysona_remove(struct hid_device *hdev) -{ - struct kysona_drvdata *drv_data = hid_get_drvdata(hdev); - - if (drv_data->battery) - cancel_delayed_work_sync(&drv_data->battery_work); - - hid_hw_stop(hdev); -} - -static const struct hid_device_id kysona_devices[] = { - { HID_USB_DEVICE(USB_VENDOR_ID_KYSONA, USB_DEVICE_ID_KYSONA_M600_DONGLE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_KYSONA, USB_DEVICE_ID_KYSONA_M600_WIRED) }, - { HID_USB_DEVICE(USB_VENDOR_ID_VXE, USB_DEVICE_ID_VXE_DRAGONFLY_R1_PRO_DONGLE) }, - { HID_USB_DEVICE(USB_VENDOR_ID_VXE, USB_DEVICE_ID_VXE_DRAGONFLY_R1_PRO_WIRED) }, - { } -}; -MODULE_DEVICE_TABLE(hid, kysona_devices); - -static struct hid_driver kysona_driver = { - .name = "kysona", - .id_table = kysona_devices, - .probe = kysona_probe, - .raw_event = kysona_raw_event, - .remove = kysona_remove -}; -module_hid_driver(kysona_driver); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("HID driver for Kysona devices"); -MODULE_AUTHOR("Lode Willems <me@lodewillems.com>");
diff --git a/drivers/hid/hid-lenovo-go-s.c b/drivers/hid/hid-lenovo-go-s.c index a72f7f7..7102786 100644 --- a/drivers/hid/hid-lenovo-go-s.c +++ b/drivers/hid/hid-lenovo-go-s.c
@@ -10,6 +10,7 @@ #include <linux/array_size.h> #include <linux/cleanup.h> #include <linux/completion.h> +#include <linux/container_of.h> #include <linux/delay.h> #include <linux/dev_printk.h> #include <linux/device.h> @@ -32,33 +33,42 @@ #define GO_S_CFG_INTF_IN 0x84 #define GO_S_PACKET_SIZE 64 -static struct hid_gos_cfg { - struct delayed_work gos_cfg_setup; +struct gos_cfg_drvdata { + /* MCU General Variables */ struct completion send_cmd_complete; - struct led_classdev *led_cdev; + struct delayed_work gos_cfg_setup; struct hid_device *hdev; + bool orphan_ack_pending; struct mutex cfg_mutex; /*ensure single synchronous output report*/ + int cmd_status; + + /* Gamepad Variables */ u8 gp_auto_sleep_time; - u8 gp_dpad_mode; - u8 gp_mode; - u8 gp_poll_rate; - u8 imu_bypass_en; u8 imu_manufacturer; + bool gp_registered; + u8 tp_windows_mode; + u8 tp_manufacturer; + u8 tp_linux_mode; + u8 imu_bypass_en; u8 imu_sensor_en; + u8 gp_dpad_mode; + u8 gp_poll_rate; u8 mcu_id[12]; u8 mouse_step; - u8 os_mode; - u8 rgb_effect; - u8 rgb_en; - u8 rgb_mode; - u8 rgb_profile; - u8 rgb_speed; - u8 tp_en; - u8 tp_linux_mode; - u8 tp_windows_mode; u8 tp_version; - u8 tp_manufacturer; -} drvdata; + u8 gp_mode; + u8 os_mode; + u8 tp_en; + + /* RGB Variables */ + struct led_classdev_mc led_mc; + bool rgb_registered; + u8 rgb_profile; + u8 rgb_effect; + u8 rgb_speed; + u8 rgb_mode; + u8 rgb_en; +}; struct gos_cfg_attr { u8 index; @@ -234,56 +244,57 @@ static const char *const imu_manufacturer_text[] = { [IMU_ST] = "ST", }; -static int hid_gos_version_event(u8 *data) +static int hid_gos_version_event(struct gos_cfg_drvdata *drvdata, u8 *data) { struct version_report *ver_rep = (struct version_report *)data; - drvdata.hdev->firmware_version = get_unaligned_le32(&ver_rep->version); + drvdata->hdev->firmware_version = get_unaligned_le32(&ver_rep->version); return 0; } -static int hid_gos_mcu_id_event(struct command_report *cmd_rep) +static int hid_gos_mcu_id_event(struct gos_cfg_drvdata *drvdata, struct command_report *cmd_rep) { - drvdata.mcu_id[0] = cmd_rep->sub_cmd; - memcpy(&drvdata.mcu_id[1], cmd_rep->data, 11); + drvdata->mcu_id[0] = cmd_rep->sub_cmd; + memcpy(&drvdata->mcu_id[1], cmd_rep->data, 11); return 0; } -static int hid_gos_gamepad_cfg_event(struct command_report *cmd_rep) +static int hid_gos_gamepad_cfg_event(struct gos_cfg_drvdata *drvdata, + struct command_report *cmd_rep) { int ret = 0; switch (cmd_rep->sub_cmd) { case FEATURE_GAMEPAD_MODE: - drvdata.gp_mode = cmd_rep->data[0]; + drvdata->gp_mode = cmd_rep->data[0]; break; case FEATURE_AUTO_SLEEP_TIME: - drvdata.gp_auto_sleep_time = cmd_rep->data[0]; + drvdata->gp_auto_sleep_time = cmd_rep->data[0]; break; case FEATURE_IMU_BYPASS: - drvdata.imu_bypass_en = cmd_rep->data[0]; + drvdata->imu_bypass_en = cmd_rep->data[0]; break; case FEATURE_RGB_ENABLE: - drvdata.rgb_en = cmd_rep->data[0]; + drvdata->rgb_en = cmd_rep->data[0]; break; case FEATURE_IMU_ENABLE: - drvdata.imu_sensor_en = cmd_rep->data[0]; + drvdata->imu_sensor_en = cmd_rep->data[0]; break; case FEATURE_TOUCHPAD_ENABLE: - drvdata.tp_en = cmd_rep->data[0]; + drvdata->tp_en = cmd_rep->data[0]; break; case FEATURE_OS_MODE: - drvdata.os_mode = cmd_rep->data[0]; + drvdata->os_mode = cmd_rep->data[0]; break; case FEATURE_POLL_RATE: - drvdata.gp_poll_rate = cmd_rep->data[0]; + drvdata->gp_poll_rate = cmd_rep->data[0]; break; case FEATURE_DPAD_MODE: - drvdata.gp_dpad_mode = cmd_rep->data[0]; + drvdata->gp_dpad_mode = cmd_rep->data[0]; break; case FEATURE_MOUSE_WHEEL_STEP: - drvdata.mouse_step = cmd_rep->data[0]; + drvdata->mouse_step = cmd_rep->data[0]; break; default: ret = -EINVAL; @@ -293,16 +304,16 @@ static int hid_gos_gamepad_cfg_event(struct command_report *cmd_rep) return ret; } -static int hid_gos_touchpad_event(struct command_report *cmd_rep) +static int hid_gos_touchpad_event(struct gos_cfg_drvdata *drvdata, struct command_report *cmd_rep) { int ret = 0; switch (cmd_rep->sub_cmd) { case CFG_LINUX_MODE: - drvdata.tp_linux_mode = cmd_rep->data[0]; + drvdata->tp_linux_mode = cmd_rep->data[0]; break; case CFG_WINDOWS_MODE: - drvdata.tp_windows_mode = cmd_rep->data[0]; + drvdata->tp_windows_mode = cmd_rep->data[0]; break; default: ret = -EINVAL; @@ -312,21 +323,21 @@ static int hid_gos_touchpad_event(struct command_report *cmd_rep) return ret; } -static int hid_gos_pl_test_event(struct command_report *cmd_rep) +static int hid_gos_pl_test_event(struct gos_cfg_drvdata *drvdata, struct command_report *cmd_rep) { int ret = 0; switch (cmd_rep->sub_cmd) { case TEST_TP_MFR: - drvdata.tp_manufacturer = cmd_rep->data[0]; + drvdata->tp_manufacturer = cmd_rep->data[0]; ret = 0; break; case TEST_IMU_MFR: - drvdata.imu_manufacturer = cmd_rep->data[0]; + drvdata->imu_manufacturer = cmd_rep->data[0]; ret = 0; break; case TEST_TP_VER: - drvdata.tp_version = cmd_rep->data[0]; + drvdata->tp_version = cmd_rep->data[0]; ret = 0; break; default: @@ -336,30 +347,30 @@ static int hid_gos_pl_test_event(struct command_report *cmd_rep) return ret; } -static int hid_gos_light_event(struct command_report *cmd_rep) +static int hid_gos_light_event(struct gos_cfg_drvdata *drvdata, struct command_report *cmd_rep) { - struct led_classdev_mc *mc_cdev; + struct led_classdev_mc *led_mc; int ret = 0; switch (cmd_rep->sub_cmd) { case LIGHT_MODE_SEL: - drvdata.rgb_mode = cmd_rep->data[0]; + drvdata->rgb_mode = cmd_rep->data[0]; ret = 0; break; case LIGHT_PROFILE_SEL: - drvdata.rgb_profile = cmd_rep->data[0]; + drvdata->rgb_profile = cmd_rep->data[0]; ret = 0; break; case USR_LIGHT_PROFILE_1: case USR_LIGHT_PROFILE_2: case USR_LIGHT_PROFILE_3: - mc_cdev = lcdev_to_mccdev(drvdata.led_cdev); - drvdata.rgb_effect = cmd_rep->data[0]; - mc_cdev->subled_info[0].intensity = cmd_rep->data[1]; - mc_cdev->subled_info[1].intensity = cmd_rep->data[2]; - mc_cdev->subled_info[2].intensity = cmd_rep->data[3]; - drvdata.led_cdev->brightness = cmd_rep->data[4]; - drvdata.rgb_speed = cmd_rep->data[5]; + led_mc = &drvdata->led_mc; + drvdata->rgb_effect = cmd_rep->data[0]; + led_mc->subled_info[0].intensity = cmd_rep->data[1]; + led_mc->subled_info[1].intensity = cmd_rep->data[2]; + led_mc->subled_info[2].intensity = cmd_rep->data[3]; + led_mc->led_cdev.brightness = cmd_rep->data[4]; + drvdata->rgb_speed = cmd_rep->data[5]; ret = 0; break; default: @@ -392,6 +403,7 @@ static int get_endpoint_address(struct hid_device *hdev) static int hid_gos_raw_event(struct hid_device *hdev, struct hid_report *report, u8 *data, int size) { + struct gos_cfg_drvdata *drvdata = hid_get_drvdata(hdev); struct command_report *cmd_rep; int ep, ret; @@ -399,6 +411,9 @@ static int hid_gos_raw_event(struct hid_device *hdev, struct hid_report *report, if (ep != GO_S_CFG_INTF_IN) return 0; + if (!drvdata) + return -ENODEV; + if (size != GO_S_PACKET_SIZE) return -EINVAL; @@ -406,22 +421,22 @@ static int hid_gos_raw_event(struct hid_device *hdev, struct hid_report *report, switch (cmd_rep->cmd) { case GET_VERSION: - ret = hid_gos_version_event(data); + ret = hid_gos_version_event(drvdata, data); break; case GET_MCU_ID: - ret = hid_gos_mcu_id_event(cmd_rep); + ret = hid_gos_mcu_id_event(drvdata, cmd_rep); break; case GET_GAMEPAD_CFG: - ret = hid_gos_gamepad_cfg_event(cmd_rep); + ret = hid_gos_gamepad_cfg_event(drvdata, cmd_rep); break; case GET_TP_PARAM: - ret = hid_gos_touchpad_event(cmd_rep); + ret = hid_gos_touchpad_event(drvdata, cmd_rep); break; case GET_PL_TEST: - ret = hid_gos_pl_test_event(cmd_rep); + ret = hid_gos_pl_test_event(drvdata, cmd_rep); break; case GET_RGB_CFG: - ret = hid_gos_light_event(cmd_rep); + ret = hid_gos_light_event(drvdata, cmd_rep); break; case SET_GAMEPAD_CFG: case SET_RGB_CFG: @@ -435,22 +450,41 @@ static int hid_gos_raw_event(struct hid_device *hdev, struct hid_report *report, dev_dbg(&hdev->dev, "Rx data as raw input report: [%*ph]\n", GO_S_PACKET_SIZE, data); - complete(&drvdata.send_cmd_complete); + drvdata->cmd_status = ret; + complete(&drvdata->send_cmd_complete); + return ret; } static int mcu_property_out(struct hid_device *hdev, u8 command, u8 index, u8 *data, size_t len) { + struct gos_cfg_drvdata *drvdata = hid_get_drvdata(hdev); unsigned char *dmabuf __free(kfree) = NULL; u8 header[] = { command, index }; size_t header_size = ARRAY_SIZE(header); int timeout, ret; + if (!drvdata) + return -ENODEV; + if (header_size + len > GO_S_PACKET_SIZE) return -EINVAL; - guard(mutex)(&drvdata.cfg_mutex); + guard(mutex)(&drvdata->cfg_mutex); + + /* + * A reply to the previous command may still be in flight. Give it a + * short window to arrive and be consumed before this call reinits the + * completion, so a late reply can't be mistaken for this command's. + */ + if (drvdata->orphan_ack_pending) { + wait_for_completion_timeout(&drvdata->send_cmd_complete, msecs_to_jiffies(25)); + drvdata->orphan_ack_pending = false; + drvdata->cmd_status = -ETIMEDOUT; + } + reinit_completion(&drvdata->send_cmd_complete); + /* We can't use a devm_alloc reusable buffer without side effects during suspend */ dmabuf = kzalloc(GO_S_PACKET_SIZE, GFP_KERNEL); if (!dmabuf) @@ -472,14 +506,14 @@ static int mcu_property_out(struct hid_device *hdev, u8 command, u8 index, /* PL_TEST commands can take longer because they go out to another device */ timeout = (command == GET_PL_TEST) ? 200 : 5; - ret = wait_for_completion_interruptible_timeout(&drvdata.send_cmd_complete, + ret = wait_for_completion_interruptible_timeout(&drvdata->send_cmd_complete, msecs_to_jiffies(timeout)); + ret = ret > 0 ? drvdata->cmd_status : ret ?: -EBUSY; - if (ret == 0) /* timeout occurred */ - ret = -EBUSY; + if (ret) + drvdata->orphan_ack_pending = true; - reinit_completion(&drvdata.send_cmd_complete); - return 0; + return ret; } static ssize_t gamepad_property_store(struct device *dev, @@ -487,10 +521,34 @@ static ssize_t gamepad_property_store(struct device *dev, const char *buf, size_t count, enum feature_status_index index) { + struct gos_cfg_drvdata *drvdata; + struct led_classdev_mc *led_mc; + struct led_classdev *led_cdev; + struct hid_device *hdev; + bool dev_registered; size_t size = 1; u8 val = 0; int ret; + /* rgb_enabled is attached to led_classdev, not hid_device */ + if (index == FEATURE_RGB_ENABLE) { + led_cdev = dev_get_drvdata(dev); + led_mc = lcdev_to_mccdev(led_cdev); + drvdata = container_of(led_mc, struct gos_cfg_drvdata, led_mc); + hdev = drvdata->hdev; + /* Pairs with smp_store_release from gos_cfg_setup */ + dev_registered = smp_load_acquire(&drvdata->rgb_registered); + + } else { + hdev = to_hid_device(dev); + drvdata = hid_get_drvdata(hdev); + /* Pairs with smp_store_release from gos_cfg_setup */ + dev_registered = smp_load_acquire(&drvdata->gp_registered); + } + + if (!dev_registered) + return -ENODEV; + switch (index) { case FEATURE_GAMEPAD_MODE: ret = sysfs_match_string(gamepad_mode_text, buf); @@ -559,7 +617,7 @@ static ssize_t gamepad_property_store(struct device *dev, if (!val) size = 0; - ret = mcu_property_out(drvdata.hdev, SET_GAMEPAD_CFG, index, &val, + ret = mcu_property_out(hdev, SET_GAMEPAD_CFG, index, &val, size); if (ret < 0) return ret; @@ -571,67 +629,92 @@ static ssize_t gamepad_property_show(struct device *dev, struct device_attribute *attr, char *buf, enum feature_status_index index) { + struct gos_cfg_drvdata *drvdata; + struct led_classdev_mc *led_mc; + struct led_classdev *led_cdev; + struct hid_device *hdev; + bool dev_registered; + ssize_t count = 0; u8 i; - count = mcu_property_out(drvdata.hdev, GET_GAMEPAD_CFG, index, NULL, 0); + /* rgb_enabled is attached to led_classdev, not hid_device */ + if (index == FEATURE_RGB_ENABLE) { + led_cdev = dev_get_drvdata(dev); + led_mc = lcdev_to_mccdev(led_cdev); + drvdata = container_of(led_mc, struct gos_cfg_drvdata, led_mc); + hdev = drvdata->hdev; + /* Pairs with smp_store_release from gos_cfg_setup */ + dev_registered = smp_load_acquire(&drvdata->rgb_registered); + + } else { + hdev = to_hid_device(dev); + drvdata = hid_get_drvdata(hdev); + /* Pairs with smp_store_release from gos_cfg_setup */ + dev_registered = smp_load_acquire(&drvdata->gp_registered); + } + + if (!dev_registered) + return -ENODEV; + + count = mcu_property_out(hdev, GET_GAMEPAD_CFG, index, NULL, 0); if (count < 0) return count; switch (index) { case FEATURE_GAMEPAD_MODE: - i = drvdata.gp_mode; + i = drvdata->gp_mode; if (i >= ARRAY_SIZE(gamepad_mode_text)) return -EINVAL; count = sysfs_emit(buf, "%s\n", gamepad_mode_text[i]); break; case FEATURE_AUTO_SLEEP_TIME: - count = sysfs_emit(buf, "%u\n", drvdata.gp_auto_sleep_time); + count = sysfs_emit(buf, "%u\n", drvdata->gp_auto_sleep_time); break; case FEATURE_IMU_ENABLE: - i = drvdata.imu_sensor_en; + i = drvdata->imu_sensor_en; if (i >= ARRAY_SIZE(feature_enabled_text)) return -EINVAL; count = sysfs_emit(buf, "%s\n", feature_enabled_text[i]); break; case FEATURE_IMU_BYPASS: - i = drvdata.imu_bypass_en; + i = drvdata->imu_bypass_en; if (i >= ARRAY_SIZE(feature_enabled_text)) return -EINVAL; count = sysfs_emit(buf, "%s\n", feature_enabled_text[i]); break; case FEATURE_RGB_ENABLE: - i = drvdata.rgb_en; + i = drvdata->rgb_en; if (i >= ARRAY_SIZE(feature_enabled_text)) return -EINVAL; count = sysfs_emit(buf, "%s\n", feature_enabled_text[i]); break; case FEATURE_TOUCHPAD_ENABLE: - i = drvdata.tp_en; + i = drvdata->tp_en; if (i >= ARRAY_SIZE(feature_enabled_text)) return -EINVAL; count = sysfs_emit(buf, "%s\n", feature_enabled_text[i]); break; case FEATURE_OS_MODE: - i = drvdata.os_mode; + i = drvdata->os_mode; if (i >= ARRAY_SIZE(os_type_text)) return -EINVAL; count = sysfs_emit(buf, "%s\n", os_type_text[i]); break; case FEATURE_POLL_RATE: - i = drvdata.gp_poll_rate; + i = drvdata->gp_poll_rate; if (i >= ARRAY_SIZE(poll_rate_text)) return -EINVAL; count = sysfs_emit(buf, "%s\n", poll_rate_text[i]); break; case FEATURE_DPAD_MODE: - i = drvdata.gp_dpad_mode; + i = drvdata->gp_dpad_mode; if (i >= ARRAY_SIZE(dpad_mode_text)) return -EINVAL; count = sysfs_emit(buf, "%s\n", dpad_mode_text[i]); break; case FEATURE_MOUSE_WHEEL_STEP: - i = drvdata.mouse_step; + i = drvdata->mouse_step; if (i < 1 || i > 127) return -EINVAL; count = sysfs_emit(buf, "%u\n", i); @@ -709,10 +792,21 @@ static ssize_t touchpad_property_store(struct device *dev, const char *buf, size_t count, enum touchpad_config_index index) { + struct hid_device *hdev = to_hid_device(dev); + struct gos_cfg_drvdata *drvdata = hid_get_drvdata(hdev); + bool gp_registered; size_t size = 1; u8 val = 0; int ret; + if (!drvdata) + return -ENODEV; + +/* Pairs with smp_store_release from gos_cfg_setup */ + gp_registered = smp_load_acquire(&drvdata->gp_registered); + if (!gp_registered) + return -ENODEV; + switch (index) { case CFG_WINDOWS_MODE: ret = sysfs_match_string(touchpad_mode_text, buf); @@ -732,7 +826,7 @@ static ssize_t touchpad_property_store(struct device *dev, if (!val) size = 0; - ret = mcu_property_out(drvdata.hdev, SET_TP_PARAM, index, &val, size); + ret = mcu_property_out(hdev, SET_TP_PARAM, index, &val, size); if (ret < 0) return ret; @@ -743,19 +837,30 @@ static ssize_t touchpad_property_show(struct device *dev, struct device_attribute *attr, char *buf, enum touchpad_config_index index) { + struct hid_device *hdev = to_hid_device(dev); + struct gos_cfg_drvdata *drvdata = hid_get_drvdata(hdev); + bool gp_registered; int ret = 0; u8 i; - ret = mcu_property_out(drvdata.hdev, GET_TP_PARAM, index, NULL, 0); + if (!drvdata) + return -ENODEV; + +/* Pairs with smp_store_release from gos_cfg_setup */ + gp_registered = smp_load_acquire(&drvdata->gp_registered); + if (!gp_registered) + return -ENODEV; + + ret = mcu_property_out(hdev, GET_TP_PARAM, index, NULL, 0); if (ret < 0) return ret; switch (index) { case CFG_WINDOWS_MODE: - i = drvdata.tp_windows_mode; + i = drvdata->tp_windows_mode; break; case CFG_LINUX_MODE: - i = drvdata.tp_linux_mode; + i = drvdata->tp_linux_mode; break; default: return -EINVAL; @@ -797,24 +902,35 @@ static ssize_t test_property_show(struct device *dev, struct device_attribute *attr, char *buf, enum test_command_index index) { + struct hid_device *hdev = to_hid_device(dev); + struct gos_cfg_drvdata *drvdata = hid_get_drvdata(hdev); + bool gp_registered; size_t count = 0; u8 i; + if (!drvdata) + return -ENODEV; + +/* Pairs with smp_store_release from gos_cfg_setup */ + gp_registered = smp_load_acquire(&drvdata->gp_registered); + if (!gp_registered) + return -ENODEV; + switch (index) { case TEST_TP_MFR: - i = drvdata.tp_manufacturer; + i = drvdata->tp_manufacturer; if (i >= ARRAY_SIZE(touchpad_manufacturer_text)) return -EINVAL; count = sysfs_emit(buf, "%s\n", touchpad_manufacturer_text[i]); break; case TEST_IMU_MFR: - i = drvdata.imu_manufacturer; + i = drvdata->imu_manufacturer; if (i >= ARRAY_SIZE(imu_manufacturer_text)) return -EINVAL; count = sysfs_emit(buf, "%s\n", imu_manufacturer_text[i]); break; case TEST_TP_VER: - count = sysfs_emit(buf, "%u\n", drvdata.tp_version); + count = sysfs_emit(buf, "%u\n", drvdata->tp_version); break; default: count = -EINVAL; @@ -827,7 +943,13 @@ static ssize_t test_property_show(struct device *dev, static ssize_t mcu_id_show(struct device *dev, struct device_attribute *attr, char *buf) { - return sysfs_emit(buf, "%*phN\n", 12, &drvdata.mcu_id); + struct hid_device *hdev = to_hid_device(dev); + struct gos_cfg_drvdata *drvdata = hid_get_drvdata(hdev); + + if (!drvdata) + return -ENODEV; + + return sysfs_emit(buf, "%*phN\n", 12, &drvdata->mcu_id); } static int rgb_cfg_call(struct hid_device *hdev, enum mcu_command_index cmd, @@ -842,58 +964,75 @@ static int rgb_cfg_call(struct hid_device *hdev, enum mcu_command_index cmd, return mcu_property_out(hdev, cmd, index, val, size); } -static int rgb_attr_show(void) +static int rgb_attr_show(struct gos_cfg_drvdata *drvdata) { enum rgb_config_index index; - index = drvdata.rgb_profile + 2; + index = drvdata->rgb_profile + 2; - return rgb_cfg_call(drvdata.hdev, GET_RGB_CFG, index, NULL, 0); + return rgb_cfg_call(drvdata->hdev, GET_RGB_CFG, index, NULL, 0); }; static ssize_t rgb_effect_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(drvdata.led_cdev); + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct led_classdev_mc *led_mc = lcdev_to_mccdev(led_cdev); + struct gos_cfg_drvdata *drvdata = container_of(led_mc, struct gos_cfg_drvdata, led_mc); enum rgb_config_index index; + bool rgb_registered; u8 effect; int ret; +/* Pairs with smp_store_release from gos_cfg_setup */ + rgb_registered = smp_load_acquire(&drvdata->rgb_registered); + if (!rgb_registered) + return -ENODEV; + ret = sysfs_match_string(rgb_effect_text, buf); if (ret < 0) return ret; effect = ret; - index = drvdata.rgb_profile + 2; + index = drvdata->rgb_profile + 2; u8 rgb_profile[6] = { effect, - mc_cdev->subled_info[0].intensity, - mc_cdev->subled_info[1].intensity, - mc_cdev->subled_info[2].intensity, - drvdata.led_cdev->brightness, - drvdata.rgb_speed }; + led_mc->subled_info[0].intensity, + led_mc->subled_info[1].intensity, + led_mc->subled_info[2].intensity, + led_mc->led_cdev.brightness, + drvdata->rgb_speed }; - ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, index, rgb_profile, 6); + ret = rgb_cfg_call(drvdata->hdev, SET_RGB_CFG, index, rgb_profile, 6); if (ret) return ret; - drvdata.rgb_effect = effect; + drvdata->rgb_effect = effect; return count; }; static ssize_t rgb_effect_show(struct device *dev, struct device_attribute *attr, char *buf) { + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct led_classdev_mc *led_mc = lcdev_to_mccdev(led_cdev); + struct gos_cfg_drvdata *drvdata = container_of(led_mc, struct gos_cfg_drvdata, led_mc); + bool rgb_registered; int ret; - ret = rgb_attr_show(); +/* Pairs with smp_store_release from gos_cfg_setup */ + rgb_registered = smp_load_acquire(&drvdata->rgb_registered); + if (!rgb_registered) + return -ENODEV; + + ret = rgb_attr_show(drvdata); if (ret) return ret; - if (drvdata.rgb_effect >= ARRAY_SIZE(rgb_effect_text)) + if (drvdata->rgb_effect >= ARRAY_SIZE(rgb_effect_text)) return -EINVAL; - return sysfs_emit(buf, "%s\n", rgb_effect_text[drvdata.rgb_effect]); + return sysfs_emit(buf, "%s\n", rgb_effect_text[drvdata->rgb_effect]); } static ssize_t rgb_effect_index_show(struct device *dev, @@ -915,11 +1054,19 @@ static ssize_t rgb_speed_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { - struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(drvdata.led_cdev); + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct led_classdev_mc *led_mc = lcdev_to_mccdev(led_cdev); + struct gos_cfg_drvdata *drvdata = container_of(led_mc, struct gos_cfg_drvdata, led_mc); enum rgb_config_index index; + bool rgb_registered; int val = 0; int ret; +/* Pairs with smp_store_release from gos_cfg_setup */ + rgb_registered = smp_load_acquire(&drvdata->rgb_registered); + if (!rgb_registered) + return -ENODEV; + ret = kstrtoint(buf, 10, &val); if (ret) return ret; @@ -927,19 +1074,19 @@ static ssize_t rgb_speed_store(struct device *dev, if (val < 0 || val > 100) return -EINVAL; - index = drvdata.rgb_profile + 2; - u8 rgb_profile[6] = { drvdata.rgb_effect, - mc_cdev->subled_info[0].intensity, - mc_cdev->subled_info[1].intensity, - mc_cdev->subled_info[2].intensity, - drvdata.led_cdev->brightness, + index = drvdata->rgb_profile + 2; + u8 rgb_profile[6] = { drvdata->rgb_effect, + led_mc->subled_info[0].intensity, + led_mc->subled_info[1].intensity, + led_mc->subled_info[2].intensity, + led_mc->led_cdev.brightness, val }; - ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, index, rgb_profile, 6); + ret = rgb_cfg_call(drvdata->hdev, SET_RGB_CFG, index, rgb_profile, 6); if (ret) return ret; - drvdata.rgb_speed = val; + drvdata->rgb_speed = val; return count; }; @@ -947,16 +1094,25 @@ static ssize_t rgb_speed_store(struct device *dev, static ssize_t rgb_speed_show(struct device *dev, struct device_attribute *attr, char *buf) { + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct led_classdev_mc *led_mc = lcdev_to_mccdev(led_cdev); + struct gos_cfg_drvdata *drvdata = container_of(led_mc, struct gos_cfg_drvdata, led_mc); + bool rgb_registered; int ret; - ret = rgb_attr_show(); +/* Pairs with smp_store_release from gos_cfg_setup */ + rgb_registered = smp_load_acquire(&drvdata->rgb_registered); + if (!rgb_registered) + return -ENODEV; + + ret = rgb_attr_show(drvdata); if (ret) return ret; - if (drvdata.rgb_speed > 100) + if (drvdata->rgb_speed > 100) return -EINVAL; - return sysfs_emit(buf, "%hhu\n", drvdata.rgb_speed); + return sysfs_emit(buf, "%hhu\n", drvdata->rgb_speed); } static ssize_t rgb_speed_range_show(struct device *dev, @@ -968,21 +1124,30 @@ static ssize_t rgb_speed_range_show(struct device *dev, static ssize_t rgb_mode_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct led_classdev_mc *led_mc = lcdev_to_mccdev(led_cdev); + struct gos_cfg_drvdata *drvdata = container_of(led_mc, struct gos_cfg_drvdata, led_mc); + bool rgb_registered; int ret; u8 val; +/* Pairs with smp_store_release from gos_cfg_setup */ + rgb_registered = smp_load_acquire(&drvdata->rgb_registered); + if (!rgb_registered) + return -ENODEV; + ret = sysfs_match_string(rgb_mode_text, buf); if (ret <= 0) return ret; val = ret; - ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, LIGHT_MODE_SEL, &val, + ret = rgb_cfg_call(drvdata->hdev, SET_RGB_CFG, LIGHT_MODE_SEL, &val, 1); if (ret) return ret; - drvdata.rgb_mode = val; + drvdata->rgb_mode = val; return count; }; @@ -990,16 +1155,25 @@ static ssize_t rgb_mode_store(struct device *dev, struct device_attribute *attr, static ssize_t rgb_mode_show(struct device *dev, struct device_attribute *attr, char *buf) { + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct led_classdev_mc *led_mc = lcdev_to_mccdev(led_cdev); + struct gos_cfg_drvdata *drvdata = container_of(led_mc, struct gos_cfg_drvdata, led_mc); + bool rgb_registered; int ret; - ret = rgb_cfg_call(drvdata.hdev, GET_RGB_CFG, LIGHT_MODE_SEL, NULL, 0); +/* Pairs with smp_store_release from gos_cfg_setup */ + rgb_registered = smp_load_acquire(&drvdata->rgb_registered); + if (!rgb_registered) + return -ENODEV; + + ret = rgb_cfg_call(drvdata->hdev, GET_RGB_CFG, LIGHT_MODE_SEL, NULL, 0); if (ret) return ret; - if (drvdata.rgb_mode >= ARRAY_SIZE(rgb_mode_text)) + if (drvdata->rgb_mode >= ARRAY_SIZE(rgb_mode_text)) return -EINVAL; - return sysfs_emit(buf, "%s\n", rgb_mode_text[drvdata.rgb_mode]); + return sysfs_emit(buf, "%s\n", rgb_mode_text[drvdata->rgb_mode]); }; static ssize_t rgb_mode_index_show(struct device *dev, @@ -1021,10 +1195,19 @@ static ssize_t rgb_profile_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct led_classdev_mc *led_mc = lcdev_to_mccdev(led_cdev); + struct gos_cfg_drvdata *drvdata = container_of(led_mc, struct gos_cfg_drvdata, led_mc); + bool rgb_registered; size_t size = 1; int ret; u8 val; +/* Pairs with smp_store_release from gos_cfg_setup */ + rgb_registered = smp_load_acquire(&drvdata->rgb_registered); + if (!rgb_registered) + return -ENODEV; + ret = kstrtou8(buf, 10, &val); if (ret < 0) return ret; @@ -1032,11 +1215,11 @@ static ssize_t rgb_profile_store(struct device *dev, if (val < 1 || val > 3) return -EINVAL; - ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, LIGHT_PROFILE_SEL, &val, size); + ret = rgb_cfg_call(drvdata->hdev, SET_RGB_CFG, LIGHT_PROFILE_SEL, &val, size); if (ret) return ret; - drvdata.rgb_profile = val; + drvdata->rgb_profile = val; return count; }; @@ -1044,16 +1227,25 @@ static ssize_t rgb_profile_store(struct device *dev, static ssize_t rgb_profile_show(struct device *dev, struct device_attribute *attr, char *buf) { + struct led_classdev *led_cdev = dev_get_drvdata(dev); + struct led_classdev_mc *led_mc = lcdev_to_mccdev(led_cdev); + struct gos_cfg_drvdata *drvdata = container_of(led_mc, struct gos_cfg_drvdata, led_mc); + bool rgb_registered; int ret; - ret = rgb_cfg_call(drvdata.hdev, GET_RGB_CFG, LIGHT_PROFILE_SEL, NULL, 0); +/* Pairs with smp_store_release from gos_cfg_setup */ + rgb_registered = smp_load_acquire(&drvdata->rgb_registered); + if (!rgb_registered) + return -ENODEV; + + ret = rgb_cfg_call(drvdata->hdev, GET_RGB_CFG, LIGHT_PROFILE_SEL, NULL, 0); if (ret) return ret; - if (drvdata.rgb_profile < 1 || drvdata.rgb_profile > 3) + if (drvdata->rgb_profile < 1 || drvdata->rgb_profile > 3) return -EINVAL; - return sysfs_emit(buf, "%hhu\n", drvdata.rgb_profile); + return sysfs_emit(buf, "%hhu\n", drvdata->rgb_profile); }; static ssize_t rgb_profile_range_show(struct device *dev, @@ -1065,24 +1257,31 @@ static ssize_t rgb_profile_range_show(struct device *dev, static void hid_gos_brightness_set(struct led_classdev *led_cdev, enum led_brightness brightness) { - struct led_classdev_mc *mc_cdev = lcdev_to_mccdev(drvdata.led_cdev); + struct led_classdev_mc *led_mc = lcdev_to_mccdev(led_cdev); + struct gos_cfg_drvdata *drvdata = container_of(led_mc, struct gos_cfg_drvdata, led_mc); enum rgb_config_index index; + bool rgb_registered; int ret; +/* Pairs with smp_store_release from gos_cfg_setup */ + rgb_registered = smp_load_acquire(&drvdata->rgb_registered); + if (!rgb_registered) + return; + if (brightness > led_cdev->max_brightness) { dev_err(led_cdev->dev, "Invalid argument\n"); return; } - index = drvdata.rgb_profile + 2; - u8 rgb_profile[6] = { drvdata.rgb_effect, - mc_cdev->subled_info[0].intensity, - mc_cdev->subled_info[1].intensity, - mc_cdev->subled_info[2].intensity, + index = drvdata->rgb_profile + 2; + u8 rgb_profile[6] = { drvdata->rgb_effect, + led_mc->subled_info[0].intensity, + led_mc->subled_info[1].intensity, + led_mc->subled_info[2].intensity, brightness, - drvdata.rgb_speed }; + drvdata->rgb_speed }; - ret = rgb_cfg_call(drvdata.hdev, SET_RGB_CFG, index, rgb_profile, 6); + ret = rgb_cfg_call(drvdata->hdev, SET_RGB_CFG, index, rgb_profile, 6); switch (ret) { case 0: led_cdev->brightness = brightness; @@ -1318,103 +1517,140 @@ static struct mc_subled gos_rgb_subled_info[] = { }, }; -static struct led_classdev_mc gos_cdev_rgb = { - .led_cdev = { - .name = "go_s:rgb:joystick_rings", - .brightness = 0x50, - .max_brightness = 0x64, - .brightness_set = hid_gos_brightness_set, - }, - .num_colors = ARRAY_SIZE(gos_rgb_subled_info), - .subled_info = gos_rgb_subled_info, -}; - static void cfg_setup(struct work_struct *work) { + struct delayed_work *dwork = container_of(work, struct delayed_work, work); + struct gos_cfg_drvdata *drvdata = container_of(dwork, struct gos_cfg_drvdata, + gos_cfg_setup); + bool gp_registered, rgb_registered; int ret; + if (!drvdata) + return; + /* MCU */ - ret = mcu_property_out(drvdata.hdev, GET_MCU_ID, FEATURE_NONE, NULL, 0); + ret = mcu_property_out(drvdata->hdev, GET_MCU_ID, FEATURE_NONE, NULL, 0); if (ret) { - dev_err(&drvdata.hdev->dev, "Failed to retrieve MCU ID: %i\n", + dev_err(&drvdata->hdev->dev, "Failed to retrieve MCU ID: %i\n", ret); return; } - ret = mcu_property_out(drvdata.hdev, GET_VERSION, FEATURE_NONE, NULL, 0); + ret = mcu_property_out(drvdata->hdev, GET_VERSION, FEATURE_NONE, NULL, 0); if (ret) { - dev_err(&drvdata.hdev->dev, "Failed to retrieve MCU Version: %i\n", ret); + dev_err(&drvdata->hdev->dev, "Failed to retrieve MCU Version: %i\n", ret); return; } - ret = mcu_property_out(drvdata.hdev, GET_PL_TEST, TEST_TP_MFR, NULL, 0); + ret = mcu_property_out(drvdata->hdev, GET_PL_TEST, TEST_TP_MFR, NULL, 0); if (ret) { - dev_err(&drvdata.hdev->dev, + dev_err(&drvdata->hdev->dev, "Failed to retrieve Touchpad Manufacturer: %i\n", ret); return; } - ret = mcu_property_out(drvdata.hdev, GET_PL_TEST, TEST_TP_VER, NULL, 0); + ret = mcu_property_out(drvdata->hdev, GET_PL_TEST, TEST_TP_VER, NULL, 0); if (ret) { - dev_err(&drvdata.hdev->dev, + dev_err(&drvdata->hdev->dev, "Failed to retrieve Touchpad Firmware Version: %i\n", ret); return; } - ret = mcu_property_out(drvdata.hdev, GET_PL_TEST, TEST_IMU_MFR, NULL, 0); + ret = mcu_property_out(drvdata->hdev, GET_PL_TEST, TEST_IMU_MFR, NULL, 0); if (ret) { - dev_err(&drvdata.hdev->dev, + dev_err(&drvdata->hdev->dev, "Failed to retrieve IMU Manufacturer: %i\n", ret); return; } - ret = mcu_property_out(drvdata.hdev, GET_GAMEPAD_CFG, FEATURE_OS_MODE, + ret = mcu_property_out(drvdata->hdev, GET_GAMEPAD_CFG, FEATURE_OS_MODE, NULL, 0); if (ret) { - dev_err(&drvdata.hdev->dev, + dev_err(&drvdata->hdev->dev, "Failed to retrieve OS Mode: %i\n", ret); return; } + +/* Pairs with smp_store_release from below */ + gp_registered = smp_load_acquire(&drvdata->gp_registered); + if (gp_registered) + goto try_rgb; + + ret = sysfs_create_groups(&drvdata->hdev->dev.kobj, top_level_attr_groups); + if (ret) { + dev_err(&drvdata->hdev->dev, + "Failed to create gamepad configuration attributes: %i\n", ret); + goto try_rgb; + } + +/* Pairs with smp_load_acquire in attribute show/store functions */ + smp_store_release(&drvdata->gp_registered, true); + gp_registered = true; + +try_rgb: +/* Pairs with smp_store_release from below */ + rgb_registered = smp_load_acquire(&drvdata->rgb_registered); + if (rgb_registered) + goto update_kobjects; + + ret = devm_led_classdev_multicolor_register(&drvdata->hdev->dev, &drvdata->led_mc); + if (ret) { + dev_err(&drvdata->hdev->dev, + "Failed to create RGB device: %i\n", ret); + goto update_kobjects; + } + + ret = devm_device_add_group(drvdata->led_mc.led_cdev.dev, &rgb_attr_group); + if (ret) { + dev_err(&drvdata->hdev->dev, + "Failed to create RGB configuration attributes: %i\n", ret); + goto update_kobjects; + } + +/* Pairs with smp_load_acquire in attribute show/store functions */ + smp_store_release(&drvdata->rgb_registered, true); + rgb_registered = true; + +update_kobjects: + if (gp_registered) + kobject_uevent(&drvdata->hdev->dev.kobj, KOBJ_CHANGE); + if (rgb_registered) + kobject_uevent(&drvdata->led_mc.led_cdev.dev->kobj, KOBJ_CHANGE); } static int hid_gos_cfg_probe(struct hid_device *hdev, const struct hid_device_id *_id) { + struct gos_cfg_drvdata *drvdata; int ret; - hid_set_drvdata(hdev, &drvdata); - drvdata.hdev = hdev; - mutex_init(&drvdata.cfg_mutex); + drvdata = devm_kzalloc(&hdev->dev, sizeof(struct gos_cfg_drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; - ret = sysfs_create_groups(&hdev->dev.kobj, top_level_attr_groups); - if (ret) { - dev_err_probe(&hdev->dev, ret, - "Failed to create gamepad configuration attributes\n"); - return ret; - } + hid_set_drvdata(hdev, drvdata); + drvdata->hdev = hdev; - ret = devm_led_classdev_multicolor_register(&hdev->dev, &gos_cdev_rgb); - if (ret) { - dev_err_probe(&hdev->dev, ret, "Failed to create RGB device\n"); - return ret; - } + mutex_init(&drvdata->cfg_mutex); + init_completion(&drvdata->send_cmd_complete); - ret = devm_device_add_group(gos_cdev_rgb.led_cdev.dev, &rgb_attr_group); - if (ret) { - dev_err_probe(&hdev->dev, ret, - "Failed to create RGB configuration attributes\n"); - return ret; - } - - drvdata.led_cdev = &gos_cdev_rgb.led_cdev; - - init_completion(&drvdata.send_cmd_complete); + /* Device is hardwired and name is guaranteed to be unique */ + drvdata->led_mc.led_cdev.name = "go_s:rgb:joystick_rings"; + drvdata->led_mc.led_cdev.brightness = 0x50; + drvdata->led_mc.led_cdev.max_brightness = 0x64; + drvdata->led_mc.led_cdev.color = LED_COLOR_ID_RGB; + drvdata->led_mc.led_cdev.brightness_set = hid_gos_brightness_set; + drvdata->led_mc.num_colors = 3; + drvdata->led_mc.subled_info = devm_kmemdup(&hdev->dev, gos_rgb_subled_info, + sizeof(gos_rgb_subled_info), GFP_KERNEL); + if (!drvdata->led_mc.subled_info) + return -ENOMEM; /* Executing calls prior to returning from probe will lock the MCU. Schedule * initial data call after probe has completed and MCU can accept calls. */ - INIT_DELAYED_WORK(&drvdata.gos_cfg_setup, &cfg_setup); - ret = schedule_delayed_work(&drvdata.gos_cfg_setup, msecs_to_jiffies(2)); + INIT_DELAYED_WORK(&drvdata->gos_cfg_setup, &cfg_setup); + ret = schedule_delayed_work(&drvdata->gos_cfg_setup, msecs_to_jiffies(2)); if (!ret) { dev_err(&hdev->dev, "Failed to schedule startup delayed work\n"); return -ENODEV; @@ -1425,8 +1661,12 @@ static int hid_gos_cfg_probe(struct hid_device *hdev, static void hid_gos_cfg_remove(struct hid_device *hdev) { - guard(mutex)(&drvdata.cfg_mutex); - cancel_delayed_work_sync(&drvdata.gos_cfg_setup); + struct gos_cfg_drvdata *drvdata = hid_get_drvdata(hdev); + + if (!drvdata) + return; + + disable_delayed_work_sync(&drvdata->gos_cfg_setup); sysfs_remove_groups(&hdev->dev.kobj, top_level_attr_groups); hid_hw_close(hdev); hid_hw_stop(hdev); @@ -1435,22 +1675,43 @@ static void hid_gos_cfg_remove(struct hid_device *hdev) static int hid_gos_cfg_reset_resume(struct hid_device *hdev) { - u8 os_mode = drvdata.os_mode; + struct gos_cfg_drvdata *drvdata = hid_get_drvdata(hdev); + bool gp_registered, rgb_registered; + u8 os_mode; int ret; - ret = mcu_property_out(drvdata.hdev, SET_GAMEPAD_CFG, + if (!drvdata) + return -ENODEV; + + os_mode = drvdata->os_mode; +/* Pairs with smp_store_release from gos_cfg_setup */ + gp_registered = smp_load_acquire(&drvdata->gp_registered); +/* Pairs with smp_store_release from gos_cfg_setup */ + rgb_registered = smp_load_acquire(&drvdata->rgb_registered); + if (!gp_registered || !rgb_registered) { + ret = schedule_delayed_work(&drvdata->gos_cfg_setup, msecs_to_jiffies(2)); + if (!ret) { + dev_err(&hdev->dev, "Failed to schedule startup delayed work\n"); + return -ENODEV; + } + + return 0; + } + + ret = mcu_property_out(drvdata->hdev, SET_GAMEPAD_CFG, FEATURE_OS_MODE, &os_mode, 1); if (ret < 0) return ret; - ret = mcu_property_out(drvdata.hdev, GET_GAMEPAD_CFG, + ret = mcu_property_out(drvdata->hdev, GET_GAMEPAD_CFG, FEATURE_OS_MODE, NULL, 0); if (ret < 0) return ret; - if (drvdata.os_mode != os_mode) + if (drvdata->os_mode != os_mode) return -ENODEV; + kobject_uevent(&drvdata->hdev->dev.kobj, KOBJ_CHANGE); return 0; } @@ -1525,6 +1786,35 @@ static int hid_gos_reset_resume(struct hid_device *hdev) return 0; } +static int hid_gos_cfg_suspend(struct hid_device *hdev) +{ + struct gos_cfg_drvdata *drvdata = hid_get_drvdata(hdev); + + if (!drvdata) + return -ENODEV; + + disable_delayed_work_sync(&drvdata->gos_cfg_setup); + + return 0; +} + +static int hid_gos_suspend(struct hid_device *hdev, pm_message_t msg) +{ + int ret; + u8 ep; + + /* Safe assumption. SET_INTERFACE ioctl can't be used while driver is bound */ + ret = get_endpoint_address(hdev); + if (ret <= 0) + return 0; + + ep = ret; + if (ep == GO_S_CFG_INTF_IN) + return hid_gos_cfg_suspend(hdev); + + return 0; +} + static const struct hid_device_id hid_gos_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_QHE, USB_DEVICE_ID_LENOVO_LEGION_GO_S_XINPUT) }, @@ -1540,7 +1830,8 @@ static struct hid_driver hid_lenovo_go_s = { .probe = hid_gos_probe, .remove = hid_gos_remove, .raw_event = hid_gos_raw_event, - .reset_resume = hid_gos_reset_resume, + .reset_resume = pm_ptr(hid_gos_reset_resume), + .suspend = pm_ptr(hid_gos_suspend), }; module_hid_driver(hid_lenovo_go_s);
diff --git a/drivers/hid/hid-lenovo.c b/drivers/hid/hid-lenovo.c index 3976d7b..617bba6 100644 --- a/drivers/hid/hid-lenovo.c +++ b/drivers/hid/hid-lenovo.c
@@ -476,6 +476,16 @@ static int lenovo_input_mapping_x1_tab_kbd(struct hid_device *hdev, return 0; } +static int lenovo_input_mapping_yoga7x_g11_kbd(struct hid_device *hdev, + struct hid_input *hi, struct hid_field *field, + struct hid_usage *usage, unsigned long **bit, int *max) +{ + if (field->application == HID_GD_WIRELESS_RADIO_CTLS) + return -1; + + return 0; +} + static int lenovo_input_mapping(struct hid_device *hdev, struct hid_input *hi, struct hid_field *field, struct hid_usage *usage, unsigned long **bit, int *max) @@ -510,6 +520,8 @@ static int lenovo_input_mapping(struct hid_device *hdev, case USB_DEVICE_ID_LENOVO_X1_TAB2: case USB_DEVICE_ID_LENOVO_X1_TAB3: return lenovo_input_mapping_x1_tab_kbd(hdev, hi, field, usage, bit, max); + case I2C_DEVICE_ID_ITE_LENOVO_YOGA_SLIM_7X_G11_KEYBOARD: + return lenovo_input_mapping_yoga7x_g11_kbd(hdev, hi, field, usage, bit, max); default: return 0; } @@ -1568,6 +1580,8 @@ static const struct hid_device_id lenovo_devices[] = { USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X13_TAB) }, { HID_DEVICE(BUS_I2C, HID_GROUP_GENERIC, USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_YOGA_SLIM_7X_KEYBOARD) }, + { HID_DEVICE(BUS_I2C, HID_GROUP_GENERIC, + USB_VENDOR_ID_ITE, I2C_DEVICE_ID_ITE_LENOVO_YOGA_SLIM_7X_G11_KEYBOARD) }, { } };
diff --git a/drivers/hid/hid-logitech-dj.c b/drivers/hid/hid-logitech-dj.c index 390d106d..6e8db01 100644 --- a/drivers/hid/hid-logitech-dj.c +++ b/drivers/hid/hid-logitech-dj.c
@@ -1790,6 +1790,9 @@ static int logi_dj_raw_event(struct hid_device *hdev, if (!hdev->report_enum[HID_INPUT_REPORT].numbered) { if (djrcv_dev->unnumbered_application == HID_GD_KEYBOARD) { + if (size < 2) + return false; + /* * For the keyboard, we can reuse the same report by * using the second byte which is constant in the USB
diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c index 9646380..27d83b8 100644 --- a/drivers/hid/hid-logitech-hidpp.c +++ b/drivers/hid/hid-logitech-hidpp.c
@@ -4791,6 +4791,7 @@ static int hidpp_probe(struct hid_device *hdev, const struct hid_device_id *id) hid_hw_start_fail: sysfs_remove_group(&hdev->dev.kobj, &ps_attribute_group); cancel_work_sync(&hidpp->work); + cancel_work_sync(&hidpp->reset_hi_res_work); mutex_destroy(&hidpp->send_mutex); return ret; }
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index d637c04..e6d4d49 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c
@@ -553,6 +553,10 @@ static int magicmouse_event(struct hid_device *hdev, struct hid_field *field, struct hid_usage *usage, __s32 value) { struct magicmouse_sc *msc = hid_get_drvdata(hdev); + + if (!msc || !msc->input) + return 0; + if ((msc->input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 || msc->input->id.product == USB_DEVICE_ID_APPLE_MAGICMOUSE2_USBC) && field->report->id == MOUSE2_REPORT_ID) {
diff --git a/drivers/hid/hid-mcp2200.c b/drivers/hid/hid-mcp2200.c index dafdd5b..c6fd5fb 100644 --- a/drivers/hid/hid-mcp2200.c +++ b/drivers/hid/hid-mcp2200.c
@@ -301,6 +301,11 @@ static int mcp2200_raw_event(struct hid_device *hdev, struct hid_report *report, switch (data[0]) { case READ_ALL: + if (size < sizeof(*all_resp)) { + mcp->status = -EPROTO; + break; + } + all_resp = (struct mcp_read_all_resp *) data; mcp->status = 0; mcp->gpio_inval = all_resp->io_port_val_bmap;
diff --git a/drivers/hid/hid-mcp2221.c b/drivers/hid/hid-mcp2221.c index d52ce35..053377d 100644 --- a/drivers/hid/hid-mcp2221.c +++ b/drivers/hid/hid-mcp2221.c
@@ -865,7 +865,7 @@ static int mcp2221_raw_event(struct hid_device *hdev, u8 *buf; struct mcp2221 *mcp = hid_get_drvdata(hdev); - if (size < 4) + if (size < sizeof(mcp->txbuf)) return 0; switch (data[0]) { @@ -1072,8 +1072,7 @@ static void mcp2221_remove(struct hid_device *hdev) #if IS_REACHABLE(CONFIG_IIO) struct mcp2221 *mcp = hid_get_drvdata(hdev); - if (!gpio_mode_enforce) - cancel_delayed_work_sync(&mcp->init_work); + cancel_delayed_work_sync(&mcp->init_work); #endif } @@ -1347,10 +1346,9 @@ static int mcp2221_probe(struct hid_device *hdev, #endif #if IS_REACHABLE(CONFIG_IIO) - if (!gpio_mode_enforce) { - INIT_DELAYED_WORK(&mcp->init_work, mcp_init_work); + INIT_DELAYED_WORK(&mcp->init_work, mcp_init_work); + if (!gpio_mode_enforce) schedule_delayed_work(&mcp->init_work, msecs_to_jiffies(100)); - } #endif return 0;
diff --git a/drivers/hid/hid-nintendo-switch2-usb.c b/drivers/hid/hid-nintendo-switch2-usb.c new file mode 100644 index 0000000..8b3b684 --- /dev/null +++ b/drivers/hid/hid-nintendo-switch2-usb.c
@@ -0,0 +1,493 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * USB driver for Nintendo Switch 2 controllers configuration interface + * + * Copyright (c) 2025 Valve Software + * + * This driver is based on the following work: + * https://gist.github.com/shinyquagsire23/66f006b46c56216acbaac6c1e2279b64 + * https://github.com/ndeadly/switch2_controller_research + */ + +#include "hid-ids.h" +#include "hid-nintendo.h" +#include <linux/module.h> +#include <linux/usb/input.h> + +#define NS2_BULK_SIZE 64 +#define NS2_IN_URBS 2 +#define NS2_OUT_URBS 4 + +static struct usb_driver switch2_usb; + +enum switch2_urb_state { + NS2_URB_FREE, + NS2_URB_OUT, + NS2_URB_IN, +}; + +struct switch2_urb { + struct urb *urb; + uint8_t *data; + enum switch2_urb_state state; +}; + +struct switch2_usb { + struct switch2_cfg_intf cfg; + struct usb_device *udev; + + struct switch2_urb bulk_in[NS2_IN_URBS]; + struct usb_anchor bulk_in_anchor; + bool shutdown; + spinlock_t bulk_in_lock; + + struct switch2_urb bulk_out[NS2_OUT_URBS]; + struct usb_anchor bulk_out_anchor; + spinlock_t bulk_out_lock; + + struct work_struct message_in_work; +}; + +static void switch2_bulk_in(struct urb *urb) +{ + struct switch2_usb *ns2_usb = urb->context; + int i; + bool schedule = false; + unsigned long flags; + + switch (urb->status) { + case 0: + schedule = true; + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + case -EPIPE: + dev_dbg(&ns2_usb->udev->dev, "shutting down input urb: %d\n", urb->status); + return; + default: + dev_dbg(&ns2_usb->udev->dev, "unknown input urb status: %d\n", urb->status); + break; + } + + spin_lock_irqsave(&ns2_usb->bulk_in_lock, flags); + if (ns2_usb->shutdown) + schedule = false; + + for (i = 0; i < NS2_IN_URBS; i++) { + int err; + struct switch2_urb *ns2_urb; + + if (ns2_usb->bulk_in[i].urb == urb) { + if (schedule) { + ns2_usb->bulk_in[i].state = NS2_URB_IN; + continue; + } else { + ns2_usb->bulk_in[i].state = NS2_URB_FREE; + } + } + + if (ns2_usb->bulk_in[i].state != NS2_URB_FREE) + continue; + + if (ns2_usb->shutdown) + continue; + + /* + * We want exactly one bulk in URB scheduled at a time, so only + * reschedule this immediately if nothing else is scheduled + * currently. + */ + if (!usb_anchor_empty(&ns2_usb->bulk_in_anchor)) + continue; + + ns2_urb = &ns2_usb->bulk_in[i]; + if (!ns2_urb) + continue; + + usb_anchor_urb(ns2_urb->urb, &ns2_usb->bulk_in_anchor); + err = usb_submit_urb(ns2_urb->urb, GFP_ATOMIC); + if (err) { + usb_unanchor_urb(ns2_urb->urb); + dev_dbg(&ns2_usb->udev->dev, "failed to queue input urb: %d\n", err); + } else { + ns2_urb->state = NS2_URB_OUT; + } + } + spin_unlock_irqrestore(&ns2_usb->bulk_in_lock, flags); + + if (schedule) + schedule_work(&ns2_usb->message_in_work); +} + +static void switch2_bulk_out(struct urb *urb) +{ + struct switch2_usb *ns2_usb = urb->context; + int i; + + guard(spinlock_irqsave)(&ns2_usb->bulk_out_lock); + + switch (urb->status) { + case 0: + break; + case -ECONNRESET: + case -ENOENT: + case -ESHUTDOWN: + dev_dbg(&ns2_usb->udev->dev, "shutting down output urb: %d\n", urb->status); + return; + case -EPIPE: + break; + default: + dev_dbg(&ns2_usb->udev->dev, "unknown output urb status: %d\n", urb->status); + break; + } + + for (i = 0; i < NS2_OUT_URBS; i++) { + if (ns2_usb->bulk_out[i].urb != urb) + continue; + + ns2_usb->bulk_out[i].state = NS2_URB_FREE; + break; + } +} + +static int switch2_usb_send_cmd(enum switch2_cmd command, uint8_t subcommand, + const void *message, size_t size, struct switch2_cfg_intf *cfg) +{ + struct switch2_usb *ns2_usb = (struct switch2_usb *)cfg; + struct switch2_urb *urb = NULL; + int i; + int ret; + unsigned long flags; + + struct switch2_cmd_header header = { + command, NS2_DIR_OUT | NS2_FLAG_OK, NS2_TRANS_USB, subcommand, 0, size + }; + + if (WARN_ON(size > 56)) + return -EINVAL; + + spin_lock_irqsave(&ns2_usb->bulk_out_lock, flags); + for (i = 0; i < NS2_OUT_URBS; i++) { + if (ns2_usb->bulk_out[i].state != NS2_URB_FREE) + continue; + + urb = &ns2_usb->bulk_out[i]; + urb->state = NS2_URB_OUT; + break; + } + spin_unlock_irqrestore(&ns2_usb->bulk_out_lock, flags); + + if (!urb) { + dev_warn(&ns2_usb->udev->dev, "output queue full, dropping message\n"); + return -ENOBUFS; + } + + memcpy(urb->data, &header, sizeof(header)); + if (message && size) + memcpy(&urb->data[8], message, size); + urb->urb->transfer_buffer_length = size + sizeof(header); + + print_hex_dump_debug("sending cmd: ", DUMP_PREFIX_OFFSET, 16, 1, urb->data, + size + sizeof(header), false); + + usb_anchor_urb(urb->urb, &ns2_usb->bulk_out_anchor); + ret = usb_submit_urb(urb->urb, GFP_KERNEL); + if (ret) { + if (ret != -ENODEV) + dev_warn(&ns2_usb->udev->dev, "failed to submit output urb: %i", ret); + spin_lock_irqsave(&ns2_usb->bulk_out_lock, flags); + urb->state = NS2_URB_FREE; + spin_unlock_irqrestore(&ns2_usb->bulk_out_lock, flags); + usb_unanchor_urb(urb->urb); + return ret; + } + + return 0; +} + +static void switch2_usb_free_in_urbs(struct switch2_usb *ns2_usb) +{ + struct urb *urb; + uint8_t *data; + int i; + unsigned long flags; + + spin_lock_irqsave(&ns2_usb->bulk_in_lock, flags); + ns2_usb->shutdown = true; + spin_unlock_irqrestore(&ns2_usb->bulk_in_lock, flags); + + cancel_work_sync(&ns2_usb->message_in_work); + + usb_kill_anchored_urbs(&ns2_usb->bulk_in_anchor); + for (i = 0; i < NS2_IN_URBS; i++) { + spin_lock_irqsave(&ns2_usb->bulk_in_lock, flags); + urb = ns2_usb->bulk_in[i].urb; + data = ns2_usb->bulk_in[i].data; + if (!urb) { + spin_unlock_irqrestore(&ns2_usb->bulk_in_lock, flags); + continue; + } + + ns2_usb->bulk_in[i].urb = NULL; + ns2_usb->bulk_in[i].data = NULL; + spin_unlock_irqrestore(&ns2_usb->bulk_in_lock, flags); + + usb_kill_urb(urb); + usb_free_coherent(ns2_usb->udev, NS2_BULK_SIZE, data, urb->transfer_dma); + usb_free_urb(urb); + } +} + +static void switch2_usb_free_out_urbs(struct switch2_usb *ns2_usb) +{ + struct urb *urb; + uint8_t *data; + int i; + unsigned long flags; + + usb_kill_anchored_urbs(&ns2_usb->bulk_out_anchor); + for (i = 0; i < NS2_OUT_URBS; i++) { + spin_lock_irqsave(&ns2_usb->bulk_out_lock, flags); + urb = ns2_usb->bulk_out[i].urb; + data = ns2_usb->bulk_out[i].data; + if (!urb) { + spin_unlock_irqrestore(&ns2_usb->bulk_out_lock, flags); + continue; + } + + ns2_usb->bulk_out[i].urb = NULL; + ns2_usb->bulk_out[i].data = NULL; + spin_unlock_irqrestore(&ns2_usb->bulk_out_lock, flags); + + usb_kill_urb(urb); + usb_free_coherent(ns2_usb->udev, NS2_BULK_SIZE, data, urb->transfer_dma); + usb_free_urb(urb); + } +} + +static void switch2_usb_shutdown(struct switch2_cfg_intf *intf) +{ + struct switch2_usb *ns2_usb = (struct switch2_usb *)intf; + int i; + unsigned long flags; + + spin_lock_irqsave(&ns2_usb->bulk_in_lock, flags); + ns2_usb->shutdown = true; + spin_unlock_irqrestore(&ns2_usb->bulk_in_lock, flags); + + cancel_work_sync(&ns2_usb->message_in_work); + + usb_kill_anchored_urbs(&ns2_usb->bulk_in_anchor); + spin_lock_irqsave(&ns2_usb->bulk_in_lock, flags); + for (i = 0; i < NS2_IN_URBS; i++) + ns2_usb->bulk_in[i].state = NS2_URB_FREE; + spin_unlock_irqrestore(&ns2_usb->bulk_in_lock, flags); +} + +static void switch2_usb_message_in_work(struct work_struct *work) +{ + struct switch2_usb *ns2_usb = container_of(work, struct switch2_usb, message_in_work); + struct switch2_urb *urb; + int err; + int i; + unsigned long flags; + + spin_lock_irqsave(&ns2_usb->bulk_in_lock, flags); + for (i = 0; i < NS2_IN_URBS; i++) { + urb = &ns2_usb->bulk_in[i]; + if (urb->state != NS2_URB_IN) + continue; + spin_unlock_irqrestore(&ns2_usb->bulk_in_lock, flags); + + if (ns2_usb->cfg.parent) { + err = switch2_receive_command(ns2_usb->cfg.parent, + urb->urb->transfer_buffer, urb->urb->actual_length); + if (err) + dev_dbg(&ns2_usb->udev->dev, "receive command failed: %d\n", err); + } else { + dev_err(&ns2_usb->udev->dev, + "Got message before controller is fully set up; discarding\n"); + } + + spin_lock_irqsave(&ns2_usb->bulk_in_lock, flags); + if (!urb->urb) + /* We're shutting down and this URB was freed */ + break; + + urb->state = NS2_URB_FREE; + /* + * We want exactly one bulk in URB scheduled at a time, so only + * reschedule this immediately if nothing else is scheduled + * currently. + */ + if (!usb_anchor_empty(&ns2_usb->bulk_in_anchor)) + continue; + + usb_anchor_urb(urb->urb, &ns2_usb->bulk_in_anchor); + err = usb_submit_urb(urb->urb, GFP_ATOMIC); + if (err) { + usb_unanchor_urb(urb->urb); + dev_dbg(&ns2_usb->udev->dev, + "failed to queue input urb: %d\n", err); + } else { + urb->state = NS2_URB_OUT; + } + } + spin_unlock_irqrestore(&ns2_usb->bulk_in_lock, flags); +} + +static int switch2_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct switch2_usb *ns2_usb; + struct usb_device *udev; + struct usb_endpoint_descriptor *bulk_in, *bulk_out; + struct urb *urb; + uint8_t *data; + char phys[64]; + int ret; + int i; + unsigned long flags; + + udev = interface_to_usbdev(intf); + if (usb_make_path(udev, phys, sizeof(phys)) < 0) + return -EINVAL; + + ret = usb_find_common_endpoints(intf->cur_altsetting, &bulk_in, &bulk_out, NULL, NULL); + if (ret) { + dev_err(&intf->dev, "failed to find bulk EPs\n"); + return ret; + } + + ns2_usb = devm_kzalloc(&intf->dev, sizeof(*ns2_usb), GFP_KERNEL); + if (!ns2_usb) + return -ENOMEM; + + init_usb_anchor(&ns2_usb->bulk_out_anchor); + spin_lock_init(&ns2_usb->bulk_out_lock); + init_usb_anchor(&ns2_usb->bulk_in_anchor); + spin_lock_init(&ns2_usb->bulk_in_lock); + INIT_WORK(&ns2_usb->message_in_work, switch2_usb_message_in_work); + + ns2_usb->udev = udev; + for (i = 0; i < NS2_IN_URBS; i++) { + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) { + ret = -ENOMEM; + goto err_free_in; + } + + data = usb_alloc_coherent(udev, NS2_BULK_SIZE, GFP_KERNEL, + &urb->transfer_dma); + if (!data) { + usb_free_urb(urb); + ret = -ENOMEM; + goto err_free_in; + } + + spin_lock_irqsave(&ns2_usb->bulk_in_lock, flags); + usb_fill_bulk_urb(urb, udev, + usb_rcvbulkpipe(udev, bulk_in->bEndpointAddress), + data, NS2_BULK_SIZE, switch2_bulk_in, ns2_usb); + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + ns2_usb->bulk_in[i].urb = urb; + ns2_usb->bulk_in[i].data = data; + spin_unlock_irqrestore(&ns2_usb->bulk_in_lock, flags); + } + + for (i = 0; i < NS2_OUT_URBS; i++) { + urb = usb_alloc_urb(0, GFP_KERNEL); + if (!urb) { + ret = -ENOMEM; + goto err_free_out; + } + + data = usb_alloc_coherent(udev, NS2_BULK_SIZE, GFP_KERNEL, + &urb->transfer_dma); + if (!data) { + usb_free_urb(urb); + ret = -ENOMEM; + goto err_free_out; + } + + spin_lock_irqsave(&ns2_usb->bulk_out_lock, flags); + usb_fill_bulk_urb(urb, udev, + usb_sndbulkpipe(udev, bulk_out->bEndpointAddress), + data, NS2_BULK_SIZE, switch2_bulk_out, ns2_usb); + urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP; + + ns2_usb->bulk_out[i].urb = urb; + ns2_usb->bulk_out[i].data = data; + spin_unlock_irqrestore(&ns2_usb->bulk_out_lock, flags); + } + + usb_set_intfdata(intf, ns2_usb); + + ns2_usb->cfg.dev = &ns2_usb->udev->dev; + ns2_usb->cfg.send_command = switch2_usb_send_cmd; + + spin_lock_irqsave(&ns2_usb->bulk_in_lock, flags); + ns2_usb->bulk_in[0].state = NS2_URB_OUT; + usb_anchor_urb(ns2_usb->bulk_in[0].urb, &ns2_usb->bulk_in_anchor); + ret = usb_submit_urb(ns2_usb->bulk_in[0].urb, GFP_ATOMIC); + spin_unlock_irqrestore(&ns2_usb->bulk_in_lock, flags); + + if (ret < 0) + goto err_free_out; + + ns2_usb->cfg.shutdown = switch2_usb_shutdown; + ret = switch2_controller_attach_cfg(phys, &ns2_usb->cfg); + if (ret < 0) + goto err_free_out; + + return 0; + +err_free_out: + switch2_usb_free_out_urbs(ns2_usb); +err_free_in: + switch2_usb_free_in_urbs(ns2_usb); + devm_kfree(&intf->dev, ns2_usb); + + return ret; +} + +static void switch2_usb_disconnect(struct usb_interface *intf) +{ + struct switch2_usb *ns2_usb = usb_get_intfdata(intf); + + switch2_usb_free_in_urbs(ns2_usb); + + /* + * We need to detach *before* we kill the out URBs to make sure no + * further URBs get scheduled by the HID endpoint in the meantime. + */ + if (ns2_usb->cfg.parent) + switch2_controller_detach_cfg(ns2_usb->cfg.parent); + + switch2_usb_free_out_urbs(ns2_usb); +} + +#define SWITCH2_CONTROLLER(vend, prod) \ + USB_DEVICE_AND_INTERFACE_INFO(vend, prod, USB_CLASS_VENDOR_SPEC, 0, 0) + +static const struct usb_device_id switch2_usb_devices[] = { + { SWITCH2_CONTROLLER(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_NS2_JOYCONL) }, + { SWITCH2_CONTROLLER(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_NS2_JOYCONR) }, + { SWITCH2_CONTROLLER(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_NS2_PROCON) }, + { SWITCH2_CONTROLLER(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_NS2_GCCON) }, + { } +}; +MODULE_DEVICE_TABLE(usb, switch2_usb_devices); + +static struct usb_driver switch2_usb = { + .name = "nintendo-switch2", + .id_table = switch2_usb_devices, + .probe = switch2_usb_probe, + .disconnect = switch2_usb_disconnect, +}; +module_usb_driver(switch2_usb); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Vicki Pfau <vi@endrift.com>"); +MODULE_DESCRIPTION("Driver for Nintendo Switch 2 Controllers");
diff --git a/drivers/hid/hid-nintendo.c b/drivers/hid/hid-nintendo.c index 43e0f2a..4d40f67 100644 --- a/drivers/hid/hid-nintendo.c +++ b/drivers/hid/hid-nintendo.c
@@ -1,11 +1,13 @@ // SPDX-License-Identifier: GPL-2.0+ /* - * HID driver for Nintendo Switch Joy-Cons and Pro Controllers + * HID driver for Nintendo Switch Joy-Cons and Pro Controllers, as well as + * Nintendo Switch 2 Joy-Cons, Pro Controller, and GameCube Controller * * Copyright (c) 2019-2021 Daniel J. Ogorchock <djogorchock@gmail.com> * Portions Copyright (c) 2020 Nadia Holmquist Pedersen <nadia@nhp.sh> * Copyright (c) 2022 Emily Strickland <linux@emily.st> * Copyright (c) 2023 Ryan McClelland <rymcclel@gmail.com> + * Copyright (c) 2026 Valve Software * * The following resources/projects were referenced for this driver: * https://github.com/dekuNukem/Nintendo_Switch_Reverse_Engineering @@ -13,6 +15,8 @@ * https://github.com/FrotBot/SwitchProConLinuxUSB * https://github.com/MTCKC/ProconXInput * https://github.com/Davidobot/BetterJoyForCemu + * https://gist.github.com/shinyquagsire23/66f006b46c56216acbaac6c1e2279b64 + * https://github.com/ndeadly/switch2_controller_research * hid-wiimote kernel hid driver * hid-logitech-hidpp driver * hid-sony driver @@ -29,9 +33,11 @@ */ #include "hid-ids.h" +#include "hid-nintendo.h" #include <linux/unaligned.h> #include <linux/delay.h> #include <linux/device.h> +#include <linux/devm-helpers.h> #include <linux/kernel.h> #include <linux/hid.h> #include <linux/idr.h> @@ -41,6 +47,8 @@ #include <linux/module.h> #include <linux/power_supply.h> #include <linux/spinlock.h> +#include <linux/usb.h> +#include "usbhid/usbhid.h" /* * Reference the url below for the following HID report defines: @@ -434,8 +442,8 @@ static const struct joycon_ctlr_button_mapping procon_button_mappings[] = { { /* sentinel */ }, }; -/* Licensed Pro Controllers (e.g. HORI) swap X/Y bits in the report */ -static const struct joycon_ctlr_button_mapping lic_procon_button_mappings[] = { +/* HORI Licensed Pro Controllers swap X/Y bits in the report */ +static const struct joycon_ctlr_button_mapping lic_hori_procon_button_mappings[] = { { BTN_EAST, JC_BTN_A, }, { BTN_SOUTH, JC_BTN_B, }, { BTN_NORTH, JC_BTN_Y, }, @@ -1767,8 +1775,8 @@ static void joycon_parse_report(struct joycon_ctlr *ctlr, joycon_report_left_stick(ctlr, rep); joycon_report_right_stick(ctlr, rep); joycon_report_dpad(ctlr, rep); - if (ctlr->ctlr_type == JOYCON_CTLR_TYPE_LIC_PRO) - joycon_report_buttons(ctlr, rep, lic_procon_button_mappings); + if (ctlr->hdev->vendor == USB_VENDOR_ID_HORI) + joycon_report_buttons(ctlr, rep, lic_hori_procon_button_mappings); else joycon_report_buttons(ctlr, rep, procon_button_mappings); } else if (joycon_type_is_any_nescon(ctlr)) { @@ -2212,8 +2220,8 @@ static int joycon_input_create(struct joycon_ctlr *ctlr) joycon_config_left_stick(ctlr->input); joycon_config_right_stick(ctlr->input); joycon_config_dpad(ctlr->input); - if (ctlr->ctlr_type == JOYCON_CTLR_TYPE_LIC_PRO) - joycon_config_buttons(ctlr->input, lic_procon_button_mappings); + if (ctlr->hdev->vendor == USB_VENDOR_ID_HORI) + joycon_config_buttons(ctlr->input, lic_hori_procon_button_mappings); else joycon_config_buttons(ctlr->input, procon_button_mappings); } else if (joycon_type_is_any_nescon(ctlr)) { @@ -2703,7 +2711,7 @@ static int joycon_ctlr_handle_event(struct joycon_ctlr *ctlr, u8 *data, return ret; } -static int nintendo_hid_event(struct hid_device *hdev, +static int joycon_event(struct hid_device *hdev, struct hid_report *report, u8 *raw_data, int size) { struct joycon_ctlr *ctlr = hid_get_drvdata(hdev); @@ -2714,7 +2722,7 @@ static int nintendo_hid_event(struct hid_device *hdev, return joycon_ctlr_handle_event(ctlr, raw_data, size); } -static int nintendo_hid_probe(struct hid_device *hdev, +static int joycon_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; @@ -2819,7 +2827,7 @@ static int nintendo_hid_probe(struct hid_device *hdev, return ret; } -static void nintendo_hid_remove(struct hid_device *hdev) +static void joycon_remove(struct hid_device *hdev) { struct joycon_ctlr *ctlr = hid_get_drvdata(hdev); unsigned long flags; @@ -2838,7 +2846,7 @@ static void nintendo_hid_remove(struct hid_device *hdev) hid_hw_stop(hdev); } -static int nintendo_hid_resume(struct hid_device *hdev) +static int joycon_resume(struct hid_device *hdev) { struct joycon_ctlr *ctlr = hid_get_drvdata(hdev); int ret; @@ -2861,7 +2869,7 @@ static int nintendo_hid_resume(struct hid_device *hdev) return ret; } -static int nintendo_hid_suspend(struct hid_device *hdev, pm_message_t message) +static int joycon_suspend(struct hid_device *hdev, pm_message_t message) { struct joycon_ctlr *ctlr = hid_get_drvdata(hdev); @@ -2880,7 +2888,1559 @@ static int nintendo_hid_suspend(struct hid_device *hdev, pm_message_t message) return 0; } +/* + * ============================================================================= + * Switch 2 support + * ============================================================================= + */ +#define NS2_BTNR_B BIT(0) +#define NS2_BTNR_A BIT(1) +#define NS2_BTNR_Y BIT(2) +#define NS2_BTNR_X BIT(3) +#define NS2_BTNR_R BIT(4) +#define NS2_BTNR_ZR BIT(5) +#define NS2_BTNR_PLUS BIT(6) +#define NS2_BTNR_RS BIT(7) + +#define NS2_BTNL_DOWN BIT(0) +#define NS2_BTNL_RIGHT BIT(1) +#define NS2_BTNL_LEFT BIT(2) +#define NS2_BTNL_UP BIT(3) +#define NS2_BTNL_L BIT(4) +#define NS2_BTNL_ZL BIT(5) +#define NS2_BTNL_MINUS BIT(6) +#define NS2_BTNL_LS BIT(7) + +#define NS2_BTN3_C BIT(4) +#define NS2_BTN3_SR BIT(6) +#define NS2_BTN3_SL BIT(7) + +#define NS2_BTN_U1_Y BIT(0) +#define NS2_BTN_U1_X BIT(1) +#define NS2_BTN_U1_B BIT(2) +#define NS2_BTN_U1_A BIT(3) +#define NS2_BTN_U1_SR BIT(4) +#define NS2_BTN_U1_SL BIT(5) +#define NS2_BTN_U1_R BIT(6) +#define NS2_BTN_U1_ZR BIT(7) + +#define NS2_BTN_U2_MINUS BIT(0) +#define NS2_BTN_U2_PLUS BIT(1) +#define NS2_BTN_U2_RS BIT(2) +#define NS2_BTN_U2_LS BIT(3) +#define NS2_BTN_U2_HOME BIT(4) +#define NS2_BTN_U2_CAPTURE BIT(5) +#define NS2_BTN_U2_C BIT(6) + +#define NS2_BTN_U3_DOWN BIT(0) +#define NS2_BTN_U3_UP BIT(1) +#define NS2_BTN_U3_RIGHT BIT(2) +#define NS2_BTN_U3_LEFT BIT(3) +#define NS2_BTN_U3_SR BIT(4) +#define NS2_BTN_U3_SL BIT(5) +#define NS2_BTN_U3_L BIT(6) +#define NS2_BTN_U3_ZL BIT(7) + +#define NS2_BTN_U4_GR BIT(0) +#define NS2_BTN_U4_GL BIT(1) +#define NS2_BTN_U4_HEADSET BIT(5) + +#define NS2_BTN_JCR_HOME BIT(0) +#define NS2_BTN_JCR_GR BIT(2) +#define NS2_BTN_JCR_C NS2_BTN3_C +#define NS2_BTN_JCR_SR NS2_BTN3_SR +#define NS2_BTN_JCR_SL NS2_BTN3_SL + +#define NS2_BTN_JCL_CAPTURE BIT(0) +#define NS2_BTN_JCL_GL BIT(2) +#define NS2_BTN_JCL_SR NS2_BTN3_SR +#define NS2_BTN_JCL_SL NS2_BTN3_SL + +#define NS2_BTN_PRO_HOME BIT(0) +#define NS2_BTN_PRO_CAPTURE BIT(1) +#define NS2_BTN_PRO_GR BIT(2) +#define NS2_BTN_PRO_GL BIT(3) +#define NS2_BTN_PRO_C NS2_BTN3_C + +#define NS2_BTN_GC_HOME BIT(0) +#define NS2_BTN_GC_CAPTURE BIT(1) +#define NS2_BTN_GC_C NS2_BTN3_C + +#define NS2_TRIGGER_RANGE 4095 +#define NS2_AXIS_MIN -32768 +#define NS2_AXIS_MAX 32767 + +#define NS2_MAX_PLAYER_ID 8 + +#define NS2_MAX_INIT_RETRIES 4 + +#define NS2_FLASH_ADDR_SERIAL 0x13002 +#define NS2_FLASH_ADDR_FACTORY_PRIMARY_CALIB 0x130a8 +#define NS2_FLASH_ADDR_FACTORY_SECONDARY_CALIB 0x130e8 +#define NS2_FLASH_ADDR_FACTORY_TRIGGER_CALIB 0x13140 +#define NS2_FLASH_ADDR_USER_PRIMARY_CALIB 0x1fc040 +#define NS2_FLASH_ADDR_USER_SECONDARY_CALIB 0x1fc080 + +#define NS2_FLASH_SIZE_SERIAL 0x10 +#define NS2_FLASH_SIZE_FACTORY_AXIS_CALIB 9 +#define NS2_FLASH_SIZE_FACTORY_TRIGGER_CALIB 2 +#define NS2_FLASH_SIZE_USER_AXIS_CALIB 11 + +#define NS2_USER_CALIB_MAGIC 0xa1b2 + +#define NS2_FEATURE_BUTTONS BIT(0) +#define NS2_FEATURE_ANALOG BIT(1) +#define NS2_FEATURE_IMU BIT(2) +#define NS2_FEATURE_MOUSE BIT(4) +#define NS2_FEATURE_RUMBLE BIT(5) +#define NS2_FEATURE_MAGNETO BIT(7) + +enum switch2_subcmd_flash { + NS2_SUBCMD_FLASH_READ_BLOCK = 0x01, + NS2_SUBCMD_FLASH_WRITE_BLOCK = 0x02, + NS2_SUBCMD_FLASH_ERASE_BLOCK = 0x03, + NS2_SUBCMD_FLASH_READ = 0x04, + NS2_SUBCMD_FLASH_WRITE = 0x05, +}; + +enum switch2_subcmd_init { + NS2_SUBCMD_INIT_SELECT_REPORT = 0xa, + NS2_SUBCMD_INIT_USB = 0xd, +}; + +enum switch2_subcmd_feature_select { + NS2_SUBCMD_FEATSEL_GET_INFO = 0x1, + NS2_SUBCMD_FEATSEL_SET_MASK = 0x2, + NS2_SUBCMD_FEATSEL_CLEAR_MASK = 0x3, + NS2_SUBCMD_FEATSEL_ENABLE = 0x4, + NS2_SUBCMD_FEATSEL_DISABLE = 0x5, +}; + +enum switch2_subcmd_grip { + NS2_SUBCMD_GRIP_GET_INFO = 0x1, + NS2_SUBCMD_GRIP_ENABLE_BUTTONS = 0x2, + NS2_SUBCMD_GRIP_GET_INFO_EXT = 0x3, +}; + +enum switch2_subcmd_led { + NS2_SUBCMD_LED_P1 = 0x1, + NS2_SUBCMD_LED_P2 = 0x2, + NS2_SUBCMD_LED_P3 = 0x3, + NS2_SUBCMD_LED_P4 = 0x4, + NS2_SUBCMD_LED_ALL_ON = 0x5, + NS2_SUBCMD_LED_ALL_OFF = 0x6, + NS2_SUBCMD_LED_PATTERN = 0x7, + NS2_SUBCMD_LED_BLINK = 0x8, +}; + +enum switch2_subcmd_fw_info { + NS2_SUBCMD_FW_INFO_GET = 0x1, +}; + +enum switch2_ctlr_type { + NS2_CTLR_TYPE_JCL = 0x00, + NS2_CTLR_TYPE_JCR = 0x01, + NS2_CTLR_TYPE_PRO = 0x02, + NS2_CTLR_TYPE_GC = 0x03, +}; + +enum switch2_report_id { + NS2_REPORT_UNIFIED = 0x05, + NS2_REPORT_JCL = 0x07, + NS2_REPORT_JCR = 0x08, + NS2_REPORT_PRO = 0x09, + NS2_REPORT_GC = 0x0a, +}; + +enum switch2_init_step { + NS2_INIT_READ_SERIAL, + NS2_INIT_GET_FIRMWARE_INFO, + NS2_INIT_READ_FACTORY_PRIMARY_CALIB, + NS2_INIT_READ_FACTORY_SECONDARY_CALIB, + NS2_INIT_READ_FACTORY_TRIGGER_CALIB, + NS2_INIT_READ_USER_PRIMARY_CALIB, + NS2_INIT_READ_USER_SECONDARY_CALIB, + NS2_INIT_SET_FEATURE_MASK, + NS2_INIT_ENABLE_FEATURES, + NS2_INIT_ENABLE_RUMBLE, + NS2_INIT_GRIP_BUTTONS, + NS2_INIT_REPORT_FORMAT, + NS2_INIT_INPUT, + NS2_INIT_SET_PLAYER_LEDS, + NS2_INIT_FINISH, + NS2_INIT_DONE, +}; + +struct switch2_version_info { + uint8_t major; + uint8_t minor; + uint8_t patch; + uint8_t ctlr_type; + __le32 unk; + int8_t dsp_major; + int8_t dsp_minor; + int8_t dsp_patch; + int8_t dsp_type; +}; + +struct switch2_axis_calibration { + uint16_t neutral; + uint16_t negative; + uint16_t positive; +}; + +struct switch2_stick_calibration { + struct switch2_axis_calibration x; + struct switch2_axis_calibration y; +}; + +struct switch2_hd_rumble { + uint16_t hi_freq : 10; + uint16_t hi_amp : 10; + uint16_t lo_freq : 10; + uint16_t lo_amp : 10; +} __packed; + +struct switch2_erm_rumble { + uint16_t error; + uint16_t amplitude; +}; + +struct switch2_controller { + struct hid_device *hdev; + struct switch2_cfg_intf *cfg; + struct kref refcount; + + char name[64]; + char phys[64]; + struct list_head entry; + struct mutex lock; + + enum switch2_ctlr_type ctlr_type; + enum switch2_init_step init_step; + int init_retries; + struct input_dev __rcu *input; + char serial[NS2_FLASH_SIZE_SERIAL + 1]; + struct switch2_version_info version; + + struct switch2_stick_calibration stick_calib[2]; + uint8_t lt_zero; + uint8_t rt_zero; + + uint32_t player_id; + struct led_classdev *leds; + +#if IS_ENABLED(CONFIG_NINTENDO_FF) + spinlock_t rumble_lock; + uint8_t rumble_seq; + union { + struct switch2_hd_rumble hd; + struct switch2_erm_rumble sd; + } rumble; + uint64_t last_rumble_work; + struct delayed_work rumble_work; + uint8_t *rumble_buffer; +#endif +}; + +enum gc_rumble { + GC_RUMBLE_OFF = 0, + GC_RUMBLE_ON = 1, + GC_RUMBLE_STOP = 2, +}; + +/* + * The highest rumble level for "HD Rumble" is strong enough to potentially damage the controller, + * and also leaves your hands feeling like melted jelly, so we set a semi-arbitrary scaling factor + * to artificially limit the maximum for safety and comfort. It is currently unknown if the Switch + * 2 itself does something similar, but it's quite likely. + * + * This value must be between 0 and 1024, otherwise the math below will overflow. + */ +#define RUMBLE_MAX 450u + +/* + * Semi-arbitrary values used to simulate the "rumble" sensation of an eccentric rotating + * mass type haptic motor on the Switch 2 controllers' linear resonant actuator type haptics. + * + * The units used are unknown, but the values must be between 0 and 1023. + */ +#define RUMBLE_HI_FREQ 0x187 +#define RUMBLE_LO_FREQ 0x112 + +static DEFINE_MUTEX(switch2_controllers_lock); +static LIST_HEAD(switch2_controllers); + +struct switch2_ctlr_button_mapping { + uint32_t code; + int byte; + uint32_t bit; +}; + +static const struct switch2_ctlr_button_mapping ns2_left_joycon_button_mappings[] = { + { BTN_DPAD_LEFT, 0, NS2_BTNL_LEFT, }, + { BTN_DPAD_UP, 0, NS2_BTNL_UP, }, + { BTN_DPAD_DOWN, 0, NS2_BTNL_DOWN, }, + { BTN_DPAD_RIGHT, 0, NS2_BTNL_RIGHT, }, + { BTN_TL, 0, NS2_BTNL_L, }, + { BTN_TL2, 0, NS2_BTNL_ZL, }, + { BTN_SELECT, 0, NS2_BTNL_MINUS, }, + { BTN_THUMBL, 0, NS2_BTNL_LS, }, + { KEY_RECORD, 1, NS2_BTN_JCL_CAPTURE, }, + { BTN_GRIPR, 1, NS2_BTN_JCL_SL, }, + { BTN_GRIPR2, 1, NS2_BTN_JCL_SR, }, + { BTN_GRIPL, 1, NS2_BTN_JCL_GL, }, + { /* sentinel */ }, +}; + +static const struct switch2_ctlr_button_mapping ns2_left_joycon_button_unified_mappings[] = { + { BTN_DPAD_LEFT, 2, NS2_BTN_U3_LEFT, }, + { BTN_DPAD_UP, 2, NS2_BTN_U3_UP, }, + { BTN_DPAD_DOWN, 2, NS2_BTN_U3_DOWN, }, + { BTN_DPAD_RIGHT, 2, NS2_BTN_U3_RIGHT, }, + { BTN_TL, 2, NS2_BTN_U3_L, }, + { BTN_TL2, 2, NS2_BTN_U3_ZL, }, + { BTN_SELECT, 1, NS2_BTN_U2_MINUS, }, + { BTN_THUMBL, 1, NS2_BTN_U2_LS, }, + { KEY_RECORD, 1, NS2_BTN_U2_CAPTURE, }, + { BTN_GRIPR, 2, NS2_BTN_U3_SL, }, + { BTN_GRIPR2, 2, NS2_BTN_U3_SR, }, + { BTN_GRIPL, 3, NS2_BTN_U4_GL, }, + { /* sentinel */ }, +}; + +static const struct switch2_ctlr_button_mapping ns2_right_joycon_button_mappings[] = { + { BTN_SOUTH, 0, NS2_BTNR_A, }, + { BTN_EAST, 0, NS2_BTNR_B, }, + { BTN_NORTH, 0, NS2_BTNR_X, }, + { BTN_WEST, 0, NS2_BTNR_Y, }, + { BTN_TR, 0, NS2_BTNR_R, }, + { BTN_TR2, 0, NS2_BTNR_ZR, }, + { BTN_START, 0, NS2_BTNR_PLUS, }, + { BTN_THUMBR, 0, NS2_BTNR_RS, }, + { BTN_C, 1, NS2_BTN_JCR_C, }, + { BTN_MODE, 1, NS2_BTN_JCR_HOME, }, + { BTN_GRIPL2, 1, NS2_BTN_JCR_SL, }, + { BTN_GRIPL, 1, NS2_BTN_JCR_SR, }, + { BTN_GRIPR, 1, NS2_BTN_JCR_GR, }, + { /* sentinel */ }, +}; + +static const struct switch2_ctlr_button_mapping ns2_right_joycon_button_unified_mappings[] = { + { BTN_SOUTH, 0, NS2_BTN_U1_A, }, + { BTN_EAST, 0, NS2_BTN_U1_B, }, + { BTN_NORTH, 0, NS2_BTN_U1_X, }, + { BTN_WEST, 0, NS2_BTN_U1_Y, }, + { BTN_TR, 0, NS2_BTN_U1_R, }, + { BTN_TR2, 0, NS2_BTN_U1_ZR }, + { BTN_START, 1, NS2_BTN_U2_PLUS, }, + { BTN_THUMBR, 1, NS2_BTN_U2_RS, }, + { BTN_C, 1, NS2_BTN_U2_C, }, + { BTN_MODE, 1, NS2_BTN_U2_HOME, }, + { BTN_GRIPL2, 0, NS2_BTN_U1_SL, }, + { BTN_GRIPL, 0, NS2_BTN_U1_SR, }, + { BTN_GRIPR, 3, NS2_BTN_U4_GR, }, + { /* sentinel */ }, +}; + +static const struct switch2_ctlr_button_mapping ns2_procon_mappings[] = { + { BTN_SOUTH, 0, NS2_BTNR_A, }, + { BTN_EAST, 0, NS2_BTNR_B, }, + { BTN_NORTH, 0, NS2_BTNR_X, }, + { BTN_WEST, 0, NS2_BTNR_Y, }, + { BTN_TL, 1, NS2_BTNL_L, }, + { BTN_TR, 0, NS2_BTNR_R, }, + { BTN_TL2, 1, NS2_BTNL_ZL, }, + { BTN_TR2, 0, NS2_BTNR_ZR, }, + { BTN_SELECT, 1, NS2_BTNL_MINUS, }, + { BTN_START, 0, NS2_BTNR_PLUS, }, + { BTN_THUMBL, 1, NS2_BTNL_LS, }, + { BTN_THUMBR, 0, NS2_BTNR_RS, }, + { BTN_MODE, 2, NS2_BTN_PRO_HOME }, + { KEY_RECORD, 2, NS2_BTN_PRO_CAPTURE }, + { BTN_GRIPR, 2, NS2_BTN_PRO_GR }, + { BTN_GRIPL, 2, NS2_BTN_PRO_GL }, + { BTN_C, 2, NS2_BTN_PRO_C }, + { /* sentinel */ }, +}; + +static const struct switch2_ctlr_button_mapping ns2_procon_unified_mappings[] = { + { BTN_SOUTH, 0, NS2_BTN_U1_A, }, + { BTN_EAST, 0, NS2_BTN_U1_B, }, + { BTN_NORTH, 0, NS2_BTN_U1_X, }, + { BTN_WEST, 0, NS2_BTN_U1_Y, }, + { BTN_TL, 2, NS2_BTN_U3_L, }, + { BTN_TR, 0, NS2_BTN_U1_R, }, + { BTN_TL2, 2, NS2_BTN_U3_ZL, }, + { BTN_TR2, 0, NS2_BTN_U1_ZR, }, + { BTN_SELECT, 1, NS2_BTN_U2_MINUS, }, + { BTN_START, 1, NS2_BTN_U2_PLUS, }, + { BTN_THUMBL, 1, NS2_BTN_U2_LS, }, + { BTN_THUMBR, 1, NS2_BTN_U2_RS, }, + { BTN_MODE, 1, NS2_BTN_U2_HOME }, + { KEY_RECORD, 1, NS2_BTN_U2_CAPTURE }, + { BTN_GRIPR, 3, NS2_BTN_U4_GR }, + { BTN_GRIPL, 3, NS2_BTN_U4_GL }, + { BTN_C, 1, NS2_BTN_U2_C }, + { /* sentinel */ }, +}; + +static const struct switch2_ctlr_button_mapping ns2_gccon_mappings[] = { + { BTN_SOUTH, 0, NS2_BTNR_A, }, + { BTN_EAST, 0, NS2_BTNR_B, }, + { BTN_NORTH, 0, NS2_BTNR_X, }, + { BTN_WEST, 0, NS2_BTNR_Y, }, + { BTN_TL2, 1, NS2_BTNL_L, }, + { BTN_TR2, 0, NS2_BTNR_R, }, + { BTN_TL, 1, NS2_BTNL_ZL, }, + { BTN_TR, 0, NS2_BTNR_ZR, }, + { BTN_SELECT, 1, NS2_BTNL_MINUS, }, + { BTN_START, 0, NS2_BTNR_PLUS, }, + { BTN_MODE, 2, NS2_BTN_GC_HOME }, + { KEY_RECORD, 2, NS2_BTN_GC_CAPTURE }, + { BTN_C, 2, NS2_BTN_GC_C }, + { /* sentinel */ }, +}; + +static const struct switch2_ctlr_button_mapping ns2_gccon_unified_mappings[] = { + { BTN_SOUTH, 0, NS2_BTN_U1_A, }, + { BTN_EAST, 0, NS2_BTN_U1_B, }, + { BTN_NORTH, 0, NS2_BTN_U1_X, }, + { BTN_WEST, 0, NS2_BTN_U1_Y, }, + { BTN_TL2, 2, NS2_BTN_U3_L, }, + { BTN_TR2, 0, NS2_BTN_U1_R, }, + { BTN_TL, 2, NS2_BTN_U3_ZL }, + { BTN_TR, 0, NS2_BTN_U1_ZR }, + { BTN_SELECT, 1, NS2_BTN_U2_MINUS, }, + { BTN_START, 1, NS2_BTN_U2_PLUS, }, + { BTN_MODE, 1, NS2_BTN_U2_HOME }, + { KEY_RECORD, 1, NS2_BTN_U2_CAPTURE }, + { BTN_C, 1, NS2_BTN_U2_C }, + { /* sentinel */ }, +}; + +static const uint8_t switch2_init_cmd_data[] = { + /* + * The last 6 bytes of this packet are the MAC address of + * the console, but we don't need that for USB + */ + 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF +}; + +static const uint8_t switch2_one_data[] = { 0x01, 0x00, 0x00, 0x00 }; + +static const uint8_t switch2_feature_mask[] = { + NS2_FEATURE_BUTTONS | NS2_FEATURE_ANALOG | NS2_FEATURE_IMU | NS2_FEATURE_RUMBLE, + 0x00, 0x00, 0x00 +}; + +static int switch2_init_controller(struct switch2_controller *ns2); + +static void switch2_init_step_done(struct switch2_controller *ns2, enum switch2_init_step step) +{ + if (ns2->init_step != step) + return; + + ns2->init_retries = 0; + ns2->init_step++; +} + +static inline bool switch2_ctlr_is_joycon(enum switch2_ctlr_type type) +{ + return type == NS2_CTLR_TYPE_JCL || type == NS2_CTLR_TYPE_JCR; +} + +static struct switch2_controller *switch2_get_controller(const char *phys) +{ + struct switch2_controller *ns2; + + guard(mutex)(&switch2_controllers_lock); + list_for_each_entry(ns2, &switch2_controllers, entry) { + if (strncmp(ns2->phys, phys, sizeof(ns2->phys)) == 0) { + if (kref_get_unless_zero(&ns2->refcount)) + return ns2; + } + } + ns2 = kzalloc_obj(*ns2); + if (!ns2) + return ERR_PTR(-ENOMEM); + + kref_init(&ns2->refcount); + mutex_init(&ns2->lock); + INIT_LIST_HEAD(&ns2->entry); + list_add(&ns2->entry, &switch2_controllers); + strscpy(ns2->phys, phys, sizeof(ns2->phys)); +#if IS_ENABLED(CONFIG_NINTENDO_FF) + spin_lock_init(&ns2->rumble_lock); +#endif + return ns2; +} + +static void switch2_controller_put(struct switch2_controller *ns2) +{ + struct input_dev *input; + + mutex_lock(&ns2->lock); + rcu_read_lock(); + input = rcu_dereference(ns2->input); + rcu_read_unlock(); + + rcu_assign_pointer(ns2->input, NULL); + synchronize_rcu(); + + ns2->init_step = 0; + mutex_unlock(&ns2->lock); + + if (input) + input_unregister_device(input); +} + +static void switch2_kref_put(struct kref *refcount) +{ + struct switch2_controller *ns2 = container_of(refcount, + struct switch2_controller, refcount); + + guard(mutex)(&switch2_controllers_lock); + list_del_init(&ns2->entry); + mutex_destroy(&ns2->lock); + kfree(ns2); +} + +#if IS_ENABLED(CONFIG_NINTENDO_FF) +static void switch2_encode_rumble(struct switch2_hd_rumble *rumble, uint8_t buffer[5]) +{ + buffer[0] = rumble->hi_freq; + buffer[1] = (rumble->hi_freq >> 8) | (rumble->hi_amp << 2); + buffer[2] = (rumble->hi_amp >> 6) | (rumble->lo_freq << 4); + buffer[3] = (rumble->lo_freq >> 4) | (rumble->lo_amp << 6); + buffer[4] = rumble->lo_amp >> 2; +} + +static int switch2_play_effect(struct input_dev *dev, void *data, struct ff_effect *effect) +{ + struct switch2_controller *ns2 = input_get_drvdata(dev); + unsigned long flags; + + if (effect->type != FF_RUMBLE) + return 0; + + if (!ns2) + return -ENODEV; + + spin_lock_irqsave(&ns2->rumble_lock, flags); + if (ns2->ctlr_type == NS2_CTLR_TYPE_GC) { + ns2->rumble.sd.amplitude = max(effect->u.rumble.strong_magnitude, + (uint16_t) (effect->u.rumble.weak_magnitude >> 1)); + } else { + ns2->rumble.hd.hi_freq = RUMBLE_HI_FREQ; + ns2->rumble.hd.lo_freq = RUMBLE_LO_FREQ; + ns2->rumble.hd.hi_amp = effect->u.rumble.weak_magnitude * RUMBLE_MAX >> 16; + ns2->rumble.hd.lo_amp = effect->u.rumble.strong_magnitude * RUMBLE_MAX >> 16; + } + spin_unlock_irqrestore(&ns2->rumble_lock, flags); + + schedule_delayed_work(&ns2->rumble_work, 0); + + return 0; +} + +static void switch2_rumble_work(struct work_struct *work) +{ + struct switch2_controller *ns2 = container_of(to_delayed_work(work), + struct switch2_controller, rumble_work); + unsigned long flags; + bool active; + int ret = 0; + + spin_lock_irqsave(&ns2->rumble_lock, flags); + ns2->rumble_buffer[0x1] = 0x50 | ns2->rumble_seq; + if (ns2->ctlr_type == NS2_CTLR_TYPE_GC) { + ns2->rumble_buffer[0] = 3; + if (ns2->rumble.sd.amplitude == 0) { + ns2->rumble_buffer[2] = GC_RUMBLE_STOP; + ns2->rumble.sd.error = 0; + active = false; + } else { + if (ns2->rumble.sd.error < ns2->rumble.sd.amplitude) { + ns2->rumble_buffer[2] = GC_RUMBLE_ON; + ns2->rumble.sd.error += U16_MAX - ns2->rumble.sd.amplitude; + } else { + ns2->rumble_buffer[2] = GC_RUMBLE_OFF; + ns2->rumble.sd.error -= ns2->rumble.sd.amplitude; + } + active = true; + } + } else { + ns2->rumble_buffer[0] = 1; + switch2_encode_rumble(&ns2->rumble.hd, &ns2->rumble_buffer[0x2]); + active = ns2->rumble.hd.hi_amp || ns2->rumble.hd.lo_amp; + if (ns2->ctlr_type == NS2_CTLR_TYPE_PRO) { + /* + * The Pro Controller contains separate LRAs on each + * side that can be controlled individually. + */ + ns2->rumble_buffer[0] = 2; + ns2->rumble_buffer[0x11] = 0x50 | ns2->rumble_seq; + switch2_encode_rumble(&ns2->rumble.hd, &ns2->rumble_buffer[0x12]); + } + } + ns2->rumble_seq = (ns2->rumble_seq + 1) & 0xF; + spin_unlock_irqrestore(&ns2->rumble_lock, flags); + + if (active) { + unsigned long interval = msecs_to_jiffies(4); + uint64_t current_jiffies = get_jiffies_64(); + + if (!ns2->last_rumble_work) + ns2->last_rumble_work = current_jiffies; + else + ns2->last_rumble_work += interval; + + /* Reschedule a little early to make sure the buffer never underruns */ + interval -= msecs_to_jiffies(2); + if (ns2->last_rumble_work + interval >= current_jiffies) + schedule_delayed_work(&ns2->rumble_work, + ns2->last_rumble_work + interval - current_jiffies); + else + schedule_delayed_work(&ns2->rumble_work, 0); + } else { + ns2->last_rumble_work = 0; + } + + mutex_lock(&ns2->lock); + if (!ns2->hdev) { + cancel_delayed_work(&ns2->rumble_work); + } else { + ret = hid_hw_output_report(ns2->hdev, ns2->rumble_buffer, 64); + /* + * Don't log on ENODEV, ESHUTDOWN, or EPROTO, which can happen + * mid-hotplug. Also cancel any further work on ENODEV or + * ESHUTDOWN as they're clear indications that the endpoint + * is dead. + */ + if (ret == -ENODEV || ret == -ESHUTDOWN) + cancel_delayed_work(&ns2->rumble_work); + else if (ret < 0 && ret != -EPROTO) + hid_warn_ratelimited(ns2->hdev, + "Failed to send output report ret=%d\n", ret); + } + mutex_unlock(&ns2->lock); +} +#endif + +static int switch2_set_leds(struct switch2_controller *ns2) +{ + int i; + uint8_t message[8] = { 0 }; + + for (i = 0; i < JC_NUM_LEDS; i++) + message[0] |= (!!ns2->leds[i].brightness) << i; + + if (!ns2->cfg) + return -ENOTCONN; + return ns2->cfg->send_command(NS2_CMD_LED, NS2_SUBCMD_LED_PATTERN, + &message, sizeof(message), + ns2->cfg); +} + +static int switch2_player_led_brightness_set(struct led_classdev *led, + enum led_brightness brightness) +{ + struct device *dev = led->dev->parent; + struct input_dev *input = to_input_dev(dev); + struct switch2_controller *ns2 = input_get_drvdata(input); + + if (!ns2) + return -ENODEV; + + guard(mutex)(&ns2->lock); + return switch2_set_leds(ns2); +} + +static void switch2_config_buttons(struct input_dev *idev, + const struct switch2_ctlr_button_mapping button_mappings[]) +{ + const struct switch2_ctlr_button_mapping *button; + + for (button = button_mappings; button->code; button++) + input_set_capability(idev, EV_KEY, button->code); +} + +static int switch2_input_ref(struct input_dev *input) +{ + struct switch2_controller *ns2 = input_get_drvdata(input); + + kref_get(&ns2->refcount); + + return 0; +} + +static void switch2_input_deref(struct input_dev *input) +{ + struct switch2_controller *ns2 = input_get_drvdata(input); + + kref_put(&ns2->refcount, switch2_kref_put); +} + +static int switch2_init_input(struct switch2_controller *ns2) +{ + struct input_dev *input; + struct hid_device *hdev = ns2->hdev; + int player_led_pattern; + int i; + int ret; + + rcu_read_lock(); + input = rcu_dereference(ns2->input); + rcu_read_unlock(); + + if (input) { + switch2_init_step_done(ns2, NS2_INIT_INPUT); + return 0; + } + + input = input_allocate_device(); + if (!input) + return -ENOMEM; + + input_set_drvdata(input, ns2); + input->open = switch2_input_ref; + input->close = switch2_input_deref; + input->dev.parent = &hdev->dev; + input->id.bustype = hdev->bus; + input->id.vendor = hdev->vendor; + input->id.product = hdev->product; + input->id.version = hdev->version; + input->uniq = ns2->serial; + input->name = ns2->name; + input->phys = hdev->phys; + + switch (ns2->ctlr_type) { + case NS2_CTLR_TYPE_JCL: + input_set_abs_params(input, ABS_X, NS2_AXIS_MIN, NS2_AXIS_MAX, 32, 128); + input_set_abs_params(input, ABS_Y, NS2_AXIS_MIN, NS2_AXIS_MAX, 32, 128); + switch2_config_buttons(input, ns2_left_joycon_button_mappings); + break; + case NS2_CTLR_TYPE_JCR: + input_set_abs_params(input, ABS_X, NS2_AXIS_MIN, NS2_AXIS_MAX, 32, 128); + input_set_abs_params(input, ABS_Y, NS2_AXIS_MIN, NS2_AXIS_MAX, 32, 128); + switch2_config_buttons(input, ns2_right_joycon_button_mappings); + break; + case NS2_CTLR_TYPE_GC: + input_set_abs_params(input, ABS_X, NS2_AXIS_MIN, NS2_AXIS_MAX, 32, 128); + input_set_abs_params(input, ABS_Y, NS2_AXIS_MIN, NS2_AXIS_MAX, 32, 128); + input_set_abs_params(input, ABS_RX, NS2_AXIS_MIN, NS2_AXIS_MAX, 32, 128); + input_set_abs_params(input, ABS_RY, NS2_AXIS_MIN, NS2_AXIS_MAX, 32, 128); + input_set_abs_params(input, ABS_Z, 0, NS2_TRIGGER_RANGE, 32, 128); + input_set_abs_params(input, ABS_RZ, 0, NS2_TRIGGER_RANGE, 32, 128); + input_set_abs_params(input, ABS_HAT0X, -1, 1, 0, 0); + input_set_abs_params(input, ABS_HAT0Y, -1, 1, 0, 0); + switch2_config_buttons(input, ns2_gccon_mappings); + break; + case NS2_CTLR_TYPE_PRO: + input_set_abs_params(input, ABS_X, NS2_AXIS_MIN, NS2_AXIS_MAX, 32, 128); + input_set_abs_params(input, ABS_Y, NS2_AXIS_MIN, NS2_AXIS_MAX, 32, 128); + input_set_abs_params(input, ABS_RX, NS2_AXIS_MIN, NS2_AXIS_MAX, 32, 128); + input_set_abs_params(input, ABS_RY, NS2_AXIS_MIN, NS2_AXIS_MAX, 32, 128); + input_set_abs_params(input, ABS_HAT0X, -1, 1, 0, 0); + input_set_abs_params(input, ABS_HAT0Y, -1, 1, 0, 0); + switch2_config_buttons(input, ns2_procon_mappings); + break; + default: + input_free_device(input); + return -EINVAL; + } + +#if IS_ENABLED(CONFIG_NINTENDO_FF) + ns2->rumble_buffer = devm_kzalloc(&input->dev, 64, GFP_KERNEL); + if (!ns2->rumble_buffer) { + input_free_device(input); + return -ENOMEM; + } + ret = devm_delayed_work_autocancel(&input->dev, &ns2->rumble_work, switch2_rumble_work); + if (ret < 0) { + input_free_device(input); + return ret; + } + + input_set_capability(input, EV_FF, FF_RUMBLE); + ret = input_ff_create_memless(input, NULL, switch2_play_effect); + if (ret) { + input_free_device(input); + return ret; + } +#endif + + hid_info(ns2->hdev, "Firmware version %u.%u.%u (type %i)\n", ns2->version.major, + ns2->version.minor, ns2->version.patch, ns2->version.ctlr_type); + if (ns2->version.dsp_type >= 0) + hid_info(ns2->hdev, "DSP version %u.%u.%u\n", ns2->version.dsp_major, + ns2->version.dsp_minor, ns2->version.dsp_patch); + + ret = input_register_device(input); + if (ret < 0) { + hid_err(ns2->hdev, "Failed to register input; ret=%d\n", ret); + input_free_device(input); + return ret; + } + + player_led_pattern = ns2->player_id % JC_NUM_LED_PATTERNS; + hid_dbg(hdev, "assigned player %d led pattern", player_led_pattern + 1); + + ns2->leds = devm_kcalloc(&input->dev, JC_NUM_LEDS, sizeof(*ns2->leds), GFP_KERNEL); + if (!ns2->leds) { + input_unregister_device(input); + return -ENOMEM; + } + + for (i = 0; i < JC_NUM_LEDS; i++) { + struct led_classdev *led = &ns2->leds[i]; + + led->brightness = joycon_player_led_patterns[player_led_pattern][i]; + led->max_brightness = 1; + led->brightness_set_blocking = switch2_player_led_brightness_set; + led->flags = LED_CORE_SUSPENDRESUME | LED_HW_PLUGGABLE | LED_RETAIN_AT_SHUTDOWN; + char *name = devm_kasprintf(&input->dev, GFP_KERNEL, "%s:%s:%s", + dev_name(&input->dev), + "green", + joycon_player_led_names[i]); + + if (!name) { + dev_err(&input->dev, "Failed to allocate name for player %d LED; ret=%d\n", + i + 1, ret); + break; + } + + led->name = name; + ret = devm_led_classdev_register(&input->dev, led); + if (ret < 0) { + dev_err(&input->dev, "Failed to register player %d LED; ret=%d\n", + i + 1, ret); + break; + } + } + + rcu_assign_pointer(ns2->input, input); + synchronize_rcu(); + + switch2_init_step_done(ns2, NS2_INIT_INPUT); + return switch2_init_controller(ns2); +} + +static bool switch2_parse_stick_calibration(struct switch2_stick_calibration *calib, + const uint8_t *data) +{ + static const uint8_t UNCALIBRATED[9] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF + }; + if (memcmp(UNCALIBRATED, data, sizeof(UNCALIBRATED)) == 0) + return false; + + calib->x.neutral = data[0]; + calib->x.neutral |= (data[1] & 0x0F) << 8; + + calib->y.neutral = data[1] >> 4; + calib->y.neutral |= data[2] << 4; + + calib->x.positive = data[3]; + calib->x.positive |= (data[4] & 0x0F) << 8; + + calib->y.positive = data[4] >> 4; + calib->y.positive |= data[5] << 4; + + calib->x.negative = data[6]; + calib->x.negative |= (data[7] & 0x0F) << 8; + + calib->y.negative = data[7] >> 4; + calib->y.negative |= data[8] << 4; + + return true; +} + +static void switch2_handle_flash_read(struct switch2_controller *ns2, uint8_t size, + uint32_t address, const uint8_t *data) +{ + bool ok; + + switch (address) { + case NS2_FLASH_ADDR_SERIAL: + if (size != NS2_FLASH_SIZE_SERIAL) + return; + memcpy(ns2->serial, data, size); + switch2_init_step_done(ns2, NS2_INIT_READ_SERIAL); + break; + case NS2_FLASH_ADDR_FACTORY_PRIMARY_CALIB: + if (size != NS2_FLASH_SIZE_FACTORY_AXIS_CALIB) + return; + switch2_init_step_done(ns2, NS2_INIT_READ_FACTORY_PRIMARY_CALIB); + ok = switch2_parse_stick_calibration(&ns2->stick_calib[0], data); + if (ns2->hdev) { + if (ok) { + hid_dbg(ns2->hdev, "Got factory primary stick calibration:\n"); + hid_dbg(ns2->hdev, "Left max: %i, neutral: %i, right max: %i\n", + ns2->stick_calib[0].x.negative, + ns2->stick_calib[0].x.neutral, + ns2->stick_calib[0].x.positive); + hid_dbg(ns2->hdev, "Down max: %i, neutral: %i, up max: %i\n", + ns2->stick_calib[0].y.negative, + ns2->stick_calib[0].y.neutral, + ns2->stick_calib[0].y.positive); + } else { + hid_dbg(ns2->hdev, "Factory primary stick calibration not present\n"); + } + } + break; + case NS2_FLASH_ADDR_FACTORY_SECONDARY_CALIB: + if (size != NS2_FLASH_SIZE_FACTORY_AXIS_CALIB) + return; + switch2_init_step_done(ns2, NS2_INIT_READ_FACTORY_SECONDARY_CALIB); + ok = switch2_parse_stick_calibration(&ns2->stick_calib[1], data); + if (ns2->hdev) { + if (ok) { + hid_dbg(ns2->hdev, "Got factory secondary stick calibration:\n"); + hid_dbg(ns2->hdev, "Left max: %i, neutral: %i, right max: %i\n", + ns2->stick_calib[1].x.negative, + ns2->stick_calib[1].x.neutral, + ns2->stick_calib[1].x.positive); + hid_dbg(ns2->hdev, "Down max: %i, neutral: %i, up max: %i\n", + ns2->stick_calib[1].y.negative, + ns2->stick_calib[1].y.neutral, + ns2->stick_calib[1].y.positive); + } else { + hid_dbg(ns2->hdev, "Factory secondary stick calibration not present\n"); + } + } + break; + case NS2_FLASH_ADDR_FACTORY_TRIGGER_CALIB: + if (size != NS2_FLASH_SIZE_FACTORY_TRIGGER_CALIB) + return; + switch2_init_step_done(ns2, NS2_INIT_READ_FACTORY_TRIGGER_CALIB); + if (data[0] != 0xFF && data[1] != 0xFF) { + ns2->lt_zero = data[0]; + ns2->rt_zero = data[1]; + + if (ns2->hdev) { + hid_dbg(ns2->hdev, "Got factory trigger calibration:\n"); + hid_dbg(ns2->hdev, "Left zero point: %i\n", ns2->lt_zero); + hid_dbg(ns2->hdev, "Right zero point: %i\n", ns2->rt_zero); + } + } else if (ns2->hdev) { + hid_dbg(ns2->hdev, "Factory trigger calibration not present\n"); + } + break; + case NS2_FLASH_ADDR_USER_PRIMARY_CALIB: + if (size != NS2_FLASH_SIZE_USER_AXIS_CALIB) + return; + switch2_init_step_done(ns2, NS2_INIT_READ_USER_PRIMARY_CALIB); + if (get_unaligned_le16((__le16 *)data) != NS2_USER_CALIB_MAGIC) { + if (ns2->hdev) + hid_dbg(ns2->hdev, "No user primary stick calibration present\n"); + break; + } + + ok = switch2_parse_stick_calibration(&ns2->stick_calib[0], &data[2]); + if (ns2->hdev) { + if (ok) { + hid_dbg(ns2->hdev, "Got user primary stick calibration:\n"); + hid_dbg(ns2->hdev, "Left max: %i, neutral: %i, right max: %i\n", + ns2->stick_calib[0].x.negative, + ns2->stick_calib[0].x.neutral, + ns2->stick_calib[0].x.positive); + hid_dbg(ns2->hdev, "Down max: %i, neutral: %i, up max: %i\n", + ns2->stick_calib[0].y.negative, + ns2->stick_calib[0].y.neutral, + ns2->stick_calib[0].y.positive); + } else { + hid_dbg(ns2->hdev, "No user primary stick calibration present\n"); + } + } + break; + case NS2_FLASH_ADDR_USER_SECONDARY_CALIB: + if (size != NS2_FLASH_SIZE_USER_AXIS_CALIB) + return; + switch2_init_step_done(ns2, NS2_INIT_READ_USER_SECONDARY_CALIB); + if (get_unaligned_le16((__le16 *)data) != NS2_USER_CALIB_MAGIC) { + if (ns2->hdev) + hid_dbg(ns2->hdev, "No user secondary stick calibration present\n"); + break; + } + + ok = switch2_parse_stick_calibration(&ns2->stick_calib[1], &data[2]); + if (ns2->hdev) { + if (ok) { + hid_dbg(ns2->hdev, "Got user secondary stick calibration:\n"); + hid_dbg(ns2->hdev, "Left max: %i, neutral: %i, right max: %i\n", + ns2->stick_calib[1].x.negative, + ns2->stick_calib[1].x.neutral, + ns2->stick_calib[1].x.positive); + hid_dbg(ns2->hdev, "Down max: %i, neutral: %i, up max: %i\n", + ns2->stick_calib[1].y.negative, + ns2->stick_calib[1].y.neutral, + ns2->stick_calib[1].y.positive); + } else { + hid_dbg(ns2->hdev, "No user secondary stick calibration present\n"); + } + } + break; + } +} + +static void switch2_report_buttons(struct input_dev *input, const uint8_t *bytes, + const struct switch2_ctlr_button_mapping button_mappings[]) +{ + const struct switch2_ctlr_button_mapping *button; + + for (button = button_mappings; button->code; button++) + input_report_key(input, button->code, bytes[button->byte] & button->bit); +} + +static void switch2_report_axis(struct input_dev *input, struct switch2_axis_calibration *calib, + int axis, bool invert, int value) +{ + if (calib && calib->neutral && calib->negative && calib->positive) { + value -= calib->neutral; + value *= NS2_AXIS_MAX + 1; + if (value < 0) + value /= calib->negative; + else + value /= calib->positive; + } else { + value = (value - 2048) * 16; + } + + if (invert) + value = -value; + input_report_abs(input, axis, + clamp(value, NS2_AXIS_MIN, NS2_AXIS_MAX)); +} + +static void switch2_report_stick(struct input_dev *input, struct switch2_stick_calibration *calib, + int x, bool invert_x, int y, bool invert_y, const uint8_t *data) +{ + switch2_report_axis(input, &calib->x, x, invert_x, data[0] | ((data[1] & 0x0F) << 8)); + switch2_report_axis(input, &calib->y, y, invert_y, (data[1] >> 4) | (data[2] << 4)); +} + +static void switch2_report_trigger(struct input_dev *input, uint8_t zero, int abs, uint8_t data) +{ + int value = (NS2_TRIGGER_RANGE + 1) * (data - zero); + + if (zero != 232) + value /= (232 - zero); + input_report_abs(input, abs, clamp(value, 0, NS2_TRIGGER_RANGE)); +} + +static int switch2_event(struct hid_device *hdev, struct hid_report *report, uint8_t *raw_data, + int size) +{ + struct switch2_controller *ns2 = hid_get_drvdata(hdev); + struct input_dev *input; + + if (report->type != HID_INPUT_REPORT) + return 0; + + if (size < 15) + return -EINVAL; + + guard(rcu)(); + input = rcu_dereference(ns2->input); + + if (!input) + return 0; + + switch (report->id) { + case NS2_REPORT_UNIFIED: + if (size < 0x3f) + return -EINVAL; + + switch (ns2->ctlr_type) { + case NS2_CTLR_TYPE_JCL: + switch2_report_stick(input, &ns2->stick_calib[0], + ABS_X, false, ABS_Y, true, &raw_data[11]); + switch2_report_buttons(input, &raw_data[5], + ns2_left_joycon_button_unified_mappings); + break; + case NS2_CTLR_TYPE_JCR: + switch2_report_stick(input, &ns2->stick_calib[0], + ABS_X, false, ABS_Y, true, &raw_data[14]); + switch2_report_buttons(input, &raw_data[5], + ns2_right_joycon_button_unified_mappings); + break; + case NS2_CTLR_TYPE_GC: + input_report_abs(input, ABS_HAT0X, + !!(raw_data[7] & NS2_BTN_U3_RIGHT) - + !!(raw_data[7] & NS2_BTN_U3_LEFT)); + input_report_abs(input, ABS_HAT0Y, + !!(raw_data[7] & NS2_BTN_U3_DOWN) - + !!(raw_data[7] & NS2_BTN_U3_UP)); + switch2_report_buttons(input, &raw_data[5], ns2_gccon_unified_mappings); + switch2_report_stick(input, &ns2->stick_calib[0], + ABS_X, false, ABS_Y, true, &raw_data[11]); + switch2_report_stick(input, &ns2->stick_calib[1], + ABS_RX, false, ABS_RY, true, &raw_data[14]); + switch2_report_trigger(input, ns2->lt_zero, ABS_Z, raw_data[0x3d]); + switch2_report_trigger(input, ns2->rt_zero, ABS_RZ, raw_data[0x3e]); + break; + case NS2_CTLR_TYPE_PRO: + input_report_abs(input, ABS_HAT0X, + !!(raw_data[7] & NS2_BTN_U3_RIGHT) - + !!(raw_data[7] & NS2_BTN_U3_LEFT)); + input_report_abs(input, ABS_HAT0Y, + !!(raw_data[7] & NS2_BTN_U3_DOWN) - + !!(raw_data[7] & NS2_BTN_U3_UP)); + switch2_report_buttons(input, &raw_data[5], ns2_procon_unified_mappings); + switch2_report_stick(input, &ns2->stick_calib[0], + ABS_X, false, ABS_Y, true, &raw_data[11]); + switch2_report_stick(input, &ns2->stick_calib[1], + ABS_RX, false, ABS_RY, true, &raw_data[14]); + break; + } + break; + case NS2_REPORT_JCL: + switch2_report_stick(input, &ns2->stick_calib[0], ABS_X, false, + ABS_Y, true, &raw_data[6]); + switch2_report_buttons(input, &raw_data[3], ns2_left_joycon_button_mappings); + break; + case NS2_REPORT_JCR: + switch2_report_stick(input, &ns2->stick_calib[0], ABS_X, false, + ABS_Y, true, &raw_data[6]); + switch2_report_buttons(input, &raw_data[3], ns2_right_joycon_button_mappings); + break; + case NS2_REPORT_GC: + input_report_abs(input, ABS_HAT0X, + !!(raw_data[4] & NS2_BTNL_RIGHT) - + !!(raw_data[4] & NS2_BTNL_LEFT)); + input_report_abs(input, ABS_HAT0Y, + !!(raw_data[4] & NS2_BTNL_DOWN) - + !!(raw_data[4] & NS2_BTNL_UP)); + switch2_report_buttons(input, &raw_data[3], ns2_gccon_mappings); + switch2_report_stick(input, &ns2->stick_calib[0], ABS_X, false, + ABS_Y, true, &raw_data[6]); + switch2_report_stick(input, &ns2->stick_calib[1], ABS_RX, false, + ABS_RY, true, &raw_data[9]); + switch2_report_trigger(input, ns2->lt_zero, ABS_Z, raw_data[13]); + switch2_report_trigger(input, ns2->rt_zero, ABS_RZ, raw_data[14]); + break; + case NS2_REPORT_PRO: + input_report_abs(input, ABS_HAT0X, + !!(raw_data[4] & NS2_BTNL_RIGHT) - + !!(raw_data[4] & NS2_BTNL_LEFT)); + input_report_abs(input, ABS_HAT0Y, + !!(raw_data[4] & NS2_BTNL_DOWN) - + !!(raw_data[4] & NS2_BTNL_UP)); + switch2_report_buttons(input, &raw_data[3], ns2_procon_mappings); + switch2_report_stick(input, &ns2->stick_calib[0], ABS_X, false, + ABS_Y, true, &raw_data[6]); + switch2_report_stick(input, &ns2->stick_calib[1], ABS_RX, false, + ABS_RY, true, &raw_data[9]); + break; + default: + return -EINVAL; + } + + input_sync(input); + return 0; +} + +static int switch2_features_enable(struct switch2_controller *ns2, int features) +{ + __le32 feature_bits = __cpu_to_le32(features); + + if (!ns2->cfg) + return -ENOTCONN; + return ns2->cfg->send_command(NS2_CMD_FEATSEL, NS2_SUBCMD_FEATSEL_ENABLE, + &feature_bits, sizeof(feature_bits), + ns2->cfg); +} + +static int switch2_read_flash(struct switch2_controller *ns2, uint32_t address, + uint8_t size) +{ + uint8_t message[8] = { size, 0x7e }; + + if (!ns2->cfg) + return -ENOTCONN; + put_unaligned_le32(address, &message[4]); + return ns2->cfg->send_command(NS2_CMD_FLASH, NS2_SUBCMD_FLASH_READ, message, + sizeof(message), ns2->cfg); +} + +static int switch2_set_player_id(struct switch2_controller *ns2, uint32_t player_id) +{ + int i; + int player_led_pattern = player_id % JC_NUM_LED_PATTERNS; + + for (i = 0; i < JC_NUM_LEDS; i++) + ns2->leds[i].brightness = joycon_player_led_patterns[player_led_pattern][i]; + + return switch2_set_leds(ns2); +} + +static int switch2_set_report_format(struct switch2_controller *ns2, enum switch2_report_id fmt) +{ + __le32 format_id = __cpu_to_le32(fmt); + + if (!ns2->cfg) + return -ENOTCONN; + return ns2->cfg->send_command(NS2_CMD_INIT, NS2_SUBCMD_INIT_SELECT_REPORT, + &format_id, sizeof(format_id), + ns2->cfg); +} + +int switch2_init_controller(struct switch2_controller *ns2) +{ + if (ns2->init_step == NS2_INIT_DONE) + return 0; + + if (!ns2->cfg) + return -ENOTCONN; + + if (ns2->init_retries > NS2_MAX_INIT_RETRIES) { + if (ns2->init_retries == NS2_MAX_INIT_RETRIES + 1) { + dev_err(ns2->cfg->dev, "Failed to configure controller\n"); + ns2->init_retries++; + } + return -EIO; + } + + ns2->init_retries++; + switch (ns2->init_step) { + case NS2_INIT_READ_SERIAL: + return switch2_read_flash(ns2, NS2_FLASH_ADDR_SERIAL, + NS2_FLASH_SIZE_SERIAL); + case NS2_INIT_GET_FIRMWARE_INFO: + return ns2->cfg->send_command(NS2_CMD_FW_INFO, NS2_SUBCMD_FW_INFO_GET, + NULL, 0, ns2->cfg); + case NS2_INIT_READ_FACTORY_PRIMARY_CALIB: + return switch2_read_flash(ns2, NS2_FLASH_ADDR_FACTORY_PRIMARY_CALIB, + NS2_FLASH_SIZE_FACTORY_AXIS_CALIB); + case NS2_INIT_READ_FACTORY_SECONDARY_CALIB: + if (switch2_ctlr_is_joycon(ns2->ctlr_type)) { + switch2_init_step_done(ns2, ns2->init_step); + return switch2_init_controller(ns2); + } + return switch2_read_flash(ns2, NS2_FLASH_ADDR_FACTORY_SECONDARY_CALIB, + NS2_FLASH_SIZE_FACTORY_AXIS_CALIB); + case NS2_INIT_READ_FACTORY_TRIGGER_CALIB: + if (ns2->ctlr_type != NS2_CTLR_TYPE_GC) { + switch2_init_step_done(ns2, ns2->init_step); + return switch2_init_controller(ns2); + } + return switch2_read_flash(ns2, NS2_FLASH_ADDR_FACTORY_TRIGGER_CALIB, + NS2_FLASH_SIZE_FACTORY_TRIGGER_CALIB); + case NS2_INIT_READ_USER_PRIMARY_CALIB: + return switch2_read_flash(ns2, NS2_FLASH_ADDR_USER_PRIMARY_CALIB, + NS2_FLASH_SIZE_USER_AXIS_CALIB); + case NS2_INIT_READ_USER_SECONDARY_CALIB: + if (switch2_ctlr_is_joycon(ns2->ctlr_type)) { + switch2_init_step_done(ns2, ns2->init_step); + return switch2_init_controller(ns2); + } + return switch2_read_flash(ns2, NS2_FLASH_ADDR_USER_SECONDARY_CALIB, + NS2_FLASH_SIZE_USER_AXIS_CALIB); + case NS2_INIT_SET_FEATURE_MASK: + return ns2->cfg->send_command(NS2_CMD_FEATSEL, NS2_SUBCMD_FEATSEL_SET_MASK, + switch2_feature_mask, sizeof(switch2_feature_mask), ns2->cfg); + case NS2_INIT_ENABLE_FEATURES: + return switch2_features_enable(ns2, NS2_FEATURE_BUTTONS | + NS2_FEATURE_ANALOG | NS2_FEATURE_RUMBLE); + case NS2_INIT_ENABLE_RUMBLE: + /* + * It is unclear what this packet is supposed to be for, but it + * appears to be needed for rumble to work reliably. The reply + * data indicates it might be a query of some sort, but we + * ignore the reply so long as it doesn't return an error. + */ + return ns2->cfg->send_command(0x11, 1, NULL, 0, ns2->cfg); + case NS2_INIT_GRIP_BUTTONS: + if (!switch2_ctlr_is_joycon(ns2->ctlr_type)) { + switch2_init_step_done(ns2, ns2->init_step); + return switch2_init_controller(ns2); + } + return ns2->cfg->send_command(NS2_CMD_GRIP, NS2_SUBCMD_GRIP_ENABLE_BUTTONS, + switch2_one_data, sizeof(switch2_one_data), + ns2->cfg); + case NS2_INIT_REPORT_FORMAT: + switch (ns2->ctlr_type) { + case NS2_CTLR_TYPE_JCL: + return switch2_set_report_format(ns2, NS2_REPORT_JCL); + case NS2_CTLR_TYPE_JCR: + return switch2_set_report_format(ns2, NS2_REPORT_JCR); + case NS2_CTLR_TYPE_PRO: + return switch2_set_report_format(ns2, NS2_REPORT_PRO); + case NS2_CTLR_TYPE_GC: + return switch2_set_report_format(ns2, NS2_REPORT_GC); + default: + switch2_init_step_done(ns2, ns2->init_step); + return switch2_init_controller(ns2); + } + case NS2_INIT_INPUT: + if (ns2->hdev) + return switch2_init_input(ns2); + break; + case NS2_INIT_SET_PLAYER_LEDS: + return switch2_set_player_id(ns2, ns2->player_id); + case NS2_INIT_FINISH: + return ns2->cfg->send_command(NS2_CMD_INIT, NS2_SUBCMD_INIT_USB, + switch2_init_cmd_data, sizeof(switch2_init_cmd_data), ns2->cfg); + default: + WARN_ON_ONCE(1); + break; + } + return 0; +} + +int switch2_receive_command(struct switch2_controller *ns2, + const uint8_t *message, size_t length) +{ + const struct switch2_cmd_header *header; + int ret = 0; + + if (length < 8) + return -EINVAL; + + print_hex_dump_debug("got cmd: ", DUMP_PREFIX_OFFSET, 16, 1, message, length, false); + + mutex_lock(&ns2->lock); + + header = (const struct switch2_cmd_header *)message; + if (!(header->flags & NS2_FLAG_OK)) { + if (ns2->cfg) + dev_warn(ns2->cfg->dev, "Packet error %02x replying to command %x:%x", + header->flags, header->command, header->subcommand); + ret = -EIO; + goto exit; + } + message = &message[8]; + length -= 8; + + switch (header->command) { + case NS2_CMD_FLASH: + if (header->subcommand == NS2_SUBCMD_FLASH_READ) { + uint8_t read_size; + uint32_t read_address; + + if (length < 8) { + ret = -EINVAL; + goto exit; + } + read_size = message[0]; + read_address = get_unaligned_le32(&message[4]); + if (length < read_size + 8) { + ret = -EINVAL; + goto exit; + } + switch2_handle_flash_read(ns2, read_size, read_address, &message[8]); + } + break; + case NS2_CMD_INIT: + if (header->subcommand == NS2_SUBCMD_INIT_USB) + switch2_init_step_done(ns2, NS2_INIT_FINISH); + else if (header->subcommand == NS2_SUBCMD_INIT_SELECT_REPORT) + switch2_init_step_done(ns2, NS2_INIT_REPORT_FORMAT); + break; + case NS2_CMD_GRIP: + if (header->subcommand == NS2_SUBCMD_GRIP_ENABLE_BUTTONS) + switch2_init_step_done(ns2, NS2_INIT_GRIP_BUTTONS); + break; + case NS2_CMD_LED: + if (header->subcommand == NS2_SUBCMD_LED_PATTERN) + switch2_init_step_done(ns2, NS2_INIT_SET_PLAYER_LEDS); + break; + case NS2_CMD_FEATSEL: + if (header->subcommand == NS2_SUBCMD_FEATSEL_SET_MASK) + switch2_init_step_done(ns2, NS2_INIT_SET_FEATURE_MASK); + else if (header->subcommand == NS2_SUBCMD_FEATSEL_ENABLE) + switch2_init_step_done(ns2, NS2_INIT_ENABLE_FEATURES); + break; + case NS2_CMD_FW_INFO: + if (header->subcommand == NS2_SUBCMD_FW_INFO_GET) { + if (length < sizeof(ns2->version)) { + ret = -EINVAL; + goto exit; + } + memcpy(&ns2->version, message, sizeof(ns2->version)); + ns2->ctlr_type = ns2->version.ctlr_type; + switch2_init_step_done(ns2, NS2_INIT_GET_FIRMWARE_INFO); + } + break; + case 0x11: + if (header->subcommand == 1) + switch2_init_step_done(ns2, NS2_INIT_ENABLE_RUMBLE); + break; + default: + break; + } + +exit: + if (ns2->init_step < NS2_INIT_DONE) + switch2_init_controller(ns2); + + mutex_unlock(&ns2->lock); + return ret; +} +EXPORT_SYMBOL_GPL(switch2_receive_command); + +int switch2_controller_attach_cfg(const char *phys, struct switch2_cfg_intf *cfg) +{ + struct switch2_controller *ns2 = switch2_get_controller(phys); + int ret = 0; + + if (IS_ERR(ns2)) + return PTR_ERR(ns2); + + mutex_lock(&ns2->lock); + if (ns2->cfg) { + ret = -EBUSY; + goto out; + } + cfg->parent = ns2; + ns2->cfg = cfg; + + if (ns2->hdev) + ret = switch2_init_controller(ns2); + + if (ret < 0) { + if (cfg->shutdown) + cfg->shutdown(cfg); + cfg->parent = NULL; + ns2->cfg = NULL; + } + +out: + mutex_unlock(&ns2->lock); + + if (ret < 0) + kref_put(&ns2->refcount, switch2_kref_put); + return ret; +} +EXPORT_SYMBOL_GPL(switch2_controller_attach_cfg); + +void switch2_controller_detach_cfg(struct switch2_controller *ns2) +{ + mutex_lock(&ns2->lock); + if (!ns2->cfg || WARN_ON(ns2 != ns2->cfg->parent)) { + mutex_unlock(&ns2->lock); + return; + } + if (ns2->cfg->shutdown) + ns2->cfg->shutdown(ns2->cfg); + ns2->cfg->parent = NULL; + ns2->cfg = NULL; + mutex_unlock(&ns2->lock); + switch2_controller_put(ns2); + kref_put(&ns2->refcount, switch2_kref_put); +} +EXPORT_SYMBOL_GPL(switch2_controller_detach_cfg); + +static int switch2_probe(struct hid_device *hdev, const struct hid_device_id *id) +{ + struct switch2_controller *ns2; + struct usb_device *udev; + char phys[64]; + int ret; + + if (!hid_is_usb(hdev)) + return -ENODEV; + + udev = hid_to_usb_dev(hdev); + if (usb_make_path(udev, phys, sizeof(phys)) < 0) + return -EINVAL; + + ret = hid_parse(hdev); + if (ret) { + hid_err(hdev, "parse failed %d\n", ret); + return ret; + } + + ns2 = switch2_get_controller(phys); + if (IS_ERR(ns2)) + return PTR_ERR(ns2); + + mutex_lock(&ns2->lock); + if (ns2->hdev) { + mutex_unlock(&ns2->lock); + hid_err(hdev, + "Second hdev tried to claim same controller, first=%p vs second=%p\n", + ns2->hdev, hdev); + kref_put(&ns2->refcount, switch2_kref_put); + return -EBUSY; + } + ns2->hdev = hdev; + hid_set_drvdata(hdev, ns2); + + switch (hdev->product | (hdev->vendor << 16)) { + default: + strscpy(ns2->name, hdev->name, sizeof(ns2->name)); + break; + /* Some controllers have slightly wrong names so we override them */ + case USB_DEVICE_ID_NINTENDO_NS2_JOYCONR | (USB_VENDOR_ID_NINTENDO << 16): + /* Missing the "2" in the name */ + strscpy(ns2->name, "Nintendo Joy-Con 2 (R)", sizeof(ns2->name)); + break; + case USB_DEVICE_ID_NINTENDO_NS2_GCCON | (USB_VENDOR_ID_NINTENDO << 16): + /* Has "Nintendo" in the name twice */ + strscpy(ns2->name, "Nintendo GameCube Controller", sizeof(ns2->name)); + break; + } + + ns2->player_id = U32_MAX; + ret = ida_alloc(&nintendo_player_id_allocator, GFP_KERNEL); + if (ret < 0) + hid_warn(hdev, "Failed to allocate player ID, skipping; ret=%d\n", ret); + else + ns2->player_id = ret; + + ret = hid_hw_start(hdev, HID_CONNECT_HIDRAW); + if (ret) { + hid_err(hdev, "hw_start failed %d\n", ret); + goto err_cleanup; + } + + ret = hid_hw_open(hdev); + if (ret) { + hid_err(hdev, "hw_open failed %d\n", ret); + goto err_stop; + } + + ret = 0; + if (ns2->cfg) + ret = switch2_init_controller(ns2); + + if (!ret) { + mutex_unlock(&ns2->lock); + return 0; + } + + hid_hw_close(hdev); +err_stop: + hid_hw_stop(hdev); +err_cleanup: + ida_free(&nintendo_player_id_allocator, ns2->player_id); + ns2->hdev = NULL; + mutex_unlock(&ns2->lock); + switch2_controller_put(ns2); + kref_put(&ns2->refcount, switch2_kref_put); + + return ret; +} + +static void switch2_remove(struct hid_device *hdev) +{ + struct switch2_controller *ns2 = hid_get_drvdata(hdev); + + switch2_controller_put(ns2); + mutex_lock(&ns2->lock); + ns2->hdev = NULL; + ida_free(&nintendo_player_id_allocator, ns2->player_id); + mutex_unlock(&ns2->lock); + kref_put(&ns2->refcount, switch2_kref_put); + hid_hw_close(hdev); + hid_hw_stop(hdev); +} + static const struct hid_device_id nintendo_hid_devices[] = { + /* Switch devices */ { HID_USB_DEVICE(USB_VENDOR_ID_NINTENDO, USB_DEVICE_ID_NINTENDO_PROCON) }, { HID_USB_DEVICE(USB_VENDOR_ID_NINTENDO, @@ -2905,13 +4465,88 @@ static const struct hid_device_id nintendo_hid_devices[] = { USB_DEVICE_ID_NINTENDO_N64CON) }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_HORI, USB_DEVICE_ID_HORI_WIRELESS_SWITCH_PAD) }, + { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_PDP, + USB_DEVICE_ID_PDP_SWITCH_AFTERGLOW) }, + /* Switch 2 devices */ + { HID_USB_DEVICE(USB_VENDOR_ID_NINTENDO, + USB_DEVICE_ID_NINTENDO_NS2_JOYCONL) }, + { HID_USB_DEVICE(USB_VENDOR_ID_NINTENDO, + USB_DEVICE_ID_NINTENDO_NS2_JOYCONR) }, + { HID_USB_DEVICE(USB_VENDOR_ID_NINTENDO, + USB_DEVICE_ID_NINTENDO_NS2_PROCON) }, + { HID_USB_DEVICE(USB_VENDOR_ID_NINTENDO, + USB_DEVICE_ID_NINTENDO_NS2_GCCON) }, { } }; MODULE_DEVICE_TABLE(hid, nintendo_hid_devices); +static bool nintendo_is_switch2(struct hid_device *hdev) +{ + return hdev->vendor == USB_VENDOR_ID_NINTENDO && + hdev->product >= USB_DEVICE_ID_NINTENDO_NS2_JOYCONR; +} + +static void nintendo_hid_remove(struct hid_device *hdev) +{ + if (nintendo_is_switch2(hdev)) + switch2_remove(hdev); + else + joycon_remove(hdev); +} + +static int nintendo_hid_event(struct hid_device *hdev, + struct hid_report *report, u8 *raw_data, int size) +{ + if (nintendo_is_switch2(hdev)) + return switch2_event(hdev, report, raw_data, size); + else + return joycon_event(hdev, report, raw_data, size); +} + +static const __u8 *nintendo_hid_report_fixup(struct hid_device *hdev, + __u8 *rdesc, unsigned int *rsize) +{ + if (hdev->vendor == USB_VENDOR_ID_NINTENDO && + hdev->product == USB_DEVICE_ID_NINTENDO_NS2_JOYCONR && + *rsize == 100 && rdesc[24] == NS2_REPORT_JCL) + /* + * The NYXI Hyperion 3 right Joy-Con accidentally reports as the + * left one. Since the HID subsystem rejects report IDs that + * aren't listed in the descriptor, we need to patch it. + */ + rdesc[24] = NS2_REPORT_JCR; + return rdesc; +} + +static int nintendo_hid_probe(struct hid_device *hdev, + const struct hid_device_id *id) +{ + if (nintendo_is_switch2(hdev)) + return switch2_probe(hdev, id); + else + return joycon_probe(hdev, id); +} + +static int nintendo_hid_resume(struct hid_device *hdev) +{ + if (nintendo_is_switch2(hdev)) + return 0; + else + return joycon_resume(hdev); +} + +static int nintendo_hid_suspend(struct hid_device *hdev, pm_message_t message) +{ + if (nintendo_is_switch2(hdev)) + return 0; + else + return joycon_suspend(hdev, message); +} + static struct hid_driver nintendo_hid_driver = { .name = "nintendo", .id_table = nintendo_hid_devices, + .report_fixup = nintendo_hid_report_fixup, .probe = nintendo_hid_probe, .remove = nintendo_hid_remove, .raw_event = nintendo_hid_event, @@ -2936,4 +4571,5 @@ MODULE_LICENSE("GPL"); MODULE_AUTHOR("Ryan McClelland <rymcclel@gmail.com>"); MODULE_AUTHOR("Emily Strickland <linux@emily.st>"); MODULE_AUTHOR("Daniel J. Ogorchock <djogorchock@gmail.com>"); +MODULE_AUTHOR("Vicki Pfau <vi@endrift.com>"); MODULE_DESCRIPTION("Driver for Nintendo Switch Controllers");
diff --git a/drivers/hid/hid-nintendo.h b/drivers/hid/hid-nintendo.h new file mode 100644 index 0000000..9bdef5fff --- /dev/null +++ b/drivers/hid/hid-nintendo.h
@@ -0,0 +1,73 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * HID driver for Nintendo Switch 2 controllers + * + * Copyright (c) 2025 Valve Software + * + * This driver is based on the following work: + * https://gist.github.com/shinyquagsire23/66f006b46c56216acbaac6c1e2279b64 + * https://github.com/ndeadly/switch2_controller_research + */ + +#ifndef __HID_NINTENDO_H +#define __HID_NINTENDO_H + +#include <linux/bits.h> + +#define NS2_FLAG_OK BIT(0) +#define NS2_FLAG_NACK BIT(2) + +enum switch2_cmd { + NS2_CMD_NFC = 0x01, + NS2_CMD_FLASH = 0x02, + NS2_CMD_INIT = 0x03, + NS2_CMD_GRIP = 0x08, + NS2_CMD_LED = 0x09, + NS2_CMD_VIBRATE = 0x0a, + NS2_CMD_BATTERY = 0x0b, + NS2_CMD_FEATSEL = 0x0c, + NS2_CMD_FW_UPD = 0x0d, + NS2_CMD_FW_INFO = 0x10, + NS2_CMD_BT_PAIR = 0x15, +}; + +enum switch2_direction { + NS2_DIR_IN = 0x00, + NS2_DIR_OUT = 0x90, +}; + +enum switch2_transport { + NS2_TRANS_USB = 0x00, + NS2_TRANS_BT = 0x01, +}; + +struct switch2_cmd_header { + uint8_t command; + uint8_t flags; + uint8_t transport; + uint8_t subcommand; + uint8_t unk1; + uint8_t length; + uint16_t unk2; +}; +static_assert(sizeof(struct switch2_cmd_header) == 8); + +struct device; +struct switch2_controller; +struct switch2_cfg_intf { + struct switch2_controller *parent; + struct device *dev; + + int (*send_command)(enum switch2_cmd command, uint8_t subcommand, + const void *message, size_t length, + struct switch2_cfg_intf *intf); + void (*shutdown)(struct switch2_cfg_intf *intf); +}; + +int switch2_controller_attach_cfg(const char *phys, struct switch2_cfg_intf *cfg); +void switch2_controller_detach_cfg(struct switch2_controller *controller); + +int switch2_receive_command(struct switch2_controller *controller, + const uint8_t *message, size_t length); + +#endif
diff --git a/drivers/hid/hid-prodikeys.c b/drivers/hid/hid-prodikeys.c index fba01e4..bf5add4 100644 --- a/drivers/hid/hid-prodikeys.c +++ b/drivers/hid/hid-prodikeys.c
@@ -772,8 +772,13 @@ static int pk_raw_event(struct hid_device *hdev, struct hid_report *report, if (report->id == data[0]) switch (report->id) { case 0x01: /* midi keys (qwerty)*/ - case 0x03: /* midi keyboard (musical)*/ case 0x04: /* extra/midi keys (qwerty)*/ + if (size < 4) + break; + ret = pcmidi_handle_report(pm, report->id, + data, size); + break; + case 0x03: /* midi keyboard (musical)*/ ret = pcmidi_handle_report(pm, report->id, data, size); break;
diff --git a/drivers/hid/hid-pulsar.c b/drivers/hid/hid-pulsar.c new file mode 100644 index 0000000..b0b3484 --- /dev/null +++ b/drivers/hid/hid-pulsar.c
@@ -0,0 +1,767 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * HID driver for pulsar mice + * + * Supported pulsar devices: + * - Pulsar + * - X2 V2 + * - X2H + * - X2A + * - Xlite V3 + * - Kysona + * -M600 + * - ATK + * - VXE R1 SE+ + * - VXE + * - Dragonfly R1 Pro + * + * Copyright (c) 2026 Nikolas Koesling + */ + +#include <linux/hid.h> +#include <linux/usb.h> +#include <linux/power_supply.h> +#include "hid-ids.h" + +/* ----- driver settings ----- */ +#define CMD_TIMEOUT_MSEC 100 +#define MAX_BATTERY_AGE_NS 60000000000ULL /* 60s */ +#define MAX_UNAVAIL_AGE_NS 5000000000ULL /* 5s */ +#define INIT_RETRIES 1 +#define INIT_DELAY_MSEC 1000 + +/* ----- constants ----- */ +#define USB_INTERFACE 1 +#define USB_PAYLOAD_LEN 17 +#define CMD_HID_REPORT_ID 0x08 +#define CHECKSUM_MAGIC 0x55 +#define DEV_INFO_LEN 4 +#define CON_1K 0x00 +#define CON_4K 0x01 +#define CON_WIRED 0x02 + +/* ----- device commands ----- */ +enum pulsar_cmd { + CMD_NONE = 0, + CMD_INFO = 0x01, + CMD_STATUS = 0x03, + CMD_POWER = 0x04, + CMD_EVENT = 0x0a, /* recv only */ +}; + +#define EVENT_PWR 0x40 /* power status change */ +#define EVENT_PWR_CHK 0xf9 + +/* ----- device types ----- */ +enum dev_type { + TYPE_UNKNOWN, + TYPE_PULSAR, + TYPE_KYSONA, + TYPE_ATK, + TYPE_VXE, +}; + +/* ----- structs ----- */ +struct pulsar_battery { + struct power_supply *ps; + struct power_supply_desc desc; + char name[48]; + char model[MAX(32, sizeof((struct hid_device){}).name)]; + u8 level; /* percent */ + u16 voltage; /* millivolts */ + bool conn; + bool available; + bool refresh; /* cache invalid, read regardless of age */ + u64 last_read; + u64 last_status; +}; + +struct pulsar_data { + struct hid_device *hdev; + + enum dev_type type; + + spinlock_t raw_event_lock; /* protects response_buf, pending_event */ + struct mutex lock_cmd; /* serializes device command execution */ + struct rw_semaphore lock_bat; /* protects battery state */ + + struct completion response_ready; + u8 response_buf[USB_PAYLOAD_LEN]; + u8 pending_event; + struct work_struct power_uevent_work; + struct delayed_work init_work; + unsigned int init_retries; + atomic_t device_verified; + atomic_t stopping; + + struct pulsar_battery battery; +}; + +static u8 calc_checksum(const u8 *data, size_t len) +{ + u8 sum = 0; + + for (size_t i = 0; i < len - 1; i++) + sum += data[i]; + + return (u8)CHECKSUM_MAGIC - sum; +} + +static int send_cmd(struct hid_device *hdev, const u8 *buf, size_t len) +{ + int ret; + u8 *dmabuf; + + hid_dbg(hdev, "send command: %*ph\n", (int)len, buf); + + dmabuf = kmemdup(buf, len, GFP_KERNEL); + if (!dmabuf) + return -ENOMEM; + + /* device listens only to control transfers */ + ret = hid_hw_raw_request(hdev, dmabuf[0], dmabuf, len, + HID_OUTPUT_REPORT, HID_REQ_SET_REPORT); + + kfree(dmabuf); + + if (ret < 0) + return ret; + if (ret != len) + return -EIO; + + return 0; +} + +static int exec_cmd(struct pulsar_data *drvdata, const u8 *payload, + u8 *response, unsigned int timeout_msec) +{ + struct hid_device *hdev = drvdata->hdev; + unsigned long flags; + int ret; + unsigned long timeout; + u8 checksum; + + if (atomic_read(&drvdata->stopping)) + return -ENODEV; + + mutex_lock(&drvdata->lock_cmd); + + if (atomic_read(&drvdata->stopping)) { + ret = -ENODEV; + goto out; + } + + spin_lock_irqsave(&drvdata->raw_event_lock, flags); + reinit_completion(&drvdata->response_ready); + drvdata->pending_event = payload[1]; + spin_unlock_irqrestore(&drvdata->raw_event_lock, flags); + + ret = send_cmd(hdev, payload, USB_PAYLOAD_LEN); + + if (ret < 0) { + spin_lock_irqsave(&drvdata->raw_event_lock, flags); + drvdata->pending_event = CMD_NONE; + spin_unlock_irqrestore(&drvdata->raw_event_lock, flags); + hid_err(hdev, "failed to send command 0x%02x: %d\n", + payload[1], ret); + goto out; + } + + timeout = wait_for_completion_timeout(&drvdata->response_ready, + msecs_to_jiffies(timeout_msec)); + + if (timeout == 0) { + spin_lock_irqsave(&drvdata->raw_event_lock, flags); + drvdata->pending_event = CMD_NONE; + spin_unlock_irqrestore(&drvdata->raw_event_lock, flags); + ret = -ETIMEDOUT; + goto out; + } + + spin_lock_irqsave(&drvdata->raw_event_lock, flags); + memcpy(response, drvdata->response_buf, USB_PAYLOAD_LEN); + spin_unlock_irqrestore(&drvdata->raw_event_lock, flags); + + /* validate checksum */ + checksum = calc_checksum(response, USB_PAYLOAD_LEN); + + if (response[USB_PAYLOAD_LEN - 1] != checksum) { + hid_err(hdev, + "invalid checksum in response: 0x%02x (expected 0x%02x)\n", + response[USB_PAYLOAD_LEN - 1], checksum); + ret = -EIO; + goto out; + } + + ret = 0; +out: + mutex_unlock(&drvdata->lock_cmd); + return ret; +} + +static inline void finalize_payload(u8 *payload, u8 cmd) +{ + payload[0] = CMD_HID_REPORT_ID; + payload[1] = cmd; + payload[USB_PAYLOAD_LEN - 1] = calc_checksum(payload, USB_PAYLOAD_LEN); +} + +static int read_status(struct pulsar_data *drvdata) +{ + int ret; + u8 payload[USB_PAYLOAD_LEN] = { 0 }; + u8 response[USB_PAYLOAD_LEN]; + + finalize_payload(payload, CMD_STATUS); + + ret = exec_cmd(drvdata, payload, response, CMD_TIMEOUT_MSEC); + if (ret < 0) + return ret; + if (response[6] > 0x01) + return -EIO; + + return (int)response[6]; /* 1: available, 0: not available */ +} + +static int read_device_info(struct pulsar_data *drvdata, u8 *data) +{ + int ret; + u8 payload[USB_PAYLOAD_LEN] = { 0 }; + u8 response[USB_PAYLOAD_LEN]; + + payload[5] = DEV_INFO_LEN * 2; + get_random_bytes(payload + 6, DEV_INFO_LEN); + finalize_payload(payload, CMD_INFO); + + ret = exec_cmd(drvdata, payload, response, CMD_TIMEOUT_MSEC); + if (ret < 0) + return ret; + + if (data) + memcpy(data, response + 6 + DEV_INFO_LEN, DEV_INFO_LEN); + + response[8 + DEV_INFO_LEN] = 0; + response[9 + DEV_INFO_LEN] = 0; + + /* + * Verify challenge-response. Response layout from offset 6: + * [0..3] encoded response [4..7] device info (ID + conn type) + * + * resp[i] = challenge[i] * (i+1) + challenge[(i+1) % 4] + device_id[i] + * + * bytes 6..7 are zeroed for verification. + */ + for (int i = 0; i < DEV_INFO_LEN; i++) { + u8 expect = response[6 + DEV_INFO_LEN + i]; + u8 actual = response[6 + i] - (i + 1) * payload[6 + i] - + payload[6 + (i + 1) % DEV_INFO_LEN]; + + if (expect != actual) { + hid_warn(drvdata->hdev, + "device info[%d] mismatch: %02x != %02x\n", + i, expect, actual); + return -EIO; + } + } + + return 0; +} + +static int read_power(struct pulsar_data *drvdata) +{ + u64 now; + bool need_status, need_power; + int ret = 0; + u8 payload[USB_PAYLOAD_LEN] = { 0 }; + u8 response[USB_PAYLOAD_LEN]; + struct pulsar_battery *battery = &drvdata->battery; + + now = ktime_get_ns(); + + down_write(&drvdata->lock_bat); + + need_status = battery->refresh || + (now - battery->last_status >= MAX_UNAVAIL_AGE_NS); + need_power = battery->available && + (battery->refresh || + now - battery->last_read >= MAX_BATTERY_AGE_NS); + + if (!need_status && !need_power) + goto unlock; + + if (need_status) { + const int status = read_status(drvdata); + + if (status < 0) { + ret = status; + hid_err(drvdata->hdev, + "%s: failed to read status: %d\n", + __func__, ret); + goto unlock; + } + + battery->last_status = now; + + if (!status) { + battery->available = false; + battery->refresh = false; + goto unlock; + } + + /* device just became available, force power read */ + if (!battery->available) + need_power = true; + } + + if (!need_power) + goto unlock; + + finalize_payload(payload, CMD_POWER); + + ret = exec_cmd(drvdata, payload, response, CMD_TIMEOUT_MSEC); + if (ret < 0) { + hid_err(drvdata->hdev, "%s: failed to read power: %d\n", + __func__, ret); + goto unlock; + } + + if (response[6] > 100 || response[7] > 0x01) { + ret = -EIO; + goto unlock; + } + + battery->available = true; + battery->level = response[6]; + battery->conn = response[7] == 1; + battery->voltage = (response[8] << 8) | response[9]; + battery->last_read = now; + battery->refresh = false; + + hid_dbg(drvdata->hdev, "%s: level=%d, conn=%d, voltage=%d\n", + __func__, battery->level, battery->conn, battery->voltage); + +unlock: + up_write(&drvdata->lock_bat); + return ret; +} + +static int battery_get_property(struct power_supply *psy, + enum power_supply_property psp, + union power_supply_propval *val) +{ + struct pulsar_data *drvdata; + int ret; + + drvdata = power_supply_get_drvdata(psy); + + ret = read_power(drvdata); + if (ret) + return ret; + + down_read(&drvdata->lock_bat); + + switch (psp) { + case POWER_SUPPLY_PROP_STATUS: + if (!drvdata->battery.available) + val->intval = POWER_SUPPLY_STATUS_UNKNOWN; + else if (drvdata->battery.conn && drvdata->battery.level < 100) + val->intval = POWER_SUPPLY_STATUS_CHARGING; + else if (drvdata->battery.conn && drvdata->battery.level >= 100) + val->intval = POWER_SUPPLY_STATUS_FULL; + else + val->intval = POWER_SUPPLY_STATUS_DISCHARGING; + break; + case POWER_SUPPLY_PROP_CAPACITY: + val->intval = drvdata->battery.level; + break; + case POWER_SUPPLY_PROP_VOLTAGE_NOW: + val->intval = drvdata->battery.voltage * 1000; + break; + case POWER_SUPPLY_PROP_PRESENT: + case POWER_SUPPLY_PROP_ONLINE: + val->intval = drvdata->battery.available; + break; + case POWER_SUPPLY_PROP_SCOPE: + val->intval = POWER_SUPPLY_SCOPE_DEVICE; + break; + case POWER_SUPPLY_PROP_MODEL_NAME: + val->strval = drvdata->battery.model; + break; + default: + ret = -EINVAL; + } + + up_read(&drvdata->lock_bat); + return ret; +} + +static void power_uevent_work_handler(struct work_struct *work) +{ + struct pulsar_data *drvdata; + int ret; + + drvdata = container_of(work, struct pulsar_data, power_uevent_work); + + if (atomic_read(&drvdata->stopping)) + return; + + down_write(&drvdata->lock_bat); + drvdata->battery.refresh = true; + up_write(&drvdata->lock_bat); + + ret = read_power(drvdata); + if (ret < 0) { + hid_err(drvdata->hdev, "%s: failed to read power: %d\n", + __func__, ret); + return; + } + + power_supply_changed(drvdata->battery.ps); +} + +static int pulsar_raw_event(struct hid_device *hdev, + struct hid_report *report, u8 *data, int size) +{ + struct pulsar_data *drvdata; + + drvdata = hid_get_drvdata(hdev); + if (!drvdata) + return 0; + + hid_dbg(hdev, "received raw event: %*ph\n", size, data); + + if (size != USB_PAYLOAD_LEN || data[0] != CMD_HID_REPORT_ID) + return 0; + + if (data[1] != CMD_EVENT) { + spin_lock(&drvdata->raw_event_lock); + if (drvdata->pending_event != data[1]) { + spin_unlock(&drvdata->raw_event_lock); + return 0; + } + memcpy(drvdata->response_buf, data, size); + drvdata->pending_event = CMD_NONE; + complete(&drvdata->response_ready); + spin_unlock(&drvdata->raw_event_lock); + return 1; + } + + if (!atomic_read(&drvdata->device_verified)) + return 0; + + if (data[6] == EVENT_PWR && data[USB_PAYLOAD_LEN - 1] == EVENT_PWR_CHK) { + schedule_work(&drvdata->power_uevent_work); + hid_dbg(hdev, "received power event\n"); + return 1; + } + + return 0; +} + +static const enum power_supply_property pulsar_battery_props[] = { + POWER_SUPPLY_PROP_STATUS, POWER_SUPPLY_PROP_CAPACITY, + POWER_SUPPLY_PROP_VOLTAGE_NOW, POWER_SUPPLY_PROP_ONLINE, + POWER_SUPPLY_PROP_MODEL_NAME, POWER_SUPPLY_PROP_SCOPE, + POWER_SUPPLY_PROP_PRESENT +}; + +static void init_power_supply_desc(struct pulsar_data *drvdata) +{ + drvdata->battery.desc.name = drvdata->battery.name; + drvdata->battery.desc.type = POWER_SUPPLY_TYPE_BATTERY; + drvdata->battery.desc.properties = pulsar_battery_props; + drvdata->battery.desc.num_properties = ARRAY_SIZE(pulsar_battery_props); + drvdata->battery.desc.get_property = battery_get_property; +} + +static void model_pulsar(u8 *device_id, struct pulsar_data *drvdata) +{ + u16 model_id; + const char *con_type = "unknown"; + + model_id = device_id[0] << 8 | device_id[1]; + + switch (device_id[2]) { + case CON_1K: + con_type = "1kHz"; + break; + case CON_4K: + con_type = "4kHz"; + break; + case CON_WIRED: + con_type = "wired"; + break; + } + + switch (model_id) { + case 0x060a: + case 0x060b: + case 0x0612: + case 0x0613: + case 0x0614: + case 0x0615: + snprintf(drvdata->battery.model, sizeof(drvdata->battery.model), + "Pulsar X2 V2 (%s)", con_type); + break; + case 0x060c: + case 0x060d: + snprintf(drvdata->battery.model, sizeof(drvdata->battery.model), + "Pulsar X2H (%s)", con_type); + break; + case 0x0607: + case 0x060e: + case 0x060f: + case 0x0610: + case 0x0611: + snprintf(drvdata->battery.model, sizeof(drvdata->battery.model), + "Pulsar Xlite V3 (%s)", con_type); + break; + case 0x0608: + case 0x0609: + snprintf(drvdata->battery.model, sizeof(drvdata->battery.model), + "Pulsar X2A (%s)", con_type); + break; + default: + snprintf(drvdata->battery.model, sizeof(drvdata->battery.model), + "Pulsar unknown (%s)", con_type); + } +} + +static void model_atk(u8 *device_id, struct pulsar_data *drvdata) +{ + u16 model_id; + const char *con_type = "unknown"; + + model_id = device_id[0] << 8 | device_id[1]; + + switch (device_id[2]) { + case CON_1K: + con_type = "1kHz"; + break; + case CON_4K: + con_type = "4kHz"; + break; + case CON_WIRED: + con_type = "wired"; + break; + } + + switch (model_id) { + case 0x0220: + snprintf(drvdata->battery.model, sizeof(drvdata->battery.model), + "ATK VXE R1 SE+ (%s)", con_type); + break; + default: + snprintf(drvdata->battery.model, sizeof(drvdata->battery.model), + "Unknown ATK (%s)", con_type); + } +} + +static void pulsar_init_work(struct work_struct *work) +{ + struct pulsar_data *drvdata; + struct hid_device *hdev; + struct power_supply_config psy_cfg; + int ret; + u8 data[DEV_INFO_LEN]; + + drvdata = container_of(work, struct pulsar_data, init_work.work); + hdev = drvdata->hdev; + + ret = read_device_info(drvdata, data); + if (ret == -ETIMEDOUT) { + if (drvdata->init_retries--) { + hid_dbg(hdev, + "device info read timed out, retrying (%u left)\n", + drvdata->init_retries); + schedule_delayed_work(&drvdata->init_work, + msecs_to_jiffies + (INIT_DELAY_MSEC)); + return; + } + hid_err(hdev, "device info read timed out, giving up\n"); + return; + } + if (ret < 0) { + if (drvdata->type == TYPE_PULSAR) { + hid_err(hdev, "failed to read device info: %d\n", ret); + return; + } + hid_dbg(hdev, "failed to read device info: %d\n", ret); + snprintf(drvdata->battery.model, + sizeof(drvdata->battery.model), "%s", hdev->name); + goto register_battery; + } + + hid_dbg(hdev, "device info: %*ph (%d)\n", DEV_INFO_LEN, data, ret); + + switch (drvdata->type) { + case TYPE_PULSAR: + model_pulsar(data, drvdata); + break; + case TYPE_ATK: + model_atk(data, drvdata); + break; + default: + snprintf(drvdata->battery.model, sizeof(drvdata->battery.model), + "%s", hdev->name); + } + +register_battery: + init_power_supply_desc(drvdata); + + psy_cfg = (struct power_supply_config) {.drv_data = drvdata }; + drvdata->battery.ps = + devm_power_supply_register(&hdev->dev, &drvdata->battery.desc, + &psy_cfg); + if (IS_ERR(drvdata->battery.ps)) { + hid_err(hdev, "failed to register battery: %ld\n", + PTR_ERR(drvdata->battery.ps)); + drvdata->battery.ps = NULL; + return; + } + + atomic_set(&drvdata->device_verified, 1); + hid_info(hdev, "device verified, battery registered\n"); +} + +static int pulsar_probe(struct hid_device *hdev, const struct hid_device_id *id) +{ + int ret; + struct usb_interface *intf; + struct usb_device *usbdev; + struct pulsar_data *drvdata; + struct hid_report *report_in; + struct hid_report *report_out; + + if (!hid_is_usb(hdev)) + return -ENODEV; + + ret = hid_parse(hdev); + if (ret < 0) { + hid_err(hdev, "hid_parse failed: %d\n", ret); + return ret; + } + + intf = to_usb_interface(hdev->dev.parent); + report_in = + hdev->report_enum[HID_INPUT_REPORT].report_id_hash[CMD_HID_REPORT_ID]; + report_out = + hdev->report_enum[HID_OUTPUT_REPORT].report_id_hash[CMD_HID_REPORT_ID]; + + if (!report_in || !report_out || + hid_report_len(report_in) != USB_PAYLOAD_LEN || + hid_report_len(report_out) != USB_PAYLOAD_LEN || + intf->cur_altsetting->desc.bInterfaceNumber != USB_INTERFACE) + return hid_hw_start(hdev, HID_CONNECT_DEFAULT); + + drvdata = devm_kzalloc(&hdev->dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return -ENOMEM; + + drvdata->hdev = hdev; + drvdata->type = id->driver_data; + + mutex_init(&drvdata->lock_cmd); + init_rwsem(&drvdata->lock_bat); + + usbdev = interface_to_usbdev(intf); + + spin_lock_init(&drvdata->raw_event_lock); + hid_set_drvdata(hdev, drvdata); + init_completion(&drvdata->response_ready); + INIT_WORK(&drvdata->power_uevent_work, power_uevent_work_handler); + INIT_DELAYED_WORK(&drvdata->init_work, pulsar_init_work); + drvdata->init_retries = INIT_RETRIES; + drvdata->battery.refresh = true; + + snprintf(drvdata->battery.name, sizeof(drvdata->battery.name), + "pulsar_%s_battery", dev_name(&usbdev->dev)); + + ret = hid_hw_start(hdev, HID_CONNECT_DEFAULT); + if (ret < 0) { + hid_err(hdev, "hw start failed\n"); + return ret; + } + + ret = hid_hw_open(hdev); + if (ret < 0) { + hid_err(hdev, "hw open failed\n"); + goto err_open; + } + + schedule_delayed_work(&drvdata->init_work, 0); + + return 0; + +err_open: + hid_hw_stop(hdev); + cancel_work_sync(&drvdata->power_uevent_work); + return ret; +} + +static void pulsar_remove(struct hid_device *hdev) +{ + struct pulsar_data *drvdata; + + drvdata = hid_get_drvdata(hdev); + if (!drvdata) { + hid_hw_stop(hdev); + return; + } + + atomic_set(&drvdata->stopping, 1); + + /* + * Drain init_work before the device is torn down. + * It cannot requeue itself because exec_cmd() fails with -ENODEV. + */ + cancel_delayed_work_sync(&drvdata->init_work); + + /* wait for active device i/o (exec_cmd) */ + mutex_lock(&drvdata->lock_cmd); + hid_hw_close(hdev); + mutex_unlock(&drvdata->lock_cmd); + + hid_hw_stop(hdev); + cancel_work_sync(&drvdata->power_uevent_work); +} + +static const struct hid_device_id pulsar_table[] = { + { HID_USB_DEVICE(USB_VENDOR_ID_PULSAR, USB_DEVICE_ID_PULSAR_WIRED), + .driver_data = TYPE_PULSAR }, + { HID_USB_DEVICE(USB_VENDOR_ID_PULSAR, USB_DEVICE_ID_PULSAR_1KHZ), + .driver_data = TYPE_PULSAR }, + { HID_USB_DEVICE(USB_VENDOR_ID_PULSAR, USB_DEVICE_ID_PULSAR_4KHZ), + .driver_data = TYPE_PULSAR }, + { HID_USB_DEVICE(USB_VENDOR_ID_KYSONA, USB_DEVICE_ID_KYSONA_M600_DONGLE), + .driver_data = TYPE_KYSONA }, + { HID_USB_DEVICE(USB_VENDOR_ID_KYSONA, USB_DEVICE_ID_KYSONA_M600_WIRED), + .driver_data = TYPE_KYSONA }, + { HID_USB_DEVICE(USB_VENDOR_ID_KYSONA, USB_DEVICE_ID_KYSONA_M600V2_DONGLE), + .driver_data = TYPE_KYSONA }, + { HID_USB_DEVICE(USB_VENDOR_ID_ATK, USB_DEVICE_ID_ATK_VXE_R1_SE_WIRED), + .driver_data = TYPE_ATK }, + { HID_USB_DEVICE(USB_VENDOR_ID_ATK_ALT, USB_DEVICE_ID_ATK_VXE_R1_SE_DONGLE), + .driver_data = TYPE_ATK }, + { HID_USB_DEVICE(USB_VENDOR_ID_VXE, USB_DEVICE_ID_VXE_DRAGONFLY_R1_PRO_DONGLE), + .driver_data = TYPE_VXE }, + { HID_USB_DEVICE(USB_VENDOR_ID_VXE, USB_DEVICE_ID_VXE_DRAGONFLY_R1_PRO_WIRED), + .driver_data = TYPE_VXE }, + { } +}; + +static struct hid_driver pulsar_driver = { + .name = "pulsar", + .id_table = pulsar_table, + .probe = pulsar_probe, + .remove = pulsar_remove, + .raw_event = pulsar_raw_event, +}; + +module_hid_driver(pulsar_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("HID driver for pulsar mice"); +MODULE_AUTHOR("Nikolas Koesling"); +MODULE_DEVICE_TABLE(hid, pulsar_table);
diff --git a/drivers/hid/hid-pxrc.c b/drivers/hid/hid-pxrc.c index 71fe0c0..e3755d8 100644 --- a/drivers/hid/hid-pxrc.c +++ b/drivers/hid/hid-pxrc.c
@@ -55,6 +55,9 @@ static int pxrc_raw_event(struct hid_device *hdev, struct hid_report *report, { struct pxrc_priv *priv = hid_get_drvdata(hdev); + if (size < 8) + return 0; + if (priv->alternate) priv->slider = data[7]; else
diff --git a/drivers/hid/hid-quirks.c b/drivers/hid/hid-quirks.c index 96a36c5..793db00 100644 --- a/drivers/hid/hid-quirks.c +++ b/drivers/hid/hid-quirks.c
@@ -102,6 +102,7 @@ static const struct hid_device_id hid_quirks[] = { { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FIGHTING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_HAPP, USB_DEVICE_ID_UGCI_FLYING), HID_QUIRK_BADPAD | HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A096), HID_QUIRK_NO_INIT_REPORTS }, + { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A292), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_HOLTEK_ALT, USB_DEVICE_ID_HOLTEK_ALT_KEYBOARD_A293), HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_LOGITECH_OEM_USB_OPTICAL_MOUSE_0A4A), HID_QUIRK_ALWAYS_POLL }, { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_HP, USB_PRODUCT_ID_HP_ELITE_PRESENTER_MOUSE_464A), HID_QUIRK_MULTI_INPUT }, @@ -222,6 +223,8 @@ static const struct hid_device_id hid_quirks[] = { { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP_LTD2, USB_DEVICE_ID_SMARTJOY_DUAL_PLUS), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_WISEGROUP, USB_DEVICE_ID_QUAD_USB_JOYPAD), HID_QUIRK_NOGET | HID_QUIRK_MULTI_INPUT }, { HID_USB_DEVICE(USB_VENDOR_ID_XIN_MO, USB_DEVICE_ID_XIN_MO_DUAL_ARCADE), HID_QUIRK_MULTI_INPUT }, + { HID_USB_DEVICE(USB_VENDOR_ID_YJXCHIP, USB_DEVICE_ID_YJXCHIP_MOUSE), + HID_QUIRK_ALWAYS_POLL }, { HID_USB_DEVICE(USB_VENDOR_ID_LOGITECH, USB_DEVICE_ID_LOGITECH_GROUP_AUDIO), HID_QUIRK_NOGET }, { 0 }
diff --git a/drivers/hid/hid-roccat-isku.c b/drivers/hid/hid-roccat-isku.c index 93a49c9..ef1ec9c 100644 --- a/drivers/hid/hid-roccat-isku.c +++ b/drivers/hid/hid-roccat-isku.c
@@ -411,6 +411,9 @@ static int isku_raw_event(struct hid_device *hdev, if (isku == NULL) return 0; + if (size < sizeof(struct isku_report_button)) + return 0; + isku_keep_values_up_to_date(isku, data); if (isku->roccat_claimed)
diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c index f80a605..df39868 100644 --- a/drivers/hid/hid-roccat-koneplus.c +++ b/drivers/hid/hid-roccat-koneplus.c
@@ -523,6 +523,9 @@ static int koneplus_raw_event(struct hid_device *hdev, if (koneplus == NULL) return 0; + if (size < sizeof(struct koneplus_mouse_report_button)) + return 0; + koneplus_keep_values_up_to_date(koneplus, data); if (koneplus->roccat_claimed)
diff --git a/drivers/hid/hid-roccat-konepure.c b/drivers/hid/hid-roccat-konepure.c index 7f753df..529466c 100644 --- a/drivers/hid/hid-roccat-konepure.c +++ b/drivers/hid/hid-roccat-konepure.c
@@ -181,6 +181,9 @@ static int konepure_raw_event(struct hid_device *hdev, != USB_INTERFACE_PROTOCOL_MOUSE) return 0; + if (size < sizeof(struct konepure_mouse_report_button)) + return 0; + if (data[0] != KONEPURE_MOUSE_REPORT_NUMBER_BUTTON) return 0;
diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c index 9ec42c2..26832b2 100644 --- a/drivers/hid/hid-roccat-kovaplus.c +++ b/drivers/hid/hid-roccat-kovaplus.c
@@ -614,6 +614,9 @@ static int kovaplus_raw_event(struct hid_device *hdev, if (kovaplus == NULL) return 0; + if (size < sizeof(struct kovaplus_mouse_report_button)) + return 0; + kovaplus_keep_values_up_to_date(kovaplus, data); if (kovaplus->roccat_claimed)
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index 0d51599..44c2b416 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c
@@ -557,6 +557,9 @@ static int pyra_raw_event(struct hid_device *hdev, struct hid_report *report, if (pyra == NULL) return 0; + if (size < sizeof(struct pyra_mouse_event_button)) + return 0; + pyra_keep_values_up_to_date(pyra, data); if (pyra->roccat_claimed)
diff --git a/drivers/hid/hid-roccat-ryos.c b/drivers/hid/hid-roccat-ryos.c index db83f42..85df795 100644 --- a/drivers/hid/hid-roccat-ryos.c +++ b/drivers/hid/hid-roccat-ryos.c
@@ -189,6 +189,9 @@ static int ryos_raw_event(struct hid_device *hdev, != RYOS_USB_INTERFACE_PROTOCOL) return 0; + if (size < sizeof(struct ryos_report_special)) + return 0; + if (data[0] != RYOS_REPORT_NUMBER_SPECIAL) return 0;
diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c index 6791369..cfd8626 100644 --- a/drivers/hid/hid-roccat-savu.c +++ b/drivers/hid/hid-roccat-savu.c
@@ -182,6 +182,9 @@ static int savu_raw_event(struct hid_device *hdev, if (savu == NULL) return 0; + if (size < sizeof(struct savu_mouse_report_special)) + return 0; + if (savu->roccat_claimed) savu_report_to_chrdev(savu, data);
diff --git a/drivers/hid/hid-roccat.c b/drivers/hid/hid-roccat.c index 5deb6da..b3e69c7 100644 --- a/drivers/hid/hid-roccat.c +++ b/drivers/hid/hid-roccat.c
@@ -211,24 +211,19 @@ static int roccat_open(struct inode *inode, struct file *file) static int roccat_release(struct inode *inode, struct file *file) { - unsigned int minor = iminor(inode); struct roccat_reader *reader = file->private_data; - struct roccat_device *device; + struct roccat_device *device = reader->device; - mutex_lock(&devices_lock); - - device = devices[minor]; - if (!device) { - mutex_unlock(&devices_lock); - pr_emerg("roccat device with minor %d doesn't exist\n", minor); + if (WARN_ON(!device)) return -ENODEV; - } mutex_lock(&device->readers_lock); list_del(&reader->node); mutex_unlock(&device->readers_lock); kfree(reader); + mutex_lock(&devices_lock); + if (!--device->open) { /* removing last reader */ if (device->exist) {
diff --git a/drivers/hid/hid-wiimote-core.c b/drivers/hid/hid-wiimote-core.c index 63c4fa8..9168b85 100644 --- a/drivers/hid/hid-wiimote-core.c +++ b/drivers/hid/hid-wiimote-core.c
@@ -7,6 +7,7 @@ /* */ +#include <linux/cleanup.h> #include <linux/completion.h> #include <linux/device.h> #include <linux/hid.h> @@ -362,13 +363,12 @@ void wiiproto_req_rmem(struct wiimote_data *wdata, bool eeprom, __u32 offset, int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset, const __u8 *wmem, __u8 size) { - unsigned long flags; int ret; - spin_lock_irqsave(&wdata->state.lock, flags); - wiimote_cmd_set(wdata, WIIPROTO_REQ_WMEM, 0); - wiiproto_req_wreg(wdata, offset, wmem, size); - spin_unlock_irqrestore(&wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &wdata->state.lock) { + wiimote_cmd_set(wdata, WIIPROTO_REQ_WMEM, 0); + wiiproto_req_wreg(wdata, offset, wmem, size); + } ret = wiimote_cmd_wait(wdata); if (!ret && wdata->state.cmd_err) @@ -381,21 +381,19 @@ int wiimote_cmd_write(struct wiimote_data *wdata, __u32 offset, ssize_t wiimote_cmd_read(struct wiimote_data *wdata, __u32 offset, __u8 *rmem, __u8 size) { - unsigned long flags; ssize_t ret; - spin_lock_irqsave(&wdata->state.lock, flags); - wdata->state.cmd_read_size = size; - wdata->state.cmd_read_buf = rmem; - wiimote_cmd_set(wdata, WIIPROTO_REQ_RMEM, offset & 0xffff); - wiiproto_req_rreg(wdata, offset, size); - spin_unlock_irqrestore(&wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &wdata->state.lock) { + wdata->state.cmd_read_size = size; + wdata->state.cmd_read_buf = rmem; + wiimote_cmd_set(wdata, WIIPROTO_REQ_RMEM, offset & 0xffff); + wiiproto_req_rreg(wdata, offset, size); + } ret = wiimote_cmd_wait(wdata); - spin_lock_irqsave(&wdata->state.lock, flags); - wdata->state.cmd_read_buf = NULL; - spin_unlock_irqrestore(&wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &wdata->state.lock) + wdata->state.cmd_read_buf = NULL; if (!ret) { if (wdata->state.cmd_read_size == 0) @@ -621,6 +619,13 @@ static const __u8 * const wiimote_devtype_mods[WIIMOTE_DEV_NUM] = { }, }; +static const __u8 player_leds[] = { + WIIPROTO_FLAG_LED1, + WIIPROTO_FLAG_LED2, + WIIPROTO_FLAG_LED3, + WIIPROTO_FLAG_LED4 +}; + static void wiimote_modules_load(struct wiimote_data *wdata, unsigned int devtype) { @@ -668,9 +673,13 @@ static void wiimote_modules_load(struct wiimote_data *wdata, goto error; } - spin_lock_irq(&wdata->state.lock); - wdata->state.devtype = devtype; - spin_unlock_irq(&wdata->state.lock); + scoped_guard(spinlock_irqsave, &wdata->state.lock) { + wdata->state.devtype = devtype; + /* after loading modules, set the Player ID LED cycling the available LEDs*/ + wiiproto_req_leds(wdata, + player_leds[(wdata->player_id - 1U) % ARRAY_SIZE(player_leds)]); + } + return; error: @@ -690,13 +699,11 @@ static void wiimote_modules_unload(struct wiimote_data *wdata) { const __u8 *mods, *iter; const struct wiimod_ops *ops; - unsigned long flags; mods = wiimote_devtype_mods[wdata->state.devtype]; - spin_lock_irqsave(&wdata->state.lock, flags); - wdata->state.devtype = WIIMOTE_DEV_UNKNOWN; - spin_unlock_irqrestore(&wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &wdata->state.lock) + wdata->state.devtype = WIIMOTE_DEV_UNKNOWN; /* find end of list */ for (iter = mods; *iter != WIIMOD_NULL; ++iter) @@ -723,7 +730,6 @@ static void wiimote_modules_unload(struct wiimote_data *wdata) static void wiimote_ext_load(struct wiimote_data *wdata, unsigned int ext) { - unsigned long flags; const struct wiimod_ops *ops; int ret; @@ -735,22 +741,20 @@ static void wiimote_ext_load(struct wiimote_data *wdata, unsigned int ext) ext = WIIMOTE_EXT_UNKNOWN; } - spin_lock_irqsave(&wdata->state.lock, flags); - wdata->state.exttype = ext; - spin_unlock_irqrestore(&wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &wdata->state.lock) + wdata->state.exttype = ext; } static void wiimote_ext_unload(struct wiimote_data *wdata) { - unsigned long flags; const struct wiimod_ops *ops; ops = wiimod_ext_table[wdata->state.exttype]; - spin_lock_irqsave(&wdata->state.lock, flags); - wdata->state.exttype = WIIMOTE_EXT_UNKNOWN; - wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED; - spin_unlock_irqrestore(&wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &wdata->state.lock) { + wdata->state.exttype = WIIMOTE_EXT_UNKNOWN; + wdata->state.flags &= ~WIIPROTO_FLAG_EXT_USED; + } if (ops->remove) ops->remove(ops, wdata); @@ -758,7 +762,6 @@ static void wiimote_ext_unload(struct wiimote_data *wdata) static void wiimote_mp_load(struct wiimote_data *wdata) { - unsigned long flags; const struct wiimod_ops *ops; int ret; __u8 mode = 2; @@ -770,14 +773,12 @@ static void wiimote_mp_load(struct wiimote_data *wdata) mode = 1; } - spin_lock_irqsave(&wdata->state.lock, flags); - wdata->state.mp = mode; - spin_unlock_irqrestore(&wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &wdata->state.lock) + wdata->state.mp = mode; } static void wiimote_mp_unload(struct wiimote_data *wdata) { - unsigned long flags; const struct wiimod_ops *ops; if (wdata->state.mp < 2) @@ -785,10 +786,10 @@ static void wiimote_mp_unload(struct wiimote_data *wdata) ops = &wiimod_mp; - spin_lock_irqsave(&wdata->state.lock, flags); - wdata->state.mp = 0; - wdata->state.flags &= ~WIIPROTO_FLAG_MP_USED; - spin_unlock_irqrestore(&wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &wdata->state.lock) { + wdata->state.mp = 0; + wdata->state.flags &= ~WIIPROTO_FLAG_MP_USED; + } if (ops->remove) ops->remove(ops, wdata); @@ -855,11 +856,11 @@ static void wiimote_init_set_type(struct wiimote_data *wdata, done: if (devtype == WIIMOTE_DEV_GENERIC) - hid_info(wdata->hdev, "cannot detect device; NAME: %s VID: %04x PID: %04x EXT: %04x\n", - name, vendor, product, exttype); + hid_info(wdata->hdev, "cannot detect device; NAME: %s VID: %04x PID: %04x EXT: %04x (%d)\n", + name, vendor, product, exttype, wdata->player_id); else - hid_info(wdata->hdev, "detected device: %s\n", - wiimote_devtype_names[devtype]); + hid_info(wdata->hdev, "detected device: %s (%d)\n", + wiimote_devtype_names[devtype], wdata->player_id); wiimote_modules_load(wdata, devtype); } @@ -872,19 +873,19 @@ static void wiimote_init_detect(struct wiimote_data *wdata) wiimote_cmd_acquire_noint(wdata); - spin_lock_irq(&wdata->state.lock); - wdata->state.devtype = WIIMOTE_DEV_UNKNOWN; - wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0); - wiiproto_req_status(wdata); - spin_unlock_irq(&wdata->state.lock); + scoped_guard(spinlock_irq, &wdata->state.lock) { + wdata->state.devtype = WIIMOTE_DEV_UNKNOWN; + wiimote_cmd_set(wdata, WIIPROTO_REQ_SREQ, 0); + wiiproto_req_status(wdata); + } + ret = wiimote_cmd_wait_noint(wdata); if (ret) goto out_release; - spin_lock_irq(&wdata->state.lock); - ext = wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED; - spin_unlock_irq(&wdata->state.lock); + scoped_guard(spinlock_irq, &wdata->state.lock) + ext = wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED; if (!ext) goto out_release; @@ -897,11 +898,11 @@ static void wiimote_init_detect(struct wiimote_data *wdata) wiimote_init_set_type(wdata, exttype); /* schedule MP timer */ - spin_lock_irq(&wdata->state.lock); - if (!(wdata->state.flags & WIIPROTO_FLAG_BUILTIN_MP) && - !(wdata->state.flags & WIIPROTO_FLAG_NO_MP)) - mod_timer(&wdata->timer, jiffies + HZ * 4); - spin_unlock_irq(&wdata->state.lock); + scoped_guard(spinlock_irq, &wdata->state.lock) { + if (!(wdata->state.flags & WIIPROTO_FLAG_BUILTIN_MP) && + !(wdata->state.flags & WIIPROTO_FLAG_NO_MP)) + mod_timer(&wdata->timer, jiffies + HZ * 4); + } } /* @@ -949,9 +950,8 @@ static bool wiimote_init_check(struct wiimote_data *wdata) __u8 type, data[6]; bool ret, poll_mp; - spin_lock_irq(&wdata->state.lock); - flags = wdata->state.flags; - spin_unlock_irq(&wdata->state.lock); + scoped_guard(spinlock_irq, &wdata->state.lock) + flags = wdata->state.flags; wiimote_cmd_acquire_noint(wdata); @@ -967,11 +967,11 @@ static bool wiimote_init_check(struct wiimote_data *wdata) type = wiimote_cmd_read_mp_mapped(wdata); ret = type == WIIMOTE_MP_SINGLE; - spin_lock_irq(&wdata->state.lock); - ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE); - ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_PLUGGED); - ret = ret && (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE); - spin_unlock_irq(&wdata->state.lock); + scoped_guard(spinlock_irq, &wdata->state.lock) { + ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE); + ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_PLUGGED); + ret = ret && (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE); + } if (!ret) hid_dbg(wdata->hdev, "state left: !EXT && MP\n"); @@ -992,10 +992,10 @@ static bool wiimote_init_check(struct wiimote_data *wdata) type = wiimote_cmd_read_ext(wdata, data); ret = type == wdata->state.exttype; - spin_lock_irq(&wdata->state.lock); - ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE); - ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE); - spin_unlock_irq(&wdata->state.lock); + scoped_guard(spinlock_irq, &wdata->state.lock) { + ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE); + ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE); + } if (!ret) hid_dbg(wdata->hdev, "state left: EXT && !MP\n"); @@ -1018,11 +1018,11 @@ static bool wiimote_init_check(struct wiimote_data *wdata) type = wiimote_cmd_read_ext(wdata, data); ret = type == wdata->state.exttype; - spin_lock_irq(&wdata->state.lock); - ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE); - ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE); - ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED); - spin_unlock_irq(&wdata->state.lock); + scoped_guard(spinlock_irq, &wdata->state.lock) { + ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE); + ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE); + ret = ret && !(wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED); + } if (!ret) hid_dbg(wdata->hdev, "state left: !EXT && !MP\n"); @@ -1048,11 +1048,11 @@ static bool wiimote_init_check(struct wiimote_data *wdata) ret = ret && type != WIIMOTE_MP_UNKNOWN; ret = ret && type != WIIMOTE_MP_SINGLE; - spin_lock_irq(&wdata->state.lock); - ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED); - ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE); - ret = ret && (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE); - spin_unlock_irq(&wdata->state.lock); + scoped_guard(spinlock_irq, &wdata->state.lock) { + ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_PLUGGED); + ret = ret && (wdata->state.flags & WIIPROTO_FLAG_EXT_ACTIVE); + ret = ret && (wdata->state.flags & WIIPROTO_FLAG_MP_ACTIVE); + } if (!ret) hid_dbg(wdata->hdev, "state left: EXT && MP\n"); @@ -1107,16 +1107,14 @@ static void wiimote_init_hotplug(struct wiimote_data *wdata) wiimote_cmd_acquire_noint(wdata); - spin_lock_irq(&wdata->state.lock); + scoped_guard(spinlock_irq, &wdata->state.lock) { + /* get state snapshot that we will then work on */ + flags = wdata->state.flags; - /* get state snapshot that we will then work on */ - flags = wdata->state.flags; - - /* disable event forwarding temporarily */ - wdata->state.flags &= ~WIIPROTO_FLAG_EXT_ACTIVE; - wdata->state.flags &= ~WIIPROTO_FLAG_MP_ACTIVE; - - spin_unlock_irq(&wdata->state.lock); + /* disable event forwarding temporarily */ + wdata->state.flags &= ~WIIPROTO_FLAG_EXT_ACTIVE; + wdata->state.flags &= ~WIIPROTO_FLAG_MP_ACTIVE; + } /* init extension and MP (deactivates current extension or MP) */ wiimote_cmd_init_ext(wdata); @@ -1139,9 +1137,8 @@ static void wiimote_init_hotplug(struct wiimote_data *wdata) hid_info(wdata->hdev, "cannot detect extension; %6phC\n", extdata); } else if (exttype == WIIMOTE_EXT_NONE) { - spin_lock_irq(&wdata->state.lock); - wdata->state.exttype = WIIMOTE_EXT_NONE; - spin_unlock_irq(&wdata->state.lock); + scoped_guard(spinlock_irq, &wdata->state.lock) + wdata->state.exttype = WIIMOTE_EXT_NONE; } else { hid_info(wdata->hdev, "detected extension: %s\n", wiimote_exttype_names[exttype]); @@ -1179,28 +1176,26 @@ static void wiimote_init_hotplug(struct wiimote_data *wdata) mod_timer(&wdata->timer, jiffies + HZ * 4); } - spin_lock_irq(&wdata->state.lock); - - /* enable data forwarding again and set expected hotplug state */ - if (mp) { - wdata->state.flags |= WIIPROTO_FLAG_MP_ACTIVE; - if (wdata->state.exttype == WIIMOTE_EXT_NONE) { - wdata->state.flags &= ~WIIPROTO_FLAG_EXT_PLUGGED; - wdata->state.flags &= ~WIIPROTO_FLAG_MP_PLUGGED; - } else { - wdata->state.flags &= ~WIIPROTO_FLAG_EXT_PLUGGED; - wdata->state.flags |= WIIPROTO_FLAG_MP_PLUGGED; + scoped_guard(spinlock_irq, &wdata->state.lock) { + /* enable data forwarding again and set expected hotplug state */ + if (mp) { + wdata->state.flags |= WIIPROTO_FLAG_MP_ACTIVE; + if (wdata->state.exttype == WIIMOTE_EXT_NONE) { + wdata->state.flags &= ~WIIPROTO_FLAG_EXT_PLUGGED; + wdata->state.flags &= ~WIIPROTO_FLAG_MP_PLUGGED; + } else { + wdata->state.flags &= ~WIIPROTO_FLAG_EXT_PLUGGED; + wdata->state.flags |= WIIPROTO_FLAG_MP_PLUGGED; + wdata->state.flags |= WIIPROTO_FLAG_EXT_ACTIVE; + } + } else if (wdata->state.exttype != WIIMOTE_EXT_NONE) { wdata->state.flags |= WIIPROTO_FLAG_EXT_ACTIVE; } - } else if (wdata->state.exttype != WIIMOTE_EXT_NONE) { - wdata->state.flags |= WIIPROTO_FLAG_EXT_ACTIVE; + + /* request status report for hotplug state updates */ + wiiproto_req_status(wdata); } - /* request status report for hotplug state updates */ - wiiproto_req_status(wdata); - - spin_unlock_irq(&wdata->state.lock); - hid_dbg(wdata->hdev, "detected extensions: MP: %d EXT: %d\n", wdata->state.mp, wdata->state.exttype); } @@ -1231,11 +1226,8 @@ void __wiimote_schedule(struct wiimote_data *wdata) static void wiimote_schedule(struct wiimote_data *wdata) { - unsigned long flags; - - spin_lock_irqsave(&wdata->state.lock, flags); - __wiimote_schedule(wdata); - spin_unlock_irqrestore(&wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &wdata->state.lock) + __wiimote_schedule(wdata); } static void wiimote_init_timeout(struct timer_list *t) @@ -1625,7 +1617,6 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report, struct wiimote_data *wdata = hid_get_drvdata(hdev); const struct wiiproto_handler *h; int i; - unsigned long flags; if (size < 1) return -EINVAL; @@ -1633,9 +1624,8 @@ static int wiimote_hid_event(struct hid_device *hdev, struct hid_report *report, for (i = 0; handlers[i].id; ++i) { h = &handlers[i]; if (h->id == raw_data[0] && h->size < size) { - spin_lock_irqsave(&wdata->state.lock, flags); - h->func(wdata, &raw_data[1]); - spin_unlock_irqrestore(&wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &wdata->state.lock) + h->func(wdata, &raw_data[1]); break; } } @@ -1653,11 +1643,9 @@ static ssize_t wiimote_ext_show(struct device *dev, { struct wiimote_data *wdata = dev_to_wii(dev); __u8 type; - unsigned long flags; - spin_lock_irqsave(&wdata->state.lock, flags); - type = wdata->state.exttype; - spin_unlock_irqrestore(&wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &wdata->state.lock) + type = wdata->state.exttype; switch (type) { case WIIMOTE_EXT_NONE: @@ -1706,11 +1694,9 @@ static ssize_t wiimote_dev_show(struct device *dev, { struct wiimote_data *wdata = dev_to_wii(dev); __u8 type; - unsigned long flags; - spin_lock_irqsave(&wdata->state.lock, flags); - type = wdata->state.devtype; - spin_unlock_irqrestore(&wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &wdata->state.lock) + type = wdata->state.devtype; switch (type) { case WIIMOTE_DEV_GENERIC: @@ -1752,6 +1738,7 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev) mutex_init(&wdata->state.sync); wdata->state.drm = WIIPROTO_REQ_DRM_K; wdata->state.cmd_battery = 0xff; + wdata->player_id = 0; // min 1, u8 0 is unassigned id INIT_WORK(&wdata->init_worker, wiimote_init_worker); timer_setup(&wdata->timer, wiimote_init_timeout, 0); @@ -1759,16 +1746,19 @@ static struct wiimote_data *wiimote_create(struct hid_device *hdev) return wdata; } +/* Global id allocator for wii remotes */ +static DEFINE_IDA(wiimote_ida); + static void wiimote_destroy(struct wiimote_data *wdata) { - unsigned long flags; - wiidebug_deinit(wdata); + if (wdata->player_id > 0) + ida_free(&wiimote_ida, wdata->player_id); + /* prevent init_worker from being scheduled again */ - spin_lock_irqsave(&wdata->state.lock, flags); - wdata->state.flags |= WIIPROTO_FLAG_EXITING; - spin_unlock_irqrestore(&wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &wdata->state.lock) + wdata->state.flags |= WIIPROTO_FLAG_EXITING; cancel_work_sync(&wdata->init_worker); timer_shutdown_sync(&wdata->timer); @@ -1834,7 +1824,14 @@ static int wiimote_hid_probe(struct hid_device *hdev, if (ret) goto err_free; - hid_info(hdev, "New device registered\n"); + ret = ida_alloc_range(&wiimote_ida, 1, 255, GFP_KERNEL); + if (ret < 1) { + hid_err(hdev, "cannot allocate controller id\n"); + goto err_free; + } + + wdata->player_id = ret; + hid_info(hdev, "New device registered (Wiimote %d)\n", wdata->player_id); /* schedule device detection */ wiimote_schedule(wdata); @@ -1887,7 +1884,21 @@ static struct hid_driver wiimote_hid_driver = { .remove = wiimote_hid_remove, .raw_event = wiimote_hid_event, }; -module_hid_driver(wiimote_hid_driver); + + +static int __init wiimote_init(void) +{ + return hid_register_driver(&wiimote_hid_driver); +} + +static void __exit wiimote_exit(void) +{ + hid_unregister_driver(&wiimote_hid_driver); + ida_destroy(&wiimote_ida); +} + +module_init(wiimote_init); +module_exit(wiimote_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("David Herrmann <dh.herrmann@gmail.com>");
diff --git a/drivers/hid/hid-wiimote-debug.c b/drivers/hid/hid-wiimote-debug.c index 5f74917..b8027bb 100644 --- a/drivers/hid/hid-wiimote-debug.c +++ b/drivers/hid/hid-wiimote-debug.c
@@ -7,12 +7,13 @@ /* */ -#include <linux/debugfs.h> -#include <linux/module.h> -#include <linux/seq_file.h> -#include <linux/spinlock.h> -#include <linux/uaccess.h> -#include "hid-wiimote.h" + #include <linux/cleanup.h> + #include <linux/debugfs.h> + #include <linux/module.h> + #include <linux/seq_file.h> + #include <linux/spinlock.h> + #include <linux/uaccess.h> + #include "hid-wiimote.h" struct wiimote_debug { struct wiimote_data *wdata; @@ -25,7 +26,6 @@ static ssize_t wiidebug_eeprom_read(struct file *f, char __user *u, size_t s, { struct wiimote_debug *dbg = f->private_data; struct wiimote_data *wdata = dbg->wdata; - unsigned long flags; ssize_t ret; char buf[16]; __u16 size = 0; @@ -41,20 +41,19 @@ static ssize_t wiidebug_eeprom_read(struct file *f, char __user *u, size_t s, if (ret) return ret; - spin_lock_irqsave(&wdata->state.lock, flags); - wdata->state.cmd_read_size = s; - wdata->state.cmd_read_buf = buf; - wiimote_cmd_set(wdata, WIIPROTO_REQ_RMEM, *off & 0xffff); - wiiproto_req_reeprom(wdata, *off, s); - spin_unlock_irqrestore(&wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &wdata->state.lock) { + wdata->state.cmd_read_size = s; + wdata->state.cmd_read_buf = buf; + wiimote_cmd_set(wdata, WIIPROTO_REQ_RMEM, *off & 0xffff); + wiiproto_req_reeprom(wdata, *off, s); + } ret = wiimote_cmd_wait(wdata); if (!ret) size = wdata->state.cmd_read_size; - spin_lock_irqsave(&wdata->state.lock, flags); - wdata->state.cmd_read_buf = NULL; - spin_unlock_irqrestore(&wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &wdata->state.lock) + wdata->state.cmd_read_buf = NULL; wiimote_cmd_release(wdata); @@ -99,12 +98,10 @@ static int wiidebug_drm_show(struct seq_file *f, void *p) { struct wiimote_debug *dbg = f->private; const char *str = NULL; - unsigned long flags; __u8 drm; - spin_lock_irqsave(&dbg->wdata->state.lock, flags); - drm = dbg->wdata->state.drm; - spin_unlock_irqrestore(&dbg->wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &dbg->wdata->state.lock) + drm = dbg->wdata->state.drm; if (drm < WIIPROTO_REQ_MAX) str = wiidebug_drmmap[drm]; @@ -126,7 +123,6 @@ static ssize_t wiidebug_drm_write(struct file *f, const char __user *u, { struct seq_file *sf = f->private_data; struct wiimote_debug *dbg = sf->private; - unsigned long flags; char buf[16]; ssize_t len; int i; @@ -150,12 +146,12 @@ static ssize_t wiidebug_drm_write(struct file *f, const char __user *u, if (i == WIIPROTO_REQ_MAX) i = simple_strtoul(buf, NULL, 16); - spin_lock_irqsave(&dbg->wdata->state.lock, flags); - dbg->wdata->state.flags &= ~WIIPROTO_FLAG_DRM_LOCKED; - wiiproto_req_drm(dbg->wdata, (__u8) i); - if (i != WIIPROTO_REQ_NULL) - dbg->wdata->state.flags |= WIIPROTO_FLAG_DRM_LOCKED; - spin_unlock_irqrestore(&dbg->wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &dbg->wdata->state.lock) { + dbg->wdata->state.flags &= ~WIIPROTO_FLAG_DRM_LOCKED; + wiiproto_req_drm(dbg->wdata, (__u8) i); + if (i != WIIPROTO_REQ_NULL) + dbg->wdata->state.flags |= WIIPROTO_FLAG_DRM_LOCKED; + } return len; } @@ -172,7 +168,6 @@ static const struct file_operations wiidebug_drm_fops = { int wiidebug_init(struct wiimote_data *wdata) { struct wiimote_debug *dbg; - unsigned long flags; dbg = kzalloc_obj(*dbg); if (!dbg) @@ -186,27 +181,27 @@ int wiidebug_init(struct wiimote_data *wdata) dbg->drm = debugfs_create_file("drm", S_IRUSR, dbg->wdata->hdev->debug_dir, dbg, &wiidebug_drm_fops); - spin_lock_irqsave(&wdata->state.lock, flags); - wdata->debug = dbg; - spin_unlock_irqrestore(&wdata->state.lock, flags); + debugfs_create_u8("player_id", S_IRUSR, + dbg->wdata->hdev->debug_dir, &wdata->player_id); + + scoped_guard(spinlock_irqsave, &wdata->state.lock) + wdata->debug = dbg; return 0; - } void wiidebug_deinit(struct wiimote_data *wdata) { struct wiimote_debug *dbg = wdata->debug; - unsigned long flags; if (!dbg) return; - spin_lock_irqsave(&wdata->state.lock, flags); - wdata->debug = NULL; - spin_unlock_irqrestore(&wdata->state.lock, flags); + scoped_guard(spinlock_irqsave, &wdata->state.lock) + wdata->debug = NULL; debugfs_remove(dbg->drm); debugfs_remove(dbg->eeprom); + debugfs_lookup_and_remove("player_id", dbg->wdata->hdev->debug_dir); kfree(dbg); }
diff --git a/drivers/hid/hid-wiimote-modules.c b/drivers/hid/hid-wiimote-modules.c index dccb78b..199589c 100644 --- a/drivers/hid/hid-wiimote-modules.c +++ b/drivers/hid/hid-wiimote-modules.c
@@ -30,6 +30,7 @@ * input devices. */ +#include <linux/cleanup.h> #include <linux/device.h> #include <linux/hid.h> #include <linux/input.h> @@ -338,10 +339,9 @@ static void wiimod_led_set(struct led_classdev *led_dev, static int wiimod_led_probe(const struct wiimod_ops *ops, struct wiimote_data *wdata) { + struct led_classdev *led __free(kfree) = NULL; struct device *dev = &wdata->hdev->dev; size_t namesz = strlen(dev_name(dev)) + 9; - struct led_classdev *led; - unsigned long flags; char *name; int ret; @@ -359,22 +359,14 @@ static int wiimod_led_probe(const struct wiimod_ops *ops, wdata->leds[ops->arg] = led; ret = led_classdev_register(dev, led); - if (ret) - goto err_free; - - /* enable LED1 to stop initial LED-blinking */ - if (ops->arg == 0) { - spin_lock_irqsave(&wdata->state.lock, flags); - wiiproto_req_leds(wdata, WIIPROTO_FLAG_LED1); - spin_unlock_irqrestore(&wdata->state.lock, flags); + if (ret) { + wdata->leds[ops->arg] = NULL; + return ret; } - return 0; + retain_and_null_ptr(led); -err_free: - wdata->leds[ops->arg] = NULL; - kfree(led); - return ret; + return 0; } static void wiimod_led_remove(const struct wiimod_ops *ops,
diff --git a/drivers/hid/hid-wiimote.h b/drivers/hid/hid-wiimote.h index 9c12f63..8e5002f 100644 --- a/drivers/hid/hid-wiimote.h +++ b/drivers/hid/hid-wiimote.h
@@ -153,6 +153,7 @@ struct wiimote_data { struct input_dev *mp; struct timer_list timer; struct wiimote_debug *debug; + u8 player_id; union { struct input_dev *input;
diff --git a/drivers/hid/hid-zydacron.c b/drivers/hid/hid-zydacron.c index 1aae80f..02de153 100644 --- a/drivers/hid/hid-zydacron.c +++ b/drivers/hid/hid-zydacron.c
@@ -114,6 +114,9 @@ static int zc_raw_event(struct hid_device *hdev, struct hid_report *report, unsigned key; unsigned short index; + if (size < 2) + return 0; + if (report->id == data[0] && (hdev->claimed & HID_CLAIMED_INPUT)) { /* break keys */
diff --git a/drivers/hid/i2c-hid/i2c-hid-acpi.c b/drivers/hid/i2c-hid/i2c-hid-acpi.c index 13f977d..9371db2 100644 --- a/drivers/hid/i2c-hid/i2c-hid-acpi.c +++ b/drivers/hid/i2c-hid/i2c-hid-acpi.c
@@ -39,12 +39,12 @@ static const struct acpi_device_id i2c_hid_acpi_blacklist[] = { * The CHPN0001 ACPI device, which is used to describe the Chipone * ICN8505 controller, has a _CID of PNP0C50 but is not HID compatible. */ - { "CHPN0001" }, + { .id = "CHPN0001" }, /* * The IDEA5002 ACPI device causes high interrupt usage and spurious * wakeups from suspend. */ - { "IDEA5002" }, + { .id = "IDEA5002" }, { } }; @@ -93,8 +93,8 @@ static int i2c_hid_acpi_probe(struct i2c_client *client) } static const struct acpi_device_id i2c_hid_acpi_match[] = { - { "ACPI0C50" }, - { "PNP0C50" }, + { .id = "ACPI0C50" }, + { .id = "PNP0C50" }, { } }; MODULE_DEVICE_TABLE(acpi, i2c_hid_acpi_match);
diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c index a61fd1d..a8a9854 100644 --- a/drivers/hid/i2c-hid/i2c-hid-core.c +++ b/drivers/hid/i2c-hid/i2c-hid-core.c
@@ -1357,7 +1357,16 @@ void i2c_hid_core_shutdown(struct i2c_client *client) { struct i2c_hid *ihid = i2c_get_clientdata(client); - i2c_hid_set_power(ihid, I2C_HID_PWR_SLEEP); + /* + * Like in i2c_hid_core_remove(): if we're a follower, the act of + * unfollowing will cause us to be powered down. Otherwise we need to + * manually do it. + */ + if (ihid->is_panel_follower) + drm_panel_remove_follower(&ihid->panel_follower); + else + i2c_hid_set_power(ihid, I2C_HID_PWR_SLEEP); + free_irq(client->irq, ihid); i2c_hid_core_shutdown_tail(ihid);
diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c index 2537288..7a913f71 100644 --- a/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c +++ b/drivers/hid/intel-thc-hid/intel-quicki2c/pci-quicki2c.c
@@ -315,7 +315,7 @@ static int handle_input_report(struct quicki2c_device *qcdev) if (qcdev->state != QUICKI2C_ENABLED) continue; - quicki2c_hid_send_report(qcdev, pkt->data, + quicki2c_hid_send_report(qcdev, pkt->data, qcdev->input_len, HIDI2C_DATA_LEN(le16_to_cpu(pkt->len))); } @@ -611,6 +611,8 @@ static int quicki2c_alloc_report_buf(struct quicki2c_device *qcdev) if (!qcdev->input_buf) return -ENOMEM; + qcdev->input_len = max_report_len; + if (!le16_to_cpu(qcdev->dev_desc.max_output_len)) qcdev->dev_desc.max_output_len = cpu_to_le16(SZ_4K);
diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h index 6d25a84..e9ff044 100644 --- a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h +++ b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-dev.h
@@ -181,6 +181,7 @@ struct acpi_device; * @low_power_ltr_val: THC low power LTR value * @report_descriptor: Store a copy of device report descriptor * @input_buf: Store a copy of latest input report data + * @input_len: The data size of the input report buffer * @report_buf: Store a copy of latest input/output report packet from set/get feature * @report_len: The length of input/output report packet * @reset_ack_wq: Workqueue for waiting reset response from device @@ -212,6 +213,7 @@ struct quicki2c_device { u8 *report_descriptor; u8 *input_buf; + size_t input_len; u8 *report_buf; size_t report_len;
diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-hid.c b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-hid.c index 8075992..1a220a50 100644 --- a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-hid.c +++ b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-hid.c
@@ -157,16 +157,18 @@ void quicki2c_hid_remove(struct quicki2c_device *qcdev) * * @qcdev: point to quicki2c device * @data: point to input report data buffer + * @buf_size: the allocated size of the input report data buffer * @data_len: the length of input report data * * Return: 0 on success, non zero on error. */ int quicki2c_hid_send_report(struct quicki2c_device *qcdev, - void *data, size_t data_len) + void *data, size_t buf_size, size_t data_len) { int ret; - ret = hid_input_report(qcdev->hid_dev, HID_INPUT_REPORT, data, data_len, 1); + ret = hid_safe_input_report(qcdev->hid_dev, HID_INPUT_REPORT, data, + buf_size, data_len, 1); if (ret) dev_err(qcdev->dev, "Failed to send HID input report, ret = %d.\n", ret);
diff --git a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-hid.h b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-hid.h index e80df5f..4c6757e 100644 --- a/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-hid.h +++ b/drivers/hid/intel-thc-hid/intel-quicki2c/quicki2c-hid.h
@@ -7,7 +7,7 @@ struct quicki2c_device; int quicki2c_hid_send_report(struct quicki2c_device *qcdev, - void *data, size_t data_size); + void *data, size_t buf_size, size_t data_size); int quicki2c_hid_probe(struct quicki2c_device *qcdev); void quicki2c_hid_remove(struct quicki2c_device *qcdev);
diff --git a/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c b/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c index ad676fd..53023e3 100644 --- a/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c +++ b/drivers/hid/intel-thc-hid/intel-quickspi/pci-quickspi.c
@@ -557,6 +557,8 @@ static int quickspi_alloc_report_buf(struct quickspi_device *qsdev) if (!qsdev->input_buf) return -ENOMEM; + qsdev->input_len = max_input_len; + max_report_len = max(le16_to_cpu(qsdev->dev_desc.max_output_len), le16_to_cpu(qsdev->dev_desc.max_input_len));
diff --git a/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-dev.h b/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-dev.h index dc67a39..fe51ff5 100644 --- a/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-dev.h +++ b/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-dev.h
@@ -113,6 +113,7 @@ struct acpi_device; * @low_power_ltr_val: THC low power LTR value * @report_descriptor: store a copy of device report descriptor * @input_buf: store a copy of latest input report data + * @input_len: the data size of the input report buffer * @report_buf: store a copy of latest input/output report packet from set/get feature * @report_len: the length of input/output report packet * @reset_ack_wq: workqueue for waiting reset response from device @@ -159,6 +160,7 @@ struct quickspi_device { u8 *report_descriptor; u8 *input_buf; + u32 input_len; u8 *report_buf; u32 report_buf_size; u32 report_len;
diff --git a/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-hid.c b/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-hid.c index a60a0a7..ed1c40b 100644 --- a/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-hid.c +++ b/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-hid.c
@@ -148,16 +148,18 @@ void quickspi_hid_remove(struct quickspi_device *qsdev) * * @qsdev: point to quickspi device * @data: point to input report data buffer + * @buf_size: the allocated size of the input report data buffer * @data_len: the length of input report data * * Return: 0 on success, non zero on error. */ int quickspi_hid_send_report(struct quickspi_device *qsdev, - void *data, size_t data_len) + void *data, size_t buf_size, size_t data_len) { int ret; - ret = hid_input_report(qsdev->hid_dev, HID_INPUT_REPORT, data, data_len, 1); + ret = hid_safe_input_report(qsdev->hid_dev, HID_INPUT_REPORT, data, + buf_size, data_len, 1); if (ret) dev_err(qsdev->dev, "Failed to send HID input report, ret = %d.\n", ret);
diff --git a/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-hid.h b/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-hid.h index f640fa8..61b7c6b 100644 --- a/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-hid.h +++ b/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-hid.h
@@ -7,7 +7,7 @@ struct quickspi_device; int quickspi_hid_send_report(struct quickspi_device *qsdev, - void *data, size_t data_size); + void *data, size_t buf_size, size_t data_size); int quickspi_hid_probe(struct quickspi_device *qsdev); void quickspi_hid_remove(struct quickspi_device *qsdev);
diff --git a/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c b/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c index 847c5ec..0df33c4 100644 --- a/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c +++ b/drivers/hid/intel-thc-hid/intel-quickspi/quickspi-protocol.c
@@ -240,7 +240,7 @@ void quickspi_handle_input_data(struct quickspi_device *qsdev, u32 buf_len) input_len = sizeof(body_hdr->content_id) + input_len; input_report = input_body->content - sizeof(body_hdr->content_id); - ret = quickspi_hid_send_report(qsdev, input_report, input_len); + ret = quickspi_hid_send_report(qsdev, input_report, qsdev->input_len, input_len); if (ret) dev_err_once(qsdev->dev, "Failed to send HID input report: %d\n", ret);
diff --git a/drivers/hid/surface-hid/surface_kbd.c b/drivers/hid/surface-hid/surface_kbd.c index 0be01b5..036829b 100644 --- a/drivers/hid/surface-hid/surface_kbd.c +++ b/drivers/hid/surface-hid/surface_kbd.c
@@ -277,8 +277,8 @@ static void surface_kbd_remove(struct platform_device *pdev) } static const struct acpi_device_id surface_kbd_match[] = { - { "MSHW0096" }, - { }, + { .id = "MSHW0096" }, + { } }; MODULE_DEVICE_TABLE(acpi, surface_kbd_match);
diff --git a/drivers/hid/usbhid/hid-core.c b/drivers/hid/usbhid/hid-core.c index 96b0181..d7cf2b5 100644 --- a/drivers/hid/usbhid/hid-core.c +++ b/drivers/hid/usbhid/hid-core.c
@@ -688,7 +688,14 @@ static int usbhid_open(struct hid_device *hid) set_bit(HID_OPENED, &usbhid->iofl); - if (hid->quirks & HID_QUIRK_ALWAYS_POLL) { + /* + * ALWAYS_POLL devices are already polled from usbhid_start(), and a + * device with no input reports has nothing to send on the interrupt + * IN endpoint. In some cases polling is harmful: on the ASUS ROG + * N-Key keyboards it makes the sibling interface drop keypresses. + */ + if ((hid->quirks & HID_QUIRK_ALWAYS_POLL) || + list_empty(&hid->report_enum[HID_INPUT_REPORT].report_list)) { res = 0; goto Done; }
diff --git a/drivers/hid/usbhid/hiddev.c b/drivers/hid/usbhid/hiddev.c index 6378801..8430655 100644 --- a/drivers/hid/usbhid/hiddev.c +++ b/drivers/hid/usbhid/hiddev.c
@@ -46,6 +46,12 @@ struct hiddev_list { struct mutex thread_lock; }; +static void hiddev_put(struct hiddev *hiddev) +{ + if (refcount_dec_and_test(&hiddev->refcount)) + kfree(hiddev); +} + /* * Find a report, given the report's type and ID. The ID can be specified * indirectly by REPORT_ID_FIRST (which returns the first report of the given @@ -216,26 +222,21 @@ static int hiddev_fasync(int fd, struct file *file, int on) static int hiddev_release(struct inode * inode, struct file * file) { struct hiddev_list *list = file->private_data; + struct hiddev *hiddev = list->hiddev; unsigned long flags; - spin_lock_irqsave(&list->hiddev->list_lock, flags); + spin_lock_irqsave(&hiddev->list_lock, flags); list_del(&list->node); - spin_unlock_irqrestore(&list->hiddev->list_lock, flags); + spin_unlock_irqrestore(&hiddev->list_lock, flags); - mutex_lock(&list->hiddev->existancelock); - if (!--list->hiddev->open) { - if (list->hiddev->exist) { - hid_hw_close(list->hiddev->hid); - hid_hw_power(list->hiddev->hid, PM_HINT_NORMAL); - } else { - mutex_unlock(&list->hiddev->existancelock); - kfree(list->hiddev); - vfree(list); - return 0; - } + mutex_lock(&hiddev->existancelock); + if (!--hiddev->open && hiddev->exist) { + hid_hw_close(hiddev->hid); + hid_hw_power(hiddev->hid, PM_HINT_NORMAL); } - mutex_unlock(&list->hiddev->existancelock); + mutex_unlock(&hiddev->existancelock); + hiddev_put(hiddev); vfree(list); return 0; @@ -270,6 +271,7 @@ static int __hiddev_open(struct hiddev *hiddev, struct file *file) spin_unlock_irq(&hiddev->list_lock); file->private_data = list; + refcount_inc(&hiddev->refcount); return 0; @@ -897,9 +899,12 @@ int hiddev_connect(struct hid_device *hid, unsigned int force) INIT_LIST_HEAD(&hiddev->list); spin_lock_init(&hiddev->list_lock); mutex_init(&hiddev->existancelock); + refcount_set(&hiddev->refcount, 1); hid->hiddev = hiddev; hiddev->hid = hid; hiddev->exist = 1; + /* Honor NO_INIT_REPORTS before the character device becomes visible. */ + hiddev->initialized = hid->quirks & HID_QUIRK_NO_INIT_REPORTS; retval = usb_register_dev(usbhid->intf, &hiddev_class); if (retval) { hid_err(hid, "Not able to get a minor for this device\n"); @@ -908,12 +913,6 @@ int hiddev_connect(struct hid_device *hid, unsigned int force) return retval; } - /* - * If HID_QUIRK_NO_INIT_REPORTS is set, make sure we don't initialize - * the reports. - */ - hiddev->initialized = hid->quirks & HID_QUIRK_NO_INIT_REPORTS; - hiddev->minor = usbhid->intf->minor; return 0; @@ -937,9 +936,7 @@ void hiddev_disconnect(struct hid_device *hid) if (hiddev->open) { hid_hw_close(hiddev->hid); wake_up_interruptible(&hiddev->wait); - mutex_unlock(&hiddev->existancelock); - } else { - mutex_unlock(&hiddev->existancelock); - kfree(hiddev); } + mutex_unlock(&hiddev->existancelock); + hiddev_put(hiddev); }
diff --git a/drivers/hid/wacom.h b/drivers/hid/wacom.h index 1deacb4..d2398b1 100644 --- a/drivers/hid/wacom.h +++ b/drivers/hid/wacom.h
@@ -82,7 +82,7 @@ #include <linux/kernel.h> #include <linux/slab.h> #include <linux/module.h> -#include <linux/mod_devicetable.h> +#include <linux/device-id/hid.h> #include <linux/hid.h> #include <linux/kfifo.h> #include <linux/leds.h>
diff --git a/drivers/hid/wacom_sys.c b/drivers/hid/wacom_sys.c index 40770af..628372a 100644 --- a/drivers/hid/wacom_sys.c +++ b/drivers/hid/wacom_sys.c
@@ -758,27 +758,47 @@ static void wacom_retrieve_hid_descriptor(struct hid_device *hdev, struct wacom_hdev_data { struct list_head list; struct kref kref; - struct hid_device *dev; + char phys[64]; + __u32 vendor; + __u32 product; + __u32 device_type; struct wacom_shared shared; }; +static bool wacom_compare_device_paths(struct hid_device *hdev_a, + const char *phys_b, char separator) +{ + const char *p1 = strrchr(hdev_a->phys, separator); + const char *p2 = strrchr(phys_b, separator); + int n1, n2; + + if (!p1 || !p2) + return false; + + n1 = p1 - hdev_a->phys; + n2 = p2 - phys_b; + + if (n1 != n2 || n1 <= 0 || n2 <= 0) + return false; + + return !strncmp(hdev_a->phys, phys_b, n1); +} + static LIST_HEAD(wacom_udev_list); static DEFINE_MUTEX(wacom_udev_list_lock); static bool wacom_are_sibling(struct hid_device *hdev, - struct hid_device *sibling) + struct wacom_hdev_data *data) { struct wacom *wacom = hid_get_drvdata(hdev); struct wacom_features *features = &wacom->wacom_wac.features; - struct wacom *sibling_wacom = hid_get_drvdata(sibling); - struct wacom_features *sibling_features = &sibling_wacom->wacom_wac.features; __u32 oVid = features->oVid ? features->oVid : hdev->vendor; __u32 oPid = features->oPid ? features->oPid : hdev->product; /* The defined oVid/oPid must match that of the sibling */ - if (features->oVid != HID_ANY_ID && sibling->vendor != oVid) + if (features->oVid != HID_ANY_ID && data->vendor != oVid) return false; - if (features->oPid != HID_ANY_ID && sibling->product != oPid) + if (features->oPid != HID_ANY_ID && data->product != oPid) return false; /* @@ -786,11 +806,11 @@ static bool wacom_are_sibling(struct hid_device *hdev, * device path, while those with different VID/PID must share * the same physical parent device path. */ - if (hdev->vendor == sibling->vendor && hdev->product == sibling->product) { - if (!hid_compare_device_paths(hdev, sibling, '/')) + if (hdev->vendor == data->vendor && hdev->product == data->product) { + if (!wacom_compare_device_paths(hdev, data->phys, '/')) return false; } else { - if (!hid_compare_device_paths(hdev, sibling, '.')) + if (!wacom_compare_device_paths(hdev, data->phys, '.')) return false; } @@ -803,7 +823,7 @@ static bool wacom_are_sibling(struct hid_device *hdev, * devices. */ if ((features->device_type & WACOM_DEVICETYPE_DIRECT) && - !(sibling_features->device_type & WACOM_DEVICETYPE_DIRECT)) + !(data->device_type & WACOM_DEVICETYPE_DIRECT)) return false; /* @@ -811,17 +831,17 @@ static bool wacom_are_sibling(struct hid_device *hdev, * devices. */ if (!(features->device_type & WACOM_DEVICETYPE_DIRECT) && - (sibling_features->device_type & WACOM_DEVICETYPE_DIRECT)) + (data->device_type & WACOM_DEVICETYPE_DIRECT)) return false; /* Pen devices may only be siblings of touch devices */ if ((features->device_type & WACOM_DEVICETYPE_PEN) && - !(sibling_features->device_type & WACOM_DEVICETYPE_TOUCH)) + !(data->device_type & WACOM_DEVICETYPE_TOUCH)) return false; /* Touch devices may only be siblings of pen devices */ if ((features->device_type & WACOM_DEVICETYPE_TOUCH) && - !(sibling_features->device_type & WACOM_DEVICETYPE_PEN)) + !(data->device_type & WACOM_DEVICETYPE_PEN)) return false; /* @@ -837,7 +857,7 @@ static struct wacom_hdev_data *wacom_get_hdev_data(struct hid_device *hdev) /* Try to find an already-probed interface from the same device */ list_for_each_entry(data, &wacom_udev_list, list) { - if (hid_compare_device_paths(hdev, data->dev, '/')) { + if (wacom_compare_device_paths(hdev, data->phys, '/')) { kref_get(&data->kref); return data; } @@ -845,7 +865,7 @@ static struct wacom_hdev_data *wacom_get_hdev_data(struct hid_device *hdev) /* Fallback to finding devices that appear to be "siblings" */ list_for_each_entry(data, &wacom_udev_list, list) { - if (wacom_are_sibling(hdev, data->dev)) { + if (wacom_are_sibling(hdev, data)) { kref_get(&data->kref); return data; } @@ -859,29 +879,41 @@ static void wacom_release_shared_data(struct kref *kref) struct wacom_hdev_data *data = container_of(kref, struct wacom_hdev_data, kref); - mutex_lock(&wacom_udev_list_lock); list_del(&data->list); - mutex_unlock(&wacom_udev_list_lock); - kfree(data); } static void wacom_remove_shared_data(void *res) { - struct wacom *wacom = res; + struct wacom *res_wacom = res; struct wacom_hdev_data *data; - struct wacom_wac *wacom_wac = &wacom->wacom_wac; + struct wacom_wac *wacom_wac = &res_wacom->wacom_wac; if (wacom_wac->shared) { data = container_of(wacom_wac->shared, struct wacom_hdev_data, shared); - if (wacom_wac->shared->touch == wacom->hdev) - wacom_wac->shared->touch = NULL; - else if (wacom_wac->shared->pen == wacom->hdev) - wacom_wac->shared->pen = NULL; + scoped_guard(mutex, &wacom_udev_list_lock) { + struct hid_device *touch = + rcu_dereference_protected(wacom_wac->shared->touch, + lockdep_is_held(&wacom_udev_list_lock)); + struct hid_device *pen = + rcu_dereference_protected(wacom_wac->shared->pen, + lockdep_is_held(&wacom_udev_list_lock)); - kref_put(&data->kref, wacom_release_shared_data); + if (touch == res_wacom->hdev) { + rcu_assign_pointer(wacom_wac->shared->touch, NULL); + rcu_assign_pointer(wacom_wac->shared->touch_input, NULL); + } else if (pen == res_wacom->hdev) { + rcu_assign_pointer(wacom_wac->shared->pen, NULL); + } + } + + synchronize_rcu(); + + if (kref_put_mutex(&data->kref, wacom_release_shared_data, &wacom_udev_list_lock)) + mutex_unlock(&wacom_udev_list_lock); + wacom_wac->shared = NULL; } } @@ -904,22 +936,21 @@ static int wacom_add_shared_data(struct hid_device *hdev) } kref_init(&data->kref); - data->dev = hdev; + strscpy(data->phys, hdev->phys, sizeof(data->phys)); + data->vendor = hdev->vendor; + data->product = hdev->product; + data->device_type = wacom_wac->features.device_type; list_add_tail(&data->list, &wacom_udev_list); } - mutex_unlock(&wacom_udev_list_lock); - wacom_wac->shared = &data->shared; - retval = devm_add_action_or_reset(&hdev->dev, wacom_remove_shared_data, wacom); - if (retval) - return retval; + if (wacom_wac->has_mute_touch_switch) + WRITE_ONCE(wacom_wac->shared->has_mute_touch_switch, true); - if (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH) - wacom_wac->shared->touch = hdev; - else if (wacom_wac->features.device_type & WACOM_DEVICETYPE_PEN) - wacom_wac->shared->pen = hdev; + mutex_unlock(&wacom_udev_list_lock); + + retval = devm_add_action_or_reset(&hdev->dev, wacom_remove_shared_data, wacom); return retval; } @@ -2344,30 +2375,88 @@ static void wacom_release_resources(struct wacom *wacom) static void wacom_set_shared_values(struct wacom_wac *wacom_wac) { - if (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH) { - wacom_wac->shared->type = wacom_wac->features.type; - wacom_wac->shared->touch_input = wacom_wac->touch_input; - } + struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); + + guard(mutex)(&wacom_udev_list_lock); if (wacom_wac->has_mute_touch_switch) { - wacom_wac->shared->has_mute_touch_switch = true; + WRITE_ONCE(wacom_wac->shared->has_mute_touch_switch, true); /* Hardware touch switch may be off. Wait until * we know the switch state to decide is_touch_on. * Softkey state should be initialized to "on" to * match historic default. */ if (wacom_wac->is_soft_touch_switch) - wacom_wac->shared->is_touch_on = true; + WRITE_ONCE(wacom_wac->shared->is_touch_on, true); } - if (wacom_wac->shared->has_mute_touch_switch && - wacom_wac->shared->touch_input) { - set_bit(EV_SW, wacom_wac->shared->touch_input->evbit); - input_set_capability(wacom_wac->shared->touch_input, EV_SW, - SW_MUTE_DEVICE); + if (wacom_wac->features.device_type & WACOM_DEVICETYPE_TOUCH) { + struct hid_device *touch = + rcu_dereference_protected(wacom_wac->shared->touch, + lockdep_is_held(&wacom_udev_list_lock)); + + if (touch == wacom->hdev || !touch) { + wacom_wac->shared->type = wacom_wac->features.type; + rcu_assign_pointer(wacom_wac->shared->touch, wacom->hdev); + rcu_assign_pointer(wacom_wac->shared->touch_input, wacom_wac->touch_input); + } + } else if (wacom_wac->features.device_type & WACOM_DEVICETYPE_PEN) { + rcu_assign_pointer(wacom_wac->shared->pen, wacom->hdev); } } +static bool wacom_sibling_pending(struct wacom *wacom) +{ + const struct wacom_features *features = &wacom->wacom_wac.features; + struct hid_device *hdev = wacom->hdev; + struct usb_interface *sibling_intf; + int ifnum; + + if (features->type != HID_GENERIC || + !(features->device_type & WACOM_DEVICETYPE_TOUCH)) + return false; + + if (wacom->wacom_wac.shared) { + if (rcu_access_pointer(wacom->wacom_wac.shared->pen)) + return false; + } + + if (!hid_is_usb(hdev) || !wacom->usbdev || !wacom->intf || + !wacom->intf->cur_altsetting) + return false; + + ifnum = wacom->intf->cur_altsetting->desc.bInterfaceNumber; + + /* + * On composite Wacom devices, the Pen interface is always interface 0. + * If the Touch interface is interface 0, there is no sibling Pen + * interface on this device (standalone touch device). + */ + if (ifnum == 0) + return false; + + /* Look for the sibling Pen interface at interface 0 */ + sibling_intf = usb_ifnum_to_if(wacom->usbdev, 0); + if (!sibling_intf || !sibling_intf->cur_altsetting) + return false; + + if (sibling_intf->cur_altsetting->desc.bInterfaceClass != + USB_INTERFACE_CLASS_HID) + return false; + + if (sibling_intf->cur_altsetting->desc.bInterfaceSubClass == 1 && + (sibling_intf->cur_altsetting->desc.bInterfaceProtocol == 1 || + sibling_intf->cur_altsetting->desc.bInterfaceProtocol == 2)) + return false; + + /* + * Interface 0 is a candidate HID interface on this composite device + * whose probe has not completed yet (shared->pen is NULL). Defer until + * interface 0 finishes probing and registers shared values. + */ + return true; +} + static int wacom_parse_and_register(struct wacom *wacom, bool wireless) { struct wacom_wac *wacom_wac = &wacom->wacom_wac; @@ -2445,6 +2534,11 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless) if (error) goto fail; + if (wacom_sibling_pending(wacom)) { + error = -EPROBE_DEFER; + goto fail; + } + error = wacom_setup_inputs(wacom); if (error) goto fail; @@ -2502,6 +2596,7 @@ static int wacom_parse_and_register(struct wacom *wacom, bool wireless) fail_hw_stop: hid_hw_stop(hdev); + cancel_delayed_work_sync(&wacom->init_work); fail: wacom_release_resources(wacom); return error; @@ -2789,16 +2884,19 @@ static void wacom_mode_change_work(struct work_struct *work) bool is_direct = wacom->wacom_wac.is_direct_mode; int error = 0; - if (shared->pen) { - wacom1 = hid_get_drvdata(shared->pen); + struct hid_device *pen = rcu_access_pointer(shared->pen); + struct hid_device *touch = rcu_access_pointer(shared->touch); + + if (pen) { + wacom1 = hid_get_drvdata(pen); wacom_release_resources(wacom1); hid_hw_stop(wacom1->hdev); wacom1->wacom_wac.has_mode_change = true; wacom1->wacom_wac.is_direct_mode = is_direct; } - if (shared->touch) { - wacom2 = hid_get_drvdata(shared->touch); + if (touch) { + wacom2 = hid_get_drvdata(touch); wacom_release_resources(wacom2); hid_hw_stop(wacom2->hdev); wacom2->wacom_wac.has_mode_change = true;
diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c index 8feb802..361738b 100644 --- a/drivers/hid/wacom_wac.c +++ b/drivers/hid/wacom_wac.c
@@ -510,6 +510,18 @@ static void wacom_intuos_schedule_prox_event(struct wacom_wac *wacom_wac) } } +static void wacom_report_touch_mute(struct wacom_wac *wacom_wac, bool mute) +{ + struct input_dev *touch_input; + + guard(rcu)(); + touch_input = rcu_dereference(wacom_wac->shared->touch_input); + if (touch_input) { + input_report_switch(touch_input, SW_MUTE_DEVICE, mute); + input_sync(touch_input); + } +} + static int wacom_intuos_pad(struct wacom_wac *wacom) { struct wacom_features *features = &wacom->features; @@ -650,12 +662,8 @@ static int wacom_intuos_pad(struct wacom_wac *wacom) input_report_key(input, KEY_CONTROLPANEL, menu); input_report_key(input, KEY_INFO, info); - if (wacom->shared && wacom->shared->touch_input) { - input_report_switch(wacom->shared->touch_input, - SW_MUTE_DEVICE, - !wacom->shared->is_touch_on); - input_sync(wacom->shared->touch_input); - } + if (wacom->shared) + wacom_report_touch_mute(wacom, !wacom->shared->is_touch_on); input_report_abs(input, ABS_RX, strip1); input_report_abs(input, ABS_RY, strip2); @@ -1019,10 +1027,10 @@ static int wacom_intuos_general(struct wacom_wac *wacom) return 2; } -static int wacom_intuos_irq(struct wacom_wac *wacom) +static int wacom_intuos_irq(struct wacom_wac *wacom_wac) { - unsigned char *data = wacom->data; - struct input_dev *input = wacom->pen_input; + unsigned char *data = wacom_wac->data; + struct wacom *wacom = container_of(wacom_wac, struct wacom, wacom_wac); int result; if (data[0] != WACOM_REPORT_PENABLED && @@ -1033,23 +1041,23 @@ static int wacom_intuos_irq(struct wacom_wac *wacom) data[0] != WACOM_REPORT_CINTIQ && data[0] != WACOM_REPORT_CINTIQPAD && data[0] != WACOM_REPORT_INTUOS5PAD) { - dev_dbg(input->dev.parent, + hid_dbg(wacom->hdev, "%s: received unknown report #%d\n", __func__, data[0]); return 0; } /* process pad events */ - result = wacom_intuos_pad(wacom); + result = wacom_intuos_pad(wacom_wac); if (result) return result; /* process in/out prox events */ - result = wacom_intuos_inout(wacom); + result = wacom_intuos_inout(wacom_wac); if (result) return result - 1; /* process general packets */ - result = wacom_intuos_general(wacom); + result = wacom_intuos_general(wacom_wac); if (result) return result - 1; @@ -2168,7 +2176,7 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field */ if ((equivalent_usage == WACOM_HID_WD_MUTE_DEVICE) || (equivalent_usage == WACOM_HID_WD_TOUCHONOFF)) { - if (wacom_wac->shared->touch_input) { + if (wacom_wac->shared) { bool *is_touch_on = &wacom_wac->shared->is_touch_on; if (equivalent_usage == WACOM_HID_WD_MUTE_DEVICE && value) @@ -2176,9 +2184,7 @@ static void wacom_wac_pad_event(struct hid_device *hdev, struct hid_field *field else if (equivalent_usage == WACOM_HID_WD_TOUCHONOFF) *is_touch_on = value; - input_report_switch(wacom_wac->shared->touch_input, - SW_MUTE_DEVICE, !(*is_touch_on)); - input_sync(wacom_wac->shared->touch_input); + wacom_report_touch_mute(wacom_wac, !(*is_touch_on)); } return; } @@ -3301,6 +3307,7 @@ static int wacom_bpt_irq(struct wacom_wac *wacom, size_t len) static void wacom_bamboo_pad_pen_event(struct wacom_wac *wacom, unsigned char *data) { + struct hid_device *pen; unsigned char prefix; /* @@ -3313,13 +3320,11 @@ static void wacom_bamboo_pad_pen_event(struct wacom_wac *wacom, prefix = data[0]; data[0] = WACOM_REPORT_BPAD_PEN; - /* - * actually reroute the event. - * No need to check if wacom->shared->pen is valid, hid_input_report() - * will check for us. - */ - hid_input_report(wacom->shared->pen, HID_INPUT_REPORT, data, - WACOM_PKGLEN_PENABLED, 1); + guard(rcu)(); + pen = rcu_dereference(wacom->shared->pen); + if (pen) + hid_input_report(pen, HID_INPUT_REPORT, data, + WACOM_PKGLEN_PENABLED, 1); data[0] = prefix; } @@ -3396,11 +3401,8 @@ static int wacom_wireless_irq(struct wacom_wac *wacom, size_t len) if ((wacom->shared->type == INTUOSHT || wacom->shared->type == INTUOSHT2) && - wacom->shared->touch_input && wacom->shared->touch_max) { - input_report_switch(wacom->shared->touch_input, - SW_MUTE_DEVICE, data[5] & 0x40); - input_sync(wacom->shared->touch_input); + wacom_report_touch_mute(wacom, data[5] & 0x40); } pid = get_unaligned_be16(&data[6]); @@ -3435,11 +3437,8 @@ static int wacom_status_irq(struct wacom_wac *wacom_wac, size_t len) if ((features->type == INTUOSHT || features->type == INTUOSHT2) && - wacom_wac->shared->touch_input && features->touch_max) { - input_report_switch(wacom_wac->shared->touch_input, - SW_MUTE_DEVICE, data[8] & 0x40); - input_sync(wacom_wac->shared->touch_input); + wacom_report_touch_mute(wacom_wac, data[8] & 0x40); } if (data[9] & 0x02) { /* wireless module is attached */ @@ -3966,8 +3965,8 @@ int wacom_setup_pen_input_capabilities(struct input_dev *input_dev, int wacom_setup_touch_input_capabilities(struct input_dev *input_dev, struct wacom_wac *wacom_wac) { + struct hid_device *hdev = container_of(wacom_wac, struct wacom, wacom_wac)->hdev; struct wacom_features *features = &wacom_wac->features; - if (!(features->device_type & WACOM_DEVICETYPE_TOUCH)) return -ENODEV; @@ -3976,9 +3975,24 @@ int wacom_setup_touch_input_capabilities(struct input_dev *input_dev, else __set_bit(INPUT_PROP_POINTER, input_dev->propbit); - if (features->type == HID_GENERIC) + if (features->type == HID_GENERIC) { + hid_dbg(hdev, "generic touch setup\n"); + + /* + * This is to setup the touch switch for those devices that report + * pen interface first. The setup can only be done here since this + * routine is only called once. When we are here, the shared + * has_mute_touch_switch has been set by the pad. + + * There are two ways of reporting inputs from firmware: stylus first + * or touch first. This path covers the stylus input first case. + */ + if (wacom_wac->shared && READ_ONCE(wacom_wac->shared->has_mute_touch_switch)) { + input_set_capability(input_dev, EV_SW, SW_MUTE_DEVICE); + } /* setup has already been done */ return 0; + } input_dev->evbit[0] |= BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); __set_bit(BTN_TOUCH, input_dev->keybit); @@ -4010,19 +4024,17 @@ int wacom_setup_touch_input_capabilities(struct input_dev *input_dev, input_dev->evbit[0] |= BIT_MASK(EV_SW); __set_bit(SW_MUTE_DEVICE, input_dev->swbit); - if (wacom_wac->shared->touch->product == 0x361) { + if (hdev->product == 0x361) { input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, 12440, 4, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, 8640, 4, 0); - } - else if (wacom_wac->shared->touch->product == 0x360) { + } else if (hdev->product == 0x360) { input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, 8960, 4, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, 5920, 4, 0); - } - else if (wacom_wac->shared->touch->product == 0x393) { + } else if (hdev->product == 0x393) { input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, 6400, 4, 0); input_set_abs_params(input_dev, ABS_MT_POSITION_Y, @@ -4052,8 +4064,8 @@ int wacom_setup_touch_input_capabilities(struct input_dev *input_dev, fallthrough; case WACOM_27QHDT: - if (wacom_wac->shared->touch->product == 0x32C || - wacom_wac->shared->touch->product == 0xF6) { + if (hdev->product == 0x32C || + hdev->product == 0xF6) { input_dev->evbit[0] |= BIT_MASK(EV_SW); __set_bit(SW_MUTE_DEVICE, input_dev->swbit); wacom_wac->has_mute_touch_switch = true; @@ -4399,7 +4411,26 @@ int wacom_setup_pad_input_capabilities(struct input_dev *input_dev, break; case INTUOSHT3_BT: + break; + case HID_GENERIC: + if (wacom_wac->shared) { + /* + * The setup of touch switch capability can only be done + * here for those devices, such as Cintiq Pro 13 and 16, + * that have touch input registered before stylus and pad + * inputs. + * + * There are two ways of reporting inputs from firmware: + * stylus first or touch first. This path covers the touch + * input first case. + */ + if (wacom_wac->has_mute_touch_switch && + wacom_wac->shared->touch_input) { + input_set_capability(wacom_wac->shared->touch_input, + EV_SW, SW_MUTE_DEVICE); + } + } break; default:
diff --git a/drivers/hid/wacom_wac.h b/drivers/hid/wacom_wac.h index 126bec6..170d6ad 100644 --- a/drivers/hid/wacom_wac.h +++ b/drivers/hid/wacom_wac.h
@@ -285,9 +285,9 @@ struct wacom_shared { /* for wireless device to access USB interfaces */ unsigned touch_max; int type; - struct input_dev *touch_input; - struct hid_device *pen; - struct hid_device *touch; + struct input_dev __rcu *touch_input; + struct hid_device __rcu *pen; + struct hid_device __rcu *touch; bool has_mute_touch_switch; bool is_touch_on; };
diff --git a/drivers/hte/hte-tegra194-test.c b/drivers/hte/hte-tegra194-test.c index 32907d9..cca3386 100644 --- a/drivers/hte/hte-tegra194-test.c +++ b/drivers/hte/hte-tegra194-test.c
@@ -217,10 +217,10 @@ static void tegra_hte_test_remove(struct platform_device *pdev) { (void)pdev; + timer_shutdown_sync(&hte.timer); free_irq(hte.gpio_in_irq, &hte); gpiod_put(hte.gpio_in); gpiod_put(hte.gpio_out); - timer_delete_sync(&hte.timer); } static struct platform_driver tegra_hte_test_driver = {
diff --git a/drivers/hte/hte-tegra194.c b/drivers/hte/hte-tegra194.c index 4a7702b..189f7fc 100644 --- a/drivers/hte/hte-tegra194.c +++ b/drivers/hte/hte-tegra194.c
@@ -856,10 +856,8 @@ static int tegra_hte_probe(struct platform_device *pdev) hte_dev->hte_irq = ret; ret = devm_request_irq(dev, hte_dev->hte_irq, tegra_hte_isr, 0, dev_name(dev), hte_dev); - if (ret < 0) { - dev_err(dev, "request irq failed.\n"); + if (ret < 0) return ret; - } gc->nlines = nlines; gc->ops = &g_ops; @@ -910,17 +908,17 @@ static int tegra_hte_probe(struct platform_device *pdev) hte_dev->chip = gc; + for (i = 0; i < slices; i++) { + hte_dev->sl[i].flags = 0; + spin_lock_init(&hte_dev->sl[i].s_lock); + } + ret = devm_hte_register_chip(hte_dev->chip); if (ret) { dev_err(gc->dev, "hte chip register failed"); return ret; } - for (i = 0; i < slices; i++) { - hte_dev->sl[i].flags = 0; - spin_lock_init(&hte_dev->sl[i].s_lock); - } - val = HTE_TECTRL_ENABLE_ENABLE | (HTE_TECTRL_INTR_ENABLE << HTE_TECTRL_INTR_SHIFT) | (hte_dev->itr_thrshld << HTE_TECTRL_OCCU_SHIFT);
diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index d7b8950..275aaa7 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig
@@ -962,6 +962,17 @@ controllers. Driver can also support slave mode (select I2C_SLAVE). +config I2C_NT72676 + tristate "Novatek NT72676 I2C controller" + depends on OF + depends on COMMON_CLK || COMPILE_TEST + help + Say Y here if you want to enable I2C bus controller on + Novatek NT72676 SoC. + This driver performs fundamental read/write functions + as an I2C bus controller and supports Standard-mode and + Fast-mode. Default operation is Standard-mode. + config I2C_OCORES tristate "OpenCores I2C Controller" help @@ -1050,6 +1061,7 @@ config I2C_QCOM_CCI tristate "Qualcomm Camera Control Interface" depends on ARCH_QCOM || COMPILE_TEST + select PM_OPP help If you say yes to this option, support will be included for the built-in camera control interface on the Qualcomm SoCs.
diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index 3755c54..e5440de 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile
@@ -90,6 +90,7 @@ obj-$(CONFIG_I2C_MXS) += i2c-mxs.o obj-$(CONFIG_I2C_NOMADIK) += i2c-nomadik.o obj-$(CONFIG_I2C_NPCM) += i2c-npcm7xx.o +obj-$(CONFIG_I2C_NT72676) += i2c-nt72676.o obj-$(CONFIG_I2C_OCORES) += i2c-ocores.o obj-$(CONFIG_I2C_OMAP) += i2c-omap.o obj-$(CONFIG_I2C_OWL) += i2c-owl.o
diff --git a/drivers/i2c/busses/i2c-amd-asf-plat.c b/drivers/i2c/busses/i2c-amd-asf-plat.c index b0b40fe..2a57114 100644 --- a/drivers/i2c/busses/i2c-amd-asf-plat.c +++ b/drivers/i2c/busses/i2c-amd-asf-plat.c
@@ -354,7 +354,7 @@ static int amd_asf_probe(struct platform_device *pdev) } static const struct acpi_device_id amd_asf_acpi_ids[] = { - { "AMDI001A" }, + { .id = "AMDI001A" }, { } }; MODULE_DEVICE_TABLE(acpi, amd_asf_acpi_ids);
diff --git a/drivers/i2c/busses/i2c-amd-mp2-plat.c b/drivers/i2c/busses/i2c-amd-mp2-plat.c index 9fdd6a5..cc59613 100644 --- a/drivers/i2c/busses/i2c-amd-mp2-plat.c +++ b/drivers/i2c/busses/i2c-amd-mp2-plat.c
@@ -341,7 +341,7 @@ static void i2c_amd_remove(struct platform_device *pdev) } static const struct acpi_device_id i2c_amd_acpi_match[] = { - { "AMDI0011" }, + { .id = "AMDI0011" }, { } }; MODULE_DEVICE_TABLE(acpi, i2c_amd_acpi_match);
diff --git a/drivers/i2c/busses/i2c-bcm2835.c b/drivers/i2c/busses/i2c-bcm2835.c index 0d7e265..b30f7e0 100644 --- a/drivers/i2c/busses/i2c-bcm2835.c +++ b/drivers/i2c/busses/i2c-bcm2835.c
@@ -166,7 +166,7 @@ static struct clk *bcm2835_i2c_register_div(struct device *dev, struct clk *mclk, struct bcm2835_i2c_dev *i2c_dev) { - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_bcm2835_i2c *priv; char name[32]; const char *mclk_name;
diff --git a/drivers/i2c/busses/i2c-cros-ec-tunnel.c b/drivers/i2c/busses/i2c-cros-ec-tunnel.c index 208ce4f..a83e735 100644 --- a/drivers/i2c/busses/i2c-cros-ec-tunnel.c +++ b/drivers/i2c/busses/i2c-cros-ec-tunnel.c
@@ -300,7 +300,7 @@ static const struct of_device_id cros_ec_i2c_of_match[] __maybe_unused = { MODULE_DEVICE_TABLE(of, cros_ec_i2c_of_match); static const struct acpi_device_id cros_ec_i2c_tunnel_acpi_id[] __maybe_unused = { - { "GOOG0012", 0 }, + { .id = "GOOG0012" }, { } }; MODULE_DEVICE_TABLE(acpi, cros_ec_i2c_tunnel_acpi_id);
diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index a1bcc37..f4ad207 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c
@@ -378,7 +378,7 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev) { struct i2c_msg *msgs = dev->msgs; u32 intr_mask; - int tx_limit, rx_limit; + int tx_limit, rx_limit, rx_tl; u32 buf_len = dev->tx_buf_len; u8 *buf = dev->tx_buf; bool need_restart = false; @@ -484,6 +484,19 @@ i2c_dw_xfer_msg(struct dw_i2c_dev *dev) if (dev->msg_err) intr_mask = 0; + /* + * Size the RX FIFO threshold to the reads already queued, so the + * controller raises one RX_FULL for the whole burst instead of one per + * received byte. While messages remain to be queued, cap it so RX_FULL + * still arrives in time to drain the FIFO and let the next TX_EMPTY + * queue the rest. + */ + rx_tl = dev->rx_outstanding; + if (dev->msg_write_idx < dev->msgs_num) + rx_tl = min_t(int, rx_tl, dev->rx_fifo_depth / 2); + + regmap_write(dev->map, DW_IC_RX_TL, rx_tl ? rx_tl - 1 : 0); + __i2c_dw_write_intr_mask(dev, intr_mask); }
diff --git a/drivers/i2c/busses/i2c-designware-platdrv.c b/drivers/i2c/busses/i2c-designware-platdrv.c index 447af55..1da6b03 100644 --- a/drivers/i2c/busses/i2c-designware-platdrv.c +++ b/drivers/i2c/busses/i2c-designware-platdrv.c
@@ -260,27 +260,27 @@ static const struct of_device_id dw_i2c_of_match[] = { MODULE_DEVICE_TABLE(of, dw_i2c_of_match); static const struct acpi_device_id dw_i2c_acpi_match[] = { - { "80860F41", ACCESS_NO_IRQ_SUSPEND }, - { "808622C1", ACCESS_NO_IRQ_SUSPEND }, - { "AMD0010", ACCESS_INTR_MASK }, - { "AMDI0010", ACCESS_INTR_MASK }, - { "AMDI0019", ACCESS_INTR_MASK | ARBITRATION_SEMAPHORE }, - { "AMDI0510", 0 }, - { "APMC0D0F", 0 }, - { "FUJI200B", 0 }, - { "GOOG5000", 0 }, - { "HISI02A1", 0 }, - { "HISI02A2", 0 }, - { "HISI02A3", 0 }, - { "HJMC3001", ACCESS_INTR_MASK }, - { "HYGO0010", ACCESS_INTR_MASK }, - { "INT33C2", 0 }, - { "INT33C3", 0 }, - { "INT3432", 0 }, - { "INT3433", 0 }, - { "INTC10EF", 0 }, - { "LECA0003", 0 }, - {} + { .id = "80860F41", .driver_data = ACCESS_NO_IRQ_SUSPEND }, + { .id = "808622C1", .driver_data = ACCESS_NO_IRQ_SUSPEND }, + { .id = "AMD0010", .driver_data = ACCESS_INTR_MASK }, + { .id = "AMDI0010", .driver_data = ACCESS_INTR_MASK }, + { .id = "AMDI0019", .driver_data = ACCESS_INTR_MASK | ARBITRATION_SEMAPHORE }, + { .id = "AMDI0510" }, + { .id = "APMC0D0F" }, + { .id = "FUJI200B" }, + { .id = "GOOG5000" }, + { .id = "HISI02A1" }, + { .id = "HISI02A2" }, + { .id = "HISI02A3" }, + { .id = "HJMC3001", .driver_data = ACCESS_INTR_MASK }, + { .id = "HYGO0010", .driver_data = ACCESS_INTR_MASK }, + { .id = "INT33C2" }, + { .id = "INT33C3" }, + { .id = "INT3432" }, + { .id = "INT3433" }, + { .id = "INTC10EF" }, + { .id = "LECA0003" }, + { } }; MODULE_DEVICE_TABLE(acpi, dw_i2c_acpi_match);
diff --git a/drivers/i2c/busses/i2c-gpio.c b/drivers/i2c/busses/i2c-gpio.c index 6294b0b..56d6847 100644 --- a/drivers/i2c/busses/i2c-gpio.c +++ b/drivers/i2c/busses/i2c-gpio.c
@@ -664,7 +664,7 @@ static const struct of_device_id i2c_gpio_dt_ids[] = { MODULE_DEVICE_TABLE(of, i2c_gpio_dt_ids); static const struct acpi_device_id i2c_gpio_acpi_match[] = { - { "LOON0005" }, /* LoongArch */ + { .id = "LOON0005" }, /* LoongArch */ { } }; MODULE_DEVICE_TABLE(acpi, i2c_gpio_acpi_match);
diff --git a/drivers/i2c/busses/i2c-hisi.c b/drivers/i2c/busses/i2c-hisi.c index ba5c957..fca1ca0 100644 --- a/drivers/i2c/busses/i2c-hisi.c +++ b/drivers/i2c/busses/i2c-hisi.c
@@ -516,7 +516,7 @@ static int hisi_i2c_probe(struct platform_device *pdev) } static const struct acpi_device_id hisi_i2c_acpi_ids[] = { - { "HISI03D1", 0 }, + { .id = "HISI03D1" }, { } }; MODULE_DEVICE_TABLE(acpi, hisi_i2c_acpi_ids);
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index b29c99e..810f61e 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c
@@ -1170,6 +1170,14 @@ static void dmi_check_onboard_devices(const struct dmi_header *dm, void *adap) } } +static void i801_register_spd(struct i801_priv *priv) +{ + if (priv->original_hstcfg & SMBHSTCFG_SPD_WD) + i2c_register_spd_write_disable(&priv->adapter); + else + i2c_register_spd_write_enable(&priv->adapter); +} + /* Register optional targets */ static void i801_probe_optional_targets(struct i801_priv *priv) { @@ -1193,7 +1201,7 @@ static void i801_probe_optional_targets(struct i801_priv *priv) #ifdef CONFIG_I2C_I801_MUX if (!priv->mux_pdev) #endif - i2c_register_spd_write_enable(&priv->adapter); + i801_register_spd(priv); } #else static void __init input_apanel_init(void) {}
diff --git a/drivers/i2c/busses/i2c-imx-lpi2c.c b/drivers/i2c/busses/i2c-imx-lpi2c.c index 1cfd7a4..7302464 100644 --- a/drivers/i2c/busses/i2c-imx-lpi2c.c +++ b/drivers/i2c/busses/i2c-imx-lpi2c.c
@@ -780,7 +780,7 @@ static void lpi2c_dma_unmap(struct lpi2c_imx_dma *dma) struct dma_chan *chan = dma->dma_data_dir == DMA_FROM_DEVICE ? dma->chan_rx : dma->chan_tx; - dma_unmap_single(chan->device->dev, dma->dma_addr, + dma_unmap_single(dmaengine_get_dma_device(chan), dma->dma_addr, dma->dma_len, dma->dma_data_dir); dma->dma_data_dir = DMA_NONE; @@ -789,7 +789,7 @@ static void lpi2c_dma_unmap(struct lpi2c_imx_dma *dma) static void lpi2c_cleanup_rx_cmd_dma(struct lpi2c_imx_dma *dma) { dmaengine_terminate_sync(dma->chan_tx); - dma_unmap_single(dma->chan_tx->device->dev, dma->dma_tx_addr, + dma_unmap_single(dmaengine_get_dma_device(dma->chan_tx), dma->dma_tx_addr, dma->rx_cmd_buf_len, DMA_TO_DEVICE); } @@ -817,10 +817,10 @@ static int lpi2c_dma_rx_cmd_submit(struct lpi2c_imx_struct *lpi2c_imx) struct dma_chan *txchan = dma->chan_tx; dma_cookie_t cookie; - dma->dma_tx_addr = dma_map_single(txchan->device->dev, + dma->dma_tx_addr = dma_map_single(dmaengine_get_dma_device(txchan), dma->rx_cmd_buf, dma->rx_cmd_buf_len, DMA_TO_DEVICE); - if (dma_mapping_error(txchan->device->dev, dma->dma_tx_addr)) { + if (dma_mapping_error(dmaengine_get_dma_device(txchan), dma->dma_tx_addr)) { dev_err(&lpi2c_imx->adapter.dev, "DMA map failed, use pio\n"); return -EINVAL; } @@ -844,14 +844,13 @@ static int lpi2c_dma_rx_cmd_submit(struct lpi2c_imx_struct *lpi2c_imx) return 0; desc_prepare_err_exit: - dma_unmap_single(txchan->device->dev, dma->dma_tx_addr, + dma_unmap_single(dmaengine_get_dma_device(txchan), dma->dma_tx_addr, dma->rx_cmd_buf_len, DMA_TO_DEVICE); return -EINVAL; submit_err_exit: - dma_unmap_single(txchan->device->dev, dma->dma_tx_addr, + dma_unmap_single(dmaengine_get_dma_device(txchan), dma->dma_tx_addr, dma->rx_cmd_buf_len, DMA_TO_DEVICE); - dmaengine_desc_free(rx_cmd_desc); return -EINVAL; } @@ -872,9 +871,9 @@ static int lpi2c_dma_submit(struct lpi2c_imx_struct *lpi2c_imx) dma->dma_transfer_dir = DMA_MEM_TO_DEV; } - dma->dma_addr = dma_map_single(chan->device->dev, + dma->dma_addr = dma_map_single(dmaengine_get_dma_device(chan), dma->dma_buf, dma->dma_len, dma->dma_data_dir); - if (dma_mapping_error(chan->device->dev, dma->dma_addr)) { + if (dma_mapping_error(dmaengine_get_dma_device(chan), dma->dma_addr)) { dev_err(&lpi2c_imx->adapter.dev, "DMA map failed, use pio\n"); return -EINVAL; } @@ -910,7 +909,6 @@ static int lpi2c_dma_submit(struct lpi2c_imx_struct *lpi2c_imx) submit_err_exit: lpi2c_dma_unmap(dma); - dmaengine_desc_free(desc); return -EINVAL; } @@ -1085,7 +1083,7 @@ static int lpi2c_imx_dma_xfer(struct lpi2c_imx_struct *lpi2c_imx, } if (dma->dma_msg_flag & I2C_M_RD) - dma_unmap_single(dma->chan_tx->device->dev, dma->dma_tx_addr, + dma_unmap_single(dmaengine_get_dma_device(dma->chan_tx), dma->dma_tx_addr, dma->rx_cmd_buf_len, DMA_TO_DEVICE); lpi2c_dma_unmap(dma);
diff --git a/drivers/i2c/busses/i2c-imx.c b/drivers/i2c/busses/i2c-imx.c index ff5a911..62359a0 100644 --- a/drivers/i2c/busses/i2c-imx.c +++ b/drivers/i2c/busses/i2c-imx.c
@@ -349,7 +349,7 @@ static const struct of_device_id i2c_imx_dt_ids[] = { MODULE_DEVICE_TABLE(of, i2c_imx_dt_ids); static const struct acpi_device_id i2c_imx_acpi_ids[] = { - {"NXP0001", .driver_data = (kernel_ulong_t)&vf610_i2c_hwdata}, + { .id = "NXP0001", .driver_data = (kernel_ulong_t)&vf610_i2c_hwdata }, { } }; MODULE_DEVICE_TABLE(acpi, i2c_imx_acpi_ids);
diff --git a/drivers/i2c/busses/i2c-ljca.c b/drivers/i2c/busses/i2c-ljca.c index 93274f0..da33709 100644 --- a/drivers/i2c/busses/i2c-ljca.c +++ b/drivers/i2c/busses/i2c-ljca.c
@@ -297,7 +297,6 @@ static int ljca_i2c_probe(struct auxiliary_device *auxdev, device_set_node(&ljca_i2c->adap.dev, dev_fwnode(&auxdev->dev)); i2c_set_adapdata(&ljca_i2c->adap, ljca_i2c); - auxiliary_set_drvdata(auxdev, ljca_i2c); ret = ljca_i2c_init(ljca_i2c, ljca_i2c->i2c_info->id); if (ret) @@ -315,13 +314,6 @@ static int ljca_i2c_probe(struct auxiliary_device *auxdev, return 0; } -static void ljca_i2c_remove(struct auxiliary_device *auxdev) -{ - struct ljca_i2c_dev *ljca_i2c = auxiliary_get_drvdata(auxdev); - - i2c_del_adapter(&ljca_i2c->adap); -} - static const struct auxiliary_device_id ljca_i2c_id_table[] = { { "usb_ljca.ljca-i2c", 0 }, { /* sentinel */ } @@ -330,7 +322,6 @@ MODULE_DEVICE_TABLE(auxiliary, ljca_i2c_id_table); static struct auxiliary_driver ljca_i2c_driver = { .probe = ljca_i2c_probe, - .remove = ljca_i2c_remove, .id_table = ljca_i2c_id_table, }; module_auxiliary_driver(ljca_i2c_driver);
diff --git a/drivers/i2c/busses/i2c-ls2x.c b/drivers/i2c/busses/i2c-ls2x.c index af7bf61..ef2e2a2 100644 --- a/drivers/i2c/busses/i2c-ls2x.c +++ b/drivers/i2c/busses/i2c-ls2x.c
@@ -356,7 +356,7 @@ static const struct of_device_id ls2x_i2c_id_table[] = { MODULE_DEVICE_TABLE(of, ls2x_i2c_id_table); static const struct acpi_device_id ls2x_i2c_acpi_match[] = { - { "LOON0004" }, /* Loongson LS7A */ + { .id = "LOON0004" }, /* Loongson LS7A */ { } }; MODULE_DEVICE_TABLE(acpi, ls2x_i2c_acpi_match);
diff --git a/drivers/i2c/busses/i2c-mlxbf.c b/drivers/i2c/busses/i2c-mlxbf.c index 24ccc45..0cc8b9e 100644 --- a/drivers/i2c/busses/i2c-mlxbf.c +++ b/drivers/i2c/busses/i2c-mlxbf.c
@@ -2198,10 +2198,10 @@ static struct i2c_adapter_quirks mlxbf_i2c_quirks = { }; static const struct acpi_device_id mlxbf_i2c_acpi_ids[] = { - { "MLNXBF03", (kernel_ulong_t)&mlxbf_i2c_chip[MLXBF_I2C_CHIP_TYPE_1] }, - { "MLNXBF23", (kernel_ulong_t)&mlxbf_i2c_chip[MLXBF_I2C_CHIP_TYPE_2] }, - { "MLNXBF31", (kernel_ulong_t)&mlxbf_i2c_chip[MLXBF_I2C_CHIP_TYPE_3] }, - {}, + { .id = "MLNXBF03", .driver_data = (kernel_ulong_t)&mlxbf_i2c_chip[MLXBF_I2C_CHIP_TYPE_1] }, + { .id = "MLNXBF23", .driver_data = (kernel_ulong_t)&mlxbf_i2c_chip[MLXBF_I2C_CHIP_TYPE_2] }, + { .id = "MLNXBF31", .driver_data = (kernel_ulong_t)&mlxbf_i2c_chip[MLXBF_I2C_CHIP_TYPE_3] }, + { } }; MODULE_DEVICE_TABLE(acpi, mlxbf_i2c_acpi_ids);
diff --git a/drivers/i2c/busses/i2c-nt72676.c b/drivers/i2c/busses/i2c-nt72676.c new file mode 100644 index 0000000..1308d69 --- /dev/null +++ b/drivers/i2c/busses/i2c-nt72676.c
@@ -0,0 +1,725 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2026 Novatek Microelectronics Corp. + * Author: Ben Huang <ben_huang@novatek.com.tw> + */ + +#include <linux/clk.h> +#include <linux/completion.h> +#include <linux/i2c.h> +#include <linux/interrupt.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> + +#define I2C_REG_CTRL 0x00 +#define I2C_REG_CLK 0x04 +#define I2C_REG_ACK 0x08 +#define I2C_REG_SIZE 0x0C +#define I2C_REG_FIFO1 0x10 +#define I2C_REG_SUBADDR 0x20 +#define I2C_REG_PINGPONG 0x24 +#define I2C_REG_INTR 0x28 +#define I2C_REG_FIFO2 0x2C +#define I2C_REG_DUTY 0x3C +#define I2C_CLR_FIFO1 BIT(7) +#define I2C_CLR_FIFO2 BIT(23) +#define I2C_BUF_LITTLE_ENDIAN BIT(13) +#define I2C_BUSY BIT(1) +#define I2C_ENABLE BIT(2) +#define I2C_REPEAT_ENABLE BIT(7) +#define I2C_READ_OPERATION BIT(8) +#define I2C_NACK BIT(24) +#define I2C_CLOCK_DUTY_ENABLE BIT(21) +#define I2C_CLOCK_STRETCH_ENABLE BIT(27) +#define I2C_MASTER_CLK_STRETCH_ENABLE BIT(28) +#define I2C_TRIGGER BIT(0) +#define I2C_IRQ_CLK_STR_TIMEOUT BIT(12) +#define I2C_IRQ_NACK BIT(11) +#define I2C_IRQ_RX_FULL BIT(10) +#define I2C_IRQ_TX_EMPTY BIT(9) +#define I2C_IRQ_FINISH BIT(8) +#define I2C_IRQ_FLAG (I2C_IRQ_CLK_STR_TIMEOUT |\ + I2C_IRQ_NACK | \ + I2C_IRQ_RX_FULL | \ + I2C_IRQ_TX_EMPTY | \ + I2C_IRQ_FINISH) +#define I2C_IRQ_CLEAR_ALL GENMASK(20, 16) +#define I2C_IRQ_ENABLE_SETTING GENMASK(4, 0) +#define I2C_SUBADDR_ENABLE BIT(6) +#define I2C_16BITSUBADDR_ENABLE BIT(16) +#define I2C_24BITSUBADDR_ENABLE BIT(17) +#define I2C_32BITSUBADDR_ENABLE BIT(18) +#define I2C_ACK_CTRL_COUNTER 0x000001E0 +#define I2C_TX_EMPTY_FIFO1 BIT(6) +#define I2C_TX_EMPTY_FIFO2 BIT(22) +#define I2C_RX_FULL_FIFO1 BIT(5) +#define I2C_RX_FULL_FIFO2 BIT(21) + +#define STBC_REG_PSWD 0x0204 +#define STBC_REG_KEYPASS 0x0208 +#define STBC_REG_I2C_SWITCH 0x0220 +#define STBC_PSWD_DATA1 0x72682 +#define STBC_PSWD_DATA2 0x28627 +#define STBC_KEYPASS_ENABLE BIT(0) +#define STBC_AGPIO_SWITCH_TO_CPU BIT(14) + +#define FIFO_CHUNK_SIZE 16 +#define FIFO_WORD_BYTES 4 + +enum { + SUBADDR_DISABLE = 0, + SUBADDR_8BITS, + SUBADDR_16BITS, + SUBADDR_24BITS, + SUBADDR_32BITS, +}; + +#define SUBADDR_MAX_LEN SUBADDR_32BITS + +enum { + FIFO_1 = 0, + FIFO_2, + FIFO_ALL +}; + +struct nvt_i2c_bus { + void __iomem *base; + struct i2c_adapter adapter; + struct device *dev; + struct completion msg_complete; + struct clk *clk; + unsigned long input_clk_rate; + unsigned int bus_clk_rate; + bool stbc_i2c; + struct regmap *stbc_regmap; + int irq; + /* lock for msg and reg protection */ + spinlock_t lock; + /* used for xfer, protected by lock */ + struct i2c_msg *current_msg; + int subaddr_mode; + int remaining; + int write_ptr; + int read_ptr; + int fifo_idx; + int error_code; +}; + +static void nt72676_i2c_writel(u32 val, struct nvt_i2c_bus *i2c, unsigned int reg) +{ + writel(val, i2c->base + reg); +} + +static u32 nt72676_i2c_readl(struct nvt_i2c_bus *i2c, unsigned int reg) +{ + return readl(i2c->base + reg); +} + +static int nvt_i2c_stbc_auth(struct nvt_i2c_bus *i2c) +{ + int ret; + + if (!i2c->stbc_i2c) + return 0; + + ret = regmap_write(i2c->stbc_regmap, STBC_REG_PSWD, STBC_PSWD_DATA1); + if (ret) + return ret; + + ret = regmap_write(i2c->stbc_regmap, STBC_REG_PSWD, STBC_PSWD_DATA2); + if (ret) + return ret; + + ret = regmap_write(i2c->stbc_regmap, STBC_REG_KEYPASS, STBC_KEYPASS_ENABLE); + if (ret) + return ret; + + return regmap_update_bits(i2c->stbc_regmap, STBC_REG_I2C_SWITCH, + STBC_AGPIO_SWITCH_TO_CPU, STBC_AGPIO_SWITCH_TO_CPU); +} + +static void nvt_i2c_set_clk(struct nvt_i2c_bus *i2c) +{ + unsigned int clk_div = 0; + unsigned int duty = 0; + + clk_div = i2c->input_clk_rate / i2c->bus_clk_rate; + nt72676_i2c_writel(clk_div << 1, i2c, I2C_REG_CLK); + + duty = (clk_div * 9 + 10) / 20; + nt72676_i2c_writel(duty << 16, i2c, I2C_REG_DUTY); + + nt72676_i2c_writel(I2C_ACK_CTRL_COUNTER, i2c, I2C_REG_ACK); +} + +static int nvt_i2c_set_subaddr(struct nvt_i2c_bus *i2c, + const struct i2c_msg *msgs, + int num) +{ + unsigned int i, subaddr = 0; + + /* Sub-address can only be a write with maximum size of 4 bytes. */ + if (WARN_ON(num != 2)) + return -EINVAL; + if (!msgs || !msgs[0].buf || + msgs[0].len > i2c->adapter.quirks->max_comb_1st_msg_len || + (msgs[0].flags & I2C_M_RD) || !(msgs[1].flags & I2C_M_RD) || + msgs[0].addr != msgs[1].addr) { + dev_dbg(i2c->dev, "Invalid sub-address format\n"); + return -EOPNOTSUPP; + } + + i2c->subaddr_mode = msgs[0].len; + for (i = 0; i < msgs[0].len; i++) + subaddr |= (unsigned int)msgs[0].buf[i] << (8 * (msgs[0].len - 1 - i)); + nt72676_i2c_writel(subaddr, i2c, I2C_REG_SUBADDR); + + return 0; +} + +static int nvt_i2c_init(struct nvt_i2c_bus *i2c) +{ + if (i2c->stbc_i2c) { + int ret = nvt_i2c_stbc_auth(i2c); + + if (ret) + return ret; + } + nt72676_i2c_writel(I2C_IRQ_CLEAR_ALL, i2c, I2C_REG_INTR); + nvt_i2c_set_clk(i2c); + nt72676_i2c_writel(I2C_BUF_LITTLE_ENDIAN, i2c, I2C_REG_PINGPONG); + + return 0; +} + +static void nvt_i2c_reset(struct nvt_i2c_bus *i2c) +{ + nt72676_i2c_writel(I2C_IRQ_CLEAR_ALL, i2c, I2C_REG_INTR); + if (i2c->error_code) { + nt72676_i2c_writel(nt72676_i2c_readl(i2c, I2C_REG_CTRL) & ~I2C_ENABLE, + i2c, I2C_REG_CTRL); + nt72676_i2c_writel(nt72676_i2c_readl(i2c, I2C_REG_CTRL) | I2C_ENABLE, + i2c, I2C_REG_CTRL); + } +} + +static void nvt_i2c_release(struct nvt_i2c_bus *i2c) +{ + nt72676_i2c_writel(nt72676_i2c_readl(i2c, I2C_REG_CTRL) & ~I2C_ENABLE, + i2c, I2C_REG_CTRL); + nt72676_i2c_writel(I2C_IRQ_CLEAR_ALL, i2c, I2C_REG_INTR); +} + +static int nvt_i2c_suspend(struct device *dev) +{ + struct nvt_i2c_bus *i2c = dev_get_drvdata(dev); + unsigned long flags; + + i2c_mark_adapter_suspended(&i2c->adapter); + + spin_lock_irqsave(&i2c->lock, flags); + i2c->current_msg = NULL; + nvt_i2c_release(i2c); + spin_unlock_irqrestore(&i2c->lock, flags); + + return 0; +} + +static int nvt_i2c_resume(struct device *dev) +{ + struct nvt_i2c_bus *i2c = dev_get_drvdata(dev); + int ret = nvt_i2c_init(i2c); + + if (ret) { + dev_err(i2c->dev, "Failed to resume\n"); + return ret; + } + + i2c_mark_adapter_resumed(&i2c->adapter); + + return 0; +} + +static void nvt_i2c_clear_fifo(struct nvt_i2c_bus *i2c, unsigned int which) +{ + unsigned int regval = nt72676_i2c_readl(i2c, I2C_REG_PINGPONG); + + switch (which) { + case FIFO_1: + regval |= I2C_CLR_FIFO1; + break; + case FIFO_2: + regval |= I2C_CLR_FIFO2; + break; + case FIFO_ALL: + regval |= I2C_CLR_FIFO1 | I2C_CLR_FIFO2; + break; + default: + break; + } + nt72676_i2c_writel(regval, i2c, I2C_REG_PINGPONG); +} + +static void nvt_i2c_write_fifo(struct nvt_i2c_bus *i2c, + unsigned int fifo_reg, + const unsigned char *buf, + unsigned int buf_offset, + unsigned int length) +{ + unsigned int reg_idx = 0, copy_bytes = 0, j = 0, value = 0; + + while (length > 0) { + value = 0; + copy_bytes = min(FIFO_WORD_BYTES, length); + for (j = 0; j < copy_bytes; j++) + value |= ((unsigned int)buf[buf_offset + j]) << (j * 8); + + nt72676_i2c_writel(value, i2c, fifo_reg + reg_idx * 4); + buf_offset += copy_bytes; + length -= copy_bytes; + reg_idx++; + } +} + +static void nvt_i2c_read_fifo(struct nvt_i2c_bus *i2c, + unsigned int fifo_reg, + unsigned char *buf, + unsigned int buf_offset, + unsigned int length) +{ + unsigned int reg_idx = 0, copy_bytes = 0, j = 0, value = 0; + + while (length > 0) { + value = nt72676_i2c_readl(i2c, fifo_reg + reg_idx * 4); + copy_bytes = min(FIFO_WORD_BYTES, length); + for (j = 0; j < copy_bytes; j++) + buf[buf_offset + j] = (unsigned char)(value >> (j * 8)); + + buf_offset += copy_bytes; + length -= copy_bytes; + reg_idx++; + } +} + +static void nvt_i2c_handle(struct nvt_i2c_bus *i2c, struct i2c_msg *msg, bool is_read) +{ + unsigned int bytes, fiforeg; + + if (WARN_ON(!msg->buf)) + return; + + bytes = min(FIFO_CHUNK_SIZE, i2c->remaining); + fiforeg = i2c->fifo_idx == FIFO_1 ? I2C_REG_FIFO1 : I2C_REG_FIFO2; + + if (is_read) { + nvt_i2c_read_fifo(i2c, fiforeg, msg->buf, i2c->read_ptr, bytes); + i2c->read_ptr += bytes; + } else { + nvt_i2c_write_fifo(i2c, fiforeg, msg->buf, i2c->write_ptr, bytes); + i2c->write_ptr += bytes; + } + nvt_i2c_clear_fifo(i2c, i2c->fifo_idx); + i2c->remaining -= bytes; + i2c->fifo_idx ^= 1; +} + +static irqreturn_t nvt_i2c_isr(int irq, void *dev_id) +{ + struct nvt_i2c_bus *i2c = dev_id; + unsigned int status, clr = 0; + struct i2c_msg *msg; + int do_complete = 0; + + spin_lock(&i2c->lock); + status = nt72676_i2c_readl(i2c, I2C_REG_INTR); + /* IRQ from other I2C, ignored */ + if (!(status & I2C_IRQ_FLAG)) { + spin_unlock(&i2c->lock); + return IRQ_NONE; + } + + msg = i2c->current_msg; + if (!msg) { + nt72676_i2c_writel(I2C_IRQ_CLEAR_ALL, i2c, I2C_REG_INTR); + spin_unlock(&i2c->lock); + return IRQ_HANDLED; + } + + if (status & I2C_IRQ_CLK_STR_TIMEOUT) { + i2c->error_code = -ETIMEDOUT; + clr |= I2C_IRQ_CLK_STR_TIMEOUT << 8; + } else if (status & I2C_IRQ_NACK) { + i2c->error_code = -ENXIO; + clr |= I2C_IRQ_NACK << 8; + } else if (status & I2C_IRQ_RX_FULL) { + if (i2c->remaining > 0) + nvt_i2c_handle(i2c, msg, true); + clr |= I2C_IRQ_RX_FULL << 8; + } else if (status & I2C_IRQ_TX_EMPTY) { + if (i2c->remaining > 0) + nvt_i2c_handle(i2c, msg, false); + clr |= I2C_IRQ_TX_EMPTY << 8; + } else if (status & I2C_IRQ_FINISH) { + if (i2c->remaining > 0 && (msg->flags & I2C_M_RD)) + nvt_i2c_handle(i2c, msg, true); + clr |= I2C_IRQ_FINISH << 8; + do_complete = 1; + } + if (i2c->error_code) + do_complete = 1; + + nt72676_i2c_writel(status | clr, i2c, I2C_REG_INTR); + if (do_complete) + complete(&i2c->msg_complete); + spin_unlock(&i2c->lock); + + return IRQ_HANDLED; +} + +static void nvt_i2c_ctrl_init(struct nvt_i2c_bus *i2c) +{ + int i = 0; + + nt72676_i2c_writel(0, i2c, I2C_REG_CTRL); + for (i = 0; i < 4; i++) { + nt72676_i2c_writel(0, i2c, I2C_REG_FIFO1 + i * 4); + nt72676_i2c_writel(0, i2c, I2C_REG_FIFO2 + i * 4); + } + nvt_i2c_clear_fifo(i2c, FIFO_ALL); + nt72676_i2c_writel(0, i2c, I2C_REG_SUBADDR); + i2c->subaddr_mode = SUBADDR_DISABLE; +} + +static int nvt_i2c_check_msg(const struct i2c_msg *msg) +{ + if (!msg || !msg->buf || !msg->len) + return -EINVAL; + + return 0; +} + +static void nvt_i2c_prepare_xfer(struct nvt_i2c_bus *i2c, struct i2c_msg *msg) +{ + reinit_completion(&i2c->msg_complete); + i2c->remaining = msg->len; + i2c->current_msg = msg; + i2c->write_ptr = 0; + i2c->read_ptr = 0; + i2c->error_code = 0; + i2c->fifo_idx = FIFO_1; +} + +static int nvt_i2c_write(struct nvt_i2c_bus *i2c, struct i2c_msg *msg) +{ + int ret, offset = 0, write_bytes, fifo_num; + unsigned int ctrl_mask = 0; + unsigned long flags; + + ret = nvt_i2c_check_msg(msg); + if (ret) + return ret; + + spin_lock_irqsave(&i2c->lock, flags); + nvt_i2c_prepare_xfer(i2c, msg); + + nt72676_i2c_writel((msg->len * 8) << 8, i2c, I2C_REG_SIZE); + + /* Write FIFO data first */ + for (fifo_num = FIFO_1; fifo_num < FIFO_ALL && offset < msg->len; fifo_num++) { + write_bytes = min(FIFO_CHUNK_SIZE, msg->len - offset); + nvt_i2c_write_fifo(i2c, fifo_num == FIFO_1 ? I2C_REG_FIFO1 : I2C_REG_FIFO2, + msg->buf, offset, write_bytes); + offset += write_bytes; + } + i2c->write_ptr = offset; + i2c->remaining = msg->len - offset; + i2c->fifo_idx = FIFO_1; + + /* Enable interrupt */ + nt72676_i2c_writel(I2C_IRQ_ENABLE_SETTING | I2C_IRQ_CLEAR_ALL, + i2c, I2C_REG_INTR); + + /* Trigger */ + switch (i2c->subaddr_mode) { + case SUBADDR_8BITS: + ctrl_mask |= I2C_SUBADDR_ENABLE; + break; + case SUBADDR_16BITS: + ctrl_mask |= I2C_SUBADDR_ENABLE | I2C_16BITSUBADDR_ENABLE; + break; + case SUBADDR_24BITS: + ctrl_mask |= I2C_SUBADDR_ENABLE | I2C_24BITSUBADDR_ENABLE; + break; + case SUBADDR_32BITS: + ctrl_mask |= I2C_SUBADDR_ENABLE | I2C_32BITSUBADDR_ENABLE; + break; + default: + break; + } + ctrl_mask |= (((msg->addr << 1) << 8) | I2C_ENABLE | + I2C_CLOCK_DUTY_ENABLE | I2C_CLOCK_STRETCH_ENABLE | + I2C_MASTER_CLK_STRETCH_ENABLE | I2C_TRIGGER); + nt72676_i2c_writel(ctrl_mask, i2c, I2C_REG_CTRL); + spin_unlock_irqrestore(&i2c->lock, flags); + + ret = wait_for_completion_timeout(&i2c->msg_complete, i2c->adapter.timeout); + + spin_lock_irqsave(&i2c->lock, flags); + if (!ret) + i2c->error_code = -ETIMEDOUT; + nvt_i2c_reset(i2c); + ret = i2c->error_code; + i2c->current_msg = NULL; + spin_unlock_irqrestore(&i2c->lock, flags); + + if (ret) + dev_dbg(i2c->dev, "Write failed (err:%d); SA[0x%X]\n", + i2c->error_code, msg->addr); + + return ret; +} + +static int nvt_i2c_read(struct nvt_i2c_bus *i2c, struct i2c_msg *msg) +{ + unsigned int ctrl_mask = 0; + unsigned long flags; + int ret; + + ret = nvt_i2c_check_msg(msg); + if (ret) + return ret; + + spin_lock_irqsave(&i2c->lock, flags); + nvt_i2c_prepare_xfer(i2c, msg); + + nt72676_i2c_writel((msg->len * 8) << 8, i2c, I2C_REG_SIZE); + + /* Enable interrupt */ + nt72676_i2c_writel(I2C_IRQ_ENABLE_SETTING | I2C_IRQ_CLEAR_ALL, + i2c, I2C_REG_INTR); + + /* Trigger */ + switch (i2c->subaddr_mode) { + case SUBADDR_8BITS: + ctrl_mask |= I2C_SUBADDR_ENABLE; + break; + case SUBADDR_16BITS: + ctrl_mask |= I2C_SUBADDR_ENABLE | I2C_16BITSUBADDR_ENABLE; + break; + case SUBADDR_24BITS: + ctrl_mask |= I2C_SUBADDR_ENABLE | I2C_24BITSUBADDR_ENABLE; + break; + case SUBADDR_32BITS: + ctrl_mask |= I2C_SUBADDR_ENABLE | I2C_32BITSUBADDR_ENABLE; + break; + default: + break; + } + ctrl_mask |= (((msg->addr << 1) << 8) | I2C_ENABLE | + I2C_REPEAT_ENABLE | I2C_READ_OPERATION | + I2C_CLOCK_DUTY_ENABLE | I2C_CLOCK_STRETCH_ENABLE | + I2C_MASTER_CLK_STRETCH_ENABLE | I2C_TRIGGER); + nt72676_i2c_writel(ctrl_mask, i2c, I2C_REG_CTRL); + spin_unlock_irqrestore(&i2c->lock, flags); + + ret = wait_for_completion_timeout(&i2c->msg_complete, i2c->adapter.timeout); + + spin_lock_irqsave(&i2c->lock, flags); + if (!ret) + i2c->error_code = -ETIMEDOUT; + nvt_i2c_reset(i2c); + ret = i2c->error_code; + i2c->current_msg = NULL; + spin_unlock_irqrestore(&i2c->lock, flags); + + if (ret) + dev_dbg(i2c->dev, "Read failed (err:%d); SA[0x%X]\n", + i2c->error_code, msg->addr); + + return ret; +} + +static int nvt_i2c_xfer(struct i2c_adapter *adap, + struct i2c_msg msgs[], + int num) +{ + struct nvt_i2c_bus *i2c = i2c_get_adapdata(adap); + struct i2c_msg *msg = &msgs[0]; + int ret = 0; + + nvt_i2c_ctrl_init(i2c); + + if (num == 2) { + ret = nvt_i2c_set_subaddr(i2c, msgs, num); + if (ret) + return ret; + msg = &msgs[1]; + } + + if (msg->flags & I2C_M_RD) + ret = nvt_i2c_read(i2c, msg); + else + ret = nvt_i2c_write(i2c, msg); + + if (ret < 0) + return ret; + return num; +} + +static u32 nvt_i2c_func(struct i2c_adapter *adap) +{ + return (I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL) & ~I2C_FUNC_SMBUS_QUICK; +} + +static const struct i2c_algorithm nvt_i2c_algo = { + .master_xfer = nvt_i2c_xfer, + .functionality = nvt_i2c_func, +}; + +static int nvt_i2c_parse_dts(struct nvt_i2c_bus *i2c) +{ + struct device *dev = i2c->dev; + struct device_node *np = dev->of_node; + int ret; + + /* read DTS(novatek,stbc-syscon) for STBC I2C */ + i2c->stbc_i2c = of_property_present(dev->of_node, "novatek,stbc-syscon"); + if (i2c->stbc_i2c) { + i2c->stbc_regmap = syscon_regmap_lookup_by_phandle(dev->of_node, + "novatek,stbc-syscon"); + if (IS_ERR(i2c->stbc_regmap)) + return dev_err_probe(dev, PTR_ERR(i2c->stbc_regmap), + "Failed to get STBC syscon\n"); + } + + /* read DTS(clock-frequency) */ + ret = of_property_read_u32(np, "clock-frequency", &i2c->bus_clk_rate); + if (ret || !i2c->bus_clk_rate) { + dev_info(dev, "Not set dtb clock-frequency, set default 100kHz\n"); + i2c->bus_clk_rate = I2C_MAX_STANDARD_MODE_FREQ; + } + + return 0; +} + +static const struct of_device_id nvt_i2c_of_match[] = { + { .compatible = "novatek,nt72676-i2c" }, + { } +}; +MODULE_DEVICE_TABLE(of, nvt_i2c_of_match); + +static const struct i2c_adapter_quirks nvt_i2c_quirks = { + .flags = I2C_AQ_COMB_WRITE_THEN_READ | I2C_AQ_NO_ZERO_LEN, + .max_num_msgs = 2, + .max_write_len = 4096, + .max_read_len = 4096, + .max_comb_1st_msg_len = SUBADDR_MAX_LEN, + .max_comb_2nd_msg_len = 4096, +}; + +static int nvt_i2c_probe(struct platform_device *pdev) +{ + struct nvt_i2c_bus *i2c; + int ret; + + i2c = devm_kzalloc(&pdev->dev, sizeof(*i2c), GFP_KERNEL); + if (!i2c) + return -ENOMEM; + + i2c->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(i2c->base)) + return PTR_ERR(i2c->base); + + spin_lock_init(&i2c->lock); + init_completion(&i2c->msg_complete); + i2c->dev = &pdev->dev; + + ret = nvt_i2c_parse_dts(i2c); + if (ret) + return ret; + + i2c->clk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(i2c->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(i2c->clk), + "devm_clk_get_enabled fail\n"); + + i2c->input_clk_rate = clk_get_rate(i2c->clk); + if (!i2c->input_clk_rate) + return dev_err_probe(&pdev->dev, -EINVAL, "Invalid input clock rate\n"); + + if (i2c->input_clk_rate < i2c->bus_clk_rate) + return dev_err_probe(&pdev->dev, -EINVAL, + "Input clock rate %lu is lower than bus frequency %u\n", + i2c->input_clk_rate, i2c->bus_clk_rate); + + i2c->irq = platform_get_irq(pdev, 0); + if (i2c->irq < 0) + return i2c->irq; + + ret = nvt_i2c_init(i2c); + if (ret) + return dev_err_probe(&pdev->dev, ret, "nvt_i2c_init fail\n"); + + ret = devm_request_irq(&pdev->dev, i2c->irq, nvt_i2c_isr, + IRQF_SHARED, dev_name(&pdev->dev), i2c); + if (ret) { + nvt_i2c_release(i2c); + return dev_err_probe(&pdev->dev, ret, "devm_request_irq fail\n"); + } + + /* Setup I2C adapter */ + i2c->adapter.owner = THIS_MODULE; + i2c->adapter.algo = &nvt_i2c_algo; + i2c->adapter.dev.of_node = pdev->dev.of_node; + i2c->adapter.dev.parent = &pdev->dev; + i2c->adapter.quirks = &nvt_i2c_quirks; + i2c->adapter.timeout = 3 * HZ; + strscpy(i2c->adapter.name, dev_name(&pdev->dev), sizeof(i2c->adapter.name)); + i2c_set_adapdata(&i2c->adapter, i2c); + + ret = i2c_add_adapter(&i2c->adapter); + if (ret) { + nvt_i2c_release(i2c); + return dev_err_probe(&pdev->dev, ret, "Failed to add adapter\n"); + } + + platform_set_drvdata(pdev, i2c); + + return 0; +} + +static void nvt_i2c_remove(struct platform_device *pdev) +{ + struct nvt_i2c_bus *i2c = platform_get_drvdata(pdev); + unsigned long flags; + + i2c_del_adapter(&i2c->adapter); + spin_lock_irqsave(&i2c->lock, flags); + nvt_i2c_release(i2c); + spin_unlock_irqrestore(&i2c->lock, flags); +} + +static const struct dev_pm_ops nvt_i2c_pm_ops = { + .resume_early = nvt_i2c_resume, + .suspend_late = nvt_i2c_suspend, +}; + +static struct platform_driver nvt_i2c_driver = { + .probe = nvt_i2c_probe, + .remove = nvt_i2c_remove, + .driver = { + .name = "nt72676_i2c", + .pm = &nvt_i2c_pm_ops, + .of_match_table = of_match_ptr(nvt_i2c_of_match), + }, +}; +module_platform_driver(nvt_i2c_driver); + +MODULE_DESCRIPTION("Novatek NT72676 SoC I2C Bus Driver"); +MODULE_AUTHOR("Ben Huang <ben_huang@novatek.com.tw>"); +MODULE_LICENSE("GPL");
diff --git a/drivers/i2c/busses/i2c-qcom-cci.c b/drivers/i2c/busses/i2c-qcom-cci.c index bd70c6b..76a5ded 100644 --- a/drivers/i2c/busses/i2c-qcom-cci.c +++ b/drivers/i2c/busses/i2c-qcom-cci.c
@@ -11,6 +11,7 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/pm_opp.h> #define CCI_HW_VERSION 0x0 #define CCI_RESET_CMD 0x004 @@ -27,6 +28,7 @@ #define CCI_I2C_Mm_SDA_CTL_1(m) (0x108 + 0x100 * (m)) #define CCI_I2C_Mm_SDA_CTL_2(m) (0x10c + 0x100 * (m)) #define CCI_I2C_Mm_MISC_CTL(m) (0x110 + 0x100 * (m)) +#define CCI_I2C_MISC_CTL_SCL_STRETCH_EN BIT(8) #define CCI_I2C_Mm_READ_DATA(m) (0x118 + 0x100 * (m)) #define CCI_I2C_Mm_READ_BUF_LEVEL(m) (0x11c + 0x100 * (m)) @@ -82,6 +84,13 @@ enum { I2C_MODE_STANDARD, I2C_MODE_FAST, I2C_MODE_FAST_PLUS, + NUM_I2C_MODES, +}; + +enum { + CCI_CLK_RATE_19_2MHZ, + CCI_CLK_RATE_37_5MHZ, + NUM_CCI_CLK_RATES, }; enum cci_i2c_queue_t { @@ -97,7 +106,6 @@ struct hw_params { u16 thd_dat; /* data hold time */ u16 thd_sta; /* hold time (repeated) START condition */ u16 tbuf; /* bus free time between a STOP and START condition */ - u8 scl_stretch_en; u16 trdhld; u16 tsp; /* pulse width of spikes suppressed by the input filter */ }; @@ -117,7 +125,8 @@ struct cci_data { unsigned int num_masters; struct i2c_adapter_quirks quirks; u16 queue_size[NUM_QUEUES]; - struct hw_params params[3]; + /* Highest I2C mode supported by this variant. */ + u8 max_mode; }; struct cci { @@ -127,6 +136,7 @@ struct cci { const struct cci_data *data; struct clk_bulk_data *clocks; int nclocks; + struct clk *cci_clk; struct cci_master master[NUM_MASTERS]; }; @@ -225,7 +235,92 @@ static int cci_halt(struct cci *cci, u8 master_num) return 0; } -static void cci_init(struct cci *cci) +static const unsigned long cci_clk_rates[NUM_CCI_CLK_RATES] = { + [CCI_CLK_RATE_19_2MHZ] = 19200000, + [CCI_CLK_RATE_37_5MHZ] = 37500000, +}; + +static int cci_clk_rate_idx(unsigned long rate) +{ + int i; + + for (i = 0; i < NUM_CCI_CLK_RATES; i++) + if (cci_clk_rates[i] == rate) + return i; + + return -EINVAL; +} + +static const struct hw_params cci_hw_params[NUM_CCI_CLK_RATES][NUM_I2C_MODES] = { + [CCI_CLK_RATE_19_2MHZ][I2C_MODE_STANDARD] = { + .thigh = 78, + .tlow = 114, + .tsu_sto = 28, + .tsu_sta = 28, + .thd_dat = 10, + .thd_sta = 77, + .tbuf = 118, + .trdhld = 6, + .tsp = 1 + }, + [CCI_CLK_RATE_19_2MHZ][I2C_MODE_FAST] = { + .thigh = 20, + .tlow = 28, + .tsu_sto = 21, + .tsu_sta = 21, + .thd_dat = 13, + .thd_sta = 18, + .tbuf = 32, + .trdhld = 6, + .tsp = 3 + }, + [CCI_CLK_RATE_37_5MHZ][I2C_MODE_STANDARD] = { + .thigh = 201, + .tlow = 174, + .tsu_sto = 204, + .tsu_sta = 231, + .thd_dat = 22, + .thd_sta = 162, + .tbuf = 227, + .trdhld = 6, + .tsp = 3 + }, + [CCI_CLK_RATE_37_5MHZ][I2C_MODE_FAST] = { + .thigh = 38, + .tlow = 56, + .tsu_sto = 40, + .tsu_sta = 40, + .thd_dat = 22, + .thd_sta = 35, + .tbuf = 62, + .trdhld = 6, + .tsp = 3 + }, + [CCI_CLK_RATE_37_5MHZ][I2C_MODE_FAST_PLUS] = { + .thigh = 16, + .tlow = 22, + .tsu_sto = 17, + .tsu_sta = 18, + .thd_dat = 16, + .thd_sta = 15, + .tbuf = 24, + .trdhld = 3, + .tsp = 3 + }, +}; + +static const struct hw_params *cci_get_hw_params(struct cci *cci, int mode) +{ + unsigned long rate = clk_get_rate(cci->cci_clk); + int ri = cci_clk_rate_idx(rate); + + if (ri >= 0 && mode <= cci->data->max_mode) + return &cci_hw_params[ri][mode]; + + return NULL; +} + +static int cci_init(struct cci *cci) { u32 val = CCI_IRQ_MASK_0_I2C_M0_RD_DONE | CCI_IRQ_MASK_0_I2C_M0_Q0_REPORT | @@ -249,7 +344,12 @@ static void cci_init(struct cci *cci) if (!cci->master[i].cci) continue; - hw = &cci->data->params[mode]; + hw = cci_get_hw_params(cci, mode); + if (!hw) { + dev_err(cci->dev, "no timing for mode %d at CCI clock %lu Hz\n", + mode, clk_get_rate(cci->cci_clk)); + return -EOPNOTSUPP; + } val = hw->thigh << 16 | hw->tlow; writel(val, cci->base + CCI_I2C_Mm_SCL_CTL(i)); @@ -263,9 +363,11 @@ static void cci_init(struct cci *cci) val = hw->tbuf; writel(val, cci->base + CCI_I2C_Mm_SDA_CTL_2(i)); - val = hw->scl_stretch_en << 8 | hw->trdhld << 4 | hw->tsp; + val = CCI_I2C_MISC_CTL_SCL_STRETCH_EN | hw->trdhld << 4 | hw->tsp; writel(val, cci->base + CCI_I2C_Mm_MISC_CTL(i)); } + + return 0; } static int cci_reset(struct cci *cci) @@ -283,9 +385,7 @@ static int cci_reset(struct cci *cci) return -ETIMEDOUT; } - cci_init(cci); - - return 0; + return cci_init(cci); } static int cci_run_queue(struct cci *cci, u8 master, u8 queue) @@ -471,6 +571,69 @@ static void cci_disable_clocks(struct cci *cci) clk_bulk_disable_unprepare(cci->nclocks, cci->clocks); } +/* + * The single CCI clock is shared by all masters, which may run in different + * modes. Pick the lowest rate that has a valid timing set for every active + * master's mode. + */ +static int cci_get_required_rate(struct cci *cci, unsigned long *rate) +{ + for (int ri = 0; ri < NUM_CCI_CLK_RATES; ri++) { + bool supported = true; + + if (clk_round_rate(cci->cci_clk, cci_clk_rates[ri]) != cci_clk_rates[ri]) + continue; + + for (int i = 0; i < cci->data->num_masters; i++) { + int mode = cci->master[i].mode; + + if (!cci->master[i].cci) + continue; + + if (mode > cci->data->max_mode || + !cci_hw_params[ri][mode].thigh) { + supported = false; + break; + } + } + + if (supported) { + *rate = cci_clk_rates[ri]; + return 0; + } + } + + return -EOPNOTSUPP; +} + +static int cci_set_core_rate(struct cci *cci) +{ + struct device *dev = cci->dev; + unsigned long rate; + int ret; + + ret = cci_get_required_rate(cci, &rate); + if (ret) { + dev_err(dev, "no CCI clock rate satisfies all masters\n"); + return ret; + } + + ret = dev_pm_opp_set_rate(dev, rate); + if (ret) { + dev_err(dev, "CCI clock could not be set to %lu Hz\n", rate); + return ret; + } + + /* + * Sanity: The hw_params timings are only valid at the exact + * expected rate, verify what landed on the hardware. + */ + if (clk_get_rate(cci->cci_clk) != rate) + dev_warn(dev, "CCI clock is not at expected %lu Hz\n", rate); + + return 0; +} + static int __maybe_unused cci_suspend_runtime(struct device *dev) { struct cci *cci = dev_get_drvdata(dev); @@ -488,8 +651,7 @@ static int __maybe_unused cci_resume_runtime(struct device *dev) if (ret) return ret; - cci_init(cci); - return 0; + return cci_init(cci); } static const struct dev_pm_ops qcom_cci_pm = { @@ -577,6 +739,24 @@ static int cci_probe(struct platform_device *pdev) return dev_err_probe(dev, -EINVAL, "not enough clocks in DT\n"); cci->nclocks = ret; + cci->cci_clk = devm_clk_get(dev, "cci"); + if (IS_ERR(cci->cci_clk)) + return dev_err_probe(dev, PTR_ERR(cci->cci_clk), + "failed to get CCI clock\n"); + + ret = devm_pm_opp_set_clkname(dev, "cci"); + if (ret) + return dev_err_probe(dev, ret, "failed to set CCI OPP clk\n"); + + /* OPP table is optional */ + ret = devm_pm_opp_of_add_table(dev); + if (ret && ret != -ENODEV) + return dev_err_probe(dev, ret, "failed to add OPP table\n"); + + ret = cci_set_core_rate(cci); + if (ret) + return ret; + ret = cci_enable_clocks(cci); if (ret < 0) return ret; @@ -651,30 +831,7 @@ static const struct cci_data cci_v1_data = { .max_write_len = 10, .max_read_len = 12, }, - .params[I2C_MODE_STANDARD] = { - .thigh = 78, - .tlow = 114, - .tsu_sto = 28, - .tsu_sta = 28, - .thd_dat = 10, - .thd_sta = 77, - .tbuf = 118, - .scl_stretch_en = 0, - .trdhld = 6, - .tsp = 1 - }, - .params[I2C_MODE_FAST] = { - .thigh = 20, - .tlow = 28, - .tsu_sto = 21, - .tsu_sta = 21, - .thd_dat = 13, - .thd_sta = 18, - .tbuf = 32, - .scl_stretch_en = 0, - .trdhld = 6, - .tsp = 3 - }, + .max_mode = I2C_MODE_FAST, }; static const struct cci_data cci_v1_5_data = { @@ -684,30 +841,7 @@ static const struct cci_data cci_v1_5_data = { .max_write_len = 10, .max_read_len = 12, }, - .params[I2C_MODE_STANDARD] = { - .thigh = 78, - .tlow = 114, - .tsu_sto = 28, - .tsu_sta = 28, - .thd_dat = 10, - .thd_sta = 77, - .tbuf = 118, - .scl_stretch_en = 0, - .trdhld = 6, - .tsp = 1 - }, - .params[I2C_MODE_FAST] = { - .thigh = 20, - .tlow = 28, - .tsu_sto = 21, - .tsu_sta = 21, - .thd_dat = 13, - .thd_sta = 18, - .tbuf = 32, - .scl_stretch_en = 0, - .trdhld = 6, - .tsp = 3 - }, + .max_mode = I2C_MODE_FAST, }; static const struct cci_data cci_v2_data = { @@ -717,92 +851,12 @@ static const struct cci_data cci_v2_data = { .max_write_len = 11, .max_read_len = 12, }, - .params[I2C_MODE_STANDARD] = { - .thigh = 201, - .tlow = 174, - .tsu_sto = 204, - .tsu_sta = 231, - .thd_dat = 22, - .thd_sta = 162, - .tbuf = 227, - .scl_stretch_en = 0, - .trdhld = 6, - .tsp = 3 - }, - .params[I2C_MODE_FAST] = { - .thigh = 38, - .tlow = 56, - .tsu_sto = 40, - .tsu_sta = 40, - .thd_dat = 22, - .thd_sta = 35, - .tbuf = 62, - .scl_stretch_en = 0, - .trdhld = 6, - .tsp = 3 - }, - .params[I2C_MODE_FAST_PLUS] = { - .thigh = 16, - .tlow = 22, - .tsu_sto = 17, - .tsu_sta = 18, - .thd_dat = 16, - .thd_sta = 15, - .tbuf = 24, - .scl_stretch_en = 0, - .trdhld = 3, - .tsp = 3 - }, -}; - -static const struct cci_data cci_msm8953_data = { - .num_masters = 2, - .queue_size = { 64, 16 }, - .quirks = { - .max_write_len = 11, - .max_read_len = 12, - }, - .params[I2C_MODE_STANDARD] = { - .thigh = 78, - .tlow = 114, - .tsu_sto = 28, - .tsu_sta = 28, - .thd_dat = 10, - .thd_sta = 77, - .tbuf = 118, - .scl_stretch_en = 0, - .trdhld = 6, - .tsp = 1 - }, - .params[I2C_MODE_FAST] = { - .thigh = 20, - .tlow = 28, - .tsu_sto = 21, - .tsu_sta = 21, - .thd_dat = 13, - .thd_sta = 18, - .tbuf = 32, - .scl_stretch_en = 0, - .trdhld = 6, - .tsp = 3 - }, - .params[I2C_MODE_FAST_PLUS] = { - .thigh = 16, - .tlow = 22, - .tsu_sto = 17, - .tsu_sta = 18, - .thd_dat = 16, - .thd_sta = 15, - .tbuf = 19, - .scl_stretch_en = 1, - .trdhld = 3, - .tsp = 3 - }, + .max_mode = I2C_MODE_FAST_PLUS, }; static const struct of_device_id cci_dt_match[] = { { .compatible = "qcom,msm8226-cci", .data = &cci_v1_data}, - { .compatible = "qcom,msm8953-cci", .data = &cci_msm8953_data}, + { .compatible = "qcom,msm8953-cci", .data = &cci_v2_data}, { .compatible = "qcom,msm8974-cci", .data = &cci_v1_5_data}, { .compatible = "qcom,msm8996-cci", .data = &cci_v2_data},
diff --git a/drivers/i2c/busses/i2c-qcom-geni.c b/drivers/i2c/busses/i2c-qcom-geni.c index c4c6202..a431e98 100644 --- a/drivers/i2c/busses/i2c-qcom-geni.c +++ b/drivers/i2c/busses/i2c-qcom-geni.c
@@ -995,10 +995,9 @@ static int geni_i2c_xfer(struct i2c_adapter *adap, struct geni_i2c_dev *gi2c = i2c_get_adapdata(adap); int ret; - ret = pm_runtime_get_sync(gi2c->se.dev); + ret = pm_runtime_resume_and_get(gi2c->se.dev); if (ret < 0) { dev_err(gi2c->se.dev, "error turning SE resources:%d\n", ret); - pm_runtime_put_noidle(gi2c->se.dev); /* Set device in suspended since resume failed */ pm_runtime_set_suspended(gi2c->se.dev); return ret; @@ -1074,10 +1073,8 @@ static int geni_i2c_init(struct geni_i2c_dev *gi2c) int ret; ret = pm_runtime_resume_and_get(gi2c->se.dev); - if (ret < 0) { - dev_err(gi2c->se.dev, "error turning on device :%d\n", ret); - return ret; - } + if (ret < 0) + return dev_err_probe(gi2c->se.dev, ret, "error turning on device\n"); proto = geni_se_read_proto(&gi2c->se); if (proto == GENI_SE_INVALID_PROTO) { @@ -1177,9 +1174,6 @@ static int geni_i2c_probe(struct platform_device *pdev) gi2c->clk_freq_out = I2C_MAX_STANDARD_MODE_FREQ; } - if (has_acpi_companion(dev)) - ACPI_COMPANION_SET(&gi2c->adap.dev, ACPI_COMPANION(dev)); - gi2c->irq = platform_get_irq(pdev, 0); if (gi2c->irq < 0) return gi2c->irq; @@ -1205,7 +1199,7 @@ static int geni_i2c_probe(struct platform_device *pdev) i2c_set_adapdata(&gi2c->adap, gi2c); gi2c->adap.dev.parent = dev; - gi2c->adap.dev.of_node = dev->of_node; + device_set_node(&gi2c->adap.dev, dev_fwnode(dev)); strscpy(gi2c->adap.name, "Geni-I2C", sizeof(gi2c->adap.name)); pm_runtime_set_suspended(dev); @@ -1247,7 +1241,7 @@ static void geni_i2c_shutdown(struct platform_device *pdev) i2c_mark_adapter_suspended(&gi2c->adap); } -static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev) +static int geni_i2c_runtime_suspend(struct device *dev) { int ret = 0; struct geni_i2c_dev *gi2c = dev_get_drvdata(dev); @@ -1265,7 +1259,7 @@ static int __maybe_unused geni_i2c_runtime_suspend(struct device *dev) return 0; } -static int __maybe_unused geni_i2c_runtime_resume(struct device *dev) +static int geni_i2c_runtime_resume(struct device *dev) { int ret = 0; struct geni_i2c_dev *gi2c = dev_get_drvdata(dev); @@ -1281,7 +1275,7 @@ static int __maybe_unused geni_i2c_runtime_resume(struct device *dev) return 0; } -static int __maybe_unused geni_i2c_suspend_noirq(struct device *dev) +static int geni_i2c_suspend_noirq(struct device *dev) { struct geni_i2c_dev *gi2c = dev_get_drvdata(dev); int ret; @@ -1295,7 +1289,7 @@ static int __maybe_unused geni_i2c_suspend_noirq(struct device *dev) return ret; } -static int __maybe_unused geni_i2c_resume_noirq(struct device *dev) +static int geni_i2c_resume_noirq(struct device *dev) { struct geni_i2c_dev *gi2c = dev_get_drvdata(dev); int ret; @@ -1309,9 +1303,10 @@ static int __maybe_unused geni_i2c_resume_noirq(struct device *dev) } static const struct dev_pm_ops geni_i2c_pm_ops = { - SET_NOIRQ_SYSTEM_SLEEP_PM_OPS(geni_i2c_suspend_noirq, geni_i2c_resume_noirq) - SET_RUNTIME_PM_OPS(geni_i2c_runtime_suspend, geni_i2c_runtime_resume, - NULL) + NOIRQ_SYSTEM_SLEEP_PM_OPS(geni_i2c_suspend_noirq, + geni_i2c_resume_noirq) + RUNTIME_PM_OPS(geni_i2c_runtime_suspend, geni_i2c_runtime_resume, + NULL) }; static const struct geni_i2c_desc geni_i2c = { @@ -1337,8 +1332,8 @@ static const struct geni_i2c_desc sa8255p_geni_i2c = { #ifdef CONFIG_ACPI static const struct acpi_device_id geni_i2c_acpi_match[] = { - { "QCOM0220", (kernel_ulong_t)&geni_i2c}, - { "QCOM0411", (kernel_ulong_t)&geni_i2c}, + { .id = "QCOM0220", .driver_data = (kernel_ulong_t)&geni_i2c }, + { .id = "QCOM0411", .driver_data = (kernel_ulong_t)&geni_i2c }, { } }; MODULE_DEVICE_TABLE(acpi, geni_i2c_acpi_match);
diff --git a/drivers/i2c/busses/i2c-qup.c b/drivers/i2c/busses/i2c-qup.c index ee7915e..ce30634 100644 --- a/drivers/i2c/busses/i2c-qup.c +++ b/drivers/i2c/busses/i2c-qup.c
@@ -1688,7 +1688,7 @@ static void qup_i2c_disable_clocks(struct qup_i2c_dev *qup) } static const struct acpi_device_id qup_i2c_acpi_match[] = { - { "QCOM8010"}, + { .id = "QCOM8010" }, { } }; MODULE_DEVICE_TABLE(acpi, qup_i2c_acpi_match);
diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c index 324a63e..37442c9 100644 --- a/drivers/i2c/busses/i2c-scmi.c +++ b/drivers/i2c/busses/i2c-scmi.c
@@ -42,10 +42,10 @@ static const struct smbus_methods_t ibm_smbus_methods = { }; static const struct acpi_device_id acpi_smbus_cmi_ids[] = { - {"SMBUS01", (kernel_ulong_t)&smbus_methods}, - {ACPI_SMBUS_IBM_HID, (kernel_ulong_t)&ibm_smbus_methods}, - {ACPI_SMBUS_MS_HID, (kernel_ulong_t)&smbus_methods}, - {"", 0} + { .id = "SMBUS01", .driver_data = (kernel_ulong_t)&smbus_methods }, + { .id = ACPI_SMBUS_IBM_HID, .driver_data = (kernel_ulong_t)&ibm_smbus_methods }, + { .id = ACPI_SMBUS_MS_HID, .driver_data = (kernel_ulong_t)&smbus_methods }, + { } }; MODULE_DEVICE_TABLE(acpi, acpi_smbus_cmi_ids);
diff --git a/drivers/i2c/busses/i2c-synquacer.c b/drivers/i2c/busses/i2c-synquacer.c index 0216e39..968cbe3 100644 --- a/drivers/i2c/busses/i2c-synquacer.c +++ b/drivers/i2c/busses/i2c-synquacer.c
@@ -622,8 +622,8 @@ MODULE_DEVICE_TABLE(of, synquacer_i2c_dt_ids); #ifdef CONFIG_ACPI static const struct acpi_device_id synquacer_i2c_acpi_ids[] = { - { "SCX0003" }, - { /* sentinel */ } + { .id = "SCX0003" }, + { } }; MODULE_DEVICE_TABLE(acpi, synquacer_i2c_acpi_ids); #endif
diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 9c281b4..76d21bc 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c
@@ -2486,10 +2486,10 @@ static const struct dev_pm_ops tegra_i2c_pm = { }; static const struct acpi_device_id tegra_i2c_acpi_match[] = { - {.id = "NVDA0101", .driver_data = (kernel_ulong_t)&tegra210_i2c_hw}, - {.id = "NVDA0201", .driver_data = (kernel_ulong_t)&tegra186_i2c_hw}, - {.id = "NVDA0301", .driver_data = (kernel_ulong_t)&tegra194_i2c_hw}, - {.id = "NVDA2017", .driver_data = (kernel_ulong_t)&tegra410_i2c_hw}, + { .id = "NVDA0101", .driver_data = (kernel_ulong_t)&tegra210_i2c_hw }, + { .id = "NVDA0201", .driver_data = (kernel_ulong_t)&tegra186_i2c_hw }, + { .id = "NVDA0301", .driver_data = (kernel_ulong_t)&tegra194_i2c_hw }, + { .id = "NVDA2017", .driver_data = (kernel_ulong_t)&tegra410_i2c_hw }, { } }; MODULE_DEVICE_TABLE(acpi, tegra_i2c_acpi_match);
diff --git a/drivers/i2c/busses/i2c-usbio.c b/drivers/i2c/busses/i2c-usbio.c index 259754e..66da1e9 100644 --- a/drivers/i2c/busses/i2c-usbio.c +++ b/drivers/i2c/busses/i2c-usbio.c
@@ -24,12 +24,12 @@ struct usbio_i2c { }; static const struct acpi_device_id usbio_i2c_acpi_hids[] = { - { "INTC1008" }, /* MTL */ - { "INTC10B3" }, /* ARL */ - { "INTC10B6" }, /* LNL */ - { "INTC10D2" }, /* MTL-CVF */ - { "INTC10E3" }, /* PTL */ - { "INTC1118" }, /* NVL */ + { .id = "INTC1008" }, /* MTL */ + { .id = "INTC10B3" }, /* ARL */ + { .id = "INTC10B6" }, /* LNL */ + { .id = "INTC10D2" }, /* MTL-CVF */ + { .id = "INTC10E3" }, /* PTL */ + { .id = "INTC1118" }, /* NVL */ { } };
diff --git a/drivers/i2c/busses/i2c-viai2c-zhaoxin.c b/drivers/i2c/busses/i2c-viai2c-zhaoxin.c index 764a2db..81f0bfd 100644 --- a/drivers/i2c/busses/i2c-viai2c-zhaoxin.c +++ b/drivers/i2c/busses/i2c-viai2c-zhaoxin.c
@@ -345,7 +345,7 @@ static const struct dev_pm_ops zxi2c_pm = { }; static const struct acpi_device_id zxi2c_acpi_match[] = { - {"IIC1D17", 0 }, + { .id = "IIC1D17" }, { } }; MODULE_DEVICE_TABLE(acpi, zxi2c_acpi_match);
diff --git a/drivers/i2c/busses/i2c-xgene-slimpro.c b/drivers/i2c/busses/i2c-xgene-slimpro.c index b29dec6..08a126a 100644 --- a/drivers/i2c/busses/i2c-xgene-slimpro.c +++ b/drivers/i2c/busses/i2c-xgene-slimpro.c
@@ -539,9 +539,9 @@ MODULE_DEVICE_TABLE(of, xgene_slimpro_i2c_dt_ids); #ifdef CONFIG_ACPI static const struct acpi_device_id xgene_slimpro_i2c_acpi_ids[] = { - {"APMC0D40", XGENE_SLIMPRO_I2C_V1}, - {"APMC0D8B", XGENE_SLIMPRO_I2C_V2}, - {} + { .id = "APMC0D40", .driver_data = XGENE_SLIMPRO_I2C_V1 }, + { .id = "APMC0D8B", .driver_data = XGENE_SLIMPRO_I2C_V2 }, + { } }; MODULE_DEVICE_TABLE(acpi, xgene_slimpro_i2c_acpi_ids); #endif
diff --git a/drivers/i2c/busses/i2c-xlp9xx.c b/drivers/i2c/busses/i2c-xlp9xx.c index ad0e5cd..44cad95 100644 --- a/drivers/i2c/busses/i2c-xlp9xx.c +++ b/drivers/i2c/busses/i2c-xlp9xx.c
@@ -570,9 +570,9 @@ static void xlp9xx_i2c_remove(struct platform_device *pdev) #ifdef CONFIG_ACPI static const struct acpi_device_id xlp9xx_i2c_acpi_ids[] = { - {"BRCM9007", 0}, - {"CAV9007", 0}, - {} + { .id = "BRCM9007" }, + { .id = "CAV9007" }, + { } }; MODULE_DEVICE_TABLE(acpi, xlp9xx_i2c_acpi_ids); #endif
diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c index 8f3bdd5..703588e 100644 --- a/drivers/i2c/i2c-core-acpi.c +++ b/drivers/i2c/i2c-core-acpi.c
@@ -352,8 +352,8 @@ static const struct acpi_device_id i2c_acpi_force_400khz_device_ids[] = { * at 400KHz (as can be expected of any recent i2c hw) so we force * the speed of the bus to 400 KHz if a Silead device is present. */ - { "MSSL1680", 0 }, - {} + { .id = "MSSL1680" }, + { } }; static const struct acpi_device_id i2c_acpi_force_100khz_device_ids[] = { @@ -371,11 +371,13 @@ static const struct acpi_device_id i2c_acpi_force_100khz_device_ids[] = { * the device works without issues on Windows at what is expected to be * a 400KHz frequency. The root cause of the issue is not known. */ - { "DLL0945", 0 }, - { "ELAN0678", 0 }, - { "ELAN06FA", 0 }, - { "ELAN1300", 0 }, - {} + { .id = "ASUE140D" }, + { .id = "DELL0A86" }, + { .id = "DLL0945" }, + { .id = "ELAN0678" }, + { .id = "ELAN06FA" }, + { .id = "ELAN1300" }, + { } }; static acpi_status i2c_acpi_lookup_speed(acpi_handle handle, u32 level, @@ -607,7 +609,7 @@ static int acpi_gsb_i2c_read_bytes(struct i2c_client *client, msgs[0].buf = &cmd; msgs[1].addr = client->addr; - msgs[1].flags = client->flags | I2C_M_RD; + msgs[1].flags = client->flags | I2C_M_RD | I2C_M_DMA_SAFE; msgs[1].len = data_len; msgs[1].buf = buffer; @@ -648,7 +650,7 @@ static int acpi_gsb_i2c_write_bytes(struct i2c_client *client, memcpy(buffer + 1, data, data_len); msgs[0].addr = client->addr; - msgs[0].flags = client->flags; + msgs[0].flags = client->flags | I2C_M_DMA_SAFE; msgs[0].len = data_len + 1; msgs[0].buf = buffer;
diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index ddaacf8..852d6a0 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c
@@ -1902,6 +1902,9 @@ static int i2c_dev_or_parent_fwnode_match(struct device *dev, const void *data) * If no adapter can be found, or @fwnode is NULL, this returns NULL. * * The user must call put_device(&adapter->dev) once done with the i2c adapter. + * + * Note that i2c_get_adapter_by_fwnode(), which also takes a module reference, + * should almost always be used instead of this one. */ struct i2c_adapter *i2c_find_adapter_by_fwnode(struct fwnode_handle *fwnode) {
diff --git a/drivers/i2c/i2c-core-smbus.c b/drivers/i2c/i2c-core-smbus.c index fa63bee..57f55bb 100644 --- a/drivers/i2c/i2c-core-smbus.c +++ b/drivers/i2c/i2c-core-smbus.c
@@ -208,11 +208,11 @@ s32 i2c_smbus_write_word_data(const struct i2c_client *client, u8 command, EXPORT_SYMBOL(i2c_smbus_write_word_data); /** - * i2c_smbus_read_block_data - SMBus "block read" protocol + * __i2c_smbus_read_block_data - SMBus "block read" protocol * @client: Handle to slave device * @command: Byte interpreted by slave - * @values: Byte array into which data will be read; big enough to hold - * the data returned by the slave. SMBus allows at most 32 bytes. + * @length: size of the @values array. SMBus allows at most 32 bytes + * @values: Byte array into which data will be read * * This executes the SMBus "block read" protocol, returning negative errno * else the number of data bytes in the slave's response. @@ -222,22 +222,30 @@ EXPORT_SYMBOL(i2c_smbus_write_word_data); * support this; its emulation through I2C messaging relies on a specific * mechanism (I2C_M_RECV_LEN) which may not be implemented. */ -s32 i2c_smbus_read_block_data(const struct i2c_client *client, u8 command, - u8 *values) +s32 __i2c_smbus_read_block_data(const struct i2c_client *client, u8 command, + u8 length, u8 *values) { union i2c_smbus_data data; + int ret_len; int status; + if (length > I2C_SMBUS_BLOCK_MAX) + return -EINVAL; + status = i2c_smbus_xfer(client->adapter, client->addr, client->flags, I2C_SMBUS_READ, command, I2C_SMBUS_BLOCK_DATA, &data); if (status) return status; - memcpy(values, &data.block[1], data.block[0]); - return data.block[0]; + ret_len = data.block[0]; + if (ret_len > length) + return -EMSGSIZE; + + memcpy(values, &data.block[1], ret_len); + return ret_len; } -EXPORT_SYMBOL(i2c_smbus_read_block_data); +EXPORT_SYMBOL(__i2c_smbus_read_block_data); /** * i2c_smbus_write_block_data - SMBus "block write" protocol
diff --git a/drivers/i2c/i2c-mux.c b/drivers/i2c/i2c-mux.c index 68a4c34..5342809 100644 --- a/drivers/i2c/i2c-mux.c +++ b/drivers/i2c/i2c-mux.c
@@ -24,7 +24,7 @@ #include <linux/i2c-mux.h> #include <linux/kernel.h> #include <linux/module.h> -#include <linux/of.h> +#include <linux/property.h> #include <linux/slab.h> #include <linux/sysfs.h> @@ -33,6 +33,7 @@ struct i2c_mux_priv { struct i2c_adapter adap; struct i2c_algorithm algo; struct i2c_mux_core *muxc; + struct fwnode_handle *channel_node; u32 chan_id; }; @@ -264,6 +265,51 @@ static const struct i2c_lock_operations i2c_parent_lock_ops = { .unlock_bus = i2c_parent_unlock_bus, }; +static struct fwnode_handle * +i2c_mux_get_channel_node(struct i2c_mux_core *muxc, u32 chan_id) +{ + struct fwnode_handle *dev_node; + struct fwnode_handle *mux_node; + struct fwnode_handle *child; + u32 reg; + int ret; + + dev_node = dev_fwnode(muxc->dev); + if (!dev_node) + return NULL; + + if (muxc->arbitrator) + mux_node = fwnode_get_named_child_node(dev_node, "i2c-arb"); + else if (muxc->gate) + mux_node = fwnode_get_named_child_node(dev_node, "i2c-gate"); + else + mux_node = fwnode_get_named_child_node(dev_node, "i2c-mux"); + + if (mux_node) { + /* A "reg" property indicates an old-style firmware entry. */ + if (!fwnode_property_read_u32(mux_node, "reg", ®)) { + fwnode_handle_put(mux_node); + mux_node = NULL; + } + } + + if (!mux_node) + mux_node = fwnode_handle_get(dev_node); + else if (muxc->arbitrator || muxc->gate) + return mux_node; + + fwnode_for_each_child_node(mux_node, child) { + ret = fwnode_property_read_u32(child, "reg", ®); + if (ret) + continue; + if (chan_id == reg) + break; + } + + fwnode_handle_put(mux_node); + return child; +} + int i2c_mux_add_adapter(struct i2c_mux_core *muxc, u32 force_nr, u32 chan_id) { @@ -323,48 +369,9 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc, else priv->adap.lock_ops = &i2c_parent_lock_ops; - /* - * Try to populate the mux adapter's of_node, expands to - * nothing if !CONFIG_OF. - */ - if (muxc->dev->of_node) { - struct device_node *dev_node = muxc->dev->of_node; - struct device_node *mux_node, *child = NULL; - u32 reg; - - if (muxc->arbitrator) - mux_node = of_get_child_by_name(dev_node, "i2c-arb"); - else if (muxc->gate) - mux_node = of_get_child_by_name(dev_node, "i2c-gate"); - else - mux_node = of_get_child_by_name(dev_node, "i2c-mux"); - - if (mux_node) { - /* A "reg" property indicates an old-style DT entry */ - if (!of_property_read_u32(mux_node, "reg", ®)) { - of_node_put(mux_node); - mux_node = NULL; - } - } - - if (!mux_node) - mux_node = of_node_get(dev_node); - else if (muxc->arbitrator || muxc->gate) - child = of_node_get(mux_node); - - if (!child) { - for_each_child_of_node(mux_node, child) { - ret = of_property_read_u32(child, "reg", ®); - if (ret) - continue; - if (chan_id == reg) - break; - } - } - - priv->adap.dev.of_node = child; - of_node_put(mux_node); - } + /* Associate the mux adapter with its channel firmware node. */ + priv->channel_node = i2c_mux_get_channel_node(muxc, chan_id); + device_set_node(&priv->adap.dev, priv->channel_node); /* * Associate the mux channel with an ACPI node. @@ -408,7 +415,7 @@ int i2c_mux_add_adapter(struct i2c_mux_core *muxc, return 0; err_free_priv: - of_node_put(priv->adap.dev.of_node); + fwnode_handle_put(priv->channel_node); kfree(priv); return ret; } @@ -421,7 +428,6 @@ void i2c_mux_del_adapters(struct i2c_mux_core *muxc) while (muxc->num_adapters) { struct i2c_adapter *adap = muxc->adapter[--muxc->num_adapters]; struct i2c_mux_priv *priv = adap->algo_data; - struct device_node *np = adap->dev.of_node; muxc->adapter[muxc->num_adapters] = NULL; @@ -431,7 +437,7 @@ void i2c_mux_del_adapters(struct i2c_mux_core *muxc) sysfs_remove_link(&priv->adap.dev.kobj, "mux_device"); i2c_del_adapter(adap); - of_node_put(np); + fwnode_handle_put(priv->channel_node); kfree(priv); } }
diff --git a/drivers/input/keyboard/samsung-keypad.c b/drivers/input/keyboard/samsung-keypad.c index deffa98..f56c524 100644 --- a/drivers/input/keyboard/samsung-keypad.c +++ b/drivers/input/keyboard/samsung-keypad.c
@@ -12,6 +12,7 @@ #include <linux/delay.h> #include <linux/err.h> #include <linux/input.h> +#include <linux/input/matrix_keypad.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/module.h> @@ -21,7 +22,9 @@ #include <linux/slab.h> #include <linux/of.h> #include <linux/sched.h> -#include <linux/input/samsung-keypad.h> + +#define SAMSUNG_MAX_ROWS 8 +#define SAMSUNG_MAX_COLS 8 #define SAMSUNG_KEYIFCON 0x00 #define SAMSUNG_KEYIFSTSCLR 0x04 @@ -221,145 +224,92 @@ static void samsung_keypad_close(struct input_dev *input_dev) samsung_keypad_stop(keypad); } -#ifdef CONFIG_OF -static struct samsung_keypad_platdata * -samsung_keypad_parse_dt(struct device *dev) +static int samsung_parse_verbose_keymap(struct samsung_keypad *keypad) { - struct samsung_keypad_platdata *pdata; - struct matrix_keymap_data *keymap_data; - uint32_t *keymap, num_rows = 0, num_cols = 0; - struct device_node *np = dev->of_node, *key_np; - unsigned int key_count; + struct matrix_keymap_data keymap_data = { 0 }; + struct device *dev = &keypad->pdev->dev; + struct fwnode_handle *child; + unsigned int key_count = device_get_child_node_count(dev); + unsigned int i; - if (!np) { - dev_err(dev, "missing device tree data\n"); - return ERR_PTR(-EINVAL); - } + u32 *keymap __free(kfree) = kcalloc(key_count, sizeof(*keymap), GFP_KERNEL); + if (!keymap) + return -ENOMEM; - pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) { - dev_err(dev, "could not allocate memory for platform data\n"); - return ERR_PTR(-ENOMEM); - } + keymap_data.keymap_size = key_count; + keymap_data.keymap = keymap; - of_property_read_u32(np, "samsung,keypad-num-rows", &num_rows); - of_property_read_u32(np, "samsung,keypad-num-columns", &num_cols); - if (!num_rows || !num_cols) { - dev_err(dev, "number of keypad rows/columns not specified\n"); - return ERR_PTR(-EINVAL); - } - pdata->rows = num_rows; - pdata->cols = num_cols; - - keymap_data = devm_kzalloc(dev, sizeof(*keymap_data), GFP_KERNEL); - if (!keymap_data) { - dev_err(dev, "could not allocate memory for keymap data\n"); - return ERR_PTR(-ENOMEM); - } - pdata->keymap_data = keymap_data; - - key_count = of_get_child_count(np); - keymap_data->keymap_size = key_count; - keymap = devm_kcalloc(dev, key_count, sizeof(uint32_t), GFP_KERNEL); - if (!keymap) { - dev_err(dev, "could not allocate memory for keymap\n"); - return ERR_PTR(-ENOMEM); - } - keymap_data->keymap = keymap; - - for_each_child_of_node(np, key_np) { + i = 0; + device_for_each_child_node(dev, child) { u32 row, col, key_code; - of_property_read_u32(key_np, "keypad,row", &row); - of_property_read_u32(key_np, "keypad,column", &col); - of_property_read_u32(key_np, "linux,code", &key_code); - *keymap++ = KEY(row, col, key_code); + + fwnode_property_read_u32(child, "keypad,row", &row); + fwnode_property_read_u32(child, "keypad,column", &col); + fwnode_property_read_u32(child, "linux,code", &key_code); + + keymap[i++] = KEY(row, col, key_code); } - pdata->no_autorepeat = of_property_read_bool(np, "linux,input-no-autorepeat"); - - pdata->wakeup = of_property_read_bool(np, "wakeup-source") || - /* legacy name */ - of_property_read_bool(np, "linux,input-wakeup"); - - - return pdata; + return matrix_keypad_build_keymap(&keymap_data, NULL, + keypad->rows, keypad->cols, + keypad->keycodes, + keypad->input_dev); } -#else -static struct samsung_keypad_platdata * -samsung_keypad_parse_dt(struct device *dev) + +static int samsung_keypad_parse_keymap(struct samsung_keypad *keypad) { - dev_err(dev, "no platform data defined\n"); + struct device *dev = &keypad->pdev->dev; - return ERR_PTR(-EINVAL); + if (device_property_present(dev, "linux,keymap")) + return matrix_keypad_build_keymap(NULL, NULL, + keypad->rows, keypad->cols, + keypad->keycodes, + keypad->input_dev); + + return samsung_parse_verbose_keymap(keypad); } -#endif static int samsung_keypad_probe(struct platform_device *pdev) { - const struct samsung_keypad_platdata *pdata; - const struct matrix_keymap_data *keymap_data; const struct platform_device_id *id; + struct device *dev = &pdev->dev; struct samsung_keypad *keypad; struct resource *res; struct input_dev *input_dev; unsigned int row_shift; + u32 num_rows = 0, num_cols = 0; + bool wakeup; int error; - pdata = dev_get_platdata(&pdev->dev); - if (!pdata) { - pdata = samsung_keypad_parse_dt(&pdev->dev); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); + if (device_property_present(dev, "linux,keymap")) { + error = matrix_keypad_parse_properties(dev, &num_rows, &num_cols); + if (error) + return error; + } else { + device_property_read_u32(dev, "samsung,keypad-num-rows", &num_rows); + device_property_read_u32(dev, "samsung,keypad-num-columns", &num_cols); + if (!num_rows || !num_cols) { + dev_err(dev, "number of keypad rows/columns not specified\n"); + return -EINVAL; + } } - keymap_data = pdata->keymap_data; - if (!keymap_data) { - dev_err(&pdev->dev, "no keymap data defined\n"); - return -EINVAL; - } - - if (!pdata->rows || pdata->rows > SAMSUNG_MAX_ROWS) + if (num_rows > SAMSUNG_MAX_ROWS || num_cols > SAMSUNG_MAX_COLS) return -EINVAL; - if (!pdata->cols || pdata->cols > SAMSUNG_MAX_COLS) - return -EINVAL; - - /* initialize the gpio */ - if (pdata->cfg_gpio) - pdata->cfg_gpio(pdata->rows, pdata->cols); - - row_shift = get_count_order(pdata->cols); + row_shift = get_count_order(num_cols); keypad = devm_kzalloc(&pdev->dev, struct_size(keypad, keycodes, - pdata->rows << row_shift), + num_rows << row_shift), GFP_KERNEL); if (!keypad) return -ENOMEM; - input_dev = devm_input_allocate_device(&pdev->dev); - if (!input_dev) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - keypad->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (!keypad->base) - return -EBUSY; - - keypad->clk = devm_clk_get_prepared(&pdev->dev, "keypad"); - if (IS_ERR(keypad->clk)) { - dev_err(&pdev->dev, "failed to get keypad clk\n"); - return PTR_ERR(keypad->clk); - } - - keypad->input_dev = input_dev; keypad->pdev = pdev; keypad->row_shift = row_shift; - keypad->rows = pdata->rows; - keypad->cols = pdata->cols; + keypad->rows = num_rows; + keypad->cols = num_cols; keypad->stopped = true; init_waitqueue_head(&keypad->wait); @@ -375,26 +325,45 @@ static int samsung_keypad_probe(struct platform_device *pdev) return -EINVAL; } + input_dev = devm_input_allocate_device(&pdev->dev); + if (!input_dev) + return -ENOMEM; + + keypad->input_dev = input_dev; + input_dev->name = pdev->name; input_dev->id.bustype = BUS_HOST; input_dev->open = samsung_keypad_open; input_dev->close = samsung_keypad_close; - error = matrix_keypad_build_keymap(keymap_data, NULL, - pdata->rows, pdata->cols, - keypad->keycodes, input_dev); + error = samsung_keypad_parse_keymap(keypad); if (error) { dev_err(&pdev->dev, "failed to build keymap\n"); return error; } input_set_capability(input_dev, EV_MSC, MSC_SCAN); - if (!pdata->no_autorepeat) + + if (!device_property_read_bool(&pdev->dev, "linux,input-no-autorepeat")) __set_bit(EV_REP, input_dev->evbit); input_set_drvdata(input_dev, keypad); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + + keypad->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); + if (!keypad->base) + return -EBUSY; + + keypad->clk = devm_clk_get_prepared(&pdev->dev, "keypad"); + if (IS_ERR(keypad->clk)) { + dev_err(&pdev->dev, "failed to get keypad clk\n"); + return PTR_ERR(keypad->clk); + } + keypad->irq = platform_get_irq(pdev, 0); if (keypad->irq < 0) { error = keypad->irq; @@ -410,7 +379,11 @@ static int samsung_keypad_probe(struct platform_device *pdev) return error; } - device_init_wakeup(&pdev->dev, pdata->wakeup); + wakeup = device_property_read_bool(dev, "wakeup-source") || + /* legacy name */ + device_property_read_bool(dev, "linux,input-wakeup"); + device_init_wakeup(&pdev->dev, wakeup); + platform_set_drvdata(pdev, keypad); error = devm_pm_runtime_enable(&pdev->dev); @@ -421,11 +394,6 @@ static int samsung_keypad_probe(struct platform_device *pdev) if (error) return error; - if (pdev->dev.of_node) { - devm_kfree(&pdev->dev, (void *)pdata->keymap_data->keymap); - devm_kfree(&pdev->dev, (void *)pdata->keymap_data); - devm_kfree(&pdev->dev, (void *)pdata); - } return 0; }
diff --git a/drivers/irqchip/irq-aclint-sswi.c b/drivers/irqchip/irq-aclint-sswi.c index 5e010fc..34572db 100644 --- a/drivers/irqchip/irq-aclint-sswi.c +++ b/drivers/irqchip/irq-aclint-sswi.c
@@ -179,6 +179,7 @@ static int __init generic_aclint_sswi_early_probe(struct device_node *node, } IRQCHIP_DECLARE(mips_p8700_sswi, "mips,p8700-aclint-sswi", generic_aclint_sswi_early_probe); IRQCHIP_DECLARE(nuclei_ux900_sswi, "nuclei,ux900-aclint-sswi", generic_aclint_sswi_early_probe); +IRQCHIP_DECLARE(spacemit_k3_sswi, "spacemit,k3-aclint-sswi", generic_aclint_sswi_early_probe); /* THEAD variant */ #define THEAD_C9XX_CSR_SXSTATUS 0x5c0
diff --git a/drivers/mailbox/arm_mhu_db.c b/drivers/mailbox/arm_mhu_db.c index a39239e..9f1c7bc 100644 --- a/drivers/mailbox/arm_mhu_db.c +++ b/drivers/mailbox/arm_mhu_db.c
@@ -317,10 +317,8 @@ static int mhu_db_probe(struct amba_device *adev, const struct amba_id *id) err = devm_request_threaded_irq(dev, irq, NULL, mhu_db_mbox_rx_handler, IRQF_ONESHOT, "mhu_db_link", mhu); - if (err) { - mbox_controller_unregister(&mhu->mbox); + if (err) return err; - } } dev_info(dev, "ARM MHU Doorbell mailbox registered\n");
diff --git a/drivers/mailbox/arm_mhuv2.c b/drivers/mailbox/arm_mhuv2.c index d4077cd..0520d49 100644 --- a/drivers/mailbox/arm_mhuv2.c +++ b/drivers/mailbox/arm_mhuv2.c
@@ -27,6 +27,7 @@ #include <linux/amba/bus.h> #include <linux/interrupt.h> +#include <linux/iopoll.h> #include <linux/mailbox_controller.h> #include <linux/mailbox/arm_mhuv2_message.h> #include <linux/module.h> @@ -967,6 +968,7 @@ static int mhuv2_tx_init(struct amba_device *adev, struct mhuv2 *mhu, { struct device *dev = mhu->mbox.dev; int ret, i; + u32 val; mhu->frame = SENDER_FRAME; mhu->mbox.ops = &mhuv2_sender_ops; @@ -1007,8 +1009,11 @@ static int mhuv2_tx_init(struct amba_device *adev, struct mhuv2 *mhu, out: /* Wait for receiver to be ready */ writel_relaxed(0x1, &mhu->send->access_request); - while (!readl_relaxed(&mhu->send->access_ready)) - continue; + if (readl_relaxed_poll_timeout(&mhu->send->access_ready, val, val, + 100, 1000000)) { + dev_err(dev, "receiver not ready\n"); + return -ETIMEDOUT; + } return 0; }
diff --git a/drivers/mailbox/arm_mhuv3.c b/drivers/mailbox/arm_mhuv3.c index 6569c3d..b9addd9 100644 --- a/drivers/mailbox/arm_mhuv3.c +++ b/drivers/mailbox/arm_mhuv3.c
@@ -980,7 +980,8 @@ static int mhuv3_setup_pbx(struct mhuv3 *mhu) ret = devm_request_threaded_irq(dev, mhu->cmb_irq, NULL, mhuv3_pbx_comb_interrupt, - IRQF_ONESHOT, "mhuv3-pbx", mhu); + IRQF_ONESHOT | IRQF_NO_SUSPEND, + "mhuv3-pbx", mhu); if (ret) return ret; @@ -1016,7 +1017,8 @@ static int mhuv3_setup_mbx(struct mhuv3 *mhu) "MBX combined IRQ is missing !\n"); ret = devm_request_threaded_irq(dev, mhu->cmb_irq, NULL, - mhuv3_mbx_comb_interrupt, IRQF_ONESHOT, + mhuv3_mbx_comb_interrupt, + IRQF_ONESHOT | IRQF_NO_SUSPEND, "mhuv3-mbx", mhu); if (ret) return ret;
diff --git a/drivers/mailbox/axiado-mailbox.c b/drivers/mailbox/axiado-mailbox.c index 3a3cf74..a87693c 100644 --- a/drivers/mailbox/axiado-mailbox.c +++ b/drivers/mailbox/axiado-mailbox.c
@@ -15,6 +15,7 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/property.h> +#include <linux/sched.h> #include <linux/slab.h> #include <linux/unaligned.h> @@ -36,6 +37,12 @@ #define AXIADO_MBOX_CSR_ERRORS (AXIADO_MBOX_CSR_OVERFLOW | \ AXIADO_MBOX_CSR_UNDERFLOW) +enum axiado_mbox_frame_result { + AXIADO_MBOX_FRAME_EMPTY, + AXIADO_MBOX_FRAME_OK, + AXIADO_MBOX_FRAME_BAD, /* malformed/incomplete; FIFO flushed */ +}; + struct axiado_mbox_data { u8 num_chans; u16 msg_size; @@ -116,6 +123,13 @@ static int axiado_mbox_send_data(struct mbox_chan *chan, void *data) return -EBUSY; } + /* + * Per-word get_unaligned_le32()/writel(), not writesl(): @data is + * supplied by whatever client calls mbox_send_message(), and + * mbox_chan_ops.send_data(void *data) makes no alignment guarantee + * for that buffer. writesl() dereferences it as a native u32 *, + * which is unsafe unless alignment is known. + */ for (offset = 0; offset + sizeof(u32) <= msg_len; offset += sizeof(u32)) writel(get_unaligned_le32(buf + offset), priv->mbox_reg); @@ -131,31 +145,42 @@ static int axiado_mbox_send_data(struct mbox_chan *chan, void *data) return 0; } -static irqreturn_t axiado_rx_thread(int irq, void *dev_id) +/* + * Read and, if valid, deliver exactly one length-prefixed frame currently + * at the head of the RX FIFO. Does not loop -- the caller decides whether + * to call this again. May clear a pending FIFO error at several points + * below, wherever a new one could plausibly have appeared since the last + * check; each check is a cheap readl() when nothing is pending. + */ +static enum axiado_mbox_frame_result axiado_mbox_receive_one_frame(struct axiado_channel_data *priv, + bool *serviced) { - struct axiado_channel_data *priv = dev_id; struct mbox_chan *chan = priv->chan; struct axiado_mbox *mb = dev_get_drvdata(chan->mbox->dev); u8 *buf = priv->rx_buffer; unsigned int num_words; unsigned int remaining; - unsigned int i; u32 msg_len; u32 word; u32 csr; int ret; /* - * Clear and log/count any pending errors, but don't discard data - * on their account alone: a rejected overflow write doesn't - * corrupt what was already safely queued ahead of it, so let the - * length-based read below decide whether what's here is usable. + * Don't discard data on a cleared error's account alone: a rejected + * overflow write doesn't corrupt what was already safely queued + * ahead of it, so let the length-based read below decide whether + * what's here is usable. Count clearing a real error as @serviced + * so the handler reports IRQ_HANDLED whenever it actually handled + * a hardware condition. */ - axiado_mbox_clear_fifo_errors(priv); + if (axiado_mbox_clear_fifo_errors(priv)) + *serviced = true; csr = readl(priv->csr_reg); if (csr & AXIADO_MBOX_CSR_EMPTY) - return IRQ_NONE; + return AXIADO_MBOX_FRAME_EMPTY; + + *serviced = true; /* * The first word contains the total message length in bytes, @@ -165,8 +190,12 @@ static irqreturn_t axiado_rx_thread(int irq, void *dev_id) msg_len = word; put_unaligned_le32(word, buf); - if (msg_len < sizeof(u32) || msg_len > mb->drv_data->msg_size) - goto invalid_message; + if (msg_len < sizeof(u32) || msg_len > mb->drv_data->msg_size) { + dev_warn_ratelimited(chan->mbox->dev, + "Channel %u invalid frame length %u (max %u)\n", + priv->channel_num, msg_len, mb->drv_data->msg_size); + goto bad_frame; + } num_words = DIV_ROUND_UP(msg_len, sizeof(u32)); remaining = num_words - 1; @@ -182,33 +211,68 @@ static irqreturn_t axiado_rx_thread(int irq, void *dev_id) remaining, AXIADO_MBOX_RX_POLL_US, AXIADO_MBOX_RX_TIMEOUT_US); - if (ret) - goto incomplete_message; + /* + * The wait condition above is satisfied by EITHER the + * expected word count landing OR a FIFO error appearing. + * ret == 0 only means "didn't time out" - it does not mean + * the words are actually there. Check @csr for the error + * bit explicitly; otherwise an underflow can present as + * "success" and the read loop below pulls words that were + * never pushed, handing the client garbage. + */ + if (ret || (csr & AXIADO_MBOX_CSR_ERRORS)) { + dev_warn_ratelimited(chan->mbox->dev, + "Channel %u incomplete frame: got %lu/%u words (%s)\n", + priv->channel_num, + FIELD_GET(AXIADO_MBOX_CSR_LEVEL, csr), + num_words, + (csr & AXIADO_MBOX_CSR_ERRORS) ? + "FIFO error" : "timed out"); + goto bad_frame; + } axiado_mbox_clear_fifo_errors(priv); } - for (i = 1; i < num_words; i++) { - word = readl(priv->mbox_reg); - put_unaligned_le32(word, buf + i * sizeof(u32)); - } + /* + * readsl() streams the payload words directly into rx_buffer, which + * is allocated by this driver via devm_kzalloc() and therefore has + * suitable alignment for a stream accessor. + */ + readsl(priv->mbox_reg, buf + sizeof(u32), remaining); axiado_mbox_clear_fifo_errors(priv); if (READ_ONCE(priv->active)) mbox_chan_received_data(chan, priv->rx_buffer); - return IRQ_HANDLED; + return AXIADO_MBOX_FRAME_OK; -incomplete_message: - dev_warn_ratelimited(chan->mbox->dev, - "Channel %u received an incomplete message\n", - priv->channel_num); - -invalid_message: +bad_frame: + axiado_mbox_clear_fifo_errors(priv); writel(AXIADO_MBOX_CSR_FLUSH, priv->csr_reg); - return IRQ_HANDLED; + return AXIADO_MBOX_FRAME_BAD; +} + +static irqreturn_t axiado_rx_thread(int irq, void *dev_id) +{ + struct axiado_channel_data *priv = dev_id; + enum axiado_mbox_frame_result result; + bool handled = false; + + /* + * Drain all frames currently queued in the FIFO before returning. + * Multiple frames may accumulate while the threaded handler is + * running. cond_resched() prevents a continuously-fed channel from + * monopolizing the CPU. + */ + do { + result = axiado_mbox_receive_one_frame(priv, &handled); + cond_resched(); + } while (result == AXIADO_MBOX_FRAME_OK); + + return handled ? IRQ_HANDLED : IRQ_NONE; } static int axiado_mbox_startup(struct mbox_chan *chan) @@ -315,7 +379,7 @@ static int axiado_mbox_probe(struct platform_device *pdev) return ret; for (i = 0; i < drv_data->num_chans; i++) { - char name[16]; + char name[32]; ch_data[i].channel_num = i; ch_data[i].chan = &mb->mbox.chans[i];
diff --git a/drivers/mailbox/bcm74110-mailbox.c b/drivers/mailbox/bcm74110-mailbox.c index c8709d5..bec138d 100644 --- a/drivers/mailbox/bcm74110-mailbox.c +++ b/drivers/mailbox/bcm74110-mailbox.c
@@ -97,6 +97,8 @@ struct bcm74110_mbox_chan { int type; }; +#define BCM74110_INIT_MSG_MAX 16 + struct bcm74110_mbox { struct platform_device *pdev; void __iomem *base; @@ -105,6 +107,7 @@ struct bcm74110_mbox { int rx_chan; int rx_irq; struct list_head rx_svc_init_list; + unsigned int rx_svc_init_count; spinlock_t rx_svc_list_lock; struct mbox_controller controller; @@ -148,7 +151,15 @@ static void bcm74110_rx_push_init_msg(struct bcm74110_mbox *mbox, u32 val) msg->msg = val; spin_lock(&mbox->rx_svc_list_lock); + if (mbox->rx_svc_init_count >= BCM74110_INIT_MSG_MAX) { + spin_unlock(&mbox->rx_svc_list_lock); + kfree(msg); + dev_warn_ratelimited(&mbox->pdev->dev, + "PMC INIT msg list full, dropping message\n"); + return; + } list_add_tail(&msg->list_entry, &mbox->rx_svc_init_list); + mbox->rx_svc_init_count++; spin_unlock(&mbox->rx_svc_list_lock); } @@ -225,6 +236,7 @@ static int bcm74110_rx_pop_init_msg(struct bcm74110_mbox *mbox, u32 func_type, list_entry) { if (BCM_MSG_GET_FIELD(msg->msg, FUNC) == func_type) { list_del(&msg->list_entry); + mbox->rx_svc_init_count--; found = true; break; } @@ -248,6 +260,7 @@ static void bcm74110_rx_flush_msg(struct bcm74110_mbox *mbox) spin_lock_irqsave(&mbox->rx_svc_list_lock, flags); list_splice_init(&mbox->rx_svc_init_list, &list_temp); + mbox->rx_svc_init_count = 0; spin_unlock_irqrestore(&mbox->rx_svc_list_lock, flags); list_for_each_entry_safe(msg, msg_tmp, &list_temp, list_entry) {
diff --git a/drivers/mailbox/mailbox-altera.c b/drivers/mailbox/mailbox-altera.c index 17278c2..7cb9141 100644 --- a/drivers/mailbox/mailbox-altera.c +++ b/drivers/mailbox/mailbox-altera.c
@@ -270,7 +270,7 @@ static void altera_mbox_shutdown(struct mbox_chan *chan) writel_relaxed(~0, mbox->mbox_base + MAILBOX_INTMASK_REG); free_irq(mbox->irq, chan); } else if (!mbox->is_sender) { - timer_delete_sync(&mbox->rxpoll_timer); + timer_shutdown_sync(&mbox->rxpoll_timer); } }
diff --git a/drivers/mailbox/mailbox-xgene-slimpro.c b/drivers/mailbox/mailbox-xgene-slimpro.c index 946ea77..1f87a84 100644 --- a/drivers/mailbox/mailbox-xgene-slimpro.c +++ b/drivers/mailbox/mailbox-xgene-slimpro.c
@@ -228,8 +228,8 @@ MODULE_DEVICE_TABLE(of, slimpro_of_match); #ifdef CONFIG_ACPI static const struct acpi_device_id slimpro_acpi_ids[] = { - {"APMC0D01", 0}, - {} + { .id = "APMC0D01" }, + { } }; MODULE_DEVICE_TABLE(acpi, slimpro_acpi_ids); #endif
diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c index e523c84..96462ca 100644 --- a/drivers/mailbox/mtk-cmdq-mailbox.c +++ b/drivers/mailbox/mtk-cmdq-mailbox.c
@@ -565,8 +565,10 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout) int ret; ret = pm_runtime_get_sync(cmdq->mbox.dev); - if (ret < 0) + if (ret < 0) { + pm_runtime_put_noidle(cmdq->mbox.dev); return ret; + } spin_lock_irqsave(&thread->chan->lock, flags); if (list_empty(&thread->task_busy_list)) @@ -603,6 +605,9 @@ static int cmdq_mbox_flush(struct mbox_chan *chan, unsigned long timeout) dev_err(cmdq->mbox.dev, "Fail to wait GCE thread 0x%x done\n", (u32)(thread->base - cmdq->base)); + pm_runtime_mark_last_busy(cmdq->mbox.dev); + pm_runtime_put_autosuspend(cmdq->mbox.dev); + return -EFAULT; } pm_runtime_mark_last_busy(cmdq->mbox.dev);
diff --git a/drivers/mailbox/pcc.c b/drivers/mailbox/pcc.c index 9888dab..14dc4a1 100644 --- a/drivers/mailbox/pcc.c +++ b/drivers/mailbox/pcc.c
@@ -53,6 +53,7 @@ #include <linux/interrupt.h> #include <linux/list.h> #include <linux/log2.h> +#include <linux/mutex.h> #include <linux/platform_device.h> #include <linux/mailbox_controller.h> #include <linux/mailbox_client.h> @@ -113,6 +114,7 @@ struct pcc_chan_info { #define to_pcc_chan_info(c) container_of(c, struct pcc_chan_info, chan) static struct pcc_chan_info *chan_info; static int pcc_chan_count; +static DEFINE_MUTEX(pcc_chan_mutex); /* * PCC can be used with perf critical drivers such as CPPC @@ -392,6 +394,8 @@ pcc_mbox_request_channel(struct mbox_client *cl, int subspace_id) if (subspace_id < 0 || subspace_id >= pcc_chan_count) return ERR_PTR(-ENOENT); + guard(mutex)(&pcc_chan_mutex); + pchan = chan_info + subspace_id; chan = pchan->chan.mchan; if (IS_ERR(chan) || chan->cl) { @@ -434,16 +438,19 @@ void pcc_mbox_free_channel(struct pcc_mbox_chan *pchan) struct pcc_chan_info *pchan_info; struct pcc_mbox_chan *pcc_mbox_chan; + guard(mutex)(&pcc_chan_mutex); + if (!chan || !chan->cl) return; pchan_info = chan->con_priv; pcc_mbox_chan = &pchan_info->chan; + + mbox_free_channel(chan); + if (pcc_mbox_chan->shmem) { iounmap(pcc_mbox_chan->shmem); pcc_mbox_chan->shmem = NULL; } - - mbox_free_channel(chan); } EXPORT_SYMBOL_GPL(pcc_mbox_free_channel);
diff --git a/drivers/mailbox/qcom-cpucp-mbox.c b/drivers/mailbox/qcom-cpucp-mbox.c index 515d2d1..b88ea25 100644 --- a/drivers/mailbox/qcom-cpucp-mbox.c +++ b/drivers/mailbox/qcom-cpucp-mbox.c
@@ -61,7 +61,7 @@ static irqreturn_t qcom_cpucp_mbox_irq_fn(int irq, void *data) status = readq(cpucp->rx_base + APSS_CPUCP_RX_MBOX_STAT); for_each_set_bit(i, (unsigned long *)&status, cpucp->mbox.num_chans) { - u32 val = readl(cpucp->rx_base + APSS_CPUCP_RX_MBOX_CMD(i) + APSS_CPUCP_MBOX_CMD_OFF); + u64 val = readq(cpucp->rx_base + APSS_CPUCP_RX_MBOX_CMD(i)); struct mbox_chan *chan = &cpucp->chans[i]; struct mbox_client *cl; unsigned long flags;
diff --git a/drivers/mailbox/qcom-ipcc.c b/drivers/mailbox/qcom-ipcc.c index 185b63f..bb54295 100644 --- a/drivers/mailbox/qcom-ipcc.c +++ b/drivers/mailbox/qcom-ipcc.c
@@ -10,6 +10,7 @@ #include <linux/mailbox_controller.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/spinlock.h> #include <dt-bindings/mailbox/qcom-ipcc.h> @@ -151,6 +152,9 @@ static int qcom_ipcc_mbox_send_data(struct mbox_chan *chan, void *data) struct qcom_ipcc_chan_info *mchan = chan->con_priv; u32 hwirq; + if (!mchan) + return -EINVAL; + hwirq = qcom_ipcc_get_hwirq(mchan->client_id, mchan->signal_id); writel(hwirq, ipcc->base + IPCC_REG_SEND_ID); @@ -159,6 +163,8 @@ static int qcom_ipcc_mbox_send_data(struct mbox_chan *chan, void *data) static void qcom_ipcc_mbox_shutdown(struct mbox_chan *chan) { + guard(spinlock_irqsave)(&chan->lock); + chan->con_priv = NULL; } @@ -282,8 +288,6 @@ static int qcom_ipcc_probe(struct platform_device *pdev) { struct qcom_ipcc *ipcc; u32 config_value; - static int id; - char *name; int ret; ipcc = devm_kzalloc(&pdev->dev, sizeof(*ipcc), GFP_KERNEL); @@ -313,10 +317,6 @@ static int qcom_ipcc_probe(struct platform_device *pdev) if (ipcc->irq < 0) return ipcc->irq; - name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "ipcc_%d", id++); - if (!name) - return -ENOMEM; - ipcc->irq_domain = irq_domain_create_tree(dev_fwnode(&pdev->dev), &qcom_ipcc_irq_ops, ipcc); if (!ipcc->irq_domain) return -ENOMEM; @@ -327,17 +327,14 @@ static int qcom_ipcc_probe(struct platform_device *pdev) ret = devm_request_irq(&pdev->dev, ipcc->irq, qcom_ipcc_irq_fn, IRQF_TRIGGER_HIGH | IRQF_NO_SUSPEND | - IRQF_NO_THREAD, name, ipcc); + IRQF_NO_THREAD, dev_name(&pdev->dev), ipcc); if (ret < 0) - goto err_req_irq; + goto err_mbox; platform_set_drvdata(pdev, ipcc); return 0; -err_req_irq: - if (ipcc->num_chans) - mbox_controller_unregister(&ipcc->mbox); err_mbox: irq_domain_remove(ipcc->irq_domain); @@ -348,7 +345,6 @@ static void qcom_ipcc_remove(struct platform_device *pdev) { struct qcom_ipcc *ipcc = platform_get_drvdata(pdev); - disable_irq_wake(ipcc->irq); irq_domain_remove(ipcc->irq_domain); }
diff --git a/drivers/mailbox/riscv-sbi-mpxy-mbox.c b/drivers/mailbox/riscv-sbi-mpxy-mbox.c index ea69c6b6..4ebce35 100644 --- a/drivers/mailbox/riscv-sbi-mpxy-mbox.c +++ b/drivers/mailbox/riscv-sbi-mpxy-mbox.c
@@ -1006,8 +1006,8 @@ static const struct of_device_id mpxy_mbox_of_match[] = { MODULE_DEVICE_TABLE(of, mpxy_mbox_of_match); static const struct acpi_device_id mpxy_mbox_acpi_match[] = { - { "RSCV0005" }, - {} + { .id = "RSCV0005" }, + { } }; MODULE_DEVICE_TABLE(acpi, mpxy_mbox_acpi_match);
diff --git a/drivers/mailbox/rockchip-mailbox.c b/drivers/mailbox/rockchip-mailbox.c index bc2f9dd..790c34a 100644 --- a/drivers/mailbox/rockchip-mailbox.c +++ b/drivers/mailbox/rockchip-mailbox.c
@@ -12,25 +12,23 @@ #include <linux/module.h> #include <linux/platform_device.h> -#define MAILBOX_A2B_INTEN 0x00 -#define MAILBOX_A2B_STATUS 0x04 -#define MAILBOX_A2B_CMD(x) (0x08 + (x) * 8) -#define MAILBOX_A2B_DAT(x) (0x0c + (x) * 8) +#define ROCKCHIP_MAILBOX_A2B_INTEN 0x00 +#define ROCKCHIP_MAILBOX_A2B_STATUS 0x04 +#define ROCKCHIP_MAILBOX_A2B_CMD(x) (0x08 + (x) * 8) +#define ROCKCHIP_MAILBOX_A2B_DAT(x) (0x0c + (x) * 8) -#define MAILBOX_B2A_INTEN 0x28 -#define MAILBOX_B2A_STATUS 0x2C -#define MAILBOX_B2A_CMD(x) (0x30 + (x) * 8) -#define MAILBOX_B2A_DAT(x) (0x34 + (x) * 8) +#define ROCKCHIP_MAILBOX_B2A_INTEN 0x28 +#define ROCKCHIP_MAILBOX_B2A_STATUS 0x2C +#define ROCKCHIP_MAILBOX_B2A_CMD(x) (0x30 + (x) * 8) +#define ROCKCHIP_MAILBOX_B2A_DAT(x) (0x34 + (x) * 8) + +#define ROCKCHIP_MAILBOX_NUM_CHANS 4 struct rockchip_mbox_msg { u32 cmd; int rx_size; }; -struct rockchip_mbox_data { - int num_chans; -}; - struct rockchip_mbox_chan { int idx; int irq; @@ -68,9 +66,10 @@ static int rockchip_mbox_send_data(struct mbox_chan *chan, void *data) mb->chans[chans->idx].msg = msg; - writel_relaxed(msg->cmd, mb->mbox_base + MAILBOX_A2B_CMD(chans->idx)); + writel_relaxed(msg->cmd, mb->mbox_base + + ROCKCHIP_MAILBOX_A2B_CMD(chans->idx)); writel_relaxed(msg->rx_size, mb->mbox_base + - MAILBOX_A2B_DAT(chans->idx)); + ROCKCHIP_MAILBOX_A2B_DAT(chans->idx)); return 0; } @@ -81,7 +80,7 @@ static int rockchip_mbox_startup(struct mbox_chan *chan) /* Enable all B2A interrupts */ writel_relaxed((1 << mb->mbox.num_chans) - 1, - mb->mbox_base + MAILBOX_B2A_INTEN); + mb->mbox_base + ROCKCHIP_MAILBOX_B2A_INTEN); return 0; } @@ -92,7 +91,7 @@ static void rockchip_mbox_shutdown(struct mbox_chan *chan) struct rockchip_mbox_chan *chans = mb->chans; /* Disable all B2A interrupts */ - writel_relaxed(0, mb->mbox_base + MAILBOX_B2A_INTEN); + writel_relaxed(0, mb->mbox_base + ROCKCHIP_MAILBOX_B2A_INTEN); mb->chans[chans->idx].msg = NULL; } @@ -107,13 +106,13 @@ static irqreturn_t rockchip_mbox_irq(int irq, void *dev_id) { int idx; struct rockchip_mbox *mb = (struct rockchip_mbox *)dev_id; - u32 status = readl_relaxed(mb->mbox_base + MAILBOX_B2A_STATUS); + u32 status = readl_relaxed(mb->mbox_base + ROCKCHIP_MAILBOX_B2A_STATUS); for (idx = 0; idx < mb->mbox.num_chans; idx++) { if ((status & (1 << idx)) && (irq == mb->chans[idx].irq)) { /* Clear mbox interrupt */ writel_relaxed(1 << idx, - mb->mbox_base + MAILBOX_B2A_STATUS); + mb->mbox_base + ROCKCHIP_MAILBOX_B2A_STATUS); return IRQ_WAKE_THREAD; } } @@ -150,20 +149,15 @@ static irqreturn_t rockchip_mbox_isr(int irq, void *dev_id) return IRQ_HANDLED; } -static const struct rockchip_mbox_data rk3368_drv_data = { - .num_chans = 4, -}; - static const struct of_device_id rockchip_mbox_of_match[] = { - { .compatible = "rockchip,rk3368-mailbox", .data = &rk3368_drv_data}, - { }, + { .compatible = "rockchip,rk3368-mailbox" }, + { } }; MODULE_DEVICE_TABLE(of, rockchip_mbox_of_match); static int rockchip_mbox_probe(struct platform_device *pdev) { struct rockchip_mbox *mb; - const struct rockchip_mbox_data *drv_data; struct resource *res; struct clk *pclk; int ret, irq, i; @@ -171,13 +165,13 @@ static int rockchip_mbox_probe(struct platform_device *pdev) if (!pdev->dev.of_node) return -ENODEV; - drv_data = (const struct rockchip_mbox_data *) device_get_match_data(&pdev->dev); - - mb = devm_kzalloc(&pdev->dev, struct_size(mb, chans, drv_data->num_chans), GFP_KERNEL); + mb = devm_kzalloc(&pdev->dev, + struct_size(mb, chans, ROCKCHIP_MAILBOX_NUM_CHANS), + GFP_KERNEL); if (!mb) return -ENOMEM; - mb->mbox.chans = devm_kcalloc(&pdev->dev, drv_data->num_chans, + mb->mbox.chans = devm_kcalloc(&pdev->dev, ROCKCHIP_MAILBOX_NUM_CHANS, sizeof(*mb->mbox.chans), GFP_KERNEL); if (!mb->mbox.chans) return -ENOMEM; @@ -185,7 +179,7 @@ static int rockchip_mbox_probe(struct platform_device *pdev) platform_set_drvdata(pdev, mb); mb->mbox.dev = &pdev->dev; - mb->mbox.num_chans = drv_data->num_chans; + mb->mbox.num_chans = ROCKCHIP_MAILBOX_NUM_CHANS; mb->mbox.ops = &rockchip_mbox_chan_ops; mb->mbox.txdone_irq = true; @@ -194,7 +188,7 @@ static int rockchip_mbox_probe(struct platform_device *pdev) return PTR_ERR(mb->mbox_base); /* Each channel has two buffers for A2B and B2A */ - mb->buf_size = (size_t)resource_size(res) / (drv_data->num_chans * 2); + mb->buf_size = (size_t)resource_size(res) / (ROCKCHIP_MAILBOX_NUM_CHANS * 2); pclk = devm_clk_get_enabled(&pdev->dev, "pclk_mailbox"); if (IS_ERR(pclk)) @@ -221,9 +215,9 @@ static int rockchip_mbox_probe(struct platform_device *pdev) ret = devm_mbox_controller_register(&pdev->dev, &mb->mbox); if (ret < 0) - dev_err(&pdev->dev, "Failed to register mailbox: %d\n", ret); + return dev_err_probe(&pdev->dev, ret, "Failed to register mailbox\n"); - return ret; + return 0; } static struct platform_driver rockchip_mbox_driver = {
diff --git a/drivers/mailbox/ti-msgmgr.c b/drivers/mailbox/ti-msgmgr.c index 8eb8df8..2079996 100644 --- a/drivers/mailbox/ti-msgmgr.c +++ b/drivers/mailbox/ti-msgmgr.c
@@ -20,6 +20,7 @@ #include <linux/platform_device.h> #include <linux/property.h> #include <linux/soc/ti/ti-msgmgr.h> +#include <linux/string.h> #define Q_DATA_OFFSET(proxy, queue, reg) \ ((0x10000 * (proxy)) + (0x80 * (queue)) + ((reg) * 4)) @@ -44,8 +45,8 @@ * @is_tx: Is this a receive path? */ struct ti_msgmgr_valid_queue_desc { - u8 queue_id; - u8 proxy_id; + u16 queue_id; + u16 proxy_id; bool is_tx; }; @@ -71,7 +72,7 @@ struct ti_msgmgr_valid_queue_desc { * for a specific compatible SoC is done. */ struct ti_msgmgr_desc { - u8 queue_count; + u16 queue_count; u8 max_message_size; u8 max_messages; u8 data_first_reg; @@ -105,8 +106,8 @@ struct ti_msgmgr_desc { */ struct ti_queue_inst { char name[30]; - u8 queue_id; - u8 proxy_id; + u16 queue_id; + u16 proxy_id; int irq; bool is_tx; void __iomem *queue_buff_start; @@ -138,7 +139,7 @@ struct ti_msgmgr_inst { void __iomem *queue_proxy_region; void __iomem *queue_state_debug_region; void __iomem *queue_ctrl_region; - u8 num_valid_queues; + u16 num_valid_queues; struct ti_queue_inst *qinsts; struct mbox_controller mbox; struct mbox_chan *chans; @@ -425,10 +426,15 @@ static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data) trail_bytes = message->len % sizeof(u32); if (trail_bytes) { - u32 data_trail = *word_data; + /* + * Copy only the trailing bytes instead of reading a full u32, + * as the message buffer may end right after them and a u32 + * read would go past the end of it. This also leaves all + * unused data as 0. + */ + u32 data_trail = 0; - /* Ensure all unused data is 0 */ - data_trail &= 0xFFFFFFFF >> (8 * (sizeof(u32) - trail_bytes)); + memcpy(&data_trail, word_data, trail_bytes); writel(data_trail, data_reg); data_reg += sizeof(u32); } @@ -445,12 +451,24 @@ static int ti_msgmgr_send_data(struct mbox_chan *chan, void *data) data_reg += sizeof(u32); } - /* If we are in polled mode, wait for a response before proceeding */ - if (ti_msgmgr_chan_has_polled_queue_rx(message->chan_rx)) + /* + * If we are in polled mode, wait for a response before proceeding. + * + * The message has already been transmitted at this point, so do not + * report a missing response as a send failure. Doing so would make + * the mailbox core keep the message queued and submit it again later, + * after the client has possibly given up on it. The client detects the + * missing response by itself timing out. + */ + if (ti_msgmgr_chan_has_polled_queue_rx(message->chan_rx)) { ret = ti_msgmgr_queue_rx_poll_timeout(message->chan_rx, message->timeout_rx_ms * 1000); + if (ret) + dev_err(dev, "Queue %s timed out waiting for response: %d\n", + qinst->name, ret); + } - return ret; + return 0; } /** @@ -466,7 +484,11 @@ static int ti_msgmgr_queue_rx_irq_req(struct device *dev, struct mbox_chan *chan) { int ret = 0; - char of_rx_irq_name[7]; + /* + * To keep compiler happy about u16 proxy_id: + * "rx_" + up to 5 digits of u16 id + NULL + */ + char of_rx_irq_name[9]; struct device_node *np; snprintf(of_rx_irq_name, sizeof(of_rx_irq_name), @@ -799,9 +821,24 @@ static const struct ti_msgmgr_desc am654_desc = { .is_sproxy = true, }; +static const struct ti_msgmgr_desc tda54_main_desc = { + .queue_count = 444, + .num_valid_queues = 444, + .max_message_size = 60, + .data_region_name = "target_data", + .status_region_name = "rt", + .ctrl_region_name = "scfg", + .data_first_reg = 0, + .data_last_reg = 14, + .status_cnt_mask = SPROXY_THREAD_STATUS_COUNT_MASK, + .tx_polled = false, + .is_sproxy = true, +}; + static const struct of_device_id ti_msgmgr_of_match[] = { {.compatible = "ti,k2g-message-manager", .data = &k2g_desc}, {.compatible = "ti,am654-secure-proxy", .data = &am654_desc}, + {.compatible = "ti,tda54-main-secure-proxy", .data = &tda54_main_desc}, { /* Sentinel */ } };
diff --git a/drivers/media/i2c/isl7998x.c b/drivers/media/i2c/isl7998x.c index a77538d..8244d42 100644 --- a/drivers/media/i2c/isl7998x.c +++ b/drivers/media/i2c/isl7998x.c
@@ -1460,8 +1460,7 @@ static int isl7998x_probe(struct i2c_client *client) int nr_inputs; int ret; - ret = i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA); - if (!ret) { + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA)) { dev_warn(&adapter->dev, "I2C-Adapter doesn't support I2C_FUNC_SMBUS_WORD\n"); return -EIO;
diff --git a/drivers/memory/brcmstb_dpfe.c b/drivers/memory/brcmstb_dpfe.c index 08d9e05..04ae3cf 100644 --- a/drivers/memory/brcmstb_dpfe.c +++ b/drivers/memory/brcmstb_dpfe.c
@@ -182,6 +182,8 @@ struct brcmstb_dpfe_priv { void __iomem *regs; void __iomem *dmem; void __iomem *imem; + resource_size_t regs_size; + resource_size_t dmem_size; struct device *dev; const struct dpfe_api *dpfe_api; struct mutex lock; @@ -401,9 +403,14 @@ static void __iomem *get_msg_ptr(struct brcmstb_dpfe_priv *priv, u32 response, */ switch (msg_type) { case 1: + if (DCPU_MSG_RAM_START + offset + DRAM_VENDOR_ERROR + + sizeof(u32) > priv->regs_size) + goto bad_offset; ptr = priv->regs + DCPU_MSG_RAM_START + offset; break; case 0: + if (offset + DRAM_VENDOR_ERROR + sizeof(u32) > priv->dmem_size) + goto bad_offset; ptr = priv->dmem + offset; break; default: @@ -415,6 +422,12 @@ static void __iomem *get_msg_ptr(struct brcmstb_dpfe_priv *priv, u32 response, } return ptr; + +bad_offset: + dev_err(priv->dev, "DCPU returned out-of-range offset %#x\n", offset); + if (buf && size) + *size = sprintf(buf, "ERROR: DCPU offset out of range\n"); + return NULL; } static void __finalize_command(struct brcmstb_dpfe_priv *priv) @@ -490,6 +503,8 @@ static int __send_command(struct brcmstb_dpfe_priv *priv, unsigned int cmd, for (i = 0; i < MSG_FIELD_MAX; i++) result[i] = readl_relaxed(regs + DCPU_MSG_RAM(i)); chksum_idx = result[MSG_ARG_COUNT] + MSG_ARG_COUNT + 1; + if (chksum_idx >= MSG_FIELD_MAX) + ret = -EINVAL; } /* Tell DCPU we are done */ @@ -518,9 +533,15 @@ static int __verify_firmware(struct init_data *init, const struct firmware *fw) { const struct dpfe_firmware_header *header = (void *)fw->data; - unsigned int dmem_size, imem_size, total_size; + unsigned int dmem_size, imem_size; bool is_big_endian = false; const u32 *chksum_ptr; + size_t payload_size; + + if (fw->size < sizeof(*header) + sizeof(*chksum_ptr)) + return ERR_INVALID_SIZE; + + payload_size = fw->size - sizeof(*header) - sizeof(*chksum_ptr); if (header->magic == DPFE_BE_MAGIC) is_big_endian = true; @@ -539,13 +560,8 @@ static int __verify_firmware(struct init_data *init, if ((dmem_size % sizeof(u32)) != 0 || (imem_size % sizeof(u32)) != 0) return ERR_INVALID_SIZE; - /* - * The header + the data section + the instruction section + the - * checksum must be equal to the total firmware size. - */ - total_size = dmem_size + imem_size + sizeof(*header) + - sizeof(*chksum_ptr); - if (total_size != fw->size) + /* The data and instruction sections must fill the payload exactly. */ + if (dmem_size > payload_size || imem_size != payload_size - dmem_size) return ERR_INVALID_SIZE; /* The checksum comes at the very end. */ @@ -858,6 +874,7 @@ static int brcmstb_dpfe_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct brcmstb_dpfe_priv *priv; + struct resource *res; int ret; priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); @@ -869,17 +886,21 @@ static int brcmstb_dpfe_probe(struct platform_device *pdev) mutex_init(&priv->lock); platform_set_drvdata(pdev, priv); - priv->regs = devm_platform_ioremap_resource_byname(pdev, "dpfe-cpu"); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dpfe-cpu"); + priv->regs = devm_ioremap_resource(dev, res); if (IS_ERR(priv->regs)) { dev_err(dev, "couldn't map DCPU registers\n"); return -ENODEV; } + priv->regs_size = resource_size(res); - priv->dmem = devm_platform_ioremap_resource_byname(pdev, "dpfe-dmem"); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dpfe-dmem"); + priv->dmem = devm_ioremap_resource(dev, res); if (IS_ERR(priv->dmem)) { dev_err(dev, "Couldn't map DCPU data memory\n"); return -ENOENT; } + priv->dmem_size = resource_size(res); priv->imem = devm_platform_ioremap_resource_byname(pdev, "dpfe-imem"); if (IS_ERR(priv->imem)) {
diff --git a/drivers/memory/emif.c b/drivers/memory/emif.c index 2fadad0..886c2ca 100644 --- a/drivers/memory/emif.c +++ b/drivers/memory/emif.c
@@ -922,6 +922,7 @@ static struct emif_data *of_get_memory_device_details( if (!emif || !pd || !dev_info) { dev_err(dev, "%s: Out of memory!!\n", __func__); + of_node_put(np_ddr); goto error; } @@ -946,6 +947,7 @@ static struct emif_data *of_get_memory_device_details( pd->device_info->io_width, pd->phy_type, pd->ip_rev, emif->dev)) { dev_err(dev, "%s: invalid device data!!\n", __func__); + of_node_put(np_ddr); goto error; } /* @@ -1062,7 +1064,8 @@ static struct emif_data *get_device_details( } if (pd->min_tck) { - temp = devm_kzalloc(dev, sizeof(*pd->min_tck), GFP_KERNEL); + temp = devm_kzalloc(dev, sizeof(struct lpddr2_min_tck), + GFP_KERNEL); if (temp) { memcpy(temp, pd->min_tck, sizeof(*pd->min_tck)); pd->min_tck = temp; @@ -1140,6 +1143,7 @@ static void emif_remove(struct platform_device *pdev) struct emif_data *emif = platform_get_drvdata(pdev); emif_debugfs_exit(emif); + of_node_put(emif->np_ddr); } static void emif_shutdown(struct platform_device *pdev)
diff --git a/drivers/memory/emif.h b/drivers/memory/emif.h index 55aeb36..5dfb09a 100644 --- a/drivers/memory/emif.h +++ b/drivers/memory/emif.h
@@ -558,7 +558,7 @@ #define EMIF_SRAM_AM33_REG_LAYOUT 0x00000000 #define EMIF_SRAM_AM43_REG_LAYOUT 0x00000001 -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ /* * Structure containing shadow of important registers in EMIF * The calculation function fills in this structure to be later used for @@ -603,5 +603,5 @@ void ti_emif_enter_sr(void); void ti_emif_exit_sr(void); void ti_emif_abort_sr(void); -#endif /* __ASSEMBLY__ */ +#endif /* __ASSEMBLER__ */ #endif /* __EMIF_H */
diff --git a/drivers/memory/mtk-smi.c b/drivers/memory/mtk-smi.c index aaeba8a..8c4606c 100644 --- a/drivers/memory/mtk-smi.c +++ b/drivers/memory/mtk-smi.c
@@ -401,6 +401,30 @@ static const u8 mtk_smi_larb_mt8188_ostd[][SMI_LARB_PORT_NR_MAX] = { [25] = {0x01}, }; +static const u8 mtk_smi_larb_mt8189_ostd[][SMI_LARB_PORT_NR_MAX] = { + [0] = {0x8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10,}, + [1] = {0x8, 0x20, 0x20, 0x20, 0x20, 0x20, 0x10,}, + [2] = {0x7, 0x7, 0x4, 0x4, 0x1, 0x1, 0x2, 0x2, 0x7, 0x7,}, + [4] = {0x2f, 0x1e, 0x9, 0x1, 0x1, 0x1, 0x1, 0x2, 0x2, 0x5, 0x1, 0x17,}, + [7] = {0x20, 0x2, 0x1, 0x1, 0x1, 0x4, 0x2, 0x1, 0x1, 0x2, 0x3, 0x2, + 0xa, 0xf, 0x4, 0x6, 0x5, 0x1,}, + [9] = {0x6, 0x3, 0xc, 0x6, 0x1, 0x4, 0x3, 0x1, 0x2, 0x4, 0x5, 0x2, + 0x4, 0x2, 0x3, 0xb, 0x1, 0x4, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1,}, + [11] = {0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, 0x1, + 0x1, 0x1, 0x1, 0xb, 0x1, 0x4, 0x6, 0x5, 0x6, 0x1, 0x5, 0x2, + 0x9, 0x5,}, + [13] = {0x2, 0x8, 0x8, 0x8, 0x4, 0x4, 0x4, 0x4, 0x4, 0xe, 0x4, 0x1, + 0x6, 0x6, 0x2,}, + [14] = {0x1, 0x1, 0x1, 0x20, 0xe, 0x4, 0x8, 0x8, 0x6, 0x4,}, + [16] = {0x1e, 0xc, 0x2, 0x8, 0xe, 0x2, 0x1e, 0x10, 0x4, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x4, 0x2, 0x4,}, + [17] = {0x1e, 0xc, 0x2, 0x8, 0xe, 0x2, 0x1e, 0x10, 0x4, 0x2, 0x2, 0x2, + 0x2, 0x2, 0x4, 0x2, 0x4,}, + [19] = {0x2, 0x1, 0x3, 0x1,}, + [20] = {0x7, 0x7, 0x3, 0x3, 0x1, 0x1,}, +}; + static const u8 mtk_smi_larb_mt8192_ostd[][SMI_LARB_PORT_NR_MAX] = { [0] = {0x2, 0x2, 0x28, 0xa, 0xc, 0x28,}, [1] = {0x2, 0x2, 0x18, 0x18, 0x18, 0xa, 0xc, 0x28,}, @@ -533,6 +557,13 @@ static const struct mtk_smi_larb_gen mtk_smi_larb_mt8188 = { .ostd = mtk_smi_larb_mt8188_ostd, }; +static const struct mtk_smi_larb_gen mtk_smi_larb_mt8189 = { + .config_port = mtk_smi_larb_config_port_gen2_general, + .flags_general = MTK_SMI_FLAG_THRT_UPDATE | MTK_SMI_FLAG_SW_FLAG | + MTK_SMI_FLAG_SLEEP_CTL | MTK_SMI_FLAG_CFG_PORT_SEC_CTL, + .ostd = mtk_smi_larb_mt8189_ostd, +}; + static const struct mtk_smi_larb_gen mtk_smi_larb_mt8192 = { .config_port = mtk_smi_larb_config_port_gen2_general, .ostd = mtk_smi_larb_mt8192_ostd, @@ -556,6 +587,7 @@ static const struct of_device_id mtk_smi_larb_of_ids[] = { {.compatible = "mediatek,mt8183-smi-larb", .data = &mtk_smi_larb_mt8183}, {.compatible = "mediatek,mt8186-smi-larb", .data = &mtk_smi_larb_mt8186}, {.compatible = "mediatek,mt8188-smi-larb", .data = &mtk_smi_larb_mt8188}, + {.compatible = "mediatek,mt8189-smi-larb", .data = &mtk_smi_larb_mt8189}, {.compatible = "mediatek,mt8192-smi-larb", .data = &mtk_smi_larb_mt8192}, {.compatible = "mediatek,mt8195-smi-larb", .data = &mtk_smi_larb_mt8195}, {} @@ -808,6 +840,17 @@ static const struct mtk_smi_common_plat mtk_smi_common_mt8188_vpp = { .init = mtk_smi_common_mt8195_init, }; +static const struct mtk_smi_common_plat mtk_smi_common_mt8189 = { + .type = MTK_SMI_GEN2, + .bus_sel = F_MMU1_LARB(1) | F_MMU1_LARB(3) | F_MMU1_LARB(5) | + F_MMU1_LARB(7), +}; + +static const struct mtk_smi_common_plat mtk_smi_sub_common_mt8189 = { + .type = MTK_SMI_GEN2_SUB_COMM, + .has_gals = true, +}; + static const struct mtk_smi_common_plat mtk_smi_common_mt8192 = { .type = MTK_SMI_GEN2, .has_gals = true, @@ -852,6 +895,8 @@ static const struct of_device_id mtk_smi_common_of_ids[] = { {.compatible = "mediatek,mt8186-smi-common", .data = &mtk_smi_common_mt8186}, {.compatible = "mediatek,mt8188-smi-common-vdo", .data = &mtk_smi_common_mt8188_vdo}, {.compatible = "mediatek,mt8188-smi-common-vpp", .data = &mtk_smi_common_mt8188_vpp}, + {.compatible = "mediatek,mt8189-smi-common", .data = &mtk_smi_common_mt8189}, + {.compatible = "mediatek,mt8189-smi-sub-common", .data = &mtk_smi_sub_common_mt8189}, {.compatible = "mediatek,mt8192-smi-common", .data = &mtk_smi_common_mt8192}, {.compatible = "mediatek,mt8195-smi-common-vdo", .data = &mtk_smi_common_mt8195_vdo}, {.compatible = "mediatek,mt8195-smi-common-vpp", .data = &mtk_smi_common_mt8195_vpp},
diff --git a/drivers/memory/renesas-rpc-if.c b/drivers/memory/renesas-rpc-if.c index 3755956..ec901a5 100644 --- a/drivers/memory/renesas-rpc-if.c +++ b/drivers/memory/renesas-rpc-if.c
@@ -34,6 +34,7 @@ static const struct regmap_access_table rpcif_volatile_table = { static const struct regmap_range xspi_volatile_ranges[] = { regmap_reg_range(XSPI_CDD0BUF0, XSPI_CDD0BUF0), + regmap_reg_range(XSPI_CDD1BUF0, XSPI_CDD1BUF0), }; static const struct regmap_access_table xspi_volatile_table = { @@ -311,6 +312,14 @@ static int xspi_hw_init_impl(struct rpcif_priv *xspi, bool hyperflash) regmap_update_bits(xspi->regmap, XSPI_INTE, XSPI_INTE_CMDCMPE, XSPI_INTE_CMDCMPE); + regmap_update_bits(xspi->regmap, XSPI_BMCTL0, + XSPI_BMCTL0_CS0ACC(0xff), XSPI_BMCTL0_CS0ACC(0x03)); + + regmap_update_bits(xspi->regmap, XSPI_BMCFG, + XSPI_BMCFG_WRMD | XSPI_BMCFG_MWRCOMB | + XSPI_BMCFG_MWRSIZE(0xff) | XSPI_BMCFG_PREEN, + 0 | XSPI_BMCFG_MWRCOMB | XSPI_BMCFG_MWRSIZE(0x0f) | + XSPI_BMCFG_PREEN); return 0; } @@ -627,18 +636,14 @@ static int xspi_manual_xfer_impl(struct rpcif_priv *xspi) u32 pos = 0, max = 8; int ret = 0; - regmap_update_bits(xspi->regmap, XSPI_CDCTL0, XSPI_CDCTL0_TRNUM(0x3), + /* Clear transaction number and request */ + regmap_update_bits(xspi->regmap, XSPI_CDCTL0, + XSPI_CDCTL0_TRNUM(0x3) | XSPI_CDCTL0_TRREQ, XSPI_CDCTL0_TRNUM(0)); - regmap_update_bits(xspi->regmap, XSPI_CDCTL0, XSPI_CDCTL0_TRREQ, 0); - regmap_write(xspi->regmap, XSPI_CDTBUF0, - XSPI_CDTBUF_CMDSIZE(0x1) | XSPI_CDTBUF_CMD_FIELD(xspi->command)); - - regmap_write(xspi->regmap, XSPI_CDABUF0, 0); - - regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, XSPI_CDTBUF_ADDSIZE(0x7), - XSPI_CDTBUF_ADDSIZE(xspi->addr_nbytes)); + XSPI_CDTBUF_CMDSIZE(0x1) | XSPI_CDTBUF_CMD_FIELD(xspi->command) | + XSPI_CDTBUF_ADDSIZE(xspi->addr_nbytes)); regmap_write(xspi->regmap, XSPI_CDABUF0, xspi->smadr); @@ -651,17 +656,12 @@ static int xspi_manual_xfer_impl(struct rpcif_priv *xspi) u32 bytes_left = xspi->xferlen - pos; u32 nbytes, data[2], *p = data; - regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, - XSPI_CDTBUF_TRTYPE, XSPI_CDTBUF_TRTYPE); - nbytes = bytes_left >= max ? max : bytes_left; regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, - XSPI_CDTBUF_DATASIZE(0xf), - XSPI_CDTBUF_DATASIZE(nbytes)); - - regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, + XSPI_CDTBUF_TRTYPE | XSPI_CDTBUF_DATASIZE(0xf) | XSPI_CDTBUF_ADDSIZE(0x7), + XSPI_CDTBUF_TRTYPE | XSPI_CDTBUF_DATASIZE(nbytes) | XSPI_CDTBUF_ADDSIZE(xspi->addr_nbytes)); memcpy(data, xspi->buffer + pos, nbytes); @@ -693,30 +693,33 @@ static int xspi_manual_xfer_impl(struct rpcif_priv *xspi) while (pos < xspi->xferlen) { u32 bytes_left = xspi->xferlen - pos; u32 nbytes, data[2], *p = data; - - regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, - XSPI_CDTBUF_TRTYPE, - ~(u32)XSPI_CDTBUF_TRTYPE); + u32 cdtbuf0_mask, cdtbuf0_val; /* nbytes can be up to 8 bytes */ nbytes = bytes_left >= max ? max : bytes_left; - regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, - XSPI_CDTBUF_DATASIZE(0xf), - XSPI_CDTBUF_DATASIZE(nbytes)); + /* clear TRTYPE */ + cdtbuf0_mask = XSPI_CDTBUF_TRTYPE; + cdtbuf0_val = 0; - regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, - XSPI_CDTBUF_ADDSIZE(0x7), - XSPI_CDTBUF_ADDSIZE(xspi->addr_nbytes)); + /* program DATASIZE */ + cdtbuf0_mask |= XSPI_CDTBUF_DATASIZE(0xf); + cdtbuf0_val |= XSPI_CDTBUF_DATASIZE(nbytes); + + /* program ADDSIZE */ + cdtbuf0_mask |= XSPI_CDTBUF_ADDSIZE(0x7); + cdtbuf0_val |= XSPI_CDTBUF_ADDSIZE(xspi->addr_nbytes); + + /* program LATE */ + cdtbuf0_mask |= XSPI_CDTBUF_LATE(0x1f); + cdtbuf0_val |= XSPI_CDTBUF_LATE(xspi->dummy); + + regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, cdtbuf0_mask, cdtbuf0_val); if (xspi->addr_nbytes) regmap_write(xspi->regmap, XSPI_CDABUF0, xspi->smadr + pos); - regmap_update_bits(xspi->regmap, XSPI_CDTBUF0, - XSPI_CDTBUF_LATE(0x1f), - XSPI_CDTBUF_LATE(xspi->dummy)); - regmap_update_bits(xspi->regmap, XSPI_CDCTL0, XSPI_CDCTL0_TRREQ, XSPI_CDCTL0_TRREQ); @@ -773,7 +776,7 @@ int rpcif_manual_xfer(struct device *dev) ret = rpc->info->impl->manual_xfer(rpc); - pm_runtime_put(dev); + pm_runtime_put_autosuspend(dev); return ret; } @@ -868,15 +871,6 @@ static size_t xspi_dirmap_read_impl(struct rpcif_priv *xspi, u64 offs, XSPI_CMCFG1_RDCMD_UPPER_BYTE(xspi->command) | XSPI_CMCFG1_RDLATE(xspi->dummy)); - regmap_update_bits(xspi->regmap, XSPI_BMCTL0, XSPI_BMCTL0_CS0ACC(0xff), - XSPI_BMCTL0_CS0ACC(0x01)); - - regmap_update_bits(xspi->regmap, XSPI_BMCFG, - XSPI_BMCFG_WRMD | XSPI_BMCFG_MWRCOMB | - XSPI_BMCFG_MWRSIZE(0xff) | XSPI_BMCFG_PREEN, - 0 | XSPI_BMCFG_MWRCOMB | XSPI_BMCFG_MWRSIZE(0x0f) | - XSPI_BMCFG_PREEN); - regmap_update_bits(xspi->regmap, XSPI_LIOCFGCS0, XSPI_LIOCFG_PRTMD(0x3ff), XSPI_LIOCFG_PRTMD(xspi->proto)); @@ -897,7 +891,7 @@ ssize_t rpcif_dirmap_read(struct device *dev, u64 offs, size_t len, void *buf) read = rpc->info->impl->dirmap_read(rpc, offs, len, buf); - pm_runtime_put(dev); + pm_runtime_put_autosuspend(dev); return read; } @@ -944,15 +938,6 @@ ssize_t xspi_dirmap_write(struct device *dev, u64 offs, size_t len, const void * XSPI_CMCFG2_WRCMD_UPPER(xspi->command) | XSPI_CMCFG2_WRLATE(xspi->dummy)); - regmap_update_bits(xspi->regmap, XSPI_BMCTL0, - XSPI_BMCTL0_CS0ACC(0xff), XSPI_BMCTL0_CS0ACC(0x03)); - - regmap_update_bits(xspi->regmap, XSPI_BMCFG, - XSPI_BMCFG_WRMD | XSPI_BMCFG_MWRCOMB | - XSPI_BMCFG_MWRSIZE(0xff) | XSPI_BMCFG_PREEN, - 0 | XSPI_BMCFG_MWRCOMB | XSPI_BMCFG_MWRSIZE(0x0f) | - XSPI_BMCFG_PREEN); - regmap_update_bits(xspi->regmap, XSPI_LIOCFGCS0, XSPI_LIOCFG_PRTMD(0x3ff), XSPI_LIOCFG_PRTMD(xspi->proto)); @@ -963,7 +948,7 @@ ssize_t xspi_dirmap_write(struct device *dev, u64 offs, size_t len, const void * regmap_update_bits(xspi->regmap, XSPI_BMCTL1, XSPI_BMCTL1_MWRPUSH, XSPI_BMCTL1_MWRPUSH); - pm_runtime_put(dev); + pm_runtime_put_autosuspend(dev); return writebytes; }
diff --git a/drivers/memory/samsung/exynos5422-dmc.c b/drivers/memory/samsung/exynos5422-dmc.c index 788d49c6..98c3195 100644 --- a/drivers/memory/samsung/exynos5422-dmc.c +++ b/drivers/memory/samsung/exynos5422-dmc.c
@@ -1297,8 +1297,15 @@ static int exynos5_dmc_init_clks(struct exynos5_dmc *dmc) if (ret) return ret; - clk_prepare_enable(dmc->fout_bpll); - clk_prepare_enable(dmc->mout_bpll); + ret = clk_prepare_enable(dmc->fout_bpll); + if (ret) + return ret; + + ret = clk_prepare_enable(dmc->mout_bpll); + if (ret) { + clk_disable_unprepare(dmc->fout_bpll); + return ret; + } /* * Some bootloaders do not set clock routes correctly.
diff --git a/drivers/memory/stm32_omm.c b/drivers/memory/stm32_omm.c index 84eb23c..3599683a 100644 --- a/drivers/memory/stm32_omm.c +++ b/drivers/memory/stm32_omm.c
@@ -274,6 +274,8 @@ static int stm32_omm_configure(struct device *dev) writel_relaxed(omm->cr, omm->io_base + OMM_CR); ret = stm32_omm_set_amcr(dev, true); + if (ret && (mux & CR_MUXEN)) + stm32_omm_toggle_child_clock(dev, false); error: pm_runtime_put_sync_suspend(dev);
diff --git a/drivers/memory/tegra/tegra264.c b/drivers/memory/tegra/tegra264.c index 7903492..57e6395 100644 --- a/drivers/memory/tegra/tegra264.c +++ b/drivers/memory/tegra/tegra264.c
@@ -16,6 +16,47 @@ #include "tegra264-bwmgr.h" /* + * Description of a single MCF error type: where to read the status and the + * faulting address, how to extract the high address bits, which bits encode + * the access direction and security state and the optional error-type sub-code. + */ +struct tegra264_mc_fault { + const char *const *type_names; + u32 addr_hi_mask; + u32 addr_hi_reg; + u32 addr_hi_shift; + u32 addr_reg; + u32 rw_bit; + u32 sec_bit; + u32 status1_reg; + u32 status_reg; + u32 type_mask; + u32 type_shift; +}; + +/* + * Maps an MCF interrupt to a callback that fills in the register offsets and + * decoding parameters for that error type. The register offsets live in the + * per-SoC tegra_mc_regs, so they are collected at runtime rather than being + * stored in a static table. + */ +struct tegra264_mc_error_handler { + u32 mask; + void (*get_offsets)(struct tegra_mc *mc, struct tegra264_mc_fault *fault); +}; + +/* + * Description of a single HUB error type. addr_reg is zero for error types + * that don't latch a fault address. + */ +struct tegra264_hub_error_handler { + u32 addr_hi_reg; + u32 addr_reg; + u32 mask; + u32 status_reg; +}; + +/* * MC Client entries are sorted in the increasing order of the * override and security register offsets. */ @@ -717,11 +758,18 @@ static const char *const tegra264_rt_error_names[16] = { }; /* - * MC instance aperture mapping for hubc registers + * On Tegra264 the memory controller error interrupts are distributed across + * several HUB/HUBC apertures. Each aperture is accessed like a broadcast + * channel through mc_ch_readl()/mc_ch_writel() using its fixed index. */ -static const int mc_hubc_aperture_number[5] = { - 7, 8, 9, 10, 11 -}; +#define TEGRA264_MC_APERTURE_DISP 7 +#define TEGRA264_MC_APERTURE_SYSTEM 8 +#define TEGRA264_MC_APERTURE_VISION 9 +#define TEGRA264_MC_APERTURE_UPHY 10 +#define TEGRA264_MC_APERTURE_TOP 11 + +/* Tegra264 splits the MCF common interrupt status across five slices. */ +#define TEGRA264_MC_NUM_SLICES 5 /* * tegra264_mc_icc_set() - Pass MC client info to the BPMP-FW @@ -807,115 +855,149 @@ static int tegra264_mc_icc_get_init_bw(struct icc_node *node, u32 *avg, u32 *pea return 0; } +static void tegra264_mc_fault_emem(struct tegra_mc *mc, struct tegra264_mc_fault *fault) +{ + fault->status_reg = mc->soc->regs->err_status; + fault->addr_reg = mc->soc->regs->err_add; + fault->addr_hi_reg = mc->soc->regs->err_add_hi; + fault->type_mask = mc->soc->mc_err_status_type_mask; + fault->type_shift = MC_ERR_STATUS_TYPE_SHIFT; + fault->type_names = tegra264_mc_error_names; +} + +static void tegra264_mc_fault_vpr(struct tegra_mc *mc, struct tegra264_mc_fault *fault) +{ + fault->status_reg = mc->soc->regs->err_vpr_status; + fault->addr_reg = mc->soc->regs->err_vpr_add; + fault->addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT; + fault->addr_hi_mask = mc->soc->mc_addr_hi_mask; +} + +static void tegra264_mc_fault_sec(struct tegra_mc *mc, struct tegra264_mc_fault *fault) +{ + fault->status_reg = mc->soc->regs->err_sec_status; + fault->addr_reg = mc->soc->regs->err_sec_add; + fault->addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT; + fault->addr_hi_mask = mc->soc->mc_addr_hi_mask; +} + +static void tegra264_mc_fault_mts(struct tegra_mc *mc, struct tegra264_mc_fault *fault) +{ + fault->status_reg = mc->soc->regs->err_mts_status; + fault->addr_reg = mc->soc->regs->err_mts_add; + fault->addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT; + fault->addr_hi_mask = mc->soc->mc_addr_hi_mask; +} + +static void tegra264_mc_fault_gsc(struct tegra_mc *mc, struct tegra264_mc_fault *fault) +{ + fault->status_reg = mc->soc->regs->err_gen_co_status; + fault->status1_reg = MC_ERR_GENERALIZED_CARVEOUT_STATUS_1_0; + fault->addr_reg = mc->soc->regs->err_gen_co_add; + fault->addr_hi_shift = MC_ERR_STATUS_GSC_ADR_HI_SHIFT; + fault->addr_hi_mask = MC_ERR_STATUS_GSC_ADR_HI_MASK; +} + +static void tegra264_mc_fault_route(struct tegra_mc *mc, struct tegra264_mc_fault *fault) +{ + fault->status_reg = mc->soc->regs->err_route_status; + fault->addr_reg = mc->soc->regs->err_route_add; + fault->addr_hi_shift = MC_ERR_STATUS_RT_ADR_HI_SHIFT; + fault->addr_hi_mask = mc->soc->mc_addr_hi_mask; + fault->rw_bit = MC_ERR_ROUTE_SANITY_RW; + fault->sec_bit = MC_ERR_ROUTE_SANITY_SEC; + fault->type_mask = MC_ERR_STATUS_RT_TYPE_MASK; + fault->type_shift = MC_ERR_STATUS_RT_TYPE_SHIFT; + fault->type_names = tegra264_rt_error_names; +} + +static const struct tegra264_mc_error_handler tegra264_mc_error_handlers[] = { + { MC_INT_DECERR_EMEM, tegra264_mc_fault_emem }, + { MC_INT_SECURITY_VIOLATION, tegra264_mc_fault_emem }, + { MC_INT_DECERR_VPR, tegra264_mc_fault_vpr }, + { MC_INT_SECERR_SEC, tegra264_mc_fault_sec }, + { MC_INT_DECERR_MTS, tegra264_mc_fault_mts }, + { MC_INT_DECERR_GENERALIZED_CARVEOUT, tegra264_mc_fault_gsc }, + { MC_INT_DECERR_ROUTE_SANITY, tegra264_mc_fault_route }, + { MC_INT_DECERR_ROUTE_SANITY_GIC_MSI, tegra264_mc_fault_route }, +}; + +static void tegra264_mc_report_fault(struct tegra_mc *mc, u32 channel, + unsigned int interrupt, + const struct tegra264_mc_fault *fault) +{ + const char *client = "unknown", *desc = "NA"; + u32 value, client_id, status1 = 0; + phys_addr_t addr = 0; + unsigned int i; + u8 type; + + value = mc_ch_readl(mc, channel, fault->status_reg); + + if (fault->addr_hi_reg) { + addr = mc_ch_readl(mc, channel, fault->addr_hi_reg); + } else if (fault->status1_reg) { + status1 = mc_ch_readl(mc, channel, fault->status1_reg); + addr = (status1 >> fault->addr_hi_shift) & fault->addr_hi_mask; + } else { + addr = (value >> fault->addr_hi_shift) & fault->addr_hi_mask; + } + + addr <<= 32; + addr |= mc_ch_readl(mc, channel, fault->addr_reg); + + client_id = value & mc->soc->client_id_mask; + for (i = 0; i < mc->soc->num_clients; i++) { + if (mc->soc->clients[i].id == client_id) { + client = mc->soc->clients[i].name; + break; + } + } + + if (fault->type_names) { + type = (value & fault->type_mask) >> fault->type_shift; + desc = fault->type_names[type]; + } + + dev_err_ratelimited(mc->dev, "%s: %s %s @%pa: %s (%s)\n", + client, value & fault->sec_bit ? "secure" : "non-secure", + value & fault->rw_bit ? "write" : "read", &addr, + tegra_mc_status_names[interrupt] ?: "unknown", desc); + + if (fault->status1_reg) + dev_err_ratelimited(mc->dev, "gsc_apr_id=%u gsc_co_apr_id=%u\n", + (status1 >> ERR_GENERALIZED_APERTURE_ID_SHIFT) & + ERR_GENERALIZED_APERTURE_ID_MASK, + (status1 >> ERR_GENERALIZED_CARVEOUT_APERTURE_ID_SHIFT) & + ERR_GENERALIZED_CARVEOUT_APERTURE_ID_MASK); +} + static void mcf_log_fault(struct tegra_mc *mc, u32 channel, unsigned long mcf_ch_intstatus) { - unsigned int bit; + unsigned int interrupt; - for_each_set_bit(bit, &mcf_ch_intstatus, 32) { - const char *client = "unknown", *desc = "NA"; - u32 status_reg, status1_reg = 0, addr_reg, addr_hi_reg = 0, err_type_mask = 0; - u32 value, client_id, i, addr_hi_shift = 0, addr_hi_mask = 0, status1; - u32 mc_rw_bit = MC_ERR_STATUS_RW, mc_sec_bit = MC_ERR_STATUS_SECURITY; - phys_addr_t addr = 0; - u8 type; + for_each_set_bit(interrupt, &mcf_ch_intstatus, 32) { + const struct tegra264_mc_error_handler *handler = NULL; + struct tegra264_mc_fault fault = { + .rw_bit = MC_ERR_STATUS_RW, + .sec_bit = MC_ERR_STATUS_SECURITY, + }; + unsigned int i; - switch (BIT(bit)) { - case MC_INT_DECERR_EMEM: - case MC_INT_SECURITY_VIOLATION: - status_reg = mc->soc->regs->err_status; - addr_reg = mc->soc->regs->err_add; - addr_hi_reg = mc->soc->regs->err_add_hi; - err_type_mask = mc->soc->mc_err_status_type_mask; - break; - - case MC_INT_DECERR_VPR: - status_reg = mc->soc->regs->err_vpr_status; - addr_reg = mc->soc->regs->err_vpr_add; - addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT; - addr_hi_mask = mc->soc->mc_addr_hi_mask; - break; - - case MC_INT_SECERR_SEC: - status_reg = mc->soc->regs->err_sec_status; - addr_reg = mc->soc->regs->err_sec_add; - addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT; - addr_hi_mask = mc->soc->mc_addr_hi_mask; - break; - - case MC_INT_DECERR_MTS: - status_reg = mc->soc->regs->err_mts_status; - addr_reg = mc->soc->regs->err_mts_add; - addr_hi_shift = MC_ERR_STATUS_ADR_HI_SHIFT; - addr_hi_mask = mc->soc->mc_addr_hi_mask; - break; - - case MC_INT_DECERR_GENERALIZED_CARVEOUT: - status_reg = mc->soc->regs->err_gen_co_status; - status1_reg = MC_ERR_GENERALIZED_CARVEOUT_STATUS_1_0; - addr_reg = mc->soc->regs->err_gen_co_add; - addr_hi_shift = MC_ERR_STATUS_GSC_ADR_HI_SHIFT; - addr_hi_mask = MC_ERR_STATUS_GSC_ADR_HI_MASK; - break; - - case MC_INT_DECERR_ROUTE_SANITY: - case MC_INT_DECERR_ROUTE_SANITY_GIC_MSI: - status_reg = mc->soc->regs->err_route_status; - addr_reg = mc->soc->regs->err_route_add; - addr_hi_shift = MC_ERR_STATUS_RT_ADR_HI_SHIFT; - addr_hi_mask = mc->soc->mc_addr_hi_mask; - mc_sec_bit = MC_ERR_ROUTE_SANITY_SEC; - mc_rw_bit = MC_ERR_ROUTE_SANITY_RW; - err_type_mask = MC_ERR_STATUS_RT_TYPE_MASK; - break; - - default: - dev_err_ratelimited(mc->dev, "Incorrect MC interrupt mask\n"); - return; - } - - value = mc_ch_readl(mc, channel, status_reg); - if (addr_hi_reg) { - addr = mc_ch_readl(mc, channel, addr_hi_reg); - } else { - if (!status1_reg) { - addr = ((value >> addr_hi_shift) & addr_hi_mask); - } else { - status1 = mc_ch_readl(mc, channel, status1_reg); - addr = ((status1 >> addr_hi_shift) & addr_hi_mask); - } - } - - addr <<= 32; - addr |= mc_ch_readl(mc, channel, addr_reg); - - client_id = value & mc->soc->client_id_mask; - for (i = 0; i < mc->soc->num_clients; i++) { - if (mc->soc->clients[i].id == client_id) { - client = mc->soc->clients[i].name; + for (i = 0; i < ARRAY_SIZE(tegra264_mc_error_handlers); i++) { + if (tegra264_mc_error_handlers[i].mask == BIT(interrupt)) { + handler = &tegra264_mc_error_handlers[i]; break; } } - if (err_type_mask == MC_ERR_STATUS_RT_TYPE_MASK) { - type = (value & err_type_mask) >> - MC_ERR_STATUS_RT_TYPE_SHIFT; - desc = tegra264_rt_error_names[type]; - } else if (err_type_mask) { - type = (value & err_type_mask) >> - MC_ERR_STATUS_TYPE_SHIFT; - desc = tegra264_mc_error_names[type]; + if (!handler) { + dev_err_ratelimited(mc->dev, "Incorrect MC interrupt mask\n"); + return; } - dev_err_ratelimited(mc->dev, "%s: %s %s @%pa: %s (%s)\n", - client, value & mc_sec_bit ? "secure" : "non-secure", - value & mc_rw_bit ? "write" : "read", &addr, - tegra_mc_status_names[bit] ?: "unknown", desc); - if (status1_reg) - dev_err_ratelimited(mc->dev, "gsc_apr_id=%u gsc_co_apr_id=%u\n", - ((status1 >> ERR_GENERALIZED_APERTURE_ID_SHIFT) - & ERR_GENERALIZED_APERTURE_ID_MASK), - ((status1 >> ERR_GENERALIZED_CARVEOUT_APERTURE_ID_SHIFT) - & ERR_GENERALIZED_CARVEOUT_APERTURE_ID_MASK)); + handler->get_offsets(mc, &fault); + tegra264_mc_report_fault(mc, channel, interrupt, &fault); } /* clear interrupts */ @@ -937,7 +1019,7 @@ static irqreturn_t handle_mcf_irq(int irq, void *data) for_each_set_bit(slice, &common_intstat, 32) { /* Find out the slice number on which interrupt occurred */ - if (slice > 4) { + if (slice >= TEGRA264_MC_NUM_SLICES) { dev_err(mc->dev, "Slice index out of bounds: %u\n", slice); return IRQ_NONE; } @@ -950,53 +1032,69 @@ static irqreturn_t handle_mcf_irq(int irq, void *data) return IRQ_HANDLED; } +static const struct tegra264_hub_error_handler tegra264_hub_error_handlers[] = { + { + .mask = MSS_HUB_COALESCER_ERR_INTMASK, + .status_reg = MSS_HUB_COALESCE_ERR_STATUS_0, + .addr_reg = MSS_HUB_COALESCE_ERR_ADR_0, + .addr_hi_reg = MSS_HUB_COALESCE_ERR_ADR_HI_0, + }, + { + .mask = MSS_HUB_SMMU_BYPASS_ALLOW_ERR_INTMASK, + .status_reg = MSS_HUB_SMMU_BYPASS_ALLOW_ERR_STATUS_0, + }, + { + .mask = MSS_HUB_ILLEGAL_TBUGRP_ID_INTMASK, + .status_reg = MSS_HUB_ILLEGAL_TBUGRP_ID_ERR_STATUS_0, + }, + { + .mask = MSS_HUB_MSI_ERR_INTMASK, + .status_reg = MSS_HUB_MSI_ERR_STATUS_0, + }, + { + .mask = MSS_HUB_POISON_RSP_INTMASK, + .status_reg = MSS_HUB_POISON_RSP_STATUS_0, + }, + { + .mask = MSS_HUB_RESTRICTED_ACCESS_ERR_INTMASK, + .status_reg = MSS_HUB_RESTRICTED_ACCESS_ERR_STATUS_0, + }, + { + .mask = MSS_HUB_RESERVED_PA_ERR_INTMASK, + .status_reg = MSS_HUB_RESERVED_PA_ERR_STATUS_0, + }, +}; + static void hub_log_fault(struct tegra_mc *mc, u32 hub, unsigned long hub_intstat) { - unsigned int bit; + unsigned int interrupt; - for_each_set_bit(bit, &hub_intstat, 32) { + for_each_set_bit(interrupt, &hub_intstat, 32) { + const struct tegra264_hub_error_handler *handler = NULL; const char *client = "unknown"; - u32 client_id, status_reg, value, i; + u32 client_id, value; phys_addr_t addr = 0; + unsigned int i; - switch (BIT(bit)) { - case MSS_HUB_COALESCER_ERR_INTMASK: - status_reg = MSS_HUB_COALESCE_ERR_STATUS_0; - addr = mc_ch_readl(mc, hub, MSS_HUB_COALESCE_ERR_ADR_HI_0); - addr <<= 32; - addr |= mc_ch_readl(mc, hub, MSS_HUB_COALESCE_ERR_ADR_0); - break; + for (i = 0; i < ARRAY_SIZE(tegra264_hub_error_handlers); i++) { + if (tegra264_hub_error_handlers[i].mask == BIT(interrupt)) { + handler = &tegra264_hub_error_handlers[i]; + break; + } + } - case MSS_HUB_SMMU_BYPASS_ALLOW_ERR_INTMASK: - status_reg = MSS_HUB_SMMU_BYPASS_ALLOW_ERR_STATUS_0; - break; - - case MSS_HUB_ILLEGAL_TBUGRP_ID_INTMASK: - status_reg = MSS_HUB_ILLEGAL_TBUGRP_ID_ERR_STATUS_0; - break; - - case MSS_HUB_MSI_ERR_INTMASK: - status_reg = MSS_HUB_MSI_ERR_STATUS_0; - break; - - case MSS_HUB_POISON_RSP_INTMASK: - status_reg = MSS_HUB_POISON_RSP_STATUS_0; - break; - - case MSS_HUB_RESTRICTED_ACCESS_ERR_INTMASK: - status_reg = MSS_HUB_RESTRICTED_ACCESS_ERR_STATUS_0; - break; - - case MSS_HUB_RESERVED_PA_ERR_INTMASK: - status_reg = MSS_HUB_RESERVED_PA_ERR_STATUS_0; - break; - - default: + if (!handler) { dev_err_ratelimited(mc->dev, "Incorrect HUB interrupt mask\n"); return; } - value = mc_ch_readl(mc, hub, status_reg); + if (handler->addr_reg) { + addr = mc_ch_readl(mc, hub, handler->addr_hi_reg); + addr <<= 32; + addr |= mc_ch_readl(mc, hub, handler->addr_reg); + } + + value = mc_ch_readl(mc, hub, handler->status_reg); client_id = value & mc->soc->client_id_mask; for (i = 0; i < mc->soc->num_clients; i++) { @@ -1007,8 +1105,8 @@ static void hub_log_fault(struct tegra_mc *mc, u32 hub, unsigned long hub_intsta } dev_err_ratelimited(mc->dev, "%s: @%pa: %s status: 0x%x\n", - client, &addr, tegra264_hub_error_names[bit] ?: "unknown", - value); + client, &addr, + tegra264_hub_error_names[interrupt] ?: "unknown", value); } /* clear interrupts */ @@ -1057,27 +1155,27 @@ static irqreturn_t handle_hub_irq(int irq, void *data, int mc_hubc_aperture_numb static irqreturn_t handle_disp_hub_irq(int irq, void *data) { - return handle_hub_irq(irq, data, mc_hubc_aperture_number[0]); + return handle_hub_irq(irq, data, TEGRA264_MC_APERTURE_DISP); } static irqreturn_t handle_system_hub_irq(int irq, void *data) { - return handle_hub_irq(irq, data, mc_hubc_aperture_number[1]); + return handle_hub_irq(irq, data, TEGRA264_MC_APERTURE_SYSTEM); } static irqreturn_t handle_vision_hub_irq(int irq, void *data) { - return handle_hub_irq(irq, data, mc_hubc_aperture_number[2]); + return handle_hub_irq(irq, data, TEGRA264_MC_APERTURE_VISION); } static irqreturn_t handle_uphy_hub_irq(int irq, void *data) { - return handle_hub_irq(irq, data, mc_hubc_aperture_number[3]); + return handle_hub_irq(irq, data, TEGRA264_MC_APERTURE_UPHY); } static irqreturn_t handle_top_hub_irq(int irq, void *data) { - return handle_hub_irq(irq, data, mc_hubc_aperture_number[4]); + return handle_hub_irq(irq, data, TEGRA264_MC_APERTURE_TOP); } static irqreturn_t handle_generic_irq(struct tegra_mc *mc, unsigned long intstat_reg)
diff --git a/drivers/memstick/core/ms_block.c b/drivers/memstick/core/ms_block.c index 65154e5..cd4ff1b 100644 --- a/drivers/memstick/core/ms_block.c +++ b/drivers/memstick/core/ms_block.c
@@ -720,7 +720,7 @@ static int h_msb_parallel_switch(struct memstick_dev *card, static int msb_switch_to_parallel(struct msb_data *msb); -/* Reset the card, to guard against hw errors beeing treated as bad blocks */ +/* Reset the card, to guard against hw errors being treated as bad blocks */ static int msb_reset(struct msb_data *msb, bool full) {
diff --git a/drivers/memstick/host/r592.c b/drivers/memstick/host/r592.c index 605b226..dc3de63 100644 --- a/drivers/memstick/host/r592.c +++ b/drivers/memstick/host/r592.c
@@ -289,7 +289,7 @@ static int r592_transfer_fifo_dma(struct r592_device *dev) dev->dma_error = 0; reinit_completion(&dev->dma_done); - /* TODO: hidden assumption about nenth beeing always 1 */ + /* TODO: hidden assumption about nenth being always 1 */ sg_count = dma_map_sg(&dev->pci_dev->dev, &dev->req->sg, 1, is_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE);
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index e4fd457..439dbf5 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig
@@ -2226,7 +2226,7 @@ and emergency shut down as well as 32,768KHz clock output. config MFD_ROHM_BD71828 - tristate "ROHM BD718[15/28/79], BD72720 and BD73900 PMICs" + tristate "ROHM BD718[15/28/79], BD72720 and BD73[8/9]00 PMICs" depends on I2C=y depends on OF select REGMAP_I2C @@ -2235,14 +2235,17 @@ select MFD_ROHM_PWRBUTTON help Select this option to get support for the ROHM BD71815, BD71828, - BD71879, BD72720 and BD73900 Power Management ICs (PMICs). These are - single-chip Power Management ICs (PMIC), mainly for battery-powered - portable devices. + BD71879, BD72720, BD73800 and BD73900 Power Management ICs (PMICs). + These are single-chip Power Management ICs (PMIC), mainly for + battery-powered portable devices. The BD71815 has 5 bucks, 7 LDOs, and a boost for driving LEDs. The BD718[28/79] have 7 buck converters and 7 LDOs. The BD72720 and the BD73900 have 10 bucks and 11 LDOs. - All ICs provide a single-cell linear charger, a Coulomb counter, - a Real-Time Clock (RTC), GPIOs and a 32.768 kHz clock gate. + All the above ICs provide a single-cell linear charger, and a Coulomb + counter. + The BD73800 has 8 bucks, 4 LDOs and ADC for power/current + accumulation but no charging logic. All these PMICs integrate also a + Real-Time Clock (RTC), GPIOs and a 32.768 kHz clock gate. config MFD_ROHM_BD957XMUF tristate "ROHM BD9576MUF and BD9573MUF Power Management ICs"
diff --git a/drivers/mfd/rohm-bd71828.c b/drivers/mfd/rohm-bd71828.c index bf4df8e..46faef7 100644 --- a/drivers/mfd/rohm-bd71828.c +++ b/drivers/mfd/rohm-bd71828.c
@@ -1,8 +1,8 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (C) 2019 ROHM Semiconductors + * Copyright (C) 2019, 2026 ROHM Semiconductor * - * ROHM BD718[15/28/79] and BD72720 PMIC driver + * ROHM BD718[15/28/79], BD72720 and BD73[8/9]00 PMIC driver */ #include <linux/i2c.h> @@ -14,6 +14,7 @@ #include <linux/mfd/rohm-bd71815.h> #include <linux/mfd/rohm-bd71828.h> #include <linux/mfd/rohm-bd72720.h> +#include <linux/mfd/rohm-bd73800.h> #include <linux/mfd/rohm-generic.h> #include <linux/module.h> #include <linux/of.h> @@ -56,6 +57,12 @@ static const struct resource bd72720_rtc_irqs[] = { DEFINE_RES_IRQ_NAMED(BD72720_INT_RTC2, "bd70528-rtc-alm-2"), }; +static const struct resource bd73800_rtc_irqs[] = { + DEFINE_RES_IRQ_NAMED(BD73800_INT_RTC0, "bd70528-rtc-alm-0"), + DEFINE_RES_IRQ_NAMED(BD73800_INT_RTC1, "bd70528-rtc-alm-1"), + DEFINE_RES_IRQ_NAMED(BD73800_INT_RTC2, "bd70528-rtc-alm-2"), +}; + static const struct resource bd71815_power_irqs[] = { DEFINE_RES_IRQ_NAMED(BD71815_INT_DCIN_RMV, "bd71815-dcin-rmv"), DEFINE_RES_IRQ_NAMED(BD71815_INT_CLPS_OUT, "bd71815-dcin-clps-out"), @@ -230,6 +237,17 @@ static const struct mfd_cell bd72720_mfd_cells[] = { /* Power button is registered separately */ }; +static const struct mfd_cell bd73800_mfd_cells[] = { + { .name = "bd73800-pmic", }, + { .name = "bd73800-clk", }, + { .name = "bd73800-gpio", }, + { + .name = "bd73800-rtc", + .num_resources = ARRAY_SIZE(bd73800_rtc_irqs), + .resources = bd73800_rtc_irqs, + }, +}; + static const struct regmap_range bd71815_volatile_ranges[] = { regmap_reg_range(BD71815_REG_SEC, BD71815_REG_YEAR), regmap_reg_range(BD71815_REG_CONF, BD71815_REG_BAT_TEMP), @@ -339,6 +357,17 @@ static const struct regmap_range bd72720_volatile_ranges_4c[] = { BD72720_UNWRAP_REG_RANGE(BD72720_REG_IMPCHK_CTRL, BD72720_REG_IMPCHK_CTRL), }; +static const struct regmap_range bd73800_volatile_ranges[] = { + regmap_reg_range(BD73800_REG_POR_REASON, BD73800_REG_POW_STATE), + regmap_reg_range(BD73800_REG_PS_CTRL_1, BD73800_REG_PS_CTRL_2), + regmap_reg_range(BD73800_REG_RCVNUM, BD73800_REG_RCVNUM), + regmap_reg_range(BD73800_REG_RTC_SEC, BD73800_REG_RTC_YEAR), + regmap_reg_range(BD73800_REG_RTC_CONF, BD73800_REG_RTC_CONF), + regmap_reg_range(BD73800_REG_ADC_ACCUM_KICK, BD73800_REG_ADC_TEMP_VAL0), + regmap_reg_range(BD73800_REG_INT_MAIN_STAT, BD73800_REG_INT_5_STAT), + regmap_reg_range(BD73800_REG_INT_MAIN_SRC, BD73800_REG_INT_5_SRC), +}; + static const struct regmap_access_table bd71815_volatile_regs = { .yes_ranges = &bd71815_volatile_ranges[0], .n_yes_ranges = ARRAY_SIZE(bd71815_volatile_ranges), @@ -364,6 +393,24 @@ static const struct regmap_access_table bd72720_volatile_regs_4c = { .n_yes_ranges = ARRAY_SIZE(bd72720_volatile_ranges_4c), }; +static const struct regmap_access_table bd73800_volatile_regs = { + .yes_ranges = bd73800_volatile_ranges, + .n_yes_ranges = ARRAY_SIZE(bd73800_volatile_ranges), +}; + +static const struct regmap_range bd73800_read_only_ranges[] = { + regmap_reg_range(BD73800_REG_PRODUCT_ID, BD73800_REG_NVMVERSION), + regmap_reg_range(BD73800_REG_POW_STATE, BD73800_REG_POW_STATE), + regmap_reg_range(BD73800_REG_ADC_ACCUM_CNT2, BD73800_REG_ADC_TEMP_VAL0), + regmap_reg_range(BD73800_REG_INT_MAIN_STAT, BD73800_REG_INT_MAIN_STAT), + regmap_reg_range(BD73800_REG_INT_MAIN_SRC, BD73800_REG_INT_5_SRC), +}; + +static const struct regmap_access_table bd73800_ro_regs = { + .no_ranges = bd73800_read_only_ranges, + .n_no_ranges = ARRAY_SIZE(bd73800_read_only_ranges), +}; + static const struct regmap_config bd71815_regmap = { .reg_bits = 8, .val_bits = 8, @@ -448,6 +495,15 @@ static const struct regmap_config bd72720_regmap_4c = { .cache_type = REGCACHE_MAPLE, }; +static const struct regmap_config bd73800_regmap = { + .reg_bits = 8, + .val_bits = 8, + .wr_table = &bd73800_ro_regs, + .volatile_table = &bd73800_volatile_regs, + .max_register = BD73800_MAX_REGISTER - 1, + .cache_type = REGCACHE_MAPLE, +}; + /* * Mapping of main IRQ register bits to sub-IRQ register offsets so that we can * access corect sub-IRQ registers based on bits that are set in main IRQ @@ -779,6 +835,60 @@ static int bd72720_set_type_config(unsigned int **buf, unsigned int type, return regmap_irq_set_type_config_simple(buf, type, irq_data, idx, irq_drv_data); } +static const struct regmap_irq bd73800_irqs[] = { + /* INT_STAT_1 register IRQs, ADC and RTC */ + REGMAP_IRQ_REG(BD73800_INT_ADC_ACCUM_DONE, 0, BD73800_INT_ADC_ACCUM_DONE_MASK), + REGMAP_IRQ_REG(BD73800_INT_ADC_ACCUM_OVF, 0, BD73800_INT_ADC_ACCUM_OVF_MASK), + REGMAP_IRQ_REG(BD73800_INT_ADC_ACCUM_VAL, 0, BD73800_INT_ADC_ACCUM_VAL_MASK), + REGMAP_IRQ_REG(BD73800_INT_ADC_ACCUM_TW, 0, BD73800_INT_ADC_ACCUM_TW_MASK), + REGMAP_IRQ_REG(BD73800_INT_ADC_POW_VAL, 0, BD73800_INT_ADC_POW_VAL_MASK), + REGMAP_IRQ_REG(BD73800_INT_RTC0, 0, BD73800_INT_RTC0_MASK), + REGMAP_IRQ_REG(BD73800_INT_RTC1, 0, BD73800_INT_RTC1_MASK), + REGMAP_IRQ_REG(BD73800_INT_RTC2, 0, BD73800_INT_RTC2_MASK), + + /* BUCK reg interrupts */ + /* INT_STAT_2 IRQs */ + REGMAP_IRQ_REG(BD73800_INT_BUCK1_DVS_DONE, 1, BD73800_INT_BUCK1_DVS_DONE_MASK), + REGMAP_IRQ_REG(BD73800_INT_BUCK2_DVS_DONE, 1, BD73800_INT_BUCK2_DVS_DONE_MASK), + REGMAP_IRQ_REG(BD73800_INT_BUCK3_DVS_DONE, 1, BD73800_INT_BUCK3_DVS_DONE_MASK), + REGMAP_IRQ_REG(BD73800_INT_BUCK4_DVS_DONE, 1, BD73800_INT_BUCK4_DVS_DONE_MASK), + REGMAP_IRQ_REG(BD73800_INT_BUCK5_DVS_DONE, 1, BD73800_INT_BUCK5_DVS_DONE_MASK), + REGMAP_IRQ_REG(BD73800_INT_BUCK6_DVS_DONE, 1, BD73800_INT_BUCK6_DVS_DONE_MASK), + REGMAP_IRQ_REG(BD73800_INT_BUCK7_DVS_DONE, 1, BD73800_INT_BUCK7_DVS_DONE_MASK), + REGMAP_IRQ_REG(BD73800_INT_BUCK8_DVS_DONE, 1, BD73800_INT_BUCK8_DVS_DONE_MASK), + /* INT_STAT_3 IRQs */ + REGMAP_IRQ_REG(BD73800_INT_BUCK1_OCP, 2, BD73800_INT_BUCK1_OCP_MASK), + REGMAP_IRQ_REG(BD73800_INT_BUCK2_OCP, 2, BD73800_INT_BUCK2_OCP_MASK), + REGMAP_IRQ_REG(BD73800_INT_BUCK3_OCP, 2, BD73800_INT_BUCK3_OCP_MASK), + REGMAP_IRQ_REG(BD73800_INT_BUCK4_OCP, 2, BD73800_INT_BUCK4_OCP_MASK), + REGMAP_IRQ_REG(BD73800_INT_BUCK5_OCP, 2, BD73800_INT_BUCK5_OCP_MASK), + REGMAP_IRQ_REG(BD73800_INT_BUCK6_OCP, 2, BD73800_INT_BUCK6_OCP_MASK), + REGMAP_IRQ_REG(BD73800_INT_BUCK7_OCP, 2, BD73800_INT_BUCK7_OCP_MASK), + REGMAP_IRQ_REG(BD73800_INT_BUCK8_OCP, 2, BD73800_INT_BUCK8_OCP_MASK), + + /* INT_STAT_4 IRQs, power-button, WDG and reset */ + REGMAP_IRQ_REG(BD73800_INT_PBTN_LONG_PRESS, 3, BD73800_INT_PBTN_LONG_PRESS_MASK), + REGMAP_IRQ_REG(BD73800_INT_PBTN_MID_PRESS, 3, BD73800_INT_PBTN_MID_PRESS_MASK), + /* + * The SHORT_PUSH is generated when button is first pressed (longer + * than configured time limit), and then released before the MID_PRESS + * time limit. The SHORT_PRESS is generated immediately when button is + * pressed for longer than configured limit, whether it is released or + * not. + */ + REGMAP_IRQ_REG(BD73800_INT_PBTN_SHORT_PUSH, 3, BD73800_INT_PBTN_SHORT_PUSH_MASK), + REGMAP_IRQ_REG(BD73800_INT_PBTN_SHORT_PRESS, 3, BD73800_INT_PBTN_SHORT_PRESS_MASK), + REGMAP_IRQ_REG(BD73800_INT_WDG, 3, BD73800_INT_WDG_MASK), + REGMAP_IRQ_REG(BD73800_INT_SWRESET, 3, BD73800_INT_SWRESET_MASK), + REGMAP_IRQ_REG(BD73800_INT_SEQ_DONE, 3, BD73800_INT_SEQ_DONE_MASK), + + /* INT_STAT_5 IRQs, GPIO */ + REGMAP_IRQ_REG(BD73800_INT_GPIO1, 4, BD73800_INT_GPIO1_MASK), + REGMAP_IRQ_REG(BD73800_INT_GPIO2, 4, BD73800_INT_GPIO2_MASK), + REGMAP_IRQ_REG(BD73800_INT_GPIO3, 4, BD73800_INT_GPIO3_MASK), + REGMAP_IRQ_REG(BD73800_INT_GPIO4, 4, BD73800_INT_GPIO4_MASK), +}; + static const struct regmap_irq_chip bd71828_irq_chip = { .name = "bd71828_irq", .main_status = BD71828_REG_INT_MAIN, @@ -833,6 +943,25 @@ static const struct regmap_irq_chip bd72720_irq_chip = { .irq_reg_stride = 1, }; +static const struct regmap_irq_chip bd73800_irq_chip = { + .name = "bd73800_irq", + .main_status = BD73800_REG_INT_MAIN_STAT, + .irqs = bd73800_irqs, + .num_irqs = ARRAY_SIZE(bd73800_irqs), + .status_base = BD73800_REG_INT_1_STAT, + .unmask_base = BD73800_REG_INT_1_EN, + .ack_base = BD73800_REG_INT_1_STAT, + .init_ack_masked = true, + .num_regs = 5, + .num_main_regs = 1, + /* + * Ignore mirrored bits [7:5]. They are handled as part of normal INT_4 + * handling. + */ + .num_main_status_bits = 5, + .irq_reg_stride = 1, +}; + static int set_clk_mode(struct device *dev, struct regmap *regmap, int clkmode_reg) { @@ -971,6 +1100,17 @@ static int bd71828_i2c_probe(struct i2c_client *i2c) main_lvl_val = BD72720_MASK_LVL1_EN_ALL; break; } + case ROHM_CHIP_TYPE_BD73800: + mfd = bd73800_mfd_cells; + cells = ARRAY_SIZE(bd73800_mfd_cells); + regmap_config = &bd73800_regmap; + irqchip = &bd73800_irq_chip; + clkmode_reg = BD73800_REG_OUT32K; + button_irq = BD73800_INT_PBTN_SHORT_PUSH; + main_lvl_mask_reg = BD73800_REG_INT_MAIN_EN; + main_lvl_val = BD73800_INT_MAIN_EN_ALL; + break; + default: dev_err(&i2c->dev, "Unknown device type"); return -EINVAL; @@ -1051,6 +1191,9 @@ static const struct of_device_id bd71828_of_match[] = { }, { .compatible = "rohm,bd72720", .data = (void *)ROHM_CHIP_TYPE_BD72720, + }, { + .compatible = "rohm,bd73800", + .data = (void *)ROHM_CHIP_TYPE_BD73800, }, { }, };
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index e760d13..a02bb2f 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c
@@ -86,7 +86,7 @@ MODULE_ALIAS("mmc:block"); static DEFINE_MUTEX(block_mutex); /* - * The defaults come from config options but can be overriden by module + * The defaults come from config options but can be overridden by module * or bootarg options. */ static int perdev_minors = CONFIG_MMC_BLOCK_MINORS;
diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 29e80e5..677e445 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c
@@ -589,8 +589,8 @@ EXPORT_SYMBOL(mmc_cqe_recovery); * mmc_is_req_done() is used with requests that have * mrq->cap_cmd_during_tfr = true. mmc_is_req_done() must be called after * starting a request and before waiting for it to complete. That is, - * either in between calls to mmc_start_req(), or after mmc_wait_for_req() - * and before mmc_wait_for_req_done(). If it is called at other times the + * after mmc_start_request() or mmc_wait_for_req() and before + * mmc_wait_for_req_done(). If it is called at other times the * result is not meaningful. */ bool mmc_is_req_done(struct mmc_host *host, struct mmc_request *mrq) @@ -1388,7 +1388,7 @@ void mmc_power_off(struct mmc_host *host) * XO-1.5, require a short delay after poweroff before the card * can be successfully turned on again. */ - mmc_delay(1); + mmc_delay_us(host->ios.power_off_delay_us); } void mmc_power_cycle(struct mmc_host *host, u32 ocr) @@ -2004,7 +2004,7 @@ unsigned int mmc_calc_max_discard(struct mmc_card *card) /* * Without erase_group_def set, MMC erase timeout depends on clock - * frequence which can change. In that case, the best choice is + * frequency which can change. In that case, the best choice is * just the preferred erase size. */ if (mmc_card_mmc(card) && !(card->ext_csd.erase_group_def & 1))
diff --git a/drivers/mmc/core/core.h b/drivers/mmc/core/core.h index a028b48..9be2875 100644 --- a/drivers/mmc/core/core.h +++ b/drivers/mmc/core/core.h
@@ -73,6 +73,14 @@ static inline void mmc_delay(unsigned int ms) msleep(ms); } +static inline void mmc_delay_us(unsigned int us) +{ + if (us == 0) + return; + + fsleep(us); +} + void mmc_rescan(struct work_struct *work); void mmc_start_host(struct mmc_host *host); void __mmc_stop_host(struct mmc_host *host); @@ -162,7 +170,7 @@ int mmc_cqe_recovery(struct mmc_host *host); * @host: MMC host to prepare command * @mrq: MMC request to prepare for * - * mmc_pre_req() is called in prior to mmc_start_req() to let + * mmc_pre_req() is called in prior to mmc_start_request() to let * host prepare for the new request. Preparation of a request may be * performed while another request is running on the host. */
diff --git a/drivers/mmc/core/crypto.c b/drivers/mmc/core/crypto.c index fec4fbf..a5a90bf 100644 --- a/drivers/mmc/core/crypto.c +++ b/drivers/mmc/core/crypto.c
@@ -15,7 +15,7 @@ void mmc_crypto_set_initial_state(struct mmc_host *host) { /* Reset might clear all keys, so reprogram all the keys. */ - if (host->caps2 & MMC_CAP2_CRYPTO) + if ((host->caps2 & MMC_CAP2_CRYPTO) && !(host->caps2 & MMC_CAP2_CRYPTO_NO_REPROG)) blk_crypto_reprogram_all_keys(&host->crypto_profile); }
diff --git a/drivers/mmc/core/host.c b/drivers/mmc/core/host.c index 828078b..8e9e618 100644 --- a/drivers/mmc/core/host.c +++ b/drivers/mmc/core/host.c
@@ -421,6 +421,9 @@ int mmc_of_parse(struct mmc_host *host) device_property_read_u32(dev, "post-power-on-delay-ms", &host->ios.power_delay_ms); + device_property_read_u32(dev, "power-off-delay-us", + &host->ios.power_off_delay_us); + return mmc_pwrseq_alloc(host); } @@ -502,14 +505,7 @@ static int mmc_first_nonreserved_index(void) return max + 1; } -/** - * mmc_alloc_host - initialise the per-host structure. - * @extra: sizeof private data structure - * @dev: pointer to host device model structure - * - * Initialise the per-host structure. - */ -struct mmc_host *mmc_alloc_host(int extra, struct device *dev) +static struct mmc_host *mmc_alloc_host(struct device *dev, int extra) { int index; struct mmc_host *host; @@ -574,12 +570,19 @@ struct mmc_host *mmc_alloc_host(int extra, struct device *dev) host->fixed_drv_type = -EINVAL; host->ios.power_delay_ms = 10; + host->ios.power_off_delay_us = 1000; host->ios.power_mode = MMC_POWER_UNDEFINED; return host; } -EXPORT_SYMBOL(mmc_alloc_host); +static void mmc_free_host(struct mmc_host *host) +{ + cancel_delayed_work_sync(&host->detect); + cancel_work_sync(&host->sdio_irq_work); + mmc_pwrseq_free(host); + put_device(&host->class_dev); +} static void devm_mmc_host_release(struct device *dev, void *res) { @@ -594,7 +597,7 @@ struct mmc_host *devm_mmc_alloc_host(struct device *dev, int extra) if (!dr) return NULL; - host = mmc_alloc_host(extra, dev); + host = mmc_alloc_host(dev, extra); if (!host) { devres_free(dr); return NULL; @@ -688,19 +691,3 @@ void mmc_remove_host(struct mmc_host *host) } EXPORT_SYMBOL(mmc_remove_host); - -/** - * mmc_free_host - free the host structure - * @host: mmc host - * - * Free the host once all references to it have been dropped. - */ -void mmc_free_host(struct mmc_host *host) -{ - cancel_delayed_work_sync(&host->detect); - cancel_work_sync(&host->sdio_irq_work); - mmc_pwrseq_free(host); - put_device(&host->class_dev); -} - -EXPORT_SYMBOL(mmc_free_host);
diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 05444ec..a02b049 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c
@@ -1015,7 +1015,7 @@ static void mmc_set_bus_speed(struct mmc_card *card) } /* - * Select the bus width amoung 4-bit and 8-bit(SDR). + * Select the bus width among 4-bit and 8-bit(SDR). * If the bus width is changed successfully, return the selected width value. * Zero is returned instead of error value if the wide width is not supported. */
diff --git a/drivers/mmc/core/mmc_ops.c b/drivers/mmc/core/mmc_ops.c index a952cc8..d59ff82f 100644 --- a/drivers/mmc/core/mmc_ops.c +++ b/drivers/mmc/core/mmc_ops.c
@@ -673,7 +673,8 @@ int mmc_switch(struct mmc_card *card, u8 set, u8 index, u8 value, } EXPORT_SYMBOL_GPL(mmc_switch); -int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error) +int mmc_send_tuning_timeout(struct mmc_host *host, u32 opcode, int *cmd_error, + u32 timeout_ms) { struct mmc_request mrq = {}; struct mmc_command cmd = {}; @@ -707,12 +708,7 @@ int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error) data.blocks = 1; data.flags = MMC_DATA_READ; - /* - * According to the tuning specs, Tuning process - * is normally shorter 40 executions of CMD19, - * and timeout value should be shorter than 150 ms - */ - data.timeout_ns = 150 * NSEC_PER_MSEC; + data.timeout_ns = timeout_ms * NSEC_PER_MSEC; data.sg = &sg; data.sg_len = 1; @@ -740,6 +736,18 @@ int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error) kfree(data_buf); return err; } +EXPORT_SYMBOL_GPL(mmc_send_tuning_timeout); + +int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error) +{ + /* + * The eMMC and SD specs give the tuning process an overall + * budget of 150 ms. mmc_send_tuning() simply applies that as + * the timeout of every single tuning command. Drivers which + * want a different timeout can use mmc_send_tuning_timeout(). + */ + return mmc_send_tuning_timeout(host, opcode, cmd_error, 150); +} EXPORT_SYMBOL_GPL(mmc_send_tuning); int mmc_send_abort_tuning(struct mmc_host *host, u32 opcode)
diff --git a/drivers/mmc/core/sdio_cis.c b/drivers/mmc/core/sdio_cis.c index afaa6ca..0b818cb 100644 --- a/drivers/mmc/core/sdio_cis.c +++ b/drivers/mmc/core/sdio_cis.c
@@ -57,12 +57,11 @@ static int cistpl_vers_1(struct mmc_card *card, struct sdio_func *func, return -ENOMEM; string = (char*)(buffer + nr_strings); + memcpy(string, buf, size); for (i = 0; i < nr_strings; i++) { buffer[i] = string; - strcpy(string, buf); - string += strlen(string) + 1; - buf += strlen(buf) + 1; + string = strchr(string, 0) + 1; } if (func) {
diff --git a/drivers/mmc/host/Kconfig b/drivers/mmc/host/Kconfig index 4f060d3..79bfc42 100644 --- a/drivers/mmc/host/Kconfig +++ b/drivers/mmc/host/Kconfig
@@ -917,37 +917,6 @@ If you have a board based on such a SoC and with a SD/MMC slot, say Y or M here. -config MMC_VUB300 - tristate "VUB300 USB to SDIO/SD/MMC Host Controller support" - depends on USB - help - This selects support for Elan Digital Systems' VUB300 chip. - - The VUB300 is a USB-SDIO Host Controller Interface chip - that enables the host computer to use SDIO/SD/MMC cards - via a USB 2.0 or USB 1.1 host. - - The VUB300 chip will be found in both physically separate - USB to SDIO/SD/MMC adapters and embedded on some motherboards. - - The VUB300 chip supports SD and MMC memory cards in addition - to single and multifunction SDIO cards. - - Some SDIO cards will need a firmware file to be loaded and - sent to VUB300 chip in order to achieve better data throughput. - Download these "Offload Pseudocode" from Elan Digital Systems' - web-site http://www.elandigitalsystems.com/support/downloads.php - and put them in /lib/firmware. Note that without these additional - firmware files the VUB300 chip will still function, but not at - the best obtainable data rate. - - To compile this mmc host controller driver as a module, - choose M here: the module will be called vub300. - - If you have a computer with an embedded VUB300 chip - or if you intend connecting a USB adapter based on a - VUB300 chip say Y or M here. - config MMC_USHC tristate "USB SD Host Controller (USHC) support" depends on USB
diff --git a/drivers/mmc/host/Makefile b/drivers/mmc/host/Makefile index ee412e6b..fd043af 100644 --- a/drivers/mmc/host/Makefile +++ b/drivers/mmc/host/Makefile
@@ -60,7 +60,6 @@ obj-$(CONFIG_MMC_DW_STARFIVE) += dw_mmc-starfive.o obj-$(CONFIG_MMC_SH_MMCIF) += sh_mmcif.o obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o -obj-$(CONFIG_MMC_VUB300) += vub300.o obj-$(CONFIG_MMC_USHC) += ushc.o obj-$(CONFIG_MMC_WMT) += wmt-sdmmc.o obj-$(CONFIG_MMC_MESON_GX) += meson-gx-mmc.o @@ -80,6 +79,7 @@ obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o obj-$(CONFIG_MMC_SDHCI_CADENCE) += sdhci-cadence.o +sdhci-cadence-y += sdhci-cadence-core.o sdhci-cadence-phy-v6.o obj-$(CONFIG_MMC_SDHCI_ESDHC_MCF) += sdhci-esdhc-mcf.o obj-$(CONFIG_MMC_SDHCI_ESDHC_IMX) += sdhci-esdhc-imx.o obj-$(CONFIG_MMC_SDHCI_DOVE) += sdhci-dove.o
diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index 8f4df25..98933be 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c
@@ -1677,10 +1677,7 @@ static void atmci_detect_change(struct timer_list *t) spin_lock(&host->lock); - if (!present) - clear_bit(ATMCI_CARD_PRESENT, &slot->flags); - else - set_bit(ATMCI_CARD_PRESENT, &slot->flags); + assign_bit(ATMCI_CARD_PRESENT, &slot->flags, present); /* Clean up queue if present */ mrq = slot->mrq;
diff --git a/drivers/mmc/host/bcm2835.c b/drivers/mmc/host/bcm2835.c index c949a3e..efd1903 100644 --- a/drivers/mmc/host/bcm2835.c +++ b/drivers/mmc/host/bcm2835.c
@@ -1095,7 +1095,7 @@ static void bcm2835_set_clock(struct bcm2835_host *host, unsigned int clock) int div; /* The SDCDIV register has 11 bits, and holds (div - 2). But - * in data mode the max is 50MHz wihout a minimum, and only + * in data mode the max is 50MHz without a minimum, and only * the bottom 3 bits are used. Since the switch over is * automatic (unless we have marked the card as slow...), * chosen values have to make sense in both modes. Ident mode
diff --git a/drivers/mmc/host/cavium-thunderx.c b/drivers/mmc/host/cavium-thunderx.c index 2635ac9..ee19ea5 100644 --- a/drivers/mmc/host/cavium-thunderx.c +++ b/drivers/mmc/host/cavium-thunderx.c
@@ -157,11 +157,8 @@ static int thunder_mmc_probe(struct pci_dev *pdev, for (i = 0; i < CAVIUM_MAX_MMC; i++) { if (host->slot[i]) cvm_mmc_of_slot_remove(host->slot[i]); - if (host->slot_pdev[i]) { - get_device(&host->slot_pdev[i]->dev); + if (host->slot_pdev[i]) of_platform_device_destroy(&host->slot_pdev[i]->dev, NULL); - put_device(&host->slot_pdev[i]->dev); - } } clk_disable_unprepare(host->clk); return ret;
diff --git a/drivers/mmc/host/davinci_mmc.c b/drivers/mmc/host/davinci_mmc.c index cdb9fa9..c503e5f 100644 --- a/drivers/mmc/host/davinci_mmc.c +++ b/drivers/mmc/host/davinci_mmc.c
@@ -1249,6 +1249,10 @@ static int davinci_mmcsd_probe(struct platform_device *pdev) host->use_dma = use_dma; host->mmc_irq = irq; host->sdio_irq = platform_get_irq_optional(pdev, 1); + if (host->sdio_irq < 0 && host->sdio_irq != -ENXIO) { + ret = host->sdio_irq; + goto parse_fail; + } if (host->use_dma) { ret = davinci_acquire_dma_channels(host); @@ -1299,7 +1303,7 @@ static int davinci_mmcsd_probe(struct platform_device *pdev) if (ret) goto mmc_add_host_fail; - if (host->sdio_irq >= 0) { + if (host->sdio_irq > 0) { ret = devm_request_irq(&pdev->dev, host->sdio_irq, mmc_davinci_sdio_irq, 0, mmc_hostname(mmc), host);
diff --git a/drivers/mmc/host/dw_mmc-rockchip.c b/drivers/mmc/host/dw_mmc-rockchip.c index 75c82ff..a07707a 100644 --- a/drivers/mmc/host/dw_mmc-rockchip.c +++ b/drivers/mmc/host/dw_mmc-rockchip.c
@@ -327,7 +327,7 @@ static int dw_mci_rk3288_execute_tuning(struct dw_mci *host, u32 opcode) i, priv->num_phases)); - v = !mmc_send_tuning(mmc, opcode, NULL); + v = !mmc_send_tuning_timeout(mmc, opcode, NULL, 5); if (i == 0) first_v = v;
diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index cf5cecc..ff0b25d 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c
@@ -44,6 +44,137 @@ #define DW_MCI_FREQ_MAX 200000000 /* unit: HZ */ #define DW_MCI_FREQ_MIN 100000 /* unit: HZ */ +/* Event sets guarded by the central watchdog, see below. */ +#define DW_MCI_WD_CMD_EVENTS BIT(EVENT_CMD_COMPLETE) +#define DW_MCI_WD_DATA_EVENTS (BIT(EVENT_DATA_ERROR) | \ + BIT(EVENT_DATA_COMPLETE)) +/* Extra watch rounds granted while the completion IRQ is merely late. */ +#define DW_MCI_WD_INFLIGHT_GRACE_MS 10 + +/* + * Central watchdog + * ================ + * + * A single hrtimer guards the legs of a request (command, data, voltage + * switch) against the hardware going silent: whenever a completion event + * that was expected within a bounded time does not arrive in time, the + * callback synthesizes it so that the request state machine can error out. + * + * @wd_events holds the pending_events bits still being waited for and + * @wd_states the host->state values for which the watch is valid; both + * are protected by irq_lock. Every producer of the guarded events posts + * them under irq_lock as well, so a callback holding irq_lock can never + * miss an already-delivered event. A stale callback which raced past + * all checks therefore degrades to at most one redundant state-machine + * run instead of completing a foreign leg. Arming replaces whatever + * watch was outstanding before: command and data legs are strictly + * serial, so consecutive arms on the same path collapse onto the latest + * deadline. + * + * On expiry, before declaring a timeout, the callback double-checks that + * the completion interrupt is not already latched in hardware; if it is, + * only the interrupt latency is to blame and the watch is granted extra + * rounds instead of failing a transfer that is about to complete. + */ +static void dw_mci_wd_deliver(struct dw_mci *host, unsigned long events) +{ + host->wd_events &= ~events; + if (!host->wd_events) + hrtimer_try_to_cancel(&host->wd_timer); +} + +/* + * Arm a new watch for @events valid while host->state is one of @states, + * expiring after @ms milliseconds. @already lists bits whose delivery + * makes the watch pointless before it is even armed: arming is skipped + * when any of them has been posted concurrently. Must be called with + * irq_lock held. + */ +static void dw_mci_wd_arm(struct dw_mci *host, unsigned long ms, + unsigned long already, unsigned long events, + unsigned long states) +{ + lockdep_assert_held(&host->irq_lock); + + if (host->pending_events & already) { + /* + * The event was delivered concurrently; no need for a + * watch anymore. + */ + host->wd_events = 0; + hrtimer_try_to_cancel(&host->wd_timer); + return; + } + + host->wd_events = events; + host->wd_states = states; + host->wd_deadline_ns = ktime_get_ns() + (u64)ms * NSEC_PER_MSEC; + hrtimer_start(&host->wd_timer, ms_to_ktime(ms), HRTIMER_MODE_REL); +} + +/* Called from hardirq context on watchdog expiry. */ +static enum hrtimer_restart dw_mci_watchdog_fn(struct hrtimer *t) +{ + struct dw_mci *host = container_of(t, struct dw_mci, wd_timer); + unsigned long irqflags; + u32 pending; + + spin_lock_irqsave(&host->irq_lock, irqflags); + + /* + * Last line of defense against a false timeout: when the completion + * interrupt is already latched in MINTSTS but its handler has not + * been scheduled yet, the leg is about to finish normally. Warn + * about the latency and keep watching instead of failing the + * transfer; delivery by the real interrupt will stop the watch. + * The retired per-timer callbacks went passive here and relied on + * the latched interrupt arriving; rearming bounds the damage if + * that assumption is ever broken. + */ + if (host->wd_events) { + pending = mci_readl(host, MINTSTS); /* read-only mask reg */ + if ((host->wd_events == DW_MCI_WD_CMD_EVENTS && + (pending & (DW_MCI_CMD_ERROR_FLAGS | + SDMMC_INT_CMD_DONE))) || + (host->wd_events == DW_MCI_WD_DATA_EVENTS && + (pending & (SDMMC_INT_DATA_OVER | + DW_MCI_DATA_ERROR_FLAGS)))) { + dev_warn(host->dev, + "Interrupt latency, state %d (watched %#lx)\n", + host->state, host->wd_events); + hrtimer_forward_now(&host->wd_timer, + ms_to_ktime(DW_MCI_WD_INFLIGHT_GRACE_MS)); + spin_unlock_irqrestore(&host->irq_lock, irqflags); + return HRTIMER_RESTART; + } + } + + if (host->wd_events == DW_MCI_WD_DATA_EVENTS) { + dev_warn(host->dev, + "Data timeout, state %d\n", host->state); + host->data_status = SDMMC_INT_DRTO; + set_bit(EVENT_DATA_ERROR, &host->pending_events); + set_bit(EVENT_DATA_COMPLETE, &host->pending_events); + } else if (host->wd_events) { + dev_warn(host->dev, + "Command timeout, state %d (watched %#lx)\n", + host->state, host->wd_events); + host->cmd_status = SDMMC_INT_RTO; + set_bit(EVENT_CMD_COMPLETE, &host->pending_events); + } + + if (host->wd_events) + queue_work(system_bh_wq, &host->bh_work); + + host->wd_events = 0; + host->wd_states = 0; + host->wd_deadline_ns = 0; + + spin_unlock_irqrestore(&host->irq_lock, irqflags); + + return HRTIMER_NORESTART; +} + #define IDMAC_INT_CLR (SDMMC_IDMAC_INT_AI | SDMMC_IDMAC_INT_NI | \ SDMMC_IDMAC_INT_CES | SDMMC_IDMAC_INT_DU | \ SDMMC_IDMAC_INT_FBE | SDMMC_IDMAC_INT_RI | \ @@ -171,6 +302,10 @@ static void dw_mci_init_debugfs(struct dw_mci *host) &host->pending_events); debugfs_create_xul("completed_events", 0400, root, &host->completed_events); + debugfs_create_x64("wd_deadline_ns", 0400, root, + &host->wd_deadline_ns); + debugfs_create_xul("wd_events", 0400, root, &host->wd_events); + debugfs_create_xul("wd_states", 0400, root, &host->wd_states); #ifdef CONFIG_FAULT_INJECTION fault_create_debugfs_attr("fail_data_crc", root, &host->fail_data_crc); #endif @@ -366,18 +501,17 @@ static inline void dw_mci_set_cto(struct dw_mci *host) * extra careful about synchronization here. Specifically in hardware a * command timeout is _at most_ 5.1 ms, so that means we expect an * interrupt (either command done or timeout) to come rather quickly - * after the mci_writel. ...but just in case we have a long interrupt - * latency let's add a bit of paranoia. + * after the mci_writel. * - * In general we'll assume that at least an interrupt will be asserted - * in hardware by the time the cto_timer runs. ...and if it hasn't - * been asserted in hardware by that time then we'll assume it'll never - * come. + * dw_mci_wd_arm() skips arming when the event was already delivered, + * and the watchdog callback rechecks under the same lock before + * declaring a timeout, so both orderings of the race are covered. */ spin_lock_irqsave(&host->irq_lock, irqflags); - if (!test_bit(EVENT_CMD_COMPLETE, &host->pending_events)) - mod_timer(&host->cto_timer, - jiffies + msecs_to_jiffies(cto_ms) + 1); + dw_mci_wd_arm(host, cto_ms, DW_MCI_WD_CMD_EVENTS, + DW_MCI_WD_CMD_EVENTS, + BIT(STATE_SENDING_CMD) | BIT(STATE_SENDING_STOP) | + BIT(STATE_SENDING_CMD11)); spin_unlock_irqrestore(&host->irq_lock, irqflags); } @@ -1265,17 +1399,16 @@ static void dw_mci_start_request(struct dw_mci *host, struct mmc_command *cmd) /* * Databook says to fail after 2ms w/ no response, but evidence * shows that sometimes the cmd11 interrupt takes over 130ms. - * We'll set to 500ms, plus an extra jiffy just in case jiffies - * is just about to roll over. + * We'll set to 500ms. * * We do this whole thing under spinlock and only if the * command hasn't already completed (indicating the irq * already ran so we don't want the timeout). */ spin_lock_irqsave(&host->irq_lock, irqflags); - if (!test_bit(EVENT_CMD_COMPLETE, &host->pending_events)) - mod_timer(&host->cmd11_timer, - jiffies + msecs_to_jiffies(500) + 1); + dw_mci_wd_arm(host, 500, DW_MCI_WD_CMD_EVENTS, + DW_MCI_WD_CMD_EVENTS, + BIT(STATE_SENDING_CMD11)); spin_unlock_irqrestore(&host->irq_lock, irqflags); } @@ -1870,9 +2003,9 @@ static void dw_mci_set_drto(struct dw_mci *host) drto_ms += 10; spin_lock_irqsave(&host->irq_lock, irqflags); - if (!test_bit(EVENT_DATA_COMPLETE, &host->pending_events)) - mod_timer(&host->dto_timer, - jiffies + msecs_to_jiffies(drto_ms)); + dw_mci_wd_arm(host, drto_ms, BIT(EVENT_DATA_COMPLETE), + DW_MCI_WD_DATA_EVENTS, + BIT(STATE_SENDING_DATA) | BIT(STATE_DATA_BUSY)); spin_unlock_irqrestore(&host->irq_lock, irqflags); } @@ -1881,14 +2014,6 @@ static bool dw_mci_clear_pending_cmd_complete(struct dw_mci *host) if (!test_bit(EVENT_CMD_COMPLETE, &host->pending_events)) return false; - /* - * Really be certain that the timer has stopped. This is a bit of - * paranoia and could only really happen if we had really bad - * interrupt latency and the interrupt routine and timeout were - * running concurrently so that the timer_delete() in the interrupt - * handler couldn't run. - */ - WARN_ON(timer_delete_sync(&host->cto_timer)); clear_bit(EVENT_CMD_COMPLETE, &host->pending_events); return true; @@ -1899,8 +2024,6 @@ static bool dw_mci_clear_pending_data_complete(struct dw_mci *host) if (!test_bit(EVENT_DATA_COMPLETE, &host->pending_events)) return false; - /* Extra paranoia just like dw_mci_clear_pending_cmd_complete() */ - WARN_ON(timer_delete_sync(&host->dto_timer)); clear_bit(EVENT_DATA_COMPLETE, &host->pending_events); return true; @@ -2633,7 +2756,7 @@ static void dw_mci_write_data_pio(struct dw_mci *host) static void dw_mci_cmd_interrupt(struct dw_mci *host, u32 status) { - timer_delete(&host->cto_timer); + dw_mci_wd_deliver(host, BIT(EVENT_CMD_COMPLETE)); if (!host->cmd_status) host->cmd_status = status; @@ -2666,21 +2789,15 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) mci_writel(host, RINTSTS, SDMMC_INT_VOLT_SWITCH); pending &= ~SDMMC_INT_VOLT_SWITCH; - /* - * Hold the lock; we know cmd11_timer can't be kicked - * off after the lock is released, so safe to delete. - */ spin_lock(&host->irq_lock); dw_mci_cmd_interrupt(host, pending); spin_unlock(&host->irq_lock); - - timer_delete(&host->cmd11_timer); } if (pending & DW_MCI_CMD_ERROR_FLAGS) { spin_lock(&host->irq_lock); - timer_delete(&host->cto_timer); + dw_mci_wd_deliver(host, BIT(EVENT_CMD_COMPLETE)); mci_writel(host, RINTSTS, DW_MCI_CMD_ERROR_FLAGS); host->cmd_status = pending; smp_wmb(); /* drain writebuffer */ @@ -2693,7 +2810,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) spin_lock(&host->irq_lock); if (host->quirks & DW_MMC_QUIRK_EXTENDED_TMOUT) - timer_delete(&host->dto_timer); + dw_mci_wd_deliver(host, DW_MCI_WD_DATA_EVENTS); /* if there is an error report DATA_ERROR */ mci_writel(host, RINTSTS, DW_MCI_DATA_ERROR_FLAGS); @@ -2714,7 +2831,7 @@ static irqreturn_t dw_mci_interrupt(int irq, void *dev_id) if (pending & SDMMC_INT_DATA_OVER) { spin_lock(&host->irq_lock); - timer_delete(&host->dto_timer); + dw_mci_wd_deliver(host, DW_MCI_WD_DATA_EVENTS); mci_writel(host, RINTSTS, SDMMC_INT_DATA_OVER); if (!host->data_status) @@ -2994,126 +3111,6 @@ static void dw_mci_init_dma(struct dw_mci *host) host->use_dma = TRANS_MODE_PIO; } -static void dw_mci_cmd11_timer(struct timer_list *t) -{ - struct dw_mci *host = timer_container_of(host, t, cmd11_timer); - - if (host->state != STATE_SENDING_CMD11) { - dev_warn(host->dev, "Unexpected CMD11 timeout\n"); - return; - } - - host->cmd_status = SDMMC_INT_RTO; - set_bit(EVENT_CMD_COMPLETE, &host->pending_events); - queue_work(system_bh_wq, &host->bh_work); -} - -static void dw_mci_cto_timer(struct timer_list *t) -{ - struct dw_mci *host = timer_container_of(host, t, cto_timer); - unsigned long irqflags; - u32 pending; - - spin_lock_irqsave(&host->irq_lock, irqflags); - - /* - * If somehow we have very bad interrupt latency it's remotely possible - * that the timer could fire while the interrupt is still pending or - * while the interrupt is midway through running. Let's be paranoid - * and detect those two cases. Note that this is paranoia is somewhat - * justified because in this function we don't actually cancel the - * pending command in the controller--we just assume it will never come. - */ - pending = mci_readl(host, MINTSTS); /* read-only mask reg */ - if (pending & (DW_MCI_CMD_ERROR_FLAGS | SDMMC_INT_CMD_DONE)) { - /* The interrupt should fire; no need to act but we can warn */ - dev_warn(host->dev, "Unexpected interrupt latency\n"); - goto exit; - } - if (test_bit(EVENT_CMD_COMPLETE, &host->pending_events)) { - /* Presumably interrupt handler couldn't delete the timer */ - dev_warn(host->dev, "CTO timeout when already completed\n"); - goto exit; - } - - /* - * Continued paranoia to make sure we're in the state we expect. - * This paranoia isn't really justified but it seems good to be safe. - */ - switch (host->state) { - case STATE_SENDING_CMD11: - case STATE_SENDING_CMD: - case STATE_SENDING_STOP: - /* - * If CMD_DONE interrupt does NOT come in sending command - * state, we should notify the driver to terminate current - * transfer and report a command timeout to the core. - */ - host->cmd_status = SDMMC_INT_RTO; - set_bit(EVENT_CMD_COMPLETE, &host->pending_events); - queue_work(system_bh_wq, &host->bh_work); - break; - default: - dev_warn(host->dev, "Unexpected command timeout, state %d\n", - host->state); - break; - } - -exit: - spin_unlock_irqrestore(&host->irq_lock, irqflags); -} - -static void dw_mci_dto_timer(struct timer_list *t) -{ - struct dw_mci *host = timer_container_of(host, t, dto_timer); - unsigned long irqflags; - u32 pending; - - spin_lock_irqsave(&host->irq_lock, irqflags); - - /* - * The DTO timer is much longer than the CTO timer, so it's even less - * likely that we'll these cases, but it pays to be paranoid. - */ - pending = mci_readl(host, MINTSTS); /* read-only mask reg */ - if (pending & SDMMC_INT_DATA_OVER) { - /* The interrupt should fire; no need to act but we can warn */ - dev_warn(host->dev, "Unexpected data interrupt latency\n"); - goto exit; - } - if (test_bit(EVENT_DATA_COMPLETE, &host->pending_events)) { - /* Presumably interrupt handler couldn't delete the timer */ - dev_warn(host->dev, "DTO timeout when already completed\n"); - goto exit; - } - - /* - * Continued paranoia to make sure we're in the state we expect. - * This paranoia isn't really justified but it seems good to be safe. - */ - switch (host->state) { - case STATE_SENDING_DATA: - case STATE_DATA_BUSY: - /* - * If DTO interrupt does NOT come in sending data state, - * we should notify the driver to terminate current transfer - * and report a data timeout to the core. - */ - host->data_status = SDMMC_INT_DRTO; - set_bit(EVENT_DATA_ERROR, &host->pending_events); - set_bit(EVENT_DATA_COMPLETE, &host->pending_events); - queue_work(system_bh_wq, &host->bh_work); - break; - default: - dev_warn(host->dev, "Unexpected data timeout, state %d\n", - host->state); - break; - } - -exit: - spin_unlock_irqrestore(&host->irq_lock, irqflags); -} - static int dw_mci_parse_dt(struct dw_mci *host) { struct device *dev = host->dev; @@ -3261,9 +3258,8 @@ int dw_mci_probe(struct dw_mci *host) } } - timer_setup(&host->cmd11_timer, dw_mci_cmd11_timer, 0); - timer_setup(&host->cto_timer, dw_mci_cto_timer, 0); - timer_setup(&host->dto_timer, dw_mci_dto_timer, 0); + hrtimer_setup(&host->wd_timer, dw_mci_watchdog_fn, CLOCK_MONOTONIC, + HRTIMER_MODE_REL); spin_lock_init(&host->lock); spin_lock_init(&host->irq_lock);
diff --git a/drivers/mmc/host/dw_mmc.h b/drivers/mmc/host/dw_mmc.h index 38610c8..5c2a8d0 100644 --- a/drivers/mmc/host/dw_mmc.h +++ b/drivers/mmc/host/dw_mmc.h
@@ -69,7 +69,7 @@ struct dw_mci_dma_slave { * @cmd: The command currently being sent to the card, or NULL. * @data: The data currently being transferred, or NULL if no data * transfer is in progress. - * @stop_abort: The command currently prepared for stoping transfer. + * @stop_abort: The command currently prepared for stopping transfer. * @prev_blksz: The former transfer blksz record. * @timing: Record of current ios timing. * @use_dma: Which DMA channel is in use for the current transfer, zero @@ -122,9 +122,11 @@ struct dw_mci_dma_slave { * @irq_flags: The flags to be passed to request_irq. * @irq: The irq value to be passed to request_irq. * @sdio_irq: SDIO interrupt bit in interrupt registers. - * @cmd11_timer: Timer for SD3.0 voltage switch over scheme. - * @cto_timer: Timer for broken command transfer over scheme. - * @dto_timer: Timer for broken data transfer over scheme. + * @wd_timer: Central watchdog guarding request legs against hardware going + * silent; fires when an expected completion event fails to arrive in + * time so that the state machine can synthesize an error. + * @wd_events: pending_events bits still awaited by the armed watch. + * @wd_states: host->state values for which the armed watch is valid. * @mmc: The mmc_host representing this dw_mci. * @flags: Random state bits associated with the host. * @ctype: Card type for this host. @@ -214,7 +216,6 @@ struct dw_mci { void *priv; struct clk *biu_clk; struct clk *ciu_clk; - struct dw_mci_slot *slot; /* FIFO push and pull */ int fifo_depth; @@ -235,9 +236,10 @@ struct dw_mci { int sdio_irq; - struct timer_list cmd11_timer; - struct timer_list cto_timer; - struct timer_list dto_timer; + struct hrtimer wd_timer; + unsigned long wd_events; + unsigned long wd_states; + u64 wd_deadline_ns; #ifdef CONFIG_FAULT_INJECTION struct fault_attr fail_data_crc;
diff --git a/drivers/mmc/host/meson-gx-mmc.c b/drivers/mmc/host/meson-gx-mmc.c index 694bb44..7ef16d7 100644 --- a/drivers/mmc/host/meson-gx-mmc.c +++ b/drivers/mmc/host/meson-gx-mmc.c
@@ -139,6 +139,7 @@ struct meson_mmc_data { unsigned int always_on; unsigned int adjust; unsigned int irq_sdio_sleep; + bool has_pipeline_clk; }; struct sd_emmc_desc { @@ -418,7 +419,7 @@ static int meson_mmc_clk_set(struct meson_host *host, unsigned long rate, */ static int meson_mmc_clk_init(struct meson_host *host) { - struct clk_init_data init; + struct clk_init_data init = {}; struct clk_mux *mux; struct clk_divider *div; char clk_name[32]; @@ -1141,7 +1142,8 @@ static int meson_mmc_probe(struct platform_device *pdev) struct meson_host *host; struct mmc_host *mmc; struct clk *core_clk; - int cd_irq, ret; + int cd_irq = -ENXIO; + int ret; mmc = devm_mmc_alloc_host(&pdev->dev, sizeof(struct meson_host)); if (!mmc) @@ -1185,7 +1187,11 @@ static int meson_mmc_probe(struct platform_device *pdev) if (host->irq < 0) return host->irq; - cd_irq = platform_get_irq_optional(pdev, 1); + ret = platform_get_irq_optional(pdev, 1); + if (ret < 0 && ret != -ENXIO) + return ret; + if (ret > 0) + cd_irq = ret; mmc_gpio_set_cd_irq(mmc, cd_irq); host->pinctrl = devm_pinctrl_get(&pdev->dev); @@ -1204,6 +1210,15 @@ static int meson_mmc_probe(struct platform_device *pdev) if (IS_ERR(core_clk)) return PTR_ERR(core_clk); + if (host->data->has_pipeline_clk) { + struct clk *pipe_clk; + + pipe_clk = devm_clk_get_enabled(&pdev->dev, "pipeline"); + if (IS_ERR(pipe_clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(pipe_clk), + "missing pipeline clock\n"); + } + ret = meson_mmc_clk_init(host); if (ret) return ret; @@ -1322,12 +1337,22 @@ static const struct meson_mmc_data meson_axg_data = { .irq_sdio_sleep = CLK_V3_IRQ_SDIO_SLEEP, }; +static const struct meson_mmc_data meson_t7_data = { + .tx_delay_mask = CLK_V3_TX_DELAY_MASK, + .rx_delay_mask = CLK_V3_RX_DELAY_MASK, + .always_on = CLK_V3_ALWAYS_ON, + .adjust = SD_EMMC_V3_ADJUST, + .irq_sdio_sleep = CLK_V3_IRQ_SDIO_SLEEP, + .has_pipeline_clk = true, +}; + static const struct of_device_id meson_mmc_of_match[] = { { .compatible = "amlogic,meson-gx-mmc", .data = &meson_gx_data }, { .compatible = "amlogic,meson-gxbb-mmc", .data = &meson_gx_data }, { .compatible = "amlogic,meson-gxl-mmc", .data = &meson_gx_data }, { .compatible = "amlogic,meson-gxm-mmc", .data = &meson_gx_data }, { .compatible = "amlogic,meson-axg-mmc", .data = &meson_axg_data }, + { .compatible = "amlogic,t7-mmc", .data = &meson_t7_data }, {} }; MODULE_DEVICE_TABLE(of, meson_mmc_of_match);
diff --git a/drivers/mmc/host/mvsdio.c b/drivers/mmc/host/mvsdio.c index cf705b2..7d86426 100644 --- a/drivers/mmc/host/mvsdio.c +++ b/drivers/mmc/host/mvsdio.c
@@ -717,7 +717,7 @@ static int mvsd_probe(struct platform_device *pdev) /* * Some non-DT platforms do not pass a clock, and the clock * frequency is passed through platform_data. On DT platforms, - * a clock must always be passed, even if there is no gatable + * a clock must always be passed, even if there is no gateable * clock associated to the SDIO interface (it can simply be a * fixed rate clock). */
diff --git a/drivers/mmc/host/rtsx_usb_sdmmc.c b/drivers/mmc/host/rtsx_usb_sdmmc.c index bf37fab..d9b33aa 100644 --- a/drivers/mmc/host/rtsx_usb_sdmmc.c +++ b/drivers/mmc/host/rtsx_usb_sdmmc.c
@@ -980,6 +980,11 @@ static int sd_power_on(struct rtsx_usb_sdmmc *host) } dev_dbg(sdmmc_dev(host), "%s\n", __func__); rtsx_usb_init_cmd(ucr); + /* Start SD init at 3.3V, like the old rts5139 driver. */ + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, SD_PAD_CTL, + SD_IO_USING_1V8, SD_IO_USING_3V3); + rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, LDO_POWER_CFG, + TUNE_SD18_MASK, TUNE_SD18_3V3); rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_SELECT, 0x07, SD_MOD_SEL); rtsx_usb_add_cmd(ucr, WRITE_REG_CMD, CARD_SHARE_MODE, CARD_SHARE_MASK, CARD_SHARE_SD);
diff --git a/drivers/mmc/host/sdhci-cadence.c b/drivers/mmc/host/sdhci-cadence-core.c similarity index 67% rename from drivers/mmc/host/sdhci-cadence.c rename to drivers/mmc/host/sdhci-cadence-core.c index 435603c..7454557 100644 --- a/drivers/mmc/host/sdhci-cadence.c +++ b/drivers/mmc/host/sdhci-cadence-core.c
@@ -2,10 +2,12 @@ /* * Copyright (C) 2016 Socionext Inc. * Author: Masahiro Yamada <yamada.masahiro@socionext.com> + * Copyright (C) 2026 Altera Corporation */ #include <linux/bitfield.h> #include <linux/bits.h> +#include <linux/dma-mapping.h> #include <linux/iopoll.h> #include <linux/module.h> #include <linux/mmc/host.h> @@ -14,10 +16,10 @@ #include <linux/platform_device.h> #include <linux/reset.h> -#include "sdhci-pltfm.h" +#include "sdhci-cadence.h" /* HRS - Host Register Set (specific to Cadence) */ -#define SDHCI_CDNS_HRS04 0x10 /* PHY access port */ +/* HRS04 (PHY access) bitfields (SD4HC) */ #define SDHCI_CDNS_HRS04_ACK BIT(26) #define SDHCI_CDNS_HRS04_RD BIT(25) #define SDHCI_CDNS_HRS04_WR BIT(24) @@ -71,30 +73,17 @@ #define SDHCI_CDNS_PHY_DLY_HSMMC 0x0c #define SDHCI_CDNS_PHY_DLY_STROBE 0x0d -/* - * The tuned val register is 6 bit-wide, but not the whole of the range is - * available. The range 0-42 seems to be available (then 43 wraps around to 0) - * but I am not quite sure if it is official. Use only 0 to 39 for safety. - */ -#define SDHCI_CDNS_MAX_TUNING_LOOP 40 - -struct sdhci_cdns_phy_param { +struct sdhci_cdns4_phy_param { u8 addr; u8 data; }; -struct sdhci_cdns_priv { - void __iomem *hrs_addr; - void __iomem *ctl_addr; /* write control */ - spinlock_t wrlock; /* write lock */ - bool enhanced_strobe; - void (*priv_writel)(struct sdhci_cdns_priv *priv, u32 val, void __iomem *reg); - struct reset_control *rst_hw; +struct sdhci_cdns4_phy { unsigned int nr_phy_params; - struct sdhci_cdns_phy_param phy_params[]; + struct sdhci_cdns4_phy_param phy_params[]; }; -struct sdhci_cdns_phy_cfg { +struct sdhci_cdns4_phy_cfg { const char *property; u8 addr; }; @@ -102,9 +91,10 @@ struct sdhci_cdns_phy_cfg { struct sdhci_cdns_drv_data { int (*init)(struct platform_device *pdev); const struct sdhci_pltfm_data pltfm_data; + u64 dma_mask; }; -static const struct sdhci_cdns_phy_cfg sdhci_cdns_phy_cfgs[] = { +static const struct sdhci_cdns4_phy_cfg sdhci_cdns4_phy_cfgs[] = { { "cdns,phy-input-delay-sd-highspeed", SDHCI_CDNS_PHY_DLY_SD_HS, }, { "cdns,phy-input-delay-legacy", SDHCI_CDNS_PHY_DLY_SD_DEFAULT, }, { "cdns,phy-input-delay-sd-uhs-sdr12", SDHCI_CDNS_PHY_DLY_UHS_SDR12, }, @@ -124,8 +114,7 @@ static inline void cdns_writel(struct sdhci_cdns_priv *priv, u32 val, writel(val, reg); } -static int sdhci_cdns_write_phy_reg(struct sdhci_cdns_priv *priv, - u8 addr, u8 data) +static int sdhci_cdns4_write_phy_reg(struct sdhci_cdns_priv *priv, u8 addr, u8 data) { void __iomem *reg = priv->hrs_addr + SDHCI_CDNS_HRS04; u32 tmp; @@ -156,44 +145,43 @@ static int sdhci_cdns_write_phy_reg(struct sdhci_cdns_priv *priv, return ret; } -static unsigned int sdhci_cdns_phy_param_count(struct device_node *np) +static unsigned int sdhci_cdns4_phy_param_count(struct device_node *np) { unsigned int count = 0; int i; - for (i = 0; i < ARRAY_SIZE(sdhci_cdns_phy_cfgs); i++) - if (of_property_present(np, sdhci_cdns_phy_cfgs[i].property)) + for (i = 0; i < ARRAY_SIZE(sdhci_cdns4_phy_cfgs); i++) + if (of_property_present(np, sdhci_cdns4_phy_cfgs[i].property)) count++; return count; } -static void sdhci_cdns_phy_param_parse(struct device_node *np, - struct sdhci_cdns_priv *priv) +static void sdhci_cdns4_phy_param_parse(struct device_node *np, struct sdhci_cdns4_phy *phy) { - struct sdhci_cdns_phy_param *p = priv->phy_params; + struct sdhci_cdns4_phy_param *p = phy->phy_params; u32 val; int ret, i; - for (i = 0; i < ARRAY_SIZE(sdhci_cdns_phy_cfgs); i++) { - ret = of_property_read_u32(np, sdhci_cdns_phy_cfgs[i].property, - &val); + for (i = 0; i < ARRAY_SIZE(sdhci_cdns4_phy_cfgs); i++) { + ret = of_property_read_u32(np, sdhci_cdns4_phy_cfgs[i].property, &val); if (ret) continue; - p->addr = sdhci_cdns_phy_cfgs[i].addr; + p->addr = sdhci_cdns4_phy_cfgs[i].addr; p->data = val; p++; } } -static int sdhci_cdns_phy_init(struct sdhci_cdns_priv *priv) +static int sdhci_cdns4_phy_init(struct sdhci_cdns_priv *priv) { + struct sdhci_cdns4_phy *phy = priv->phy; int ret, i; - for (i = 0; i < priv->nr_phy_params; i++) { - ret = sdhci_cdns_write_phy_reg(priv, priv->phy_params[i].addr, - priv->phy_params[i].data); + for (i = 0; i < phy->nr_phy_params; i++) { + ret = sdhci_cdns4_write_phy_reg(priv, phy->phy_params[i].addr, + phy->phy_params[i].data); if (ret) return ret; } @@ -201,13 +189,6 @@ static int sdhci_cdns_phy_init(struct sdhci_cdns_priv *priv) return 0; } -static void *sdhci_cdns_priv(struct sdhci_host *host) -{ - struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); - - return sdhci_pltfm_priv(pltfm_host); -} - static unsigned int sdhci_cdns_get_timeout_clock(struct sdhci_host *host) { /* @@ -217,6 +198,23 @@ static unsigned int sdhci_cdns_get_timeout_clock(struct sdhci_host *host) return host->max_clk; } +static int sdhci_cdns_set_dma_mask(struct sdhci_host *host) +{ + const struct sdhci_cdns_drv_data *data; + struct device *dev = mmc_dev(host->mmc); + int ret; + + data = of_device_get_match_data(dev); + if (!data || !data->dma_mask) + return 0; + + ret = dma_set_mask_and_coherent(dev, data->dma_mask); + if (ret) + return dev_err_probe(dev, ret, "failed to set DMA mask\n"); + + return 0; +} + static void sdhci_cdns_set_emmc_mode(struct sdhci_cdns_priv *priv, u32 mode) { u32 tmp; @@ -243,6 +241,9 @@ static int sdhci_cdns_set_tune_val(struct sdhci_host *host, unsigned int val) u32 tmp; int i, ret; + if (host->version >= SDHCI_SPEC_420) + return sdhci_cdns6_set_tune_val(host, val); + if (WARN_ON(!FIELD_FIT(SDHCI_CDNS_HRS06_TUNE, val))) return -EINVAL; @@ -323,8 +324,10 @@ static int sdhci_cdns_execute_tuning(struct sdhci_host *host, u32 opcode) * The delay is set by probe, based on the DT properties. */ if (host->timing != MMC_TIMING_MMC_HS200 && - host->timing != MMC_TIMING_UHS_SDR104) + host->timing != MMC_TIMING_UHS_SDR104) { + dev_dbg(mmc_dev(host->mmc), "Tuning skipped (timing: %d)\n", host->timing); return 0; + } for (i = 0; i < SDHCI_CDNS_MAX_TUNING_LOOP; i++) { if (sdhci_cdns_set_tune_val(host, i) || @@ -348,6 +351,10 @@ static int sdhci_cdns_execute_tuning(struct sdhci_host *host, u32 opcode) if (ret) return ret; + /* Block gap tuning is only required for SD4HC, not for SD6HC */ + if (host->version >= SDHCI_SPEC_420) + return 0; + return sdhci_cdns_tune_blkgap(host->mmc); } @@ -383,6 +390,10 @@ static void sdhci_cdns_set_uhs_signaling(struct sdhci_host *host, /* For SD, fall back to the default handler */ if (mode == SDHCI_CDNS_HRS06_MODE_SD) sdhci_set_uhs_signaling(host, timing); + + /* For host controller V6, set SDHCI and PHY registers for UHS signaling */ + if (host->version >= SDHCI_SPEC_420) + sdhci_cdns6_set_uhs_signaling(host, timing); } /* Elba control register bits [6:3] are byte-lane enables */ @@ -470,7 +481,49 @@ static int elba_drv_init(struct platform_device *pdev) return 0; } -static const struct sdhci_ops sdhci_cdns_ops = { +static const struct reset_control_bulk_data sdhci_cdns6_agilex5_reset_ids[] = { + { .id = "sdhc-reset" }, + { .id = "combophy" }, + { .id = "sdmmc-ocp" }, +}; + +static int sdhci_cdns6_agilex5_init(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct reset_control_bulk_data *resets; + int ret; + + resets = devm_kmemdup(dev, sdhci_cdns6_agilex5_reset_ids, + sizeof(sdhci_cdns6_agilex5_reset_ids), GFP_KERNEL); + if (!resets) + return -ENOMEM; + + /* + * Assert SDHCI, SoftPHY (combophy), and SDMMC OCP/AXI resets together + * so their active periods overlap before all domains are released. + * SoftPHY is shared with NAND, but only one of SDMMC + * or NAND is enabled on a given board. + */ + ret = devm_reset_control_bulk_get_exclusive(dev, ARRAY_SIZE(sdhci_cdns6_agilex5_reset_ids), + resets); + if (ret) + return dev_err_probe(dev, ret, "failed to get resets\n"); + + ret = reset_control_bulk_assert(ARRAY_SIZE(sdhci_cdns6_agilex5_reset_ids), resets); + if (ret) + return dev_err_probe(dev, ret, "failed to assert resets\n"); + + /* Hold resets asserted long enough for all clock domains to capture. */ + usleep_range(10, 20); + + ret = reset_control_bulk_deassert(ARRAY_SIZE(sdhci_cdns6_agilex5_reset_ids), resets); + if (ret) + return dev_err_probe(dev, ret, "failed to deassert resets\n"); + + return 0; +} + +static const struct sdhci_ops sdhci_cdns4_ops = { .set_clock = sdhci_set_clock, .get_timeout_clock = sdhci_cdns_get_timeout_clock, .set_bus_width = sdhci_set_bus_width, @@ -479,9 +532,31 @@ static const struct sdhci_ops sdhci_cdns_ops = { .set_uhs_signaling = sdhci_cdns_set_uhs_signaling, }; +static const struct sdhci_ops sdhci_cdns6_ops = { + .set_clock = sdhci_cdns6_set_clock, + .get_timeout_clock = sdhci_cdns_get_timeout_clock, + .set_bus_width = sdhci_set_bus_width, + .reset = sdhci_reset, + .platform_execute_tuning = sdhci_cdns_execute_tuning, + .set_uhs_signaling = sdhci_cdns_set_uhs_signaling, + .hw_reset = sdhci_cdns6_hw_reset, +}; + +static const struct sdhci_ops sdhci_cdns6_agilex5_ops = { + .set_clock = sdhci_cdns6_set_clock, + .get_max_clock = sdhci_pltfm_clk_get_max_clock, + .get_timeout_clock = sdhci_cdns_get_timeout_clock, + .set_bus_width = sdhci_set_bus_width, + .reset = sdhci_reset, + .platform_execute_tuning = sdhci_cdns_execute_tuning, + .set_uhs_signaling = sdhci_cdns_set_uhs_signaling, + .hw_reset = sdhci_cdns6_hw_reset, + .set_dma_mask = sdhci_cdns_set_dma_mask, +}; + static const struct sdhci_cdns_drv_data sdhci_cdns_uniphier_drv_data = { .pltfm_data = { - .ops = &sdhci_cdns_ops, + .ops = &sdhci_cdns4_ops, .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, }, }; @@ -495,14 +570,32 @@ static const struct sdhci_cdns_drv_data sdhci_elba_drv_data = { static const struct sdhci_cdns_drv_data sdhci_eyeq_drv_data = { .pltfm_data = { - .ops = &sdhci_cdns_ops, + .ops = &sdhci_cdns4_ops, .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, }, }; -static const struct sdhci_cdns_drv_data sdhci_cdns_drv_data = { +static const struct sdhci_cdns_drv_data sdhci_cdns4_drv_data = { .pltfm_data = { - .ops = &sdhci_cdns_ops, + .ops = &sdhci_cdns4_ops, + }, +}; + +static const struct sdhci_cdns_drv_data sdhci_cdns6_agilex5_drv_data = { + .init = sdhci_cdns6_agilex5_init, + .pltfm_data = { + .ops = &sdhci_cdns6_agilex5_ops, + .quirks = SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN | + SDHCI_QUIRK_MULTIBLOCK_READ_ACMD12, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | + SDHCI_QUIRK2_ACMD23_BROKEN, + }, + .dma_mask = DMA_BIT_MASK(40), +}; + +static const struct sdhci_cdns_drv_data sdhci_cdns6_drv_data = { + .pltfm_data = { + .ops = &sdhci_cdns6_ops, }, }; @@ -524,6 +617,14 @@ static void sdhci_cdns_hs400_enhanced_strobe(struct mmc_host *mmc, if (mode == SDHCI_CDNS_HRS06_MODE_MMC_HS400ES && !ios->enhanced_strobe) sdhci_cdns_set_emmc_mode(priv, SDHCI_CDNS_HRS06_MODE_MMC_HS400); + + /* + * Reprogram the SD6HC PHY for the current timing. Enhanced strobe + * affects PHY delays, and this callback may run with either HS400 + * (enabling/disabling ES) or Legacy (initial bus state). + */ + if (host->version >= SDHCI_SPEC_420) + sdhci_cdns6_set_uhs_signaling(host, ios->timing); } static void sdhci_cdns_mmc_hw_reset(struct mmc_host *mmc) @@ -542,6 +643,24 @@ static void sdhci_cdns_mmc_hw_reset(struct mmc_host *mmc) usleep_range(300, 1000); } +static int sdhci_cdns4_phy_probe(struct platform_device *pdev, struct sdhci_cdns_priv *priv) +{ + struct device *dev = &pdev->dev; + struct sdhci_cdns4_phy *phy; + unsigned int nr_phy_params; + + nr_phy_params = sdhci_cdns4_phy_param_count(dev->of_node); + phy = devm_kzalloc(dev, struct_size(phy, phy_params, nr_phy_params), GFP_KERNEL); + if (!phy) + return -ENOMEM; + + phy->nr_phy_params = nr_phy_params; + sdhci_cdns4_phy_param_parse(dev->of_node, phy); + priv->phy = phy; + + return sdhci_cdns4_phy_init(priv); +} + static int sdhci_cdns_probe(struct platform_device *pdev) { struct sdhci_host *host; @@ -549,22 +668,30 @@ static int sdhci_cdns_probe(struct platform_device *pdev) struct sdhci_pltfm_host *pltfm_host; struct sdhci_cdns_priv *priv; struct clk *clk; - unsigned int nr_phy_params; + struct clk *biu_clk; int ret; struct device *dev = &pdev->dev; static const u16 version = SDHCI_SPEC_400 << SDHCI_SPEC_VER_SHIFT; - clk = devm_clk_get_enabled(dev, NULL); - if (IS_ERR(clk)) - return PTR_ERR(clk); + if (of_device_is_compatible(dev->of_node, "cdns,sd6hc")) { + clk = devm_clk_get_enabled(dev, "ciu"); + if (IS_ERR(clk)) + return dev_err_probe(dev, PTR_ERR(clk), "failed to enable ciu clock\n"); + + biu_clk = devm_clk_get_enabled(dev, "biu"); + if (IS_ERR(biu_clk)) + return dev_err_probe(dev, PTR_ERR(biu_clk), "failed to enable biu clock\n"); + } else { + clk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(clk)) + return PTR_ERR(clk); + } data = of_device_get_match_data(dev); if (!data) - data = &sdhci_cdns_drv_data; + return dev_err_probe(dev, -EINVAL, "missing platform driver data\n"); - nr_phy_params = sdhci_cdns_phy_param_count(dev->of_node); - host = sdhci_pltfm_init(pdev, &data->pltfm_data, - struct_size(priv, phy_params, nr_phy_params)); + host = sdhci_pltfm_init(pdev, &data->pltfm_data, sizeof(*priv)); if (IS_ERR(host)) return PTR_ERR(host); @@ -572,7 +699,6 @@ static int sdhci_cdns_probe(struct platform_device *pdev) pltfm_host->clk = clk; priv = sdhci_pltfm_priv(pltfm_host); - priv->nr_phy_params = nr_phy_params; priv->hrs_addr = host->ioaddr; priv->enhanced_strobe = false; priv->priv_writel = cdns_writel; @@ -585,32 +711,46 @@ static int sdhci_cdns_probe(struct platform_device *pdev) return ret; } sdhci_enable_v4_mode(host); - __sdhci_read_caps(host, &version, NULL, NULL); - sdhci_get_of_property(pdev); ret = mmc_of_parse(host->mmc); if (ret) return ret; - sdhci_cdns_phy_param_parse(dev->of_node, priv); + /* + * For SD4HC, read capabilities with fixed version override and set up + * the optional eMMC card RST_n reset control. + * For SD6HC, sdhci_add_host() will automatically read capabilities + * and version from the host controller registers. + */ + if (of_device_is_compatible(dev->of_node, "cdns,sd4hc")) { + __sdhci_read_caps(host, &version, NULL, NULL); + ret = sdhci_cdns4_phy_probe(pdev, priv); + if (ret) + return ret; - ret = sdhci_cdns_phy_init(priv); - if (ret) - return ret; - - if (host->mmc->caps & MMC_CAP_HW_RESET) { - priv->rst_hw = devm_reset_control_get_optional_exclusive(dev, NULL); - if (IS_ERR(priv->rst_hw)) - return dev_err_probe(mmc_dev(host->mmc), PTR_ERR(priv->rst_hw), - "reset controller error\n"); - if (priv->rst_hw) - host->mmc_host_ops.card_hw_reset = sdhci_cdns_mmc_hw_reset; + if (host->mmc->caps & MMC_CAP_HW_RESET) { + priv->rst_hw = devm_reset_control_get_optional_exclusive(dev, NULL); + if (IS_ERR(priv->rst_hw)) + return dev_err_probe(mmc_dev(host->mmc), PTR_ERR(priv->rst_hw), + "reset controller error\n"); + if (priv->rst_hw) + host->mmc_host_ops.card_hw_reset = sdhci_cdns_mmc_hw_reset; + } + } else { + ret = sdhci_cdns6_phy_probe(pdev, priv); + if (ret) + return ret; } return sdhci_add_host(host); } +/* + * Only the CIU clock is gated on suspend. The SD6HC "biu" clock is not + * toggled here as it may be a shared bus clock; a dedicated biu clock + * would need explicit PM gating added here. + */ static int sdhci_cdns_resume(struct device *dev) { struct sdhci_host *host = dev_get_drvdata(dev); @@ -622,7 +762,11 @@ static int sdhci_cdns_resume(struct device *dev) if (ret) return ret; - ret = sdhci_cdns_phy_init(priv); + if (host->version >= SDHCI_SPEC_420) + ret = sdhci_cdns6_phy_init(priv); + else + ret = sdhci_cdns4_phy_init(priv); + if (ret) goto disable_clk; @@ -653,7 +797,18 @@ static const struct of_device_id sdhci_cdns_match[] = { .compatible = "mobileye,eyeq-sd4hc", .data = &sdhci_eyeq_drv_data, }, - { .compatible = "cdns,sd4hc" }, + { + .compatible = "cdns,sd4hc", + .data = &sdhci_cdns4_drv_data, + }, + { + .compatible = "altr,agilex5-sd6hc", + .data = &sdhci_cdns6_agilex5_drv_data, + }, + { + .compatible = "cdns,sd6hc", + .data = &sdhci_cdns6_drv_data, + }, { /* sentinel */ } }; MODULE_DEVICE_TABLE(of, sdhci_cdns_match);
diff --git a/drivers/mmc/host/sdhci-cadence-phy-v6.c b/drivers/mmc/host/sdhci-cadence-phy-v6.c new file mode 100644 index 0000000..22d56bb --- /dev/null +++ b/drivers/mmc/host/sdhci-cadence-phy-v6.c
@@ -0,0 +1,975 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * PHY and host controller support for Cadence SD6HC SDHCI + * + * This file provides support for Cadence's sixth-generation SDHCI controller (SD6HC). + * Implements PHY initialization, DLL management, per-speed-mode timing calculations, + * and host controller register programming for the SD6HC integrated combo-PHY. + * + * Copyright (C) 2026 Altera Corporation + * Author: Tanmay Kathpalia <tanmay.kathpalia@altera.com> + */ + +#include <linux/bitfield.h> +#include <linux/bits.h> +#include <linux/iopoll.h> +#include <linux/of.h> + +#include "sdhci-cadence.h" + +/* IO Delay Information */ +#define SDHCI_CDNS_HRS07 0x1c +#define SDHCI_CDNS_HRS07_RW_COMPENSATE GENMASK(20, 16) +#define SDHCI_CDNS_HRS07_IDELAY_VAL GENMASK(4, 0) + +/* PHY Control and Status */ +#define SDHCI_CDNS_HRS09 0x24 +#define SDHCI_CDNS_HRS09_RDDATA_EN BIT(16) +#define SDHCI_CDNS_HRS09_RDCMD_EN BIT(15) +#define SDHCI_CDNS_HRS09_EXTENDED_WR_MODE BIT(3) +#define SDHCI_CDNS_HRS09_EXTENDED_RD_MODE BIT(2) +#define SDHCI_CDNS_HRS09_PHY_INIT_COMPLETE BIT(1) +#define SDHCI_CDNS_HRS09_PHY_SW_RESET BIT(0) + +/* SDCLK start point adjustment */ +#define SDHCI_CDNS_HRS10 0x28 +#define SDHCI_CDNS_HRS10_HCSDCLKADJ GENMASK(19, 16) + +/* eMMC Control */ +#define SDHCI_CDNS_HRS11 0x2c +#define SDHCI_CDNS_HRS11_EMMC_RST BIT(0) /* eMMC reset */ + +/* CMD/DAT output delay */ +#define SDHCI_CDNS_HRS16 0x40 +#define SDHCI_CDNS_HRS16_WRDATA1_SDCLK_DLY GENMASK(31, 28) +#define SDHCI_CDNS_HRS16_WRDATA0_SDCLK_DLY GENMASK(27, 24) +#define SDHCI_CDNS_HRS16_WRCMD1_SDCLK_DLY GENMASK(23, 20) +#define SDHCI_CDNS_HRS16_WRCMD0_SDCLK_DLY GENMASK(19, 16) +#define SDHCI_CDNS_HRS16_WRDATA1_DLY GENMASK(15, 12) +#define SDHCI_CDNS_HRS16_WRDATA0_DLY GENMASK(11, 8) +#define SDHCI_CDNS_HRS16_WRCMD1_DLY GENMASK(7, 4) +#define SDHCI_CDNS_HRS16_WRCMD0_DLY GENMASK(3, 0) + +/* PHY Special Function Registers */ +/* DQ timing */ +#define SDHCI_CDNS6_PHY_DQ_TIMING_REG 0x2000 +#define SDHCI_CDNS6_PHY_DQ_TIMING_IO_MASK_ALWAYS_ON BIT(31) +#define SDHCI_CDNS6_PHY_DQ_TIMING_IO_MASK_END GENMASK(29, 27) +#define SDHCI_CDNS6_PHY_DQ_TIMING_IO_MASK_START GENMASK(26, 24) +#define SDHCI_CDNS6_PHY_DQ_TIMING_DATA_SELECT_OE_END GENMASK(2, 0) + +/* DQS timing */ +#define SDHCI_CDNS6_PHY_DQS_TIMING_REG 0x2004 +#define SDHCI_CDNS6_PHY_DQS_TIMING_USE_EXT_LPBK_DQS BIT(22) +#define SDHCI_CDNS6_PHY_DQS_TIMING_USE_LPBK_DQS BIT(21) +#define SDHCI_CDNS6_PHY_DQS_TIMING_USE_PHONY_DQS BIT(20) +#define SDHCI_CDNS6_PHY_DQS_TIMING_USE_PHONY_DQS_CMD BIT(19) + +/* Gate and loopback control */ +#define SDHCI_CDNS6_PHY_GATE_LPBK_CTRL_REG 0x2008 +#define SDHCI_CDNS6_PHY_GATE_LPBK_CTRL_SYNC_METHOD BIT(31) +#define SDHCI_CDNS6_PHY_GATE_LPBK_CTRL_RD_DEL_SEL GENMASK(24, 19) +#define SDHCI_CDNS6_PHY_GATE_LPBK_CTRL_UNDERRUN_SUPPRESS BIT(18) +#define SDHCI_CDNS6_PHY_GATE_LPBK_CTRL_GATE_CFG_ALWAYS_ON BIT(6) + +/* Master DLL logic */ +#define SDHCI_CDNS6_PHY_DLL_MASTER_CTRL_REG 0x200c +#define SDHCI_CDNS6_PHY_DLL_MASTER_CTRL_BYPASS_MODE BIT(23) +#define SDHCI_CDNS6_PHY_DLL_MASTER_CTRL_PHASE_DETECT_SEL GENMASK(22, 20) +#define SDHCI_CDNS6_PHY_DLL_MASTER_CTRL_DLL_LOCK_NUM GENMASK(18, 16) +#define SDHCI_CDNS6_PHY_DLL_MASTER_CTRL_DLL_START_POINT GENMASK(7, 0) + +/* Slave DLL logic */ +#define SDHCI_CDNS6_PHY_DLL_SLAVE_CTRL_REG 0x2010 +#define SDHCI_CDNS6_PHY_DLL_SLAVE_CTRL_READ_DQS_CMD_DELAY GENMASK(31, 24) +#define SDHCI_CDNS6_PHY_DLL_SLAVE_CTRL_CLK_WRDQS_DELAY GENMASK(23, 16) +#define SDHCI_CDNS6_PHY_DLL_SLAVE_CTRL_CLK_WR_DELAY GENMASK(15, 8) +#define SDHCI_CDNS6_PHY_DLL_SLAVE_CTRL_READ_DQS_DELAY GENMASK(7, 0) + +/* Global control settings */ +#define SDHCI_CDNS6_PHY_CTRL_REG 0x2080 +#define SDHCI_CDNS6_PHY_CTRL_PHONY_DQS_TIMING GENMASK(9, 4) + +/* Default PHY settings */ +#define SDHCI_CDNS6_PHY_DEFAULT_IOCELL_DELAY 2500 +#define SDHCI_CDNS6_PHY_DEFAULT_DELAY_ELEMENT 24 +#define SDHCI_CDNS6_PHY_DEFAULT_RD_DEL_SEL 52 +#define SDHCI_CDNS6_PHY_DEFAULT_DLL_START 4 +#define SDHCI_CDNS6_PHY_DEFAULT_PHASE_DETECT_SEL 2 +#define SDHCI_CDNS6_PHY_DEFAULT_DLL_LOCK_NUM 0 +#define SDHCI_CDNS6_PHY_DEFAULT_DATA_SELECT_OE_END 1 + +/* Scale tuning tap (0..39) to 8-bit PHY DLL delay field (0..255) */ +#define SDHCI_CDNS6_PHY_DLL_FIELD_SIZE 256 + +struct sdhci_cdns6_phy { + /* + * Mode-specific timing constraints (in picoseconds) + * These define valid output windows per SD/eMMC spec + */ + u32 t_cmd_output_min; + u32 t_cmd_output_max; + u32 t_dat_output_min; + u32 t_dat_output_max; + + /* + * PHY delay configuration (in picoseconds) + * Derived from clock period and board-level IO cell delays + */ + u32 phy_sdclk_delay; + u32 phy_cmd_o_delay; + u32 phy_dat_o_delay; + u32 iocell_input_delay; + u32 iocell_output_delay; + /* Configured delay element (ps); preserved across clock changes */ + u32 delay_element_org; + /* Active delay element (ps); doubled when one SDMCLK requires > 256 steps */ + u32 delay_element; + + /* PHY_DLL_SLAVE_CTRL register fields */ + u8 cp_read_dqs_cmd_delay; /* bits [31:24] */ + u8 cp_clk_wrdqs_delay; /* bits [23:16] */ + u8 cp_clk_wr_delay; /* bits [15:8] */ + u8 cp_read_dqs_delay; /* bits [7:0] */ + + /* PHY_DLL_MASTER_CTRL register fields */ + bool cp_dll_bypass_mode; /* bit [23] */ + + /* PHY_DQ_TIMING register fields */ + u8 cp_io_mask_end; /* bits [29:27] */ + u8 cp_io_mask_start; /* bits [26:24] */ + + /* PHY_DQS_TIMING register fields */ + bool cp_use_phony_dqs; /* bit [20] */ + bool cp_use_phony_dqs_cmd; /* bit [19] */ + + /* HRS07 register - IO delay Information */ + u8 sdhc_rw_compensate; /* bits [20:16] */ + u8 sdhc_idelay_val; /* bits [4:0] */ + + /* HRS09 register - PHY control and Status */ + bool sdhc_extended_wr_mode; /* bit [3] */ + bool sdhc_extended_rd_mode; /* bit [2] */ + + /* HRS10 register - SDCLK start point adjustment */ + u8 sdhc_hcsdclkadj; /* bits [19:16] */ + + /* HRS16 register fields - CMD/DAT output delay control */ + u8 sdhc_wrdata1_sdclk_dly; /* bits [31:28] */ + u8 sdhc_wrdata0_sdclk_dly; /* bits [27:24] */ + u8 sdhc_wrcmd1_sdclk_dly; /* bits [23:20] */ + u8 sdhc_wrcmd0_sdclk_dly; /* bits [19:16] */ + u8 sdhc_wrdata1_dly; /* bits [15:12] */ + u8 sdhc_wrdata0_dly; /* bits [11:8] */ + u8 sdhc_wrcmd1_dly; /* bits [7:4] */ + u8 sdhc_wrcmd0_dly; /* bits [3:0] */ + + /* DLL calculation intermediate values, used during PHY timing calculations */ + u32 t_sdmclk_calc; /* DLL-quantized SDMCLK period */ + u32 dll_max_value; /* DLL delay field ceiling */ + + /* Tuning value for HS200/HS400 modes */ + u8 hs200_tune_val; + + /* Clock periods (in picoseconds) */ + u32 t_sdmclk; /* Master clock period */ + u32 t_sdclk; /* SD card clock period */ + + /* Current operating state */ + bool strobe_cmd; /* Enhanced strobe for CMD line */ + unsigned int mode; /* Current MMC_TIMING_* mode */ +}; + +/** + * init_ds() - Initialize PHY timing for Default Speed mode (25 MHz). + * @phy: Pointer to SD6HC PHY state. + * @t_sdclk: SD clock period in picoseconds. + */ +static void init_ds(struct sdhci_cdns6_phy *phy, u32 t_sdclk) +{ + phy->t_cmd_output_min = 5000; + phy->t_cmd_output_max = t_sdclk - 5000; + phy->t_dat_output_min = 5000; + phy->t_dat_output_max = t_sdclk - 5000; +} + +/** + * init_hs() - Initialize PHY timing for High Speed mode (50 MHz). + * @phy: Pointer to SD6HC PHY state. + * @t_sdclk: SD clock period in picoseconds. + */ +static void init_hs(struct sdhci_cdns6_phy *phy, u32 t_sdclk) +{ + phy->t_cmd_output_min = 2000; + phy->t_cmd_output_max = t_sdclk - 6000; + phy->t_dat_output_min = 2000; + phy->t_dat_output_max = t_sdclk - 6000; +} + +/** + * init_uhs_sdr12() - Initialize PHY timing for UHS SDR12 mode (25 MHz). + * @phy: Pointer to SD6HC PHY state. + * @t_sdclk: SD clock period in picoseconds. + */ +static void init_uhs_sdr12(struct sdhci_cdns6_phy *phy, u32 t_sdclk) +{ + phy->t_cmd_output_min = 800; + phy->t_cmd_output_max = t_sdclk - 3000; + phy->t_dat_output_min = 800; + phy->t_dat_output_max = t_sdclk - 3000; +} + +/** + * init_uhs_sdr25() - Initialize PHY timing for UHS SDR25 mode (50 MHz). + * @phy: Pointer to SD6HC PHY state. + * @t_sdclk: SD clock period in picoseconds. + */ +static void init_uhs_sdr25(struct sdhci_cdns6_phy *phy, u32 t_sdclk) +{ + phy->t_cmd_output_min = 800; + phy->t_cmd_output_max = t_sdclk - 3000; + phy->t_dat_output_min = 800; + phy->t_dat_output_max = t_sdclk - 3000; +} + +/** + * init_uhs_sdr50() - Initialize PHY timing for UHS SDR50 mode (100 MHz). + * @phy: Pointer to SD6HC PHY state. + * @t_sdclk: SD clock period in picoseconds. + */ +static void init_uhs_sdr50(struct sdhci_cdns6_phy *phy, u32 t_sdclk) +{ + phy->t_cmd_output_min = 800; + phy->t_cmd_output_max = t_sdclk - 3000; + phy->t_dat_output_min = 800; + phy->t_dat_output_max = t_sdclk - 3000; +} + +/** + * init_uhs_sdr104() - Initialize PHY timing for UHS SDR104 mode (200 MHz). + * @phy: Pointer to SD6HC PHY state. + * @t_sdclk: SD clock period in picoseconds. + */ +static void init_uhs_sdr104(struct sdhci_cdns6_phy *phy, u32 t_sdclk) +{ + phy->t_cmd_output_min = 800; + phy->t_cmd_output_max = t_sdclk - 1400; + phy->t_dat_output_min = 800; + phy->t_dat_output_max = t_sdclk - 1400; +} + +/** + * init_uhs_ddr50() - Initialize PHY timing for UHS DDR50 mode (50 MHz). + * @phy: Pointer to SD6HC PHY state. + * @t_sdclk: SD clock period in picoseconds. + */ +static void init_uhs_ddr50(struct sdhci_cdns6_phy *phy, u32 t_sdclk) +{ + phy->t_cmd_output_min = 800; + phy->t_cmd_output_max = t_sdclk - 3000; + phy->t_dat_output_min = 800; + phy->t_dat_output_max = t_sdclk - 3000; +} + +/** + * init_emmc_sdr() - Initialize PHY timing for eMMC legacy/SDR mode. + * @phy: Pointer to SD6HC PHY state. + * @t_sdclk: SD clock period in picoseconds. + */ +static void init_emmc_sdr(struct sdhci_cdns6_phy *phy, u32 t_sdclk) +{ + phy->t_cmd_output_min = 3000; + phy->t_cmd_output_max = t_sdclk - 3000; + phy->t_dat_output_min = 3000; + phy->t_dat_output_max = t_sdclk - 3000; +} + +/** + * init_emmc_ddr() - Initialize PHY timing for eMMC DDR52 mode. + * @phy: Pointer to SD6HC PHY state. + * @t_sdclk: SD clock period in picoseconds. + */ +static void init_emmc_ddr(struct sdhci_cdns6_phy *phy, u32 t_sdclk) +{ + phy->t_cmd_output_min = 3000; + phy->t_cmd_output_max = t_sdclk - 3000; + phy->t_dat_output_min = 2500; + phy->t_dat_output_max = t_sdclk - 2500; +} + +/** + * init_emmc_hs200() - Initialize PHY timing for eMMC HS200 mode (200 MHz). + * @phy: Pointer to SD6HC PHY state. + * @t_sdclk: SD clock period in picoseconds. + */ +static void init_emmc_hs200(struct sdhci_cdns6_phy *phy, u32 t_sdclk) +{ + phy->t_cmd_output_min = 800; + phy->t_cmd_output_max = t_sdclk - 1400; + phy->t_dat_output_min = 800; + phy->t_dat_output_max = t_sdclk - 1400; +} + +/** + * init_emmc_hs400() - Initialize PHY timing for eMMC HS400/HS400ES mode. + * @phy: Pointer to SD6HC PHY state. + * @t_sdclk: SD clock period in picoseconds. + */ +static void init_emmc_hs400(struct sdhci_cdns6_phy *phy, u32 t_sdclk) +{ + phy->t_cmd_output_min = 800; + phy->t_cmd_output_max = t_sdclk - 1400; + phy->t_dat_output_min = 400; + phy->t_dat_output_max = t_sdclk - 400; +} + +/* + * init_timings - PHY timing initializers indexed by MMC_TIMING_* value. + * + * Each entry corresponds to a MMC_TIMING_* constant and sets the appropriate cmd/dat + * output timing windows in the PHY state struct. + */ +static void (* const init_timings[])(struct sdhci_cdns6_phy *, u32) = { + [MMC_TIMING_LEGACY] = init_ds, + [MMC_TIMING_MMC_HS] = init_emmc_sdr, + [MMC_TIMING_SD_HS] = init_hs, + [MMC_TIMING_UHS_SDR12] = init_uhs_sdr12, + [MMC_TIMING_UHS_SDR25] = init_uhs_sdr25, + [MMC_TIMING_UHS_SDR50] = init_uhs_sdr50, + [MMC_TIMING_UHS_SDR104] = init_uhs_sdr104, + [MMC_TIMING_UHS_DDR50] = init_uhs_ddr50, + [MMC_TIMING_MMC_DDR52] = init_emmc_ddr, + [MMC_TIMING_MMC_HS200] = init_emmc_hs200, + [MMC_TIMING_MMC_HS400] = init_emmc_hs400, +}; + +static unsigned int sdhci_cdns6_read_phy_reg(struct sdhci_cdns_priv *priv, const u32 address) +{ + writel(address, priv->hrs_addr + SDHCI_CDNS_HRS04); + return readl(priv->hrs_addr + SDHCI_CDNS_HRS05); +} + +static void sdhci_cdns6_write_phy_reg(struct sdhci_cdns_priv *priv, const u32 address, + const u32 value) +{ + writel(address, priv->hrs_addr + SDHCI_CDNS_HRS04); + writel(value, priv->hrs_addr + SDHCI_CDNS_HRS05); +} + +static int sdhci_cdns6_phy_lock_dll(struct sdhci_cdns6_phy *phy) +{ + u32 delay_element = phy->delay_element_org; + u32 delay_elements_in_sdmclk; + + delay_elements_in_sdmclk = DIV_ROUND_UP(phy->t_sdmclk, delay_element); + if (delay_elements_in_sdmclk > 256) { + delay_element *= 2; + delay_elements_in_sdmclk = DIV_ROUND_UP(phy->t_sdmclk, delay_element); + + if (delay_elements_in_sdmclk > 256) + return -EINVAL; + + phy->dll_max_value = 127; + } else { + phy->dll_max_value = 255; + } + + phy->t_sdmclk_calc = delay_element * delay_elements_in_sdmclk; + phy->delay_element = delay_element; + phy->cp_dll_bypass_mode = false; + + return 0; +} + +static void sdhci_cdns6_phy_dll_bypass(struct sdhci_cdns6_phy *phy) +{ + phy->dll_max_value = 255; + phy->cp_dll_bypass_mode = true; +} + +static void sdhci_cdns6_phy_configure_dll(struct sdhci_cdns6_phy *phy) +{ + if (!phy->sdhc_extended_wr_mode) { + if (sdhci_cdns6_phy_lock_dll(phy) == 0) + return; + } + sdhci_cdns6_phy_dll_bypass(phy); +} + +static void sdhci_cdns6_phy_calc_out(struct sdhci_cdns6_phy *phy, bool cmd_not_dat) +{ + u32 wr0_dly = 0, wr1_dly = 0, output_min, output_max, phy_o_delay, + clk_wr_delay = 0, wr0_sdclk_dly = 0, wr1_sdclk_dly = 0; + bool ddr = (phy->mode == MMC_TIMING_UHS_DDR50) || (phy->mode == MMC_TIMING_MMC_DDR52) || + (phy->mode == MMC_TIMING_MMC_HS400); + bool data_ddr = ddr && !cmd_not_dat; + int t; + + if (cmd_not_dat) { + output_min = phy->t_cmd_output_min; + output_max = phy->t_cmd_output_max; + phy_o_delay = phy->phy_cmd_o_delay; + } else { + output_min = phy->t_dat_output_min; + output_max = phy->t_dat_output_max; + phy_o_delay = phy->phy_dat_o_delay; + } + + if (data_ddr) { + wr0_sdclk_dly = 1; + wr1_sdclk_dly = 1; + } + + t = phy_o_delay - phy->phy_sdclk_delay - output_min; + if (t < 0 && phy->sdhc_extended_wr_mode) { + u32 n_half_cycle = DIV_ROUND_UP(-t * 2, phy->t_sdmclk); + + wr0_dly = (n_half_cycle + 1) / 2; + if (data_ddr) + wr1_dly = (n_half_cycle + 1) / 2; + else + wr1_dly = (n_half_cycle + 1) % 2 + wr0_dly - 1; + } + + if (!phy->sdhc_extended_wr_mode) { + u32 out_hold, out_setup, out_hold_margin; + u32 n; + + if (!data_ddr) + wr0_dly = 1; + + out_setup = output_max; + out_hold = output_min; + out_hold_margin = DIV_ROUND_UP(out_setup - out_hold, 4); + out_hold += out_hold_margin; + + if (!phy->cp_dll_bypass_mode) + n = DIV_ROUND_UP(256 * out_hold, phy->t_sdmclk_calc); + else + n = DIV_ROUND_UP(out_hold, phy->delay_element) - 1; + + if (n <= phy->dll_max_value) + clk_wr_delay = n; + else + clk_wr_delay = 255; + } else { + /* sdhc_extended_wr_mode set => PHY IO cell work in SDR mode */ + clk_wr_delay = 0; + } + + if (cmd_not_dat) { + phy->sdhc_wrcmd0_dly = wr0_dly; + phy->sdhc_wrcmd1_dly = wr1_dly; + phy->cp_clk_wrdqs_delay = clk_wr_delay; + phy->sdhc_wrcmd0_sdclk_dly = wr0_sdclk_dly; + phy->sdhc_wrcmd1_sdclk_dly = wr1_sdclk_dly; + } else { + phy->sdhc_wrdata0_dly = wr0_dly; + phy->sdhc_wrdata1_dly = wr1_dly; + phy->cp_clk_wr_delay = clk_wr_delay; + phy->sdhc_wrdata0_sdclk_dly = wr0_sdclk_dly; + phy->sdhc_wrdata1_sdclk_dly = wr1_sdclk_dly; + } +} + +static void sdhci_cdns6_phy_calc_cmd_out(struct sdhci_cdns6_phy *phy) +{ + sdhci_cdns6_phy_calc_out(phy, true); +} + +static void sdhci_cdns6_phy_calc_cmd_in(struct sdhci_cdns6_phy *phy) +{ + phy->cp_io_mask_end = ((phy->iocell_output_delay + phy->iocell_input_delay) * 2) / + phy->t_sdmclk; + + /* cp_io_mask_end is a 3-bit field, clamp to max value of 7 */ + phy->cp_io_mask_end = min_t(u8, phy->cp_io_mask_end, 7); + + if (phy->strobe_cmd && phy->cp_io_mask_end > 0) + phy->cp_io_mask_end--; + + if (phy->strobe_cmd) { + phy->cp_use_phony_dqs_cmd = false; + phy->cp_read_dqs_cmd_delay = 64; + } else { + phy->cp_use_phony_dqs_cmd = true; + phy->cp_read_dqs_cmd_delay = 0; + } + + if ((phy->mode == MMC_TIMING_MMC_HS400 && !phy->strobe_cmd) || + phy->mode == MMC_TIMING_MMC_HS200) + phy->cp_read_dqs_cmd_delay = phy->hs200_tune_val; +} + +static void sdhci_cdns6_phy_calc_dat_in(struct sdhci_cdns6_phy *phy) +{ + u32 hcsdclkadj = 0; + bool strobe_dat = (phy->mode == MMC_TIMING_MMC_HS400); + + if (strobe_dat) { + phy->cp_use_phony_dqs = false; + phy->cp_read_dqs_delay = 64; + } else { + phy->cp_use_phony_dqs = true; + phy->cp_read_dqs_delay = 0; + } + + if (phy->mode == MMC_TIMING_MMC_HS200) + phy->cp_read_dqs_delay = phy->hs200_tune_val; + + if (strobe_dat) { + /* dqs loopback input via IO cell */ + hcsdclkadj += phy->iocell_input_delay; + /* dfi_dqs_in: mem_dqs -> clean_dqs_mod; delay of hic_dll_dqs_nand2 */ + hcsdclkadj += phy->delay_element / 2; + /* delay line */ + hcsdclkadj += phy->t_sdclk / 2; + /* PHY FIFO write pointer */ + hcsdclkadj += phy->t_sdclk / 2 + phy->delay_element; + /* 1st synchronizer */ + hcsdclkadj += DIV_ROUND_UP(hcsdclkadj, phy->t_sdmclk) * phy->t_sdmclk - hcsdclkadj; + /* + * 2nd synchronizer + PHY FIFO read pointer + PHY rddata + * + PHY rddata registered, + FIFO 1st ciu_en + */ + hcsdclkadj += 5 * phy->t_sdmclk; + /* FIFO 2nd ciu_en */ + hcsdclkadj += phy->t_sdclk; + hcsdclkadj /= phy->t_sdclk; + } else { + u32 n; + + /* rebar PHY delay */ + hcsdclkadj += 2 * phy->t_sdmclk; + /* rebar output via IO cell */ + hcsdclkadj += phy->iocell_output_delay; + /* dqs loopback input via IO cell */ + hcsdclkadj += phy->iocell_input_delay; + /* dfi_dqs_in: mem_dqs -> clean_dqs_mod delay of hic_dll_dqs_nand2 */ + hcsdclkadj += phy->delay_element / 2; + /* dll: one delay element between SIGI_0 and SIGO_0 */ + hcsdclkadj += phy->delay_element; + /* dfi_dqs_in: mem_dqs_delayed -> clk_dqs delay of hic_dll_dqs_nand2 */ + hcsdclkadj += phy->delay_element / 2; + /* deskew DLL: clk_dqs -> clk_dqN: one delay element */ + hcsdclkadj += phy->delay_element; + + if (phy->t_sdclk == phy->t_sdmclk) + n = (hcsdclkadj - 2 * phy->t_sdmclk) / phy->t_sdclk; + else + n = hcsdclkadj / phy->t_sdclk; + + /* phase shift within one t_sdclk clock cycle caused by rebar - lbk dqs delay */ + hcsdclkadj = hcsdclkadj % phy->t_sdclk; + /* PHY FIFO write pointer */ + hcsdclkadj += phy->t_sdclk / 2; + /* 1st synchronizer */ + hcsdclkadj += DIV_ROUND_UP(hcsdclkadj, phy->t_sdmclk) * phy->t_sdmclk - hcsdclkadj; + /* + * 2nd synchronizer + PHY FIFO read pointer + PHY rddata + PHY rddata registered + */ + hcsdclkadj += 4 * phy->t_sdmclk; + + if ((phy->t_sdclk / phy->t_sdmclk) > 1) { + u32 tmp1, tmp2; + + tmp1 = hcsdclkadj; + tmp2 = (hcsdclkadj / phy->t_sdclk) * phy->t_sdclk + phy->t_sdclk - + phy->t_sdmclk; + if (tmp1 == tmp2) + tmp2 += phy->t_sdclk; + + /* FIFO aligns to clock cycle before ciu_en */ + hcsdclkadj += tmp2 - tmp1; + } + + /* FIFO 1st ciu_en */ + hcsdclkadj += phy->t_sdmclk; + /* FIFO 2nd ciu_en */ + hcsdclkadj += phy->t_sdclk; + hcsdclkadj /= phy->t_sdclk; + hcsdclkadj += n; + + if ((phy->t_sdclk / phy->t_sdmclk) >= 2) { + if (phy->mode == MMC_TIMING_UHS_DDR50 || phy->mode == MMC_TIMING_MMC_DDR52) + hcsdclkadj -= 2; + else + hcsdclkadj -= 1; + } else if ((phy->t_sdclk / phy->t_sdmclk) == 1) { + hcsdclkadj += 2; + } + + if (phy->mode == MMC_TIMING_UHS_SDR104 || phy->mode == MMC_TIMING_MMC_HS200) + hcsdclkadj -= 1; + } + + /* hcsdclkadj is a 4-bit field, clamp to max value of 15 */ + if (hcsdclkadj > 15) + hcsdclkadj = 15; + + phy->sdhc_hcsdclkadj = hcsdclkadj; +} + +static void sdhci_cdns6_phy_calc_dat_out(struct sdhci_cdns6_phy *phy) +{ + sdhci_cdns6_phy_calc_out(phy, false); +} + +static void sdhci_cdns6_phy_calc_io(struct sdhci_cdns6_phy *phy) +{ + u32 rw_compensate; + + rw_compensate = ((phy->iocell_input_delay + phy->iocell_output_delay) / phy->t_sdmclk) + + phy->sdhc_wrdata0_dly + 5 + 3; + + phy->sdhc_idelay_val = (2 * phy->iocell_input_delay) / phy->t_sdmclk; + + phy->cp_io_mask_start = 0; + if (phy->t_sdclk == phy->t_sdmclk && rw_compensate > 10) + phy->cp_io_mask_start = 2 * (rw_compensate - 10); + + if (phy->mode == MMC_TIMING_UHS_SDR104) + phy->cp_io_mask_start++; + + if (phy->t_sdclk == phy->t_sdmclk && phy->mode == MMC_TIMING_UHS_SDR50) + phy->cp_io_mask_start++; + + /* cp_io_mask_start is a 3-bit field, clamp to max value of 7 */ + phy->cp_io_mask_start = min_t(u8, phy->cp_io_mask_start, 7); + + phy->sdhc_rw_compensate = rw_compensate; +} + +static void sdhci_cdns6_phy_calc_settings(struct sdhci_cdns6_phy *phy) +{ + sdhci_cdns6_phy_calc_cmd_out(phy); + sdhci_cdns6_phy_calc_cmd_in(phy); + sdhci_cdns6_phy_calc_dat_out(phy); + sdhci_cdns6_phy_calc_dat_in(phy); + sdhci_cdns6_phy_calc_io(phy); +} + +static int sdhci_cdns6_dll_reset(struct sdhci_cdns_priv *priv, bool reset) +{ + u32 reg; + int ret = 0; + + reg = readl(priv->hrs_addr + SDHCI_CDNS_HRS09); + if (reset) + reg &= ~SDHCI_CDNS_HRS09_PHY_SW_RESET; + else + reg |= SDHCI_CDNS_HRS09_PHY_SW_RESET; + + writel(reg, priv->hrs_addr + SDHCI_CDNS_HRS09); + + /* After releasing PHY from reset, wait until PHY_INIT_COMPLETE is set within 3000us */ + if (!reset) { + ret = readl_poll_timeout(priv->hrs_addr + SDHCI_CDNS_HRS09, reg, (reg & + SDHCI_CDNS_HRS09_PHY_INIT_COMPLETE), 0, 3000); + } + + return ret; +} + +int sdhci_cdns6_phy_init(struct sdhci_cdns_priv *priv) +{ + struct sdhci_cdns6_phy *phy = priv->phy; + u32 reg; + int ret; + + sdhci_cdns6_dll_reset(priv, true); + + reg = sdhci_cdns6_read_phy_reg(priv, SDHCI_CDNS6_PHY_DQS_TIMING_REG); + reg &= ~SDHCI_CDNS6_PHY_DQS_TIMING_USE_PHONY_DQS; + reg &= ~SDHCI_CDNS6_PHY_DQS_TIMING_USE_PHONY_DQS_CMD; + reg |= SDHCI_CDNS6_PHY_DQS_TIMING_USE_EXT_LPBK_DQS; + reg |= SDHCI_CDNS6_PHY_DQS_TIMING_USE_LPBK_DQS; + reg |= FIELD_PREP(SDHCI_CDNS6_PHY_DQS_TIMING_USE_PHONY_DQS, phy->cp_use_phony_dqs); + reg |= FIELD_PREP(SDHCI_CDNS6_PHY_DQS_TIMING_USE_PHONY_DQS_CMD, phy->cp_use_phony_dqs_cmd); + sdhci_cdns6_write_phy_reg(priv, SDHCI_CDNS6_PHY_DQS_TIMING_REG, reg); + + reg = sdhci_cdns6_read_phy_reg(priv, SDHCI_CDNS6_PHY_GATE_LPBK_CTRL_REG); + reg &= ~SDHCI_CDNS6_PHY_GATE_LPBK_CTRL_RD_DEL_SEL; + reg |= SDHCI_CDNS6_PHY_GATE_LPBK_CTRL_UNDERRUN_SUPPRESS; + reg |= SDHCI_CDNS6_PHY_GATE_LPBK_CTRL_GATE_CFG_ALWAYS_ON; + reg |= SDHCI_CDNS6_PHY_GATE_LPBK_CTRL_SYNC_METHOD; + reg |= FIELD_PREP(SDHCI_CDNS6_PHY_GATE_LPBK_CTRL_RD_DEL_SEL, + SDHCI_CDNS6_PHY_DEFAULT_RD_DEL_SEL); + sdhci_cdns6_write_phy_reg(priv, SDHCI_CDNS6_PHY_GATE_LPBK_CTRL_REG, reg); + + reg = FIELD_PREP(SDHCI_CDNS6_PHY_DLL_MASTER_CTRL_BYPASS_MODE, phy->cp_dll_bypass_mode); + reg |= FIELD_PREP(SDHCI_CDNS6_PHY_DLL_MASTER_CTRL_PHASE_DETECT_SEL, + SDHCI_CDNS6_PHY_DEFAULT_PHASE_DETECT_SEL); + reg |= FIELD_PREP(SDHCI_CDNS6_PHY_DLL_MASTER_CTRL_DLL_LOCK_NUM, + SDHCI_CDNS6_PHY_DEFAULT_DLL_LOCK_NUM); + reg |= FIELD_PREP(SDHCI_CDNS6_PHY_DLL_MASTER_CTRL_DLL_START_POINT, + SDHCI_CDNS6_PHY_DEFAULT_DLL_START); + sdhci_cdns6_write_phy_reg(priv, SDHCI_CDNS6_PHY_DLL_MASTER_CTRL_REG, reg); + + reg = FIELD_PREP(SDHCI_CDNS6_PHY_DLL_SLAVE_CTRL_READ_DQS_CMD_DELAY, + phy->cp_read_dqs_cmd_delay); + reg |= FIELD_PREP(SDHCI_CDNS6_PHY_DLL_SLAVE_CTRL_CLK_WRDQS_DELAY, phy->cp_clk_wrdqs_delay); + reg |= FIELD_PREP(SDHCI_CDNS6_PHY_DLL_SLAVE_CTRL_CLK_WR_DELAY, phy->cp_clk_wr_delay); + reg |= FIELD_PREP(SDHCI_CDNS6_PHY_DLL_SLAVE_CTRL_READ_DQS_DELAY, phy->cp_read_dqs_delay); + sdhci_cdns6_write_phy_reg(priv, SDHCI_CDNS6_PHY_DLL_SLAVE_CTRL_REG, reg); + + reg = sdhci_cdns6_read_phy_reg(priv, SDHCI_CDNS6_PHY_CTRL_REG); + reg &= ~SDHCI_CDNS6_PHY_CTRL_PHONY_DQS_TIMING; + sdhci_cdns6_write_phy_reg(priv, SDHCI_CDNS6_PHY_CTRL_REG, reg); + + /* + * Ensure all preceding PHY register writes complete and reach the controller before + * releasing the PHY from reset. Without this, SDR104 has been observed to fail + * intermittently on some boards. + */ + wmb(); + + ret = sdhci_cdns6_dll_reset(priv, false); + if (ret) + return ret; + + reg = sdhci_cdns6_read_phy_reg(priv, SDHCI_CDNS6_PHY_DQ_TIMING_REG); + reg &= ~SDHCI_CDNS6_PHY_DQ_TIMING_IO_MASK_ALWAYS_ON; + reg &= ~SDHCI_CDNS6_PHY_DQ_TIMING_IO_MASK_END; + reg &= ~SDHCI_CDNS6_PHY_DQ_TIMING_IO_MASK_START; + reg &= ~SDHCI_CDNS6_PHY_DQ_TIMING_DATA_SELECT_OE_END; + reg |= FIELD_PREP(SDHCI_CDNS6_PHY_DQ_TIMING_IO_MASK_END, phy->cp_io_mask_end); + reg |= FIELD_PREP(SDHCI_CDNS6_PHY_DQ_TIMING_IO_MASK_START, phy->cp_io_mask_start); + reg |= FIELD_PREP(SDHCI_CDNS6_PHY_DQ_TIMING_DATA_SELECT_OE_END, + SDHCI_CDNS6_PHY_DEFAULT_DATA_SELECT_OE_END); + sdhci_cdns6_write_phy_reg(priv, SDHCI_CDNS6_PHY_DQ_TIMING_REG, reg); + + /* Ensure DQ timing programming is visible before HRS09 follow-up writes */ + wmb(); + + reg = readl(priv->hrs_addr + SDHCI_CDNS_HRS09); + if (phy->sdhc_extended_wr_mode) + reg |= SDHCI_CDNS_HRS09_EXTENDED_WR_MODE; + else + reg &= ~SDHCI_CDNS_HRS09_EXTENDED_WR_MODE; + + if (phy->sdhc_extended_rd_mode) + reg |= SDHCI_CDNS_HRS09_EXTENDED_RD_MODE; + else + reg &= ~SDHCI_CDNS_HRS09_EXTENDED_RD_MODE; + + reg |= SDHCI_CDNS_HRS09_RDDATA_EN; + reg |= SDHCI_CDNS_HRS09_RDCMD_EN; + writel(reg, priv->hrs_addr + SDHCI_CDNS_HRS09); + + reg = FIELD_PREP(SDHCI_CDNS_HRS10_HCSDCLKADJ, phy->sdhc_hcsdclkadj); + writel(reg, priv->hrs_addr + SDHCI_CDNS_HRS10); + + reg = FIELD_PREP(SDHCI_CDNS_HRS16_WRDATA1_SDCLK_DLY, phy->sdhc_wrdata1_sdclk_dly); + reg |= FIELD_PREP(SDHCI_CDNS_HRS16_WRDATA0_SDCLK_DLY, phy->sdhc_wrdata0_sdclk_dly); + reg |= FIELD_PREP(SDHCI_CDNS_HRS16_WRCMD1_SDCLK_DLY, phy->sdhc_wrcmd1_sdclk_dly); + reg |= FIELD_PREP(SDHCI_CDNS_HRS16_WRCMD0_SDCLK_DLY, phy->sdhc_wrcmd0_sdclk_dly); + reg |= FIELD_PREP(SDHCI_CDNS_HRS16_WRDATA1_DLY, phy->sdhc_wrdata1_dly); + reg |= FIELD_PREP(SDHCI_CDNS_HRS16_WRDATA0_DLY, phy->sdhc_wrdata0_dly); + reg |= FIELD_PREP(SDHCI_CDNS_HRS16_WRCMD1_DLY, phy->sdhc_wrcmd1_dly); + reg |= FIELD_PREP(SDHCI_CDNS_HRS16_WRCMD0_DLY, phy->sdhc_wrcmd0_dly); + writel(reg, priv->hrs_addr + SDHCI_CDNS_HRS16); + + reg = FIELD_PREP(SDHCI_CDNS_HRS07_RW_COMPENSATE, phy->sdhc_rw_compensate); + reg |= FIELD_PREP(SDHCI_CDNS_HRS07_IDELAY_VAL, phy->sdhc_idelay_val); + writel(reg, priv->hrs_addr + SDHCI_CDNS_HRS07); + + /* Allow 5 to 5.5 ms for clock and PHY signals to stabilize after configuration */ + usleep_range(5000, 5500); + + return 0; +} + +int sdhci_cdns6_set_tune_val(struct sdhci_host *host, unsigned int val) +{ + struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); + struct sdhci_cdns6_phy *phy = priv->phy; + u32 tmp, tuneval; + int ret; + + /* + * Scale tuning tap (val in [0, SDHCI_CDNS_MAX_TUNING_LOOP-1]) to the + * 8-bit PHY DLL slave delay field [0, 255]. With MAX_TUNING_LOOP=40 + * and FIELD_SIZE=256, the result fits in 8 bits. + */ + tuneval = (val * SDHCI_CDNS6_PHY_DLL_FIELD_SIZE) / SDHCI_CDNS_MAX_TUNING_LOOP; + + phy->hs200_tune_val = tuneval; + phy->cp_read_dqs_cmd_delay = tuneval; + phy->cp_read_dqs_delay = tuneval; + + tmp = sdhci_cdns6_read_phy_reg(priv, SDHCI_CDNS6_PHY_DLL_SLAVE_CTRL_REG); + tmp &= ~(SDHCI_CDNS6_PHY_DLL_SLAVE_CTRL_READ_DQS_CMD_DELAY | + SDHCI_CDNS6_PHY_DLL_SLAVE_CTRL_READ_DQS_DELAY); + tmp |= FIELD_PREP(SDHCI_CDNS6_PHY_DLL_SLAVE_CTRL_READ_DQS_CMD_DELAY, tuneval); + tmp |= FIELD_PREP(SDHCI_CDNS6_PHY_DLL_SLAVE_CTRL_READ_DQS_DELAY, tuneval); + + sdhci_cdns6_dll_reset(priv, true); + sdhci_cdns6_write_phy_reg(priv, SDHCI_CDNS6_PHY_DLL_SLAVE_CTRL_REG, tmp); + + ret = sdhci_cdns6_dll_reset(priv, false); + if (ret) + dev_warn(mmc_dev(host->mmc), "%s: DLL reset release failed: %d\n", __func__, ret); + + return ret; +} + +static int sdhci_cdns6_phy_update_timings(struct sdhci_host *host) +{ + struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); + struct sdhci_cdns6_phy *phy = priv->phy; + u32 t_sdmclk = phy->t_sdmclk; + + /* Validate mode is within supported range */ + if (phy->mode >= ARRAY_SIZE(init_timings)) + return -EINVAL; + + /* initialize input */ + init_timings[phy->mode](phy, phy->t_sdclk); + + phy->strobe_cmd = false; + + if (priv->enhanced_strobe) + phy->strobe_cmd = true; + + phy->phy_sdclk_delay = 2 * t_sdmclk; + + /* + * CMD and DAT output delays are currently identical, but kept separate to allow + * independent tuning for specific modes (e.g., HS400) or board-specific optimizations + * in the future. + */ + phy->phy_cmd_o_delay = 2 * t_sdmclk + t_sdmclk / 2; + phy->phy_dat_o_delay = 2 * t_sdmclk + t_sdmclk / 2; + + if (phy->t_sdclk == phy->t_sdmclk) { + phy->sdhc_extended_wr_mode = false; + phy->sdhc_extended_rd_mode = false; + } else { + phy->sdhc_extended_wr_mode = true; + phy->sdhc_extended_rd_mode = true; + } + + sdhci_cdns6_phy_configure_dll(phy); + sdhci_cdns6_phy_calc_settings(phy); + + return 0; +} + +int sdhci_cdns6_phy_probe(struct platform_device *pdev, struct sdhci_cdns_priv *priv) +{ + struct device *dev = &pdev->dev; + struct sdhci_host *host = dev_get_drvdata(dev); + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct sdhci_cdns6_phy *phy; + unsigned long val; + int ret; + + phy = devm_kzalloc(dev, sizeof(*phy), GFP_KERNEL); + if (!phy) + return -ENOMEM; + + val = clk_get_rate(pltfm_host->clk); + if (!val) + return dev_err_probe(dev, -EINVAL, "failed to get controller clock rate\n"); + + phy->t_sdmclk = DIV_ROUND_DOWN_ULL(1000000000000ULL, val); + + /* + * Optional board-level PHY timing properties. When omitted, use the + * Cadence-recommended defaults (2500 ps IO-cell delays, 24 ps DLL + * delay element) that are valid for typical SoC packaging. + */ + ret = of_property_read_u32(dev->of_node, "cdns,iocell-input-delay-ps", + &phy->iocell_input_delay); + if (ret) + phy->iocell_input_delay = SDHCI_CDNS6_PHY_DEFAULT_IOCELL_DELAY; + + ret = of_property_read_u32(dev->of_node, "cdns,iocell-output-delay-ps", + &phy->iocell_output_delay); + if (ret) + phy->iocell_output_delay = SDHCI_CDNS6_PHY_DEFAULT_IOCELL_DELAY; + + ret = of_property_read_u32(dev->of_node, "cdns,delay-element-ps", &phy->delay_element); + if (ret) { + phy->delay_element = SDHCI_CDNS6_PHY_DEFAULT_DELAY_ELEMENT; + } else if (!phy->delay_element) { + dev_warn(dev, "cdns,delay-element-ps is 0, using default %u\n", + SDHCI_CDNS6_PHY_DEFAULT_DELAY_ELEMENT); + phy->delay_element = SDHCI_CDNS6_PHY_DEFAULT_DELAY_ELEMENT; + } + + phy->delay_element_org = phy->delay_element; + + priv->phy = phy; + + return 0; +} + +static void sdhci_cdns6_phy_reconfigure(struct sdhci_host *host, unsigned int timing) +{ + struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); + struct sdhci_cdns6_phy *phy = priv->phy; + unsigned int rate = host->mmc->actual_clock ?: host->mmc->ios.clock; + u32 t_sdclk; + int ret; + + if (!rate) + return; + + t_sdclk = DIV_ROUND_DOWN_ULL(1000000000000ULL, rate); + if (phy->mode == timing && phy->t_sdclk == t_sdclk && + phy->strobe_cmd == priv->enhanced_strobe) + return; + + phy->t_sdclk = t_sdclk; + phy->mode = timing; + + ret = sdhci_cdns6_phy_update_timings(host); + if (ret) { + phy->t_sdclk = 0; + dev_warn(mmc_dev(host->mmc), "%s: update timings failed: %d\n", __func__, ret); + return; + } + + ret = sdhci_cdns6_phy_init(priv); + if (ret) { + phy->t_sdclk = 0; + dev_warn(mmc_dev(host->mmc), "%s: phy init failed: %d\n", __func__, ret); + } +} + +void sdhci_cdns6_set_clock(struct sdhci_host *host, unsigned int clock) +{ + struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); + struct sdhci_cdns6_phy *phy = priv->phy; + + sdhci_set_clock(host, clock); + + if (!clock) { + /* Force PHY reprogramming on the next non-zero clock. */ + phy->t_sdclk = 0; + return; + } + + sdhci_cdns6_phy_reconfigure(host, host->mmc->ios.timing); +} + +void sdhci_cdns6_set_uhs_signaling(struct sdhci_host *host, unsigned int timing) +{ + sdhci_cdns6_phy_reconfigure(host, timing); +} + +void sdhci_cdns6_hw_reset(struct sdhci_host *host) +{ + struct sdhci_cdns_priv *priv = sdhci_cdns_priv(host); + void __iomem *reg; + + reg = priv->hrs_addr + SDHCI_CDNS_HRS11; + writel(SDHCI_CDNS_HRS11_EMMC_RST, reg); + /* eMMC HW reset assertion: spec requires >= 1us, give margin */ + usleep_range(10, 20); + writel(0, reg); + /* For eMMC, minimum is 200us but give it 300us for good measure */ + usleep_range(300, 1000); +}
diff --git a/drivers/mmc/host/sdhci-cadence.h b/drivers/mmc/host/sdhci-cadence.h new file mode 100644 index 0000000..2ac11be --- /dev/null +++ b/drivers/mmc/host/sdhci-cadence.h
@@ -0,0 +1,118 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright (C) 2026 Altera Corporation + * Author: Tanmay Kathpalia <tanmay.kathpalia@altera.com> + * + * Cadence SD/SDIO/eMMC Host Controller driver - common header + * Shared definitions and structures for the Cadence SDHCI driver. + * Contains private data and declarations for SD6HC-specific functions + * called by the main driver in sdhci-cadence-core.c. + */ + +#ifndef _MMC_HOST_SDHCI_CADENCE_H +#define _MMC_HOST_SDHCI_CADENCE_H + +#include <linux/compiler.h> +#include <linux/spinlock.h> +#include <linux/types.h> + +#include "sdhci-pltfm.h" + +struct reset_control; + +/* HRS - Host Register Set (specific to Cadence) */ +#define SDHCI_CDNS_HRS04 0x10 /* PHY access: address port */ +#define SDHCI_CDNS_HRS05 0x14 /* PHY access: data port */ + +/* + * The tuned val register is 6 bit-wide, but not the whole of the range is + * available. The range 0-42 seems to be available (then 43 wraps around to 0) + * but I am not quite sure if it is official. Use only 0 to 39 for safety. + */ +#define SDHCI_CDNS_MAX_TUNING_LOOP 40 + +/** + * struct sdhci_cdns_priv - Cadence SDHCI private controller data + * @hrs_addr: Base address of Cadence Host Register Set (HRS) registers. + * @ctl_addr: Base address for write control registers. + * Used only for "amd,pensando-elba-sd4hc" compatible controllers to enable + * byte-lane writes. + * @wrlock: Spinlock for protecting register writes (Elba only). + * @enhanced_strobe: Flag indicating if Enhanced Strobe (HS400ES) is enabled. + * @priv_writel: Optional SoC-specific write function for register access. + * Used for Elba to ensure correct byte-lane enable. + * @rst_hw: Hardware reset control for the eMMC card RST_n pin (SD4HC only). + * @phy: Opaque pointer to variant-specific PHY data. + * For SD4HC: points to struct sdhci_cdns4_phy. + * For SD6HC: points to struct sdhci_cdns6_phy. + */ +struct sdhci_cdns_priv { + void __iomem *hrs_addr; + void __iomem *ctl_addr; /* write control */ + spinlock_t wrlock; /* write lock */ + bool enhanced_strobe; + void (*priv_writel)(struct sdhci_cdns_priv *priv, u32 val, void __iomem *reg); + struct reset_control *rst_hw; + void *phy; +}; + +/** + * sdhci_cdns_priv - Helper to retrieve Cadence private data from sdhci_host + * @host: Pointer to struct sdhci_host. + * + * Return: Pointer to struct sdhci_cdns_priv. + */ +static inline void *sdhci_cdns_priv(struct sdhci_host *host) +{ + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + + return sdhci_pltfm_priv(pltfm_host); +} + +/** + * sdhci_cdns6_set_clock - Set SDCLK and reprogram SD6HC PHY timings. + * @host: Pointer to struct sdhci_host. + * @clock: Requested clock frequency in Hz (0 to disable). + */ +void sdhci_cdns6_set_clock(struct sdhci_host *host, unsigned int clock); + +/** + * sdhci_cdns6_set_uhs_signaling - Program PHY registers for a specific timing mode. + * @host: Pointer to struct sdhci_host. + * @timing: MMC timing mode (MMC_TIMING_*). + */ +void sdhci_cdns6_set_uhs_signaling(struct sdhci_host *host, unsigned int timing); + +/** + * sdhci_cdns6_set_tune_val - Set the PHY tuning value. + * @host: Pointer to struct sdhci_host. + * @val: Tuning value to program. + * + * Return: 0 on success, -ETIMEDOUT if DLL reset release times out. + */ +int sdhci_cdns6_set_tune_val(struct sdhci_host *host, unsigned int val); + +/** + * sdhci_cdns6_phy_probe - Probe and initialize Cadence SD6HC PHY parameters + * @pdev: Platform device pointer + * @priv: Pointer to Cadence private data structure + * + * Return: 0 on success or a negative error code. + */ +int sdhci_cdns6_phy_probe(struct platform_device *pdev, struct sdhci_cdns_priv *priv); + +/** + * sdhci_cdns6_hw_reset - Perform hardware reset of the Cadence SDHCI controller. + * @host: Pointer to struct sdhci_host. + */ +void sdhci_cdns6_hw_reset(struct sdhci_host *host); + +/** + * sdhci_cdns6_phy_init - Initialize the SD6HC PHY with current settings. + * @priv: Pointer to Cadence private data structure. + * + * Return: 0 on success, -ETIMEDOUT if PHY initialization times out. + */ +int sdhci_cdns6_phy_init(struct sdhci_cdns_priv *priv); + +#endif /* _MMC_HOST_SDHCI_CADENCE_H */
diff --git a/drivers/mmc/host/sdhci-msm.c b/drivers/mmc/host/sdhci-msm.c index 4aff965..aecd425 100644 --- a/drivers/mmc/host/sdhci-msm.c +++ b/drivers/mmc/host/sdhci-msm.c
@@ -1770,7 +1770,7 @@ static void sdhci_msm_handle_pwr_irq(struct sdhci_host *host, int irq) /* * The driver has to acknowledge the interrupt, switch voltages and - * report back if it succeded or not to this register. The voltage + * report back if it succeeded or not to this register. The voltage * switches are handled by the sdhci core, so just report success. */ msm_host_writel(msm_host, irq_ack, host, @@ -1959,6 +1959,7 @@ static int sdhci_msm_ice_init(struct sdhci_msm_host *msm_host, } mmc->caps2 |= MMC_CAP2_CRYPTO; + mmc->caps2 |= MMC_CAP2_CRYPTO_NO_REPROG; return 0; } @@ -2055,6 +2056,12 @@ static int sdhci_msm_ice_prepare_key(struct blk_crypto_profile *profile, return qcom_ice_prepare_key(msm_host->ice, lt_key, lt_key_size, eph_key); } +static void sdhci_msm_ice_restore(struct sdhci_host *host) +{ + if (host->mmc->caps2 & MMC_CAP2_CRYPTO) + blk_crypto_reprogram_all_keys(&host->mmc->crypto_profile); +} + static void sdhci_msm_non_cqe_ice_init(struct sdhci_host *host) { struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); @@ -2149,6 +2156,10 @@ sdhci_msm_ice_suspend(struct sdhci_msm_host *msm_host) { return 0; } + +static inline void sdhci_msm_ice_restore(struct sdhci_host *host) +{ +} #endif /* !CONFIG_MMC_CRYPTO */ /*****************************************************************************\ @@ -2983,9 +2994,28 @@ static int sdhci_msm_runtime_resume(struct device *dev) return ret; } +static int sdhci_msm_restore(struct device *dev) +{ + struct sdhci_host *host = dev_get_drvdata(dev); + int ret; + + ret = pm_runtime_force_resume(dev); + if (ret) + return ret; + + sdhci_msm_ice_restore(host); + + return ret; +} + static const struct dev_pm_ops sdhci_msm_pm_ops = { - SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) RUNTIME_PM_OPS(sdhci_msm_runtime_suspend, sdhci_msm_runtime_resume, NULL) + .suspend = pm_sleep_ptr(pm_runtime_force_suspend), + .resume = pm_sleep_ptr(pm_runtime_force_resume), + .freeze = pm_sleep_ptr(pm_runtime_force_suspend), + .restore = pm_sleep_ptr(sdhci_msm_restore), + .thaw = pm_sleep_ptr(pm_runtime_force_resume), + .poweroff = pm_sleep_ptr(pm_runtime_force_suspend), }; static struct platform_driver sdhci_msm_driver = {
diff --git a/drivers/mmc/host/sdhci-of-arasan.c b/drivers/mmc/host/sdhci-of-arasan.c index 4ca73e7..0ee2292 100644 --- a/drivers/mmc/host/sdhci-of-arasan.c +++ b/drivers/mmc/host/sdhci-of-arasan.c
@@ -1552,8 +1552,8 @@ sdhci_arasan_register_sdcardclk(struct sdhci_arasan_data *sdhci_arasan, struct device *dev) { struct sdhci_arasan_clk_data *clk_data = &sdhci_arasan->clk_data; + struct clk_init_data sdcardclk_init = {}; struct device_node *np = dev->of_node; - struct clk_init_data sdcardclk_init; const char *parent_clk_name; int ret; @@ -1604,8 +1604,8 @@ sdhci_arasan_register_sampleclk(struct sdhci_arasan_data *sdhci_arasan, struct device *dev) { struct sdhci_arasan_clk_data *clk_data = &sdhci_arasan->clk_data; + struct clk_init_data sampleclk_init = {}; struct device_node *np = dev->of_node; - struct clk_init_data sampleclk_init; const char *parent_clk_name; int ret;
diff --git a/drivers/mmc/host/sdhci-of-dwcmshc.c b/drivers/mmc/host/sdhci-of-dwcmshc.c index 1baa237..0970202 100644 --- a/drivers/mmc/host/sdhci-of-dwcmshc.c +++ b/drivers/mmc/host/sdhci-of-dwcmshc.c
@@ -239,6 +239,8 @@ SDHCI_TRNS_BLK_CNT_EN | \ SDHCI_TRNS_DMA) +#define CQHCI_SW_ERR_HALT_REQ_DISABLE BIT(1) + #define to_pltfm_data(priv, name) \ container_of((priv)->dwcmshc_pdata, struct name##_pltfm_data, dwcmshc_pdata) @@ -702,6 +704,8 @@ static void rk35xx_sdhci_cqe_pre_enable(struct mmc_host *mmc) static void rk35xx_sdhci_cqe_enable(struct mmc_host *mmc) { struct sdhci_host *host = mmc_priv(mmc); + struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); + struct dwcmshc_priv *dwc_priv = sdhci_pltfm_priv(pltfm_host); u32 reg; reg = sdhci_readl(host, SDHCI_PRESENT_STATE); @@ -712,6 +716,15 @@ static void rk35xx_sdhci_cqe_enable(struct mmc_host *mmc) sdhci_writew(host, DWCMSHC_SDHCI_CQE_TRNS_MODE, SDHCI_TRANSFER_MODE); + /* + * Disable the halt request raised on an I/O error, otherwise a + * doorbell write gets a slave response error while the halt request + * is pending and hangs the CPU. This bit is reserved on older SoCs, + * so the write is a no-op there. + */ + sdhci_writel(host, CQHCI_SW_ERR_HALT_REQ_DISABLE, + dwc_priv->vendor_specific_area2 + CQHCI_CTL); + sdhci_cqe_enable(mmc); }
diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index 8345e2c..1ca3562 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c
@@ -1381,7 +1381,7 @@ static void esdhc_init(struct platform_device *pdev, struct sdhci_host *host) if (!IS_ERR(clk)) { /* * esdhc->peripheral_clock would be assigned with a value - * which is eSDHC base clock when use periperal clock. + * which is eSDHC base clock when use peripheral clock. * For some platforms, the clock value got by common clk * API is peripheral clock while the eSDHC base clock is * 1/2 peripheral clock.
diff --git a/drivers/mmc/host/sdhci-omap.c b/drivers/mmc/host/sdhci-omap.c index b5d7c1a8..7a198fb 100644 --- a/drivers/mmc/host/sdhci-omap.c +++ b/drivers/mmc/host/sdhci-omap.c
@@ -332,7 +332,7 @@ static int sdhci_omap_execute_tuning(struct mmc_host *mmc, u32 opcode) u32 reg; int i; - /* clock tuning is not needed for upto 52MHz */ + /* clock tuning is not needed for up to 52MHz */ if (ios->clock <= 52000000) return 0;
diff --git a/drivers/mmc/host/sdhci-pci-core.c b/drivers/mmc/host/sdhci-pci-core.c index b121d89..a9000f3 100644 --- a/drivers/mmc/host/sdhci-pci-core.c +++ b/drivers/mmc/host/sdhci-pci-core.c
@@ -2170,14 +2170,12 @@ static struct sdhci_pci_slot *sdhci_pci_probe_slot( host->irq = pdev->irq; - ret = pcim_iomap_regions(pdev, BIT(bar), mmc_hostname(host->mmc)); - if (ret) { + host->ioaddr = pcim_iomap_region(pdev, bar, mmc_hostname(host->mmc)); + if (IS_ERR(host->ioaddr)) { dev_err(&pdev->dev, "cannot request region\n"); - return ERR_PTR(ret); + return ERR_CAST(host->ioaddr); } - host->ioaddr = pcim_iomap_table(pdev)[bar]; - if (chip->fixes && chip->fixes->probe_slot) { ret = chip->fixes->probe_slot(slot); if (ret)
diff --git a/drivers/mmc/host/sdhci-pxav3.c b/drivers/mmc/host/sdhci-pxav3.c index d082c4e..f39764f 100644 --- a/drivers/mmc/host/sdhci-pxav3.c +++ b/drivers/mmc/host/sdhci-pxav3.c
@@ -123,7 +123,7 @@ static int mv_conf_mbus_windows(struct platform_device *pdev, static int armada_38x_quirks(struct platform_device *pdev, struct sdhci_host *host) { - struct device_node *np = pdev->dev.of_node; + struct device *dev = &pdev->dev; struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host); struct sdhci_pxa *pxa = sdhci_pltfm_priv(pltfm_host); struct resource *res; @@ -155,7 +155,7 @@ static int armada_38x_quirks(struct platform_device *pdev, * controller has different capabilities than the ones shown * in its registers */ - if (of_property_read_bool(np, "no-1-8-v")) { + if (device_property_present(dev, "no-1-8-v")) { host->caps &= ~SDHCI_CAN_VDD_180; host->mmc->caps &= ~MMC_CAP_1_8V_DDR; } else { @@ -284,7 +284,8 @@ static void pxav3_set_uhs_signaling(struct sdhci_host *host, unsigned int uhs) uhs == MMC_TIMING_UHS_DDR50) { reg_val &= ~SDIO3_CONF_CLK_INV; reg_val |= SDIO3_CONF_SD_FB_CLK; - } else if (uhs == MMC_TIMING_MMC_HS) { + } else if (uhs == MMC_TIMING_MMC_HS || + uhs == MMC_TIMING_SD_HS) { reg_val &= ~SDIO3_CONF_CLK_INV; reg_val &= ~SDIO3_CONF_SD_FB_CLK; } else { @@ -363,14 +364,13 @@ MODULE_DEVICE_TABLE(of, sdhci_pxav3_of_match); static struct sdhci_pxa_platdata *pxav3_get_mmc_pdata(struct device *dev) { struct sdhci_pxa_platdata *pdata; - struct device_node *np = dev->of_node; u32 clk_delay_cycles; pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return NULL; - if (!of_property_read_u32(np, "mrvl,clk-delay-cycles", + if (!device_property_read_u32(dev, "mrvl,clk-delay-cycles", &clk_delay_cycles)) pdata->clk_delay_cycles = clk_delay_cycles; @@ -401,7 +401,6 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) struct sdhci_pltfm_host *pltfm_host; struct sdhci_pxa_platdata *pdata = pdev->dev.platform_data; struct device *dev = &pdev->dev; - struct device_node *np = pdev->dev.of_node; struct sdhci_host *host = NULL; struct sdhci_pxa *pxa = NULL; const struct of_device_id *match; @@ -432,7 +431,7 @@ static int sdhci_pxav3_probe(struct platform_device *pdev) /* enable 1/8V DDR capable */ host->mmc->caps |= MMC_CAP_1_8V_DDR; - if (of_device_is_compatible(np, "marvell,armada-380-sdhci")) { + if (device_is_compatible(dev, "marvell,armada-380-sdhci")) { ret = armada_38x_quirks(pdev, host); if (ret < 0) goto err_mbus_win;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h index f0fd814..98c1fe2 100644 --- a/drivers/mmc/host/sdhci.h +++ b/drivers/mmc/host/sdhci.h
@@ -409,7 +409,7 @@ struct sdhci_adma2_64_desc { #define SDHCI_MAX_MRQS 2 /* - * 48bit command and 136 bit response in 100KHz clock could take upto 2.48ms. + * 48bit command and 136 bit response in 100KHz clock could take up to 2.48ms. * However since the start time of the command, the time between * command and response, and the time between response and start of data is * not known, set the command transfer time to 10ms.
diff --git a/drivers/mmc/host/sunplus-mmc.c b/drivers/mmc/host/sunplus-mmc.c index 6327976..e947c84 100644 --- a/drivers/mmc/host/sunplus-mmc.c +++ b/drivers/mmc/host/sunplus-mmc.c
@@ -294,6 +294,11 @@ static void spmmc_set_bus_timing(struct spmmc_host *host, unsigned int timing) value = readl(host->base + SPMMC_SD_CONFIG0_REG); value |= SPMMC_SD_DDR_MODE; writel(value, host->base + SPMMC_SD_CONFIG0_REG); + /* DDR mode needs rd_crc_dly=1 */ + value = readl(host->base + SPMMC_SD_TIMING_CONFIG0_REG); + value &= ~SPMMC_SD_READ_CRC_DELAY; + value |= FIELD_PREP(SPMMC_SD_READ_CRC_DELAY, 1); + writel(value, host->base + SPMMC_SD_TIMING_CONFIG0_REG); } else { value = readl(host->base + SPMMC_SD_CONFIG0_REG); value &= ~SPMMC_SD_DDR_MODE;
diff --git a/drivers/mmc/host/ushc.c b/drivers/mmc/host/ushc.c index 7e8af5a..410e5bb 100644 --- a/drivers/mmc/host/ushc.c +++ b/drivers/mmc/host/ushc.c
@@ -388,10 +388,7 @@ static void ushc_enable_sdio_irq(struct mmc_host *mmc, int enable) { struct ushc_data *ushc = mmc_priv(mmc); - if (enable) - set_bit(INT_EN, &ushc->flags); - else - clear_bit(INT_EN, &ushc->flags); + assign_bit(INT_EN, &ushc->flags, enable); } static void ushc_clean_up(struct ushc_data *ushc)
diff --git a/drivers/mmc/host/vub300.c b/drivers/mmc/host/vub300.c deleted file mode 100644 index 2dae474..0000000 --- a/drivers/mmc/host/vub300.c +++ /dev/null
@@ -1,2493 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Remote VUB300 SDIO/SDmem Host Controller Driver - * - * Copyright (C) 2010 Elan Digital Systems Limited - * - * based on USB Skeleton driver - 2.2 - * - * Copyright (C) 2001-2004 Greg Kroah-Hartman (greg@kroah.com) - * - * VUB300: is a USB 2.0 client device with a single SDIO/SDmem/MMC slot - * Any SDIO/SDmem/MMC device plugged into the VUB300 will appear, - * by virtue of this driver, to have been plugged into a local - * SDIO host controller, similar to, say, a PCI Ricoh controller - * This is because this kernel device driver is both a USB 2.0 - * client device driver AND an MMC host controller driver. Thus - * if there is an existing driver for the inserted SDIO/SDmem/MMC - * device then that driver will be used by the kernel to manage - * the device in exactly the same fashion as if it had been - * directly plugged into, say, a local pci bus Ricoh controller - * - * RANT: this driver was written using a display 128x48 - converting it - * to a line width of 80 makes it very difficult to support. In - * particular functions have been broken down into sub functions - * and the original meaningful names have been shortened into - * cryptic ones. - * The problem is that executing a fragment of code subject to - * two conditions means an indentation of 24, thus leaving only - * 56 characters for a C statement. And that is quite ridiculous! - * - * Data types: data passed to/from the VUB300 is fixed to a number of - * bits and driver data fields reflect that limit by using - * u8, u16, u32 - */ -#include <linux/kernel.h> -#include <linux/errno.h> -#include <linux/init.h> -#include <linux/slab.h> -#include <linux/module.h> -#include <linux/kref.h> -#include <linux/uaccess.h> -#include <linux/usb.h> -#include <linux/mutex.h> -#include <linux/mmc/host.h> -#include <linux/mmc/card.h> -#include <linux/mmc/sdio_func.h> -#include <linux/mmc/sdio_ids.h> -#include <linux/workqueue.h> -#include <linux/ctype.h> -#include <linux/firmware.h> -#include <linux/scatterlist.h> - -struct host_controller_info { - u8 info_size; - u16 firmware_version; - u8 number_of_ports; -} __packed; - -#define FIRMWARE_BLOCK_BOUNDARY 1024 -struct sd_command_header { - u8 header_size; - u8 header_type; - u8 port_number; - u8 command_type; /* Bit7 - Rd/Wr */ - u8 command_index; - u8 transfer_size[4]; /* ReadSize + ReadSize */ - u8 response_type; - u8 arguments[4]; - u8 block_count[2]; - u8 block_size[2]; - u8 block_boundary[2]; - u8 reserved[44]; /* to pad out to 64 bytes */ -} __packed; - -struct sd_irqpoll_header { - u8 header_size; - u8 header_type; - u8 port_number; - u8 command_type; /* Bit7 - Rd/Wr */ - u8 padding[16]; /* don't ask why !! */ - u8 poll_timeout_msb; - u8 poll_timeout_lsb; - u8 reserved[42]; /* to pad out to 64 bytes */ -} __packed; - -struct sd_common_header { - u8 header_size; - u8 header_type; - u8 port_number; -} __packed; - -struct sd_response_header { - u8 header_size; - u8 header_type; - u8 port_number; - u8 command_type; - u8 command_index; - u8 command_response[]; -} __packed; - -struct sd_status_header { - u8 header_size; - u8 header_type; - u8 port_number; - u16 port_flags; - u32 sdio_clock; - u16 host_header_size; - u16 func_header_size; - u16 ctrl_header_size; -} __packed; - -struct sd_error_header { - u8 header_size; - u8 header_type; - u8 port_number; - u8 error_code; -} __packed; - -struct sd_interrupt_header { - u8 header_size; - u8 header_type; - u8 port_number; -} __packed; - -struct offload_registers_access { - u8 command_byte[4]; - u8 Respond_Byte[4]; -} __packed; - -#define INTERRUPT_REGISTER_ACCESSES 15 -struct sd_offloaded_interrupt { - u8 header_size; - u8 header_type; - u8 port_number; - struct offload_registers_access reg[INTERRUPT_REGISTER_ACCESSES]; -} __packed; - -struct sd_register_header { - u8 header_size; - u8 header_type; - u8 port_number; - u8 command_type; - u8 command_index; - u8 command_response[6]; -} __packed; - -#define PIGGYBACK_REGISTER_ACCESSES 14 -struct sd_offloaded_piggyback { - struct sd_register_header sdio; - struct offload_registers_access reg[PIGGYBACK_REGISTER_ACCESSES]; -} __packed; - -union sd_response { - struct sd_common_header common; - struct sd_status_header status; - struct sd_error_header error; - struct sd_interrupt_header interrupt; - struct sd_response_header response; - struct sd_offloaded_interrupt irq; - struct sd_offloaded_piggyback pig; -} __packed; - -union sd_command { - struct sd_command_header head; - struct sd_irqpoll_header poll; -} __packed; - -enum SD_RESPONSE_TYPE { - SDRT_UNSPECIFIED = 0, - SDRT_NONE, - SDRT_1, - SDRT_1B, - SDRT_2, - SDRT_3, - SDRT_4, - SDRT_5, - SDRT_5B, - SDRT_6, - SDRT_7, -}; - -#define RESPONSE_INTERRUPT 0x01 -#define RESPONSE_ERROR 0x02 -#define RESPONSE_STATUS 0x03 -#define RESPONSE_IRQ_DISABLED 0x05 -#define RESPONSE_IRQ_ENABLED 0x06 -#define RESPONSE_PIGGYBACKED 0x07 -#define RESPONSE_NO_INTERRUPT 0x08 -#define RESPONSE_PIG_DISABLED 0x09 -#define RESPONSE_PIG_ENABLED 0x0A -#define SD_ERROR_1BIT_TIMEOUT 0x01 -#define SD_ERROR_4BIT_TIMEOUT 0x02 -#define SD_ERROR_1BIT_CRC_WRONG 0x03 -#define SD_ERROR_4BIT_CRC_WRONG 0x04 -#define SD_ERROR_1BIT_CRC_ERROR 0x05 -#define SD_ERROR_4BIT_CRC_ERROR 0x06 -#define SD_ERROR_NO_CMD_ENDBIT 0x07 -#define SD_ERROR_NO_1BIT_DATEND 0x08 -#define SD_ERROR_NO_4BIT_DATEND 0x09 -#define SD_ERROR_1BIT_UNEXPECTED_TIMEOUT 0x0A -#define SD_ERROR_4BIT_UNEXPECTED_TIMEOUT 0x0B -#define SD_ERROR_ILLEGAL_COMMAND 0x0C -#define SD_ERROR_NO_DEVICE 0x0D -#define SD_ERROR_TRANSFER_LENGTH 0x0E -#define SD_ERROR_1BIT_DATA_TIMEOUT 0x0F -#define SD_ERROR_4BIT_DATA_TIMEOUT 0x10 -#define SD_ERROR_ILLEGAL_STATE 0x11 -#define SD_ERROR_UNKNOWN_ERROR 0x12 -#define SD_ERROR_RESERVED_ERROR 0x13 -#define SD_ERROR_INVALID_FUNCTION 0x14 -#define SD_ERROR_OUT_OF_RANGE 0x15 -#define SD_ERROR_STAT_CMD 0x16 -#define SD_ERROR_STAT_DATA 0x17 -#define SD_ERROR_STAT_CMD_TIMEOUT 0x18 -#define SD_ERROR_SDCRDY_STUCK 0x19 -#define SD_ERROR_UNHANDLED 0x1A -#define SD_ERROR_OVERRUN 0x1B -#define SD_ERROR_PIO_TIMEOUT 0x1C - -#define FUN(c) (0x000007 & (c->arg>>28)) -#define REG(c) (0x01FFFF & (c->arg>>9)) - -static bool limit_speed_to_24_MHz; -module_param(limit_speed_to_24_MHz, bool, 0644); -MODULE_PARM_DESC(limit_speed_to_24_MHz, "Limit Max SDIO Clock Speed to 24 MHz"); - -static bool pad_input_to_usb_pkt; -module_param(pad_input_to_usb_pkt, bool, 0644); -MODULE_PARM_DESC(pad_input_to_usb_pkt, - "Pad USB data input transfers to whole USB Packet"); - -static bool disable_offload_processing; -module_param(disable_offload_processing, bool, 0644); -MODULE_PARM_DESC(disable_offload_processing, "Disable Offload Processing"); - -static bool force_1_bit_data_xfers; -module_param(force_1_bit_data_xfers, bool, 0644); -MODULE_PARM_DESC(force_1_bit_data_xfers, - "Force SDIO Data Transfers to 1-bit Mode"); - -static bool force_polling_for_irqs; -module_param(force_polling_for_irqs, bool, 0644); -MODULE_PARM_DESC(force_polling_for_irqs, "Force Polling for SDIO interrupts"); - -static int firmware_irqpoll_timeout = 1024; -module_param(firmware_irqpoll_timeout, int, 0644); -MODULE_PARM_DESC(firmware_irqpoll_timeout, "VUB300 firmware irqpoll timeout"); - -static int force_max_req_size = 128; -module_param(force_max_req_size, int, 0644); -MODULE_PARM_DESC(force_max_req_size, "set max request size in kBytes"); - -#ifdef SMSC_DEVELOPMENT_BOARD -static int firmware_rom_wait_states = 0x04; -#else -static int firmware_rom_wait_states = 0x1C; -#endif - -module_param(firmware_rom_wait_states, int, 0644); -MODULE_PARM_DESC(firmware_rom_wait_states, - "ROM wait states byte=RRRIIEEE (Reserved Internal External)"); - -#define ELAN_VENDOR_ID 0x2201 -#define VUB300_VENDOR_ID 0x0424 -#define VUB300_PRODUCT_ID 0x012C -static const struct usb_device_id vub300_table[] = { - {USB_DEVICE(ELAN_VENDOR_ID, VUB300_PRODUCT_ID)}, - {USB_DEVICE(VUB300_VENDOR_ID, VUB300_PRODUCT_ID)}, - {} /* Terminating entry */ -}; -MODULE_DEVICE_TABLE(usb, vub300_table); - -static struct workqueue_struct *cmndworkqueue; -static struct workqueue_struct *pollworkqueue; -static struct workqueue_struct *deadworkqueue; - -static inline int interface_to_InterfaceNumber(struct usb_interface *interface) -{ - if (!interface) - return -1; - if (!interface->cur_altsetting) - return -1; - return interface->cur_altsetting->desc.bInterfaceNumber; -} - -struct sdio_register { - unsigned func_num:3; - unsigned sdio_reg:17; - unsigned activate:1; - unsigned prepared:1; - unsigned regvalue:8; - unsigned response:8; - unsigned sparebit:26; -}; - -struct vub300_mmc_host { - struct usb_device *udev; - struct usb_interface *interface; - struct kref kref; - struct mutex cmd_mutex; - struct mutex irq_mutex; - char vub_name[3 + (9 * 8) + 4 + 1]; /* max of 7 sdio fn's */ - u8 cmnd_out_ep; /* EndPoint for commands */ - u8 cmnd_res_ep; /* EndPoint for responses */ - u8 data_out_ep; /* EndPoint for out data */ - u8 data_inp_ep; /* EndPoint for inp data */ - bool card_powered; - bool card_present; - bool read_only; - bool large_usb_packets; - bool app_spec; /* ApplicationSpecific */ - bool irq_enabled; /* by the MMC CORE */ - bool irq_disabled; /* in the firmware */ - unsigned bus_width:4; - u8 total_offload_count; - u8 dynamic_register_count; - u8 resp_len; - u32 datasize; - int errors; - int usb_transport_fail; - int usb_timed_out; - int irqs_queued; - struct sdio_register sdio_register[16]; - struct offload_interrupt_function_register { -#define MAXREGBITS 4 -#define MAXREGS (1<<MAXREGBITS) -#define MAXREGMASK (MAXREGS-1) - u8 offload_count; - u32 offload_point; - struct offload_registers_access reg[MAXREGS]; - } fn[8]; - u16 fbs[8]; /* Function Block Size */ - struct mmc_command *cmd; - struct mmc_request *req; - struct mmc_data *data; - struct mmc_host *mmc; - struct urb *urb; - struct urb *command_out_urb; - struct urb *command_res_urb; - struct completion command_complete; - struct completion irqpoll_complete; - union sd_command cmnd; - union sd_response resp; - struct timer_list sg_transfer_timer; - struct usb_sg_request sg_request; - struct timer_list inactivity_timer; - struct work_struct deadwork; - struct work_struct cmndwork; - struct delayed_work pollwork; - struct host_controller_info hc_info; - struct sd_status_header system_port_status; - u8 padded_buffer[64]; -}; - -#define kref_to_vub300_mmc_host(d) container_of(d, struct vub300_mmc_host, kref) -#define SET_TRANSFER_PSEUDOCODE 21 -#define SET_INTERRUPT_PSEUDOCODE 20 -#define SET_FAILURE_MODE 18 -#define SET_ROM_WAIT_STATES 16 -#define SET_IRQ_ENABLE 13 -#define SET_CLOCK_SPEED 11 -#define SET_FUNCTION_BLOCK_SIZE 9 -#define SET_SD_DATA_MODE 6 -#define SET_SD_POWER 4 -#define ENTER_DFU_MODE 3 -#define GET_HC_INF0 1 -#define GET_SYSTEM_PORT_STATUS 0 - -static void vub300_delete(struct kref *kref) -{ /* kref callback - softirq */ - struct vub300_mmc_host *vub300 = kref_to_vub300_mmc_host(kref); - struct mmc_host *mmc = vub300->mmc; - - usb_free_urb(vub300->command_out_urb); - vub300->command_out_urb = NULL; - usb_free_urb(vub300->command_res_urb); - vub300->command_res_urb = NULL; - usb_put_dev(vub300->udev); - mmc_free_host(mmc); - /* - * and hence also frees vub300 - * which is contained at the end of struct mmc - */ -} - -static void vub300_queue_cmnd_work(struct vub300_mmc_host *vub300) -{ - kref_get(&vub300->kref); - if (queue_work(cmndworkqueue, &vub300->cmndwork)) { - /* - * then the cmndworkqueue was not previously - * running and the above get ref is obvious - * required and will be put when the thread - * terminates by a specific call - */ - } else { - /* - * the cmndworkqueue was already running from - * a previous invocation and thus to keep the - * kref counts correct we must undo the get - */ - kref_put(&vub300->kref, vub300_delete); - } -} - -static void vub300_queue_poll_work(struct vub300_mmc_host *vub300, int delay) -{ - kref_get(&vub300->kref); - if (queue_delayed_work(pollworkqueue, &vub300->pollwork, delay)) { - /* - * then the pollworkqueue was not previously - * running and the above get ref is obvious - * required and will be put when the thread - * terminates by a specific call - */ - } else { - /* - * the pollworkqueue was already running from - * a previous invocation and thus to keep the - * kref counts correct we must undo the get - */ - kref_put(&vub300->kref, vub300_delete); - } -} - -static void vub300_queue_dead_work(struct vub300_mmc_host *vub300) -{ - kref_get(&vub300->kref); - if (queue_work(deadworkqueue, &vub300->deadwork)) { - /* - * then the deadworkqueue was not previously - * running and the above get ref is obvious - * required and will be put when the thread - * terminates by a specific call - */ - } else { - /* - * the deadworkqueue was already running from - * a previous invocation and thus to keep the - * kref counts correct we must undo the get - */ - kref_put(&vub300->kref, vub300_delete); - } -} - -static void irqpoll_res_completed(struct urb *urb) -{ /* urb completion handler - hardirq */ - struct vub300_mmc_host *vub300 = (struct vub300_mmc_host *)urb->context; - if (urb->status) - vub300->usb_transport_fail = urb->status; - complete(&vub300->irqpoll_complete); -} - -static void irqpoll_out_completed(struct urb *urb) -{ /* urb completion handler - hardirq */ - struct vub300_mmc_host *vub300 = (struct vub300_mmc_host *)urb->context; - if (urb->status) { - vub300->usb_transport_fail = urb->status; - complete(&vub300->irqpoll_complete); - return; - } else { - int ret; - unsigned int pipe = - usb_rcvbulkpipe(vub300->udev, vub300->cmnd_res_ep); - usb_fill_bulk_urb(vub300->command_res_urb, vub300->udev, pipe, - &vub300->resp, sizeof(vub300->resp), - irqpoll_res_completed, vub300); - vub300->command_res_urb->actual_length = 0; - ret = usb_submit_urb(vub300->command_res_urb, GFP_ATOMIC); - if (ret) { - vub300->usb_transport_fail = ret; - complete(&vub300->irqpoll_complete); - } - return; - } -} - -static void send_irqpoll(struct vub300_mmc_host *vub300) -{ - /* cmd_mutex is held by vub300_pollwork_thread */ - int retval; - int timeout = 0xFFFF & (0x0001FFFF - firmware_irqpoll_timeout); - vub300->cmnd.poll.header_size = 22; - vub300->cmnd.poll.header_type = 1; - vub300->cmnd.poll.port_number = 0; - vub300->cmnd.poll.command_type = 2; - vub300->cmnd.poll.poll_timeout_lsb = 0xFF & (unsigned)timeout; - vub300->cmnd.poll.poll_timeout_msb = 0xFF & (unsigned)(timeout >> 8); - usb_fill_bulk_urb(vub300->command_out_urb, vub300->udev, - usb_sndbulkpipe(vub300->udev, vub300->cmnd_out_ep) - , &vub300->cmnd, sizeof(vub300->cmnd) - , irqpoll_out_completed, vub300); - retval = usb_submit_urb(vub300->command_out_urb, GFP_KERNEL); - if (0 > retval) { - vub300->usb_transport_fail = retval; - vub300_queue_poll_work(vub300, 1); - complete(&vub300->irqpoll_complete); - return; - } else { - return; - } -} - -static void new_system_port_status(struct vub300_mmc_host *vub300) -{ - int old_card_present = vub300->card_present; - int new_card_present = - (0x0001 & vub300->system_port_status.port_flags) ? 1 : 0; - vub300->read_only = - (0x0010 & vub300->system_port_status.port_flags) ? 1 : 0; - if (new_card_present && !old_card_present) { - dev_info(&vub300->udev->dev, "card just inserted\n"); - vub300->card_present = 1; - vub300->bus_width = 0; - if (disable_offload_processing) - strscpy(vub300->vub_name, "EMPTY Processing Disabled", - sizeof(vub300->vub_name)); - else - vub300->vub_name[0] = 0; - mmc_detect_change(vub300->mmc, 1); - } else if (!new_card_present && old_card_present) { - dev_info(&vub300->udev->dev, "card just ejected\n"); - vub300->card_present = 0; - mmc_detect_change(vub300->mmc, 0); - } else { - /* no change */ - } -} - -static void __add_offloaded_reg_to_fifo(struct vub300_mmc_host *vub300, - struct offload_registers_access - *register_access, u8 func) -{ - u8 r = vub300->fn[func].offload_point + vub300->fn[func].offload_count; - memcpy(&vub300->fn[func].reg[MAXREGMASK & r], register_access, - sizeof(struct offload_registers_access)); - vub300->fn[func].offload_count += 1; - vub300->total_offload_count += 1; -} - -static void add_offloaded_reg(struct vub300_mmc_host *vub300, - struct offload_registers_access *register_access) -{ - u32 Register = ((0x03 & register_access->command_byte[0]) << 15) - | ((0xFF & register_access->command_byte[1]) << 7) - | ((0xFE & register_access->command_byte[2]) >> 1); - u8 func = ((0x70 & register_access->command_byte[0]) >> 4); - u8 regs = vub300->dynamic_register_count; - u8 i = 0; - while (0 < regs-- && 1 == vub300->sdio_register[i].activate) { - if (vub300->sdio_register[i].func_num == func && - vub300->sdio_register[i].sdio_reg == Register) { - if (vub300->sdio_register[i].prepared == 0) - vub300->sdio_register[i].prepared = 1; - vub300->sdio_register[i].response = - register_access->Respond_Byte[2]; - vub300->sdio_register[i].regvalue = - register_access->Respond_Byte[3]; - return; - } else { - i += 1; - continue; - } - } - __add_offloaded_reg_to_fifo(vub300, register_access, func); -} - -static void check_vub300_port_status(struct vub300_mmc_host *vub300) -{ - /* - * cmd_mutex is held by vub300_pollwork_thread, - * vub300_deadwork_thread or vub300_cmndwork_thread - */ - int retval; - retval = - usb_control_msg(vub300->udev, usb_rcvctrlpipe(vub300->udev, 0), - GET_SYSTEM_PORT_STATUS, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0000, 0x0000, &vub300->system_port_status, - sizeof(vub300->system_port_status), 1000); - if (sizeof(vub300->system_port_status) == retval) - new_system_port_status(vub300); -} - -static void __vub300_irqpoll_response(struct vub300_mmc_host *vub300) -{ - /* cmd_mutex is held by vub300_pollwork_thread */ - if (vub300->command_res_urb->actual_length == 0) - return; - - switch (vub300->resp.common.header_type) { - case RESPONSE_INTERRUPT: - mutex_lock(&vub300->irq_mutex); - if (vub300->irq_enabled) - mmc_signal_sdio_irq(vub300->mmc); - else - vub300->irqs_queued += 1; - vub300->irq_disabled = 1; - mutex_unlock(&vub300->irq_mutex); - break; - case RESPONSE_ERROR: - if (vub300->resp.error.error_code == SD_ERROR_NO_DEVICE) - check_vub300_port_status(vub300); - break; - case RESPONSE_STATUS: - vub300->system_port_status = vub300->resp.status; - new_system_port_status(vub300); - if (!vub300->card_present) - vub300_queue_poll_work(vub300, HZ / 5); - break; - case RESPONSE_IRQ_DISABLED: - { - int offloaded_data_length = vub300->resp.common.header_size - 3; - int register_count = offloaded_data_length >> 3; - int ri = 0; - while (register_count--) { - add_offloaded_reg(vub300, &vub300->resp.irq.reg[ri]); - ri += 1; - } - mutex_lock(&vub300->irq_mutex); - if (vub300->irq_enabled) - mmc_signal_sdio_irq(vub300->mmc); - else - vub300->irqs_queued += 1; - vub300->irq_disabled = 1; - mutex_unlock(&vub300->irq_mutex); - break; - } - case RESPONSE_IRQ_ENABLED: - { - int offloaded_data_length = vub300->resp.common.header_size - 3; - int register_count = offloaded_data_length >> 3; - int ri = 0; - while (register_count--) { - add_offloaded_reg(vub300, &vub300->resp.irq.reg[ri]); - ri += 1; - } - mutex_lock(&vub300->irq_mutex); - if (vub300->irq_enabled) - mmc_signal_sdio_irq(vub300->mmc); - else - vub300->irqs_queued += 1; - vub300->irq_disabled = 0; - mutex_unlock(&vub300->irq_mutex); - break; - } - case RESPONSE_NO_INTERRUPT: - vub300_queue_poll_work(vub300, 1); - break; - default: - break; - } -} - -static void __do_poll(struct vub300_mmc_host *vub300) -{ - /* cmd_mutex is held by vub300_pollwork_thread */ - unsigned long commretval; - mod_timer(&vub300->inactivity_timer, jiffies + HZ); - init_completion(&vub300->irqpoll_complete); - send_irqpoll(vub300); - commretval = wait_for_completion_timeout(&vub300->irqpoll_complete, - msecs_to_jiffies(500)); - if (vub300->usb_transport_fail) { - /* no need to do anything */ - } else if (commretval == 0) { - vub300->usb_timed_out = 1; - usb_kill_urb(vub300->command_out_urb); - usb_kill_urb(vub300->command_res_urb); - } else { /* commretval > 0 */ - __vub300_irqpoll_response(vub300); - } -} - -/* this thread runs only when the driver - * is trying to poll the device for an IRQ - */ -static void vub300_pollwork_thread(struct work_struct *work) -{ /* NOT irq */ - struct vub300_mmc_host *vub300 = container_of(work, - struct vub300_mmc_host, pollwork.work); - if (!vub300->interface) { - kref_put(&vub300->kref, vub300_delete); - return; - } - mutex_lock(&vub300->cmd_mutex); - if (vub300->cmd) { - vub300_queue_poll_work(vub300, 1); - } else if (!vub300->card_present) { - /* no need to do anything */ - } else { /* vub300->card_present */ - mutex_lock(&vub300->irq_mutex); - if (!vub300->irq_enabled) { - mutex_unlock(&vub300->irq_mutex); - } else if (vub300->irqs_queued) { - vub300->irqs_queued -= 1; - mmc_signal_sdio_irq(vub300->mmc); - mod_timer(&vub300->inactivity_timer, jiffies + HZ); - mutex_unlock(&vub300->irq_mutex); - } else { /* NOT vub300->irqs_queued */ - mutex_unlock(&vub300->irq_mutex); - __do_poll(vub300); - } - } - mutex_unlock(&vub300->cmd_mutex); - kref_put(&vub300->kref, vub300_delete); -} - -static void vub300_deadwork_thread(struct work_struct *work) -{ /* NOT irq */ - struct vub300_mmc_host *vub300 = - container_of(work, struct vub300_mmc_host, deadwork); - if (!vub300->interface) { - kref_put(&vub300->kref, vub300_delete); - return; - } - mutex_lock(&vub300->cmd_mutex); - if (vub300->cmd) { - /* - * a command got in as the inactivity - * timer expired - so we just let the - * processing of the command show if - * the device is dead - */ - } else if (vub300->card_present) { - check_vub300_port_status(vub300); - } else if (vub300->mmc && vub300->mmc->card) { - /* - * the MMC core must not have responded - * to the previous indication - lets - * hope that it eventually does so we - * will just ignore this for now - */ - } else { - check_vub300_port_status(vub300); - } - mod_timer(&vub300->inactivity_timer, jiffies + HZ); - mutex_unlock(&vub300->cmd_mutex); - kref_put(&vub300->kref, vub300_delete); -} - -static void vub300_inactivity_timer_expired(struct timer_list *t) -{ /* softirq */ - struct vub300_mmc_host *vub300 = timer_container_of(vub300, t, - inactivity_timer); - if (!vub300->interface) { - kref_put(&vub300->kref, vub300_delete); - } else if (vub300->cmd) { - mod_timer(&vub300->inactivity_timer, jiffies + HZ); - } else { - vub300_queue_dead_work(vub300); - mod_timer(&vub300->inactivity_timer, jiffies + HZ); - } -} - -static int vub300_response_error(u8 error_code) -{ - switch (error_code) { - case SD_ERROR_PIO_TIMEOUT: - case SD_ERROR_1BIT_TIMEOUT: - case SD_ERROR_4BIT_TIMEOUT: - return -ETIMEDOUT; - case SD_ERROR_STAT_DATA: - case SD_ERROR_OVERRUN: - case SD_ERROR_STAT_CMD: - case SD_ERROR_STAT_CMD_TIMEOUT: - case SD_ERROR_SDCRDY_STUCK: - case SD_ERROR_UNHANDLED: - case SD_ERROR_1BIT_CRC_WRONG: - case SD_ERROR_4BIT_CRC_WRONG: - case SD_ERROR_1BIT_CRC_ERROR: - case SD_ERROR_4BIT_CRC_ERROR: - case SD_ERROR_NO_CMD_ENDBIT: - case SD_ERROR_NO_1BIT_DATEND: - case SD_ERROR_NO_4BIT_DATEND: - case SD_ERROR_1BIT_DATA_TIMEOUT: - case SD_ERROR_4BIT_DATA_TIMEOUT: - case SD_ERROR_1BIT_UNEXPECTED_TIMEOUT: - case SD_ERROR_4BIT_UNEXPECTED_TIMEOUT: - return -EILSEQ; - case 33: - return -EILSEQ; - case SD_ERROR_ILLEGAL_COMMAND: - return -EINVAL; - case SD_ERROR_NO_DEVICE: - return -ENOMEDIUM; - default: - return -ENODEV; - } -} - -static void command_res_completed(struct urb *urb) -{ /* urb completion handler - hardirq */ - struct vub300_mmc_host *vub300 = (struct vub300_mmc_host *)urb->context; - if (urb->status) { - /* we have to let the initiator handle the error */ - } else if (vub300->command_res_urb->actual_length == 0) { - /* - * we have seen this happen once or twice and - * we suspect a buggy USB host controller - */ - } else if (!vub300->data) { - /* this means that the command (typically CMD52) succeeded */ - } else if (vub300->resp.common.header_type != 0x02) { - /* - * this is an error response from the VUB300 chip - * and we let the initiator handle it - */ - } else if (vub300->urb) { - vub300->cmd->error = - vub300_response_error(vub300->resp.error.error_code); - usb_unlink_urb(vub300->urb); - } else { - vub300->cmd->error = - vub300_response_error(vub300->resp.error.error_code); - usb_sg_cancel(&vub300->sg_request); - } - complete(&vub300->command_complete); /* got_response_in */ -} - -static void command_out_completed(struct urb *urb) -{ /* urb completion handler - hardirq */ - struct vub300_mmc_host *vub300 = (struct vub300_mmc_host *)urb->context; - if (urb->status) { - complete(&vub300->command_complete); - } else { - int ret; - unsigned int pipe = - usb_rcvbulkpipe(vub300->udev, vub300->cmnd_res_ep); - usb_fill_bulk_urb(vub300->command_res_urb, vub300->udev, pipe, - &vub300->resp, sizeof(vub300->resp), - command_res_completed, vub300); - vub300->command_res_urb->actual_length = 0; - ret = usb_submit_urb(vub300->command_res_urb, GFP_ATOMIC); - if (ret == 0) { - /* - * the urb completion handler will call - * our completion handler - */ - } else { - /* - * and thus we only call it directly - * when it will not be called - */ - complete(&vub300->command_complete); - } - } -} - -/* - * the STUFF bits are masked out for the comparisons - */ -static void snoop_block_size_and_bus_width(struct vub300_mmc_host *vub300, - u32 cmd_arg) -{ - if ((0xFBFFFE00 & cmd_arg) == 0x80022200) - vub300->fbs[1] = (cmd_arg << 8) | (0x00FF & vub300->fbs[1]); - else if ((0xFBFFFE00 & cmd_arg) == 0x80022000) - vub300->fbs[1] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[1]); - else if ((0xFBFFFE00 & cmd_arg) == 0x80042200) - vub300->fbs[2] = (cmd_arg << 8) | (0x00FF & vub300->fbs[2]); - else if ((0xFBFFFE00 & cmd_arg) == 0x80042000) - vub300->fbs[2] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[2]); - else if ((0xFBFFFE00 & cmd_arg) == 0x80062200) - vub300->fbs[3] = (cmd_arg << 8) | (0x00FF & vub300->fbs[3]); - else if ((0xFBFFFE00 & cmd_arg) == 0x80062000) - vub300->fbs[3] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[3]); - else if ((0xFBFFFE00 & cmd_arg) == 0x80082200) - vub300->fbs[4] = (cmd_arg << 8) | (0x00FF & vub300->fbs[4]); - else if ((0xFBFFFE00 & cmd_arg) == 0x80082000) - vub300->fbs[4] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[4]); - else if ((0xFBFFFE00 & cmd_arg) == 0x800A2200) - vub300->fbs[5] = (cmd_arg << 8) | (0x00FF & vub300->fbs[5]); - else if ((0xFBFFFE00 & cmd_arg) == 0x800A2000) - vub300->fbs[5] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[5]); - else if ((0xFBFFFE00 & cmd_arg) == 0x800C2200) - vub300->fbs[6] = (cmd_arg << 8) | (0x00FF & vub300->fbs[6]); - else if ((0xFBFFFE00 & cmd_arg) == 0x800C2000) - vub300->fbs[6] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[6]); - else if ((0xFBFFFE00 & cmd_arg) == 0x800E2200) - vub300->fbs[7] = (cmd_arg << 8) | (0x00FF & vub300->fbs[7]); - else if ((0xFBFFFE00 & cmd_arg) == 0x800E2000) - vub300->fbs[7] = (0xFF & cmd_arg) | (0xFF00 & vub300->fbs[7]); - else if ((0xFBFFFE03 & cmd_arg) == 0x80000E00) - vub300->bus_width = 1; - else if ((0xFBFFFE03 & cmd_arg) == 0x80000E02) - vub300->bus_width = 4; -} - -static void send_command(struct vub300_mmc_host *vub300) -{ - /* cmd_mutex is held by vub300_cmndwork_thread */ - struct mmc_command *cmd = vub300->cmd; - struct mmc_data *data = vub300->data; - int retval; - int i; - u8 response_type; - if (vub300->app_spec) { - switch (cmd->opcode) { - case 6: - response_type = SDRT_1; - vub300->resp_len = 6; - if (0x00000000 == (0x00000003 & cmd->arg)) - vub300->bus_width = 1; - else if (0x00000002 == (0x00000003 & cmd->arg)) - vub300->bus_width = 4; - else - dev_err(&vub300->udev->dev, - "unexpected ACMD6 bus_width=%d\n", - 0x00000003 & cmd->arg); - break; - case 13: - response_type = SDRT_1; - vub300->resp_len = 6; - break; - case 22: - response_type = SDRT_1; - vub300->resp_len = 6; - break; - case 23: - response_type = SDRT_1; - vub300->resp_len = 6; - break; - case 41: - response_type = SDRT_3; - vub300->resp_len = 6; - break; - case 42: - response_type = SDRT_1; - vub300->resp_len = 6; - break; - case 51: - response_type = SDRT_1; - vub300->resp_len = 6; - break; - case 55: - response_type = SDRT_1; - vub300->resp_len = 6; - break; - default: - vub300->resp_len = 0; - cmd->error = -EINVAL; - complete(&vub300->command_complete); - return; - } - vub300->app_spec = 0; - } else { - switch (cmd->opcode) { - case 0: - response_type = SDRT_NONE; - vub300->resp_len = 0; - break; - case 1: - response_type = SDRT_3; - vub300->resp_len = 6; - break; - case 2: - response_type = SDRT_2; - vub300->resp_len = 17; - break; - case 3: - response_type = SDRT_6; - vub300->resp_len = 6; - break; - case 4: - response_type = SDRT_NONE; - vub300->resp_len = 0; - break; - case 5: - response_type = SDRT_4; - vub300->resp_len = 6; - break; - case 6: - response_type = SDRT_1; - vub300->resp_len = 6; - break; - case 7: - response_type = SDRT_1B; - vub300->resp_len = 6; - break; - case 8: - response_type = SDRT_7; - vub300->resp_len = 6; - break; - case 9: - response_type = SDRT_2; - vub300->resp_len = 17; - break; - case 10: - response_type = SDRT_2; - vub300->resp_len = 17; - break; - case 12: - response_type = SDRT_1B; - vub300->resp_len = 6; - break; - case 13: - response_type = SDRT_1; - vub300->resp_len = 6; - break; - case 15: - response_type = SDRT_NONE; - vub300->resp_len = 0; - break; - case 16: - for (i = 0; i < ARRAY_SIZE(vub300->fbs); i++) - vub300->fbs[i] = 0xFFFF & cmd->arg; - response_type = SDRT_1; - vub300->resp_len = 6; - break; - case 17: - case 18: - case 24: - case 25: - case 27: - response_type = SDRT_1; - vub300->resp_len = 6; - break; - case 28: - case 29: - response_type = SDRT_1B; - vub300->resp_len = 6; - break; - case 30: - case 32: - case 33: - response_type = SDRT_1; - vub300->resp_len = 6; - break; - case 38: - response_type = SDRT_1B; - vub300->resp_len = 6; - break; - case 42: - response_type = SDRT_1; - vub300->resp_len = 6; - break; - case 52: - response_type = SDRT_5; - vub300->resp_len = 6; - snoop_block_size_and_bus_width(vub300, cmd->arg); - break; - case 53: - response_type = SDRT_5; - vub300->resp_len = 6; - break; - case 55: - response_type = SDRT_1; - vub300->resp_len = 6; - vub300->app_spec = 1; - break; - case 56: - response_type = SDRT_1; - vub300->resp_len = 6; - break; - default: - vub300->resp_len = 0; - cmd->error = -EINVAL; - complete(&vub300->command_complete); - return; - } - } - /* - * it is a shame that we can not use "sizeof(struct sd_command_header)" - * this is because the packet _must_ be padded to 64 bytes - */ - vub300->cmnd.head.header_size = 20; - vub300->cmnd.head.header_type = 0x00; - vub300->cmnd.head.port_number = 0; /* "0" means port 1 */ - vub300->cmnd.head.command_type = 0x00; /* standard read command */ - vub300->cmnd.head.response_type = response_type; - vub300->cmnd.head.command_index = cmd->opcode; - vub300->cmnd.head.arguments[0] = cmd->arg >> 24; - vub300->cmnd.head.arguments[1] = cmd->arg >> 16; - vub300->cmnd.head.arguments[2] = cmd->arg >> 8; - vub300->cmnd.head.arguments[3] = cmd->arg >> 0; - if (cmd->opcode == 52) { - int fn = 0x7 & (cmd->arg >> 28); - vub300->cmnd.head.block_count[0] = 0; - vub300->cmnd.head.block_count[1] = 0; - vub300->cmnd.head.block_size[0] = (vub300->fbs[fn] >> 8) & 0xFF; - vub300->cmnd.head.block_size[1] = (vub300->fbs[fn] >> 0) & 0xFF; - vub300->cmnd.head.command_type = 0x00; - vub300->cmnd.head.transfer_size[0] = 0; - vub300->cmnd.head.transfer_size[1] = 0; - vub300->cmnd.head.transfer_size[2] = 0; - vub300->cmnd.head.transfer_size[3] = 0; - } else if (!data) { - vub300->cmnd.head.block_count[0] = 0; - vub300->cmnd.head.block_count[1] = 0; - vub300->cmnd.head.block_size[0] = (vub300->fbs[0] >> 8) & 0xFF; - vub300->cmnd.head.block_size[1] = (vub300->fbs[0] >> 0) & 0xFF; - vub300->cmnd.head.command_type = 0x00; - vub300->cmnd.head.transfer_size[0] = 0; - vub300->cmnd.head.transfer_size[1] = 0; - vub300->cmnd.head.transfer_size[2] = 0; - vub300->cmnd.head.transfer_size[3] = 0; - } else if (cmd->opcode == 53) { - int fn = 0x7 & (cmd->arg >> 28); - if (0x08 & vub300->cmnd.head.arguments[0]) { /* BLOCK MODE */ - vub300->cmnd.head.block_count[0] = - (data->blocks >> 8) & 0xFF; - vub300->cmnd.head.block_count[1] = - (data->blocks >> 0) & 0xFF; - vub300->cmnd.head.block_size[0] = - (data->blksz >> 8) & 0xFF; - vub300->cmnd.head.block_size[1] = - (data->blksz >> 0) & 0xFF; - } else { /* BYTE MODE */ - vub300->cmnd.head.block_count[0] = 0; - vub300->cmnd.head.block_count[1] = 0; - vub300->cmnd.head.block_size[0] = - (vub300->datasize >> 8) & 0xFF; - vub300->cmnd.head.block_size[1] = - (vub300->datasize >> 0) & 0xFF; - } - vub300->cmnd.head.command_type = - (MMC_DATA_READ & data->flags) ? 0x00 : 0x80; - vub300->cmnd.head.transfer_size[0] = - (vub300->datasize >> 24) & 0xFF; - vub300->cmnd.head.transfer_size[1] = - (vub300->datasize >> 16) & 0xFF; - vub300->cmnd.head.transfer_size[2] = - (vub300->datasize >> 8) & 0xFF; - vub300->cmnd.head.transfer_size[3] = - (vub300->datasize >> 0) & 0xFF; - if (vub300->datasize < vub300->fbs[fn]) { - vub300->cmnd.head.block_count[0] = 0; - vub300->cmnd.head.block_count[1] = 0; - } - } else { - vub300->cmnd.head.block_count[0] = (data->blocks >> 8) & 0xFF; - vub300->cmnd.head.block_count[1] = (data->blocks >> 0) & 0xFF; - vub300->cmnd.head.block_size[0] = (data->blksz >> 8) & 0xFF; - vub300->cmnd.head.block_size[1] = (data->blksz >> 0) & 0xFF; - vub300->cmnd.head.command_type = - (MMC_DATA_READ & data->flags) ? 0x00 : 0x80; - vub300->cmnd.head.transfer_size[0] = - (vub300->datasize >> 24) & 0xFF; - vub300->cmnd.head.transfer_size[1] = - (vub300->datasize >> 16) & 0xFF; - vub300->cmnd.head.transfer_size[2] = - (vub300->datasize >> 8) & 0xFF; - vub300->cmnd.head.transfer_size[3] = - (vub300->datasize >> 0) & 0xFF; - if (vub300->datasize < vub300->fbs[0]) { - vub300->cmnd.head.block_count[0] = 0; - vub300->cmnd.head.block_count[1] = 0; - } - } - if (vub300->cmnd.head.block_size[0] || vub300->cmnd.head.block_size[1]) { - u16 block_size = vub300->cmnd.head.block_size[1] | - (vub300->cmnd.head.block_size[0] << 8); - u16 block_boundary = FIRMWARE_BLOCK_BOUNDARY - - (FIRMWARE_BLOCK_BOUNDARY % block_size); - vub300->cmnd.head.block_boundary[0] = - (block_boundary >> 8) & 0xFF; - vub300->cmnd.head.block_boundary[1] = - (block_boundary >> 0) & 0xFF; - } else { - vub300->cmnd.head.block_boundary[0] = 0; - vub300->cmnd.head.block_boundary[1] = 0; - } - usb_fill_bulk_urb(vub300->command_out_urb, vub300->udev, - usb_sndbulkpipe(vub300->udev, vub300->cmnd_out_ep), - &vub300->cmnd, sizeof(vub300->cmnd), - command_out_completed, vub300); - retval = usb_submit_urb(vub300->command_out_urb, GFP_KERNEL); - if (retval < 0) { - cmd->error = retval; - complete(&vub300->command_complete); - return; - } else { - return; - } -} - -/* - * timer callback runs in atomic mode - * so it cannot call usb_kill_urb() - */ -static void vub300_sg_timed_out(struct timer_list *t) -{ - struct vub300_mmc_host *vub300 = timer_container_of(vub300, t, - sg_transfer_timer); - vub300->usb_timed_out = 1; - usb_sg_cancel(&vub300->sg_request); - usb_unlink_urb(vub300->command_out_urb); - usb_unlink_urb(vub300->command_res_urb); -} - -static u16 roundup_to_multiple_of_64(u16 number) -{ - return 0xFFC0 & (0x3F + number); -} - -/* - * this is a separate function to solve the 80 column width restriction - */ -static void __download_offload_pseudocode(struct vub300_mmc_host *vub300, - const struct firmware *fw) -{ - u8 register_count = 0; - u16 ts = 0; - u16 interrupt_size = 0; - const u8 *data = fw->data; - int size = fw->size; - u8 c; - dev_info(&vub300->udev->dev, "using %s for SDIO offload processing\n", - vub300->vub_name); - do { - c = *data++; - } while (size-- && c); /* skip comment */ - dev_info(&vub300->udev->dev, "using offload firmware %s %s\n", fw->data, - vub300->vub_name); - if (size < 4) { - dev_err(&vub300->udev->dev, - "corrupt offload pseudocode in firmware %s\n", - vub300->vub_name); - strscpy(vub300->vub_name, "corrupt offload pseudocode", - sizeof(vub300->vub_name)); - return; - } - interrupt_size += *data++; - size -= 1; - interrupt_size <<= 8; - interrupt_size += *data++; - size -= 1; - if (interrupt_size < size) { - u16 xfer_length = roundup_to_multiple_of_64(interrupt_size); - u8 *xfer_buffer = kmalloc(xfer_length, GFP_KERNEL); - if (xfer_buffer) { - int retval; - memcpy(xfer_buffer, data, interrupt_size); - memset(xfer_buffer + interrupt_size, 0, - xfer_length - interrupt_size); - size -= interrupt_size; - data += interrupt_size; - retval = - usb_control_msg(vub300->udev, - usb_sndctrlpipe(vub300->udev, 0), - SET_INTERRUPT_PSEUDOCODE, - USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, 0x0000, 0x0000, - xfer_buffer, xfer_length, 1000); - kfree(xfer_buffer); - if (retval < 0) - goto copy_error_message; - } else { - dev_err(&vub300->udev->dev, - "not enough memory for xfer buffer to send" - " INTERRUPT_PSEUDOCODE for %s %s\n", fw->data, - vub300->vub_name); - strscpy(vub300->vub_name, - "SDIO interrupt pseudocode download failed", - sizeof(vub300->vub_name)); - return; - } - } else { - dev_err(&vub300->udev->dev, - "corrupt interrupt pseudocode in firmware %s %s\n", - fw->data, vub300->vub_name); - strscpy(vub300->vub_name, "corrupt interrupt pseudocode", - sizeof(vub300->vub_name)); - return; - } - ts += *data++; - size -= 1; - ts <<= 8; - ts += *data++; - size -= 1; - if (ts < size) { - u16 xfer_length = roundup_to_multiple_of_64(ts); - u8 *xfer_buffer = kmalloc(xfer_length, GFP_KERNEL); - if (xfer_buffer) { - int retval; - memcpy(xfer_buffer, data, ts); - memset(xfer_buffer + ts, 0, - xfer_length - ts); - size -= ts; - data += ts; - retval = - usb_control_msg(vub300->udev, - usb_sndctrlpipe(vub300->udev, 0), - SET_TRANSFER_PSEUDOCODE, - USB_DIR_OUT | USB_TYPE_VENDOR | - USB_RECIP_DEVICE, 0x0000, 0x0000, - xfer_buffer, xfer_length, 1000); - kfree(xfer_buffer); - if (retval < 0) - goto copy_error_message; - } else { - dev_err(&vub300->udev->dev, - "not enough memory for xfer buffer to send" - " TRANSFER_PSEUDOCODE for %s %s\n", fw->data, - vub300->vub_name); - strscpy(vub300->vub_name, - "SDIO transfer pseudocode download failed", - sizeof(vub300->vub_name)); - return; - } - } else { - dev_err(&vub300->udev->dev, - "corrupt transfer pseudocode in firmware %s %s\n", - fw->data, vub300->vub_name); - strscpy(vub300->vub_name, "corrupt transfer pseudocode", - sizeof(vub300->vub_name)); - return; - } - register_count += *data++; - size -= 1; - if (register_count * 4 == size) { - int I = vub300->dynamic_register_count = register_count; - int i = 0; - while (I--) { - unsigned int func_num = 0; - vub300->sdio_register[i].func_num = *data++; - size -= 1; - func_num += *data++; - size -= 1; - func_num <<= 8; - func_num += *data++; - size -= 1; - func_num <<= 8; - func_num += *data++; - size -= 1; - vub300->sdio_register[i].sdio_reg = func_num; - vub300->sdio_register[i].activate = 1; - vub300->sdio_register[i].prepared = 0; - i += 1; - } - dev_info(&vub300->udev->dev, - "initialized %d dynamic pseudocode registers\n", - vub300->dynamic_register_count); - return; - } else { - dev_err(&vub300->udev->dev, - "corrupt dynamic registers in firmware %s\n", - vub300->vub_name); - strscpy(vub300->vub_name, "corrupt dynamic registers", - sizeof(vub300->vub_name)); - return; - } - -copy_error_message: - strscpy(vub300->vub_name, "SDIO pseudocode download failed", - sizeof(vub300->vub_name)); -} - -/* - * if the binary containing the EMPTY PseudoCode can not be found - * vub300->vub_name is set anyway in order to prevent an automatic retry - */ -static void download_offload_pseudocode(struct vub300_mmc_host *vub300) -{ - struct mmc_card *card = vub300->mmc->card; - int sdio_funcs = card->sdio_funcs; - const struct firmware *fw = NULL; - int l = snprintf(vub300->vub_name, sizeof(vub300->vub_name), - "vub_%04X%04X", card->cis.vendor, card->cis.device); - int n = 0; - int retval; - for (n = 0; n < sdio_funcs; n++) { - struct sdio_func *sf = card->sdio_func[n]; - l += scnprintf(vub300->vub_name + l, - sizeof(vub300->vub_name) - l, "_%04X%04X", - sf->vendor, sf->device); - } - snprintf(vub300->vub_name + l, sizeof(vub300->vub_name) - l, ".bin"); - dev_info(&vub300->udev->dev, "requesting offload firmware %s\n", - vub300->vub_name); - retval = request_firmware(&fw, vub300->vub_name, &card->dev); - if (retval < 0) { - strscpy(vub300->vub_name, "vub_default.bin", - sizeof(vub300->vub_name)); - retval = request_firmware(&fw, vub300->vub_name, &card->dev); - if (retval < 0) { - strscpy(vub300->vub_name, - "no SDIO offload firmware found", - sizeof(vub300->vub_name)); - } else { - __download_offload_pseudocode(vub300, fw); - release_firmware(fw); - } - } else { - __download_offload_pseudocode(vub300, fw); - release_firmware(fw); - } -} - -static void vub300_usb_bulk_msg_completion(struct urb *urb) -{ /* urb completion handler - hardirq */ - complete((struct completion *)urb->context); -} - -static int vub300_usb_bulk_msg(struct vub300_mmc_host *vub300, - unsigned int pipe, void *data, int len, - int *actual_length, int timeout_msecs) -{ - /* cmd_mutex is held by vub300_cmndwork_thread */ - struct usb_device *usb_dev = vub300->udev; - struct completion done; - int retval; - vub300->urb = usb_alloc_urb(0, GFP_KERNEL); - if (!vub300->urb) - return -ENOMEM; - usb_fill_bulk_urb(vub300->urb, usb_dev, pipe, data, len, - vub300_usb_bulk_msg_completion, NULL); - init_completion(&done); - vub300->urb->context = &done; - vub300->urb->actual_length = 0; - retval = usb_submit_urb(vub300->urb, GFP_KERNEL); - if (unlikely(retval)) - goto out; - if (!wait_for_completion_timeout - (&done, msecs_to_jiffies(timeout_msecs))) { - retval = -ETIMEDOUT; - usb_kill_urb(vub300->urb); - } else { - retval = vub300->urb->status; - } -out: - *actual_length = vub300->urb->actual_length; - usb_free_urb(vub300->urb); - vub300->urb = NULL; - return retval; -} - -static int __command_read_data(struct vub300_mmc_host *vub300, - struct mmc_command *cmd, struct mmc_data *data) -{ - /* cmd_mutex is held by vub300_cmndwork_thread */ - int linear_length = vub300->datasize; - int padded_length = vub300->large_usb_packets ? - ((511 + linear_length) >> 9) << 9 : - ((63 + linear_length) >> 6) << 6; - if ((padded_length == linear_length) || !pad_input_to_usb_pkt) { - int result; - unsigned pipe; - pipe = usb_rcvbulkpipe(vub300->udev, vub300->data_inp_ep); - result = usb_sg_init(&vub300->sg_request, vub300->udev, - pipe, 0, data->sg, - data->sg_len, 0, GFP_KERNEL); - if (result < 0) { - usb_unlink_urb(vub300->command_out_urb); - usb_unlink_urb(vub300->command_res_urb); - cmd->error = result; - data->bytes_xfered = 0; - return 0; - } else { - vub300->sg_transfer_timer.expires = - jiffies + msecs_to_jiffies(2000 + - (linear_length / 16384)); - add_timer(&vub300->sg_transfer_timer); - usb_sg_wait(&vub300->sg_request); - timer_delete(&vub300->sg_transfer_timer); - if (vub300->sg_request.status < 0) { - cmd->error = vub300->sg_request.status; - data->bytes_xfered = 0; - return 0; - } else { - data->bytes_xfered = vub300->datasize; - return linear_length; - } - } - } else { - u8 *buf = kmalloc(padded_length, GFP_KERNEL); - if (buf) { - int result; - unsigned pipe = usb_rcvbulkpipe(vub300->udev, - vub300->data_inp_ep); - int actual_length = 0; - result = vub300_usb_bulk_msg(vub300, pipe, buf, - padded_length, &actual_length, - 2000 + (padded_length / 16384)); - if (result < 0) { - cmd->error = result; - data->bytes_xfered = 0; - kfree(buf); - return 0; - } else if (actual_length < linear_length) { - cmd->error = -EREMOTEIO; - data->bytes_xfered = 0; - kfree(buf); - return 0; - } else { - sg_copy_from_buffer(data->sg, data->sg_len, buf, - linear_length); - kfree(buf); - data->bytes_xfered = vub300->datasize; - return linear_length; - } - } else { - cmd->error = -ENOMEM; - data->bytes_xfered = 0; - return 0; - } - } -} - -static int __command_write_data(struct vub300_mmc_host *vub300, - struct mmc_command *cmd, struct mmc_data *data) -{ - /* cmd_mutex is held by vub300_cmndwork_thread */ - unsigned pipe = usb_sndbulkpipe(vub300->udev, vub300->data_out_ep); - int linear_length = vub300->datasize; - int modulo_64_length = linear_length & 0x003F; - int modulo_512_length = linear_length & 0x01FF; - if (linear_length < 64) { - int result; - int actual_length; - sg_copy_to_buffer(data->sg, data->sg_len, - vub300->padded_buffer, - sizeof(vub300->padded_buffer)); - memset(vub300->padded_buffer + linear_length, 0, - sizeof(vub300->padded_buffer) - linear_length); - result = vub300_usb_bulk_msg(vub300, pipe, vub300->padded_buffer, - sizeof(vub300->padded_buffer), - &actual_length, 2000 + - (sizeof(vub300->padded_buffer) / - 16384)); - if (result < 0) { - cmd->error = result; - data->bytes_xfered = 0; - } else { - data->bytes_xfered = vub300->datasize; - } - } else if ((!vub300->large_usb_packets && (0 < modulo_64_length)) || - (vub300->large_usb_packets && (64 > modulo_512_length)) - ) { /* don't you just love these work-rounds */ - int padded_length = ((63 + linear_length) >> 6) << 6; - u8 *buf = kmalloc(padded_length, GFP_KERNEL); - if (buf) { - int result; - int actual_length; - sg_copy_to_buffer(data->sg, data->sg_len, buf, - padded_length); - memset(buf + linear_length, 0, - padded_length - linear_length); - result = - vub300_usb_bulk_msg(vub300, pipe, buf, - padded_length, &actual_length, - 2000 + padded_length / 16384); - kfree(buf); - if (result < 0) { - cmd->error = result; - data->bytes_xfered = 0; - } else { - data->bytes_xfered = vub300->datasize; - } - } else { - cmd->error = -ENOMEM; - data->bytes_xfered = 0; - } - } else { /* no data padding required */ - int result; - unsigned char buf[64 * 4]; - sg_copy_to_buffer(data->sg, data->sg_len, buf, sizeof(buf)); - result = usb_sg_init(&vub300->sg_request, vub300->udev, - pipe, 0, data->sg, - data->sg_len, 0, GFP_KERNEL); - if (result < 0) { - usb_unlink_urb(vub300->command_out_urb); - usb_unlink_urb(vub300->command_res_urb); - cmd->error = result; - data->bytes_xfered = 0; - } else { - vub300->sg_transfer_timer.expires = - jiffies + msecs_to_jiffies(2000 + - linear_length / 16384); - add_timer(&vub300->sg_transfer_timer); - usb_sg_wait(&vub300->sg_request); - if (cmd->error) { - data->bytes_xfered = 0; - } else { - timer_delete(&vub300->sg_transfer_timer); - if (vub300->sg_request.status < 0) { - cmd->error = vub300->sg_request.status; - data->bytes_xfered = 0; - } else { - data->bytes_xfered = vub300->datasize; - } - } - } - } - return linear_length; -} - -static bool __vub300_command_response(struct vub300_mmc_host *vub300, - struct mmc_command *cmd, - struct mmc_data *data, int data_length) -{ - /* cmd_mutex is held by vub300_cmndwork_thread */ - long respretval; - int msec_timeout = 1000 + data_length / 4; - respretval = - wait_for_completion_timeout(&vub300->command_complete, - msecs_to_jiffies(msec_timeout)); - if (respretval == 0) { /* TIMED OUT */ - /* we don't know which of "out" and "res" if any failed */ - vub300->usb_timed_out = 1; - usb_kill_urb(vub300->command_out_urb); - usb_kill_urb(vub300->command_res_urb); - cmd->error = -ETIMEDOUT; - return true; - } else if (respretval < 0) { - /* we don't know which of "out" and "res" if any failed */ - usb_kill_urb(vub300->command_out_urb); - usb_kill_urb(vub300->command_res_urb); - cmd->error = respretval; - } else if (cmd->error) { - /* - * the error occurred sending the command - * or receiving the response - */ - } else if (vub300->command_out_urb->status) { - vub300->usb_transport_fail = vub300->command_out_urb->status; - cmd->error = -EPROTO == vub300->command_out_urb->status ? - -ESHUTDOWN : vub300->command_out_urb->status; - } else if (vub300->command_res_urb->status) { - vub300->usb_transport_fail = vub300->command_res_urb->status; - cmd->error = -EPROTO == vub300->command_res_urb->status ? - -ESHUTDOWN : vub300->command_res_urb->status; - } else if (vub300->resp.common.header_type == 0x00) { - /* - * the command completed successfully - * and there was no piggybacked data - */ - } else if (vub300->resp.common.header_type == RESPONSE_ERROR) { - cmd->error = - vub300_response_error(vub300->resp.error.error_code); - if (vub300->data) - usb_sg_cancel(&vub300->sg_request); - } else if (vub300->resp.common.header_type == RESPONSE_PIGGYBACKED) { - int offloaded_data_length = - vub300->resp.common.header_size - - sizeof(struct sd_register_header); - int register_count = offloaded_data_length >> 3; - int ri = 0; - while (register_count--) { - add_offloaded_reg(vub300, &vub300->resp.pig.reg[ri]); - ri += 1; - } - vub300->resp.common.header_size = - sizeof(struct sd_register_header); - vub300->resp.common.header_type = 0x00; - cmd->error = 0; - } else if (vub300->resp.common.header_type == RESPONSE_PIG_DISABLED) { - int offloaded_data_length = - vub300->resp.common.header_size - - sizeof(struct sd_register_header); - int register_count = offloaded_data_length >> 3; - int ri = 0; - while (register_count--) { - add_offloaded_reg(vub300, &vub300->resp.pig.reg[ri]); - ri += 1; - } - mutex_lock(&vub300->irq_mutex); - if (vub300->irqs_queued) { - vub300->irqs_queued += 1; - } else if (vub300->irq_enabled) { - vub300->irqs_queued += 1; - vub300_queue_poll_work(vub300, 0); - } else { - vub300->irqs_queued += 1; - } - vub300->irq_disabled = 1; - mutex_unlock(&vub300->irq_mutex); - vub300->resp.common.header_size = - sizeof(struct sd_register_header); - vub300->resp.common.header_type = 0x00; - cmd->error = 0; - } else if (vub300->resp.common.header_type == RESPONSE_PIG_ENABLED) { - int offloaded_data_length = - vub300->resp.common.header_size - - sizeof(struct sd_register_header); - int register_count = offloaded_data_length >> 3; - int ri = 0; - while (register_count--) { - add_offloaded_reg(vub300, &vub300->resp.pig.reg[ri]); - ri += 1; - } - mutex_lock(&vub300->irq_mutex); - if (vub300->irqs_queued) { - vub300->irqs_queued += 1; - } else if (vub300->irq_enabled) { - vub300->irqs_queued += 1; - vub300_queue_poll_work(vub300, 0); - } else { - vub300->irqs_queued += 1; - } - vub300->irq_disabled = 0; - mutex_unlock(&vub300->irq_mutex); - vub300->resp.common.header_size = - sizeof(struct sd_register_header); - vub300->resp.common.header_type = 0x00; - cmd->error = 0; - } else { - cmd->error = -EINVAL; - } - - return false; -} - -static void construct_request_response(struct vub300_mmc_host *vub300, - struct mmc_command *cmd) -{ - int resp_len = vub300->resp_len; - int less_cmd = (17 == resp_len) ? resp_len : resp_len - 1; - int bytes = 3 & less_cmd; - int words = less_cmd >> 2; - u8 *r = vub300->resp.response.command_response; - - if (!resp_len) - return; - if (bytes == 3) { - cmd->resp[words] = (r[1 + (words << 2)] << 24) - | (r[2 + (words << 2)] << 16) - | (r[3 + (words << 2)] << 8); - } else if (bytes == 2) { - cmd->resp[words] = (r[1 + (words << 2)] << 24) - | (r[2 + (words << 2)] << 16); - } else if (bytes == 1) { - cmd->resp[words] = (r[1 + (words << 2)] << 24); - } - while (words-- > 0) { - cmd->resp[words] = (r[1 + (words << 2)] << 24) - | (r[2 + (words << 2)] << 16) - | (r[3 + (words << 2)] << 8) - | (r[4 + (words << 2)] << 0); - } - if ((cmd->opcode == 53) && (0x000000FF & cmd->resp[0])) - cmd->resp[0] &= 0xFFFFFF00; -} - -/* this thread runs only when there is an upper level command req outstanding */ -static void vub300_cmndwork_thread(struct work_struct *work) -{ - struct vub300_mmc_host *vub300 = - container_of(work, struct vub300_mmc_host, cmndwork); - if (!vub300->interface) { - kref_put(&vub300->kref, vub300_delete); - return; - } else { - struct mmc_request *req = vub300->req; - struct mmc_command *cmd = vub300->cmd; - struct mmc_data *data = vub300->data; - bool reset_device; - int data_length; - mutex_lock(&vub300->cmd_mutex); - init_completion(&vub300->command_complete); - if (likely(vub300->vub_name[0]) || !vub300->mmc->card) { - /* - * the name of the EMPTY Pseudo firmware file - * is used as a flag to indicate that the file - * has been already downloaded to the VUB300 chip - */ - } else if (0 == vub300->mmc->card->sdio_funcs) { - strscpy(vub300->vub_name, "SD memory device", - sizeof(vub300->vub_name)); - } else { - download_offload_pseudocode(vub300); - } - send_command(vub300); - if (!data) - data_length = 0; - else if (MMC_DATA_READ & data->flags) - data_length = __command_read_data(vub300, cmd, data); - else - data_length = __command_write_data(vub300, cmd, data); - reset_device = __vub300_command_response(vub300, cmd, - data, data_length); - vub300->req = NULL; - vub300->cmd = NULL; - vub300->data = NULL; - if (cmd->error) { - if (cmd->error == -ENOMEDIUM) - check_vub300_port_status(vub300); - mutex_unlock(&vub300->cmd_mutex); - if (reset_device) { - int result; - - result = usb_lock_device_for_reset(vub300->udev, - vub300->interface); - if (result == 0) { - result = usb_reset_device(vub300->udev); - usb_unlock_device(vub300->udev); - } - } - mmc_request_done(vub300->mmc, req); - kref_put(&vub300->kref, vub300_delete); - return; - } else { - construct_request_response(vub300, cmd); - vub300->resp_len = 0; - mutex_unlock(&vub300->cmd_mutex); - kref_put(&vub300->kref, vub300_delete); - mmc_request_done(vub300->mmc, req); - return; - } - } -} - -static int examine_cyclic_buffer(struct vub300_mmc_host *vub300, - struct mmc_command *cmd, u8 Function) -{ - /* cmd_mutex is held by vub300_mmc_request */ - u8 cmd0 = 0xFF & (cmd->arg >> 24); - u8 cmd1 = 0xFF & (cmd->arg >> 16); - u8 cmd2 = 0xFF & (cmd->arg >> 8); - u8 cmd3 = 0xFF & (cmd->arg >> 0); - int first = MAXREGMASK & vub300->fn[Function].offload_point; - struct offload_registers_access *rf = &vub300->fn[Function].reg[first]; - if (cmd0 == rf->command_byte[0] && - cmd1 == rf->command_byte[1] && - cmd2 == rf->command_byte[2] && - cmd3 == rf->command_byte[3]) { - u8 checksum = 0x00; - cmd->resp[1] = checksum << 24; - cmd->resp[0] = (rf->Respond_Byte[0] << 24) - | (rf->Respond_Byte[1] << 16) - | (rf->Respond_Byte[2] << 8) - | (rf->Respond_Byte[3] << 0); - vub300->fn[Function].offload_point += 1; - vub300->fn[Function].offload_count -= 1; - vub300->total_offload_count -= 1; - return 1; - } else { - int delta = 1; /* because it does not match the first one */ - u8 register_count = vub300->fn[Function].offload_count - 1; - u32 register_point = vub300->fn[Function].offload_point + 1; - while (0 < register_count) { - int point = MAXREGMASK & register_point; - struct offload_registers_access *r = - &vub300->fn[Function].reg[point]; - if (cmd0 == r->command_byte[0] && - cmd1 == r->command_byte[1] && - cmd2 == r->command_byte[2] && - cmd3 == r->command_byte[3]) { - u8 checksum = 0x00; - cmd->resp[1] = checksum << 24; - cmd->resp[0] = (r->Respond_Byte[0] << 24) - | (r->Respond_Byte[1] << 16) - | (r->Respond_Byte[2] << 8) - | (r->Respond_Byte[3] << 0); - vub300->fn[Function].offload_point += delta; - vub300->fn[Function].offload_count -= delta; - vub300->total_offload_count -= delta; - return 1; - } else { - register_point += 1; - register_count -= 1; - delta += 1; - continue; - } - } - return 0; - } -} - -static int satisfy_request_from_offloaded_data(struct vub300_mmc_host *vub300, - struct mmc_command *cmd) -{ - /* cmd_mutex is held by vub300_mmc_request */ - u8 regs = vub300->dynamic_register_count; - u8 i = 0; - u8 func = FUN(cmd); - u32 reg = REG(cmd); - while (0 < regs--) { - if ((vub300->sdio_register[i].func_num == func) && - (vub300->sdio_register[i].sdio_reg == reg)) { - if (!vub300->sdio_register[i].prepared) { - return 0; - } else if ((0x80000000 & cmd->arg) == 0x80000000) { - /* - * a write to a dynamic register - * nullifies our offloaded value - */ - vub300->sdio_register[i].prepared = 0; - return 0; - } else { - u8 checksum = 0x00; - u8 rsp0 = 0x00; - u8 rsp1 = 0x00; - u8 rsp2 = vub300->sdio_register[i].response; - u8 rsp3 = vub300->sdio_register[i].regvalue; - vub300->sdio_register[i].prepared = 0; - cmd->resp[1] = checksum << 24; - cmd->resp[0] = (rsp0 << 24) - | (rsp1 << 16) - | (rsp2 << 8) - | (rsp3 << 0); - return 1; - } - } else { - i += 1; - continue; - } - } - if (vub300->total_offload_count == 0) - return 0; - else if (vub300->fn[func].offload_count == 0) - return 0; - else - return examine_cyclic_buffer(vub300, cmd, func); -} - -static void vub300_mmc_request(struct mmc_host *mmc, struct mmc_request *req) -{ /* NOT irq */ - struct mmc_command *cmd = req->cmd; - struct vub300_mmc_host *vub300 = mmc_priv(mmc); - if (!vub300->interface) { - cmd->error = -ESHUTDOWN; - mmc_request_done(mmc, req); - return; - } else { - struct mmc_data *data = req->data; - if (!vub300->card_powered) { - cmd->error = -ENOMEDIUM; - mmc_request_done(mmc, req); - return; - } - if (!vub300->card_present) { - cmd->error = -ENOMEDIUM; - mmc_request_done(mmc, req); - return; - } - if (vub300->usb_transport_fail) { - cmd->error = vub300->usb_transport_fail; - mmc_request_done(mmc, req); - return; - } - if (!vub300->interface) { - cmd->error = -ENODEV; - mmc_request_done(mmc, req); - return; - } - kref_get(&vub300->kref); - mutex_lock(&vub300->cmd_mutex); - mod_timer(&vub300->inactivity_timer, jiffies + HZ); - /* - * for performance we have to return immediately - * if the requested data has been offloaded - */ - if (cmd->opcode == 52 && - satisfy_request_from_offloaded_data(vub300, cmd)) { - cmd->error = 0; - mutex_unlock(&vub300->cmd_mutex); - kref_put(&vub300->kref, vub300_delete); - mmc_request_done(mmc, req); - return; - } else { - vub300->cmd = cmd; - vub300->req = req; - vub300->data = data; - if (data) - vub300->datasize = data->blksz * data->blocks; - else - vub300->datasize = 0; - vub300_queue_cmnd_work(vub300); - mutex_unlock(&vub300->cmd_mutex); - kref_put(&vub300->kref, vub300_delete); - /* - * the kernel lock diagnostics complain - * if the cmd_mutex * is "passed on" - * to the cmndwork thread, - * so we must release it now - * and re-acquire it in the cmndwork thread - */ - } - } -} - -static void __set_clock_speed(struct vub300_mmc_host *vub300, u8 buf[8], - struct mmc_ios *ios) -{ - int buf_array_size = 8; /* ARRAY_SIZE(buf) does not work !!! */ - int retval; - u32 kHzClock; - if (ios->clock >= 48000000) - kHzClock = 48000; - else if (ios->clock >= 24000000) - kHzClock = 24000; - else if (ios->clock >= 20000000) - kHzClock = 20000; - else if (ios->clock >= 15000000) - kHzClock = 15000; - else if (ios->clock >= 200000) - kHzClock = 200; - else - kHzClock = 0; - { - int i; - u64 c = kHzClock; - for (i = 0; i < buf_array_size; i++) { - buf[i] = c; - c >>= 8; - } - } - retval = - usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0), - SET_CLOCK_SPEED, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x00, 0x00, buf, buf_array_size, 1000); - if (retval != 8) { - dev_err(&vub300->udev->dev, "SET_CLOCK_SPEED" - " %dkHz failed with retval=%d\n", kHzClock, retval); - } else { - dev_dbg(&vub300->udev->dev, "SET_CLOCK_SPEED" - " %dkHz\n", kHzClock); - } -} - -static void vub300_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -{ /* NOT irq */ - struct vub300_mmc_host *vub300 = mmc_priv(mmc); - if (!vub300->interface) - return; - kref_get(&vub300->kref); - mutex_lock(&vub300->cmd_mutex); - if ((ios->power_mode == MMC_POWER_OFF) && vub300->card_powered) { - vub300->card_powered = 0; - usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0), - SET_SD_POWER, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0000, 0x0000, NULL, 0, 1000); - /* must wait for the VUB300 u-proc to boot up */ - msleep(600); - } else if ((ios->power_mode == MMC_POWER_UP) && !vub300->card_powered) { - usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0), - SET_SD_POWER, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0001, 0x0000, NULL, 0, 1000); - msleep(600); - vub300->card_powered = 1; - } else if (ios->power_mode == MMC_POWER_ON) { - u8 *buf = kmalloc(8, GFP_KERNEL); - if (buf) { - __set_clock_speed(vub300, buf, ios); - kfree(buf); - } - } else { - /* this should mean no change of state */ - } - mutex_unlock(&vub300->cmd_mutex); - kref_put(&vub300->kref, vub300_delete); -} - -static int vub300_mmc_get_ro(struct mmc_host *mmc) -{ - struct vub300_mmc_host *vub300 = mmc_priv(mmc); - return vub300->read_only; -} - -static void vub300_enable_sdio_irq(struct mmc_host *mmc, int enable) -{ /* NOT irq */ - struct vub300_mmc_host *vub300 = mmc_priv(mmc); - if (!vub300->interface) - return; - kref_get(&vub300->kref); - if (enable) { - set_current_state(TASK_RUNNING); - mutex_lock(&vub300->irq_mutex); - if (vub300->irqs_queued) { - vub300->irqs_queued -= 1; - mmc_signal_sdio_irq(vub300->mmc); - } else if (vub300->irq_disabled) { - vub300->irq_disabled = 0; - vub300->irq_enabled = 1; - vub300_queue_poll_work(vub300, 0); - } else if (vub300->irq_enabled) { - /* this should not happen, so we will just ignore it */ - } else { - vub300->irq_enabled = 1; - vub300_queue_poll_work(vub300, 0); - } - mutex_unlock(&vub300->irq_mutex); - set_current_state(TASK_INTERRUPTIBLE); - } else { - vub300->irq_enabled = 0; - } - kref_put(&vub300->kref, vub300_delete); -} - -static const struct mmc_host_ops vub300_mmc_ops = { - .request = vub300_mmc_request, - .set_ios = vub300_mmc_set_ios, - .get_ro = vub300_mmc_get_ro, - .enable_sdio_irq = vub300_enable_sdio_irq, -}; - -static int vub300_probe(struct usb_interface *interface, - const struct usb_device_id *id) -{ /* NOT irq */ - struct vub300_mmc_host *vub300; - struct usb_host_interface *iface_desc; - struct usb_device *udev = usb_get_dev(interface_to_usbdev(interface)); - int i; - int retval = -ENOMEM; - struct urb *command_out_urb; - struct urb *command_res_urb; - struct mmc_host *mmc; - char manufacturer[48]; - char product[32]; - char serial_number[32]; - usb_string(udev, udev->descriptor.iManufacturer, manufacturer, - sizeof(manufacturer)); - usb_string(udev, udev->descriptor.iProduct, product, sizeof(product)); - usb_string(udev, udev->descriptor.iSerialNumber, serial_number, - sizeof(serial_number)); - dev_info(&udev->dev, "probing VID:PID(%04X:%04X) %s %s %s\n", - le16_to_cpu(udev->descriptor.idVendor), - le16_to_cpu(udev->descriptor.idProduct), - manufacturer, product, serial_number); - command_out_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!command_out_urb) { - retval = -ENOMEM; - goto err_put_udev; - } - command_res_urb = usb_alloc_urb(0, GFP_KERNEL); - if (!command_res_urb) { - retval = -ENOMEM; - goto err_free_out_urb; - } - /* this also allocates memory for our VUB300 mmc host device */ - mmc = mmc_alloc_host(sizeof(*vub300), &udev->dev); - if (!mmc) { - retval = -ENOMEM; - dev_err(&udev->dev, "not enough memory for the mmc_host\n"); - goto err_free_res_urb; - } - /* MMC core transfer sizes tunable parameters */ - mmc->caps = 0; - if (!force_1_bit_data_xfers) - mmc->caps |= MMC_CAP_4_BIT_DATA; - if (!force_polling_for_irqs) - mmc->caps |= MMC_CAP_SDIO_IRQ; - mmc->caps &= ~MMC_CAP_NEEDS_POLL; - /* - * MMC_CAP_NEEDS_POLL causes core.c:mmc_rescan() to poll - * for devices which results in spurious CMD7's being - * issued which stops some SDIO cards from working - */ - if (limit_speed_to_24_MHz) { - mmc->caps |= MMC_CAP_MMC_HIGHSPEED; - mmc->caps |= MMC_CAP_SD_HIGHSPEED; - mmc->f_max = 24000000; - dev_info(&udev->dev, "limiting SDIO speed to 24_MHz\n"); - } else { - mmc->caps |= MMC_CAP_MMC_HIGHSPEED; - mmc->caps |= MMC_CAP_SD_HIGHSPEED; - mmc->f_max = 48000000; - } - mmc->f_min = 200000; - mmc->max_blk_count = 511; - mmc->max_blk_size = 512; - mmc->max_segs = 128; - if (force_max_req_size) - mmc->max_req_size = force_max_req_size * 1024; - else - mmc->max_req_size = 64 * 1024; - mmc->max_seg_size = mmc->max_req_size; - mmc->ocr_avail = 0; - mmc->ocr_avail |= MMC_VDD_165_195; - mmc->ocr_avail |= MMC_VDD_20_21; - mmc->ocr_avail |= MMC_VDD_21_22; - mmc->ocr_avail |= MMC_VDD_22_23; - mmc->ocr_avail |= MMC_VDD_23_24; - mmc->ocr_avail |= MMC_VDD_24_25; - mmc->ocr_avail |= MMC_VDD_25_26; - mmc->ocr_avail |= MMC_VDD_26_27; - mmc->ocr_avail |= MMC_VDD_27_28; - mmc->ocr_avail |= MMC_VDD_28_29; - mmc->ocr_avail |= MMC_VDD_29_30; - mmc->ocr_avail |= MMC_VDD_30_31; - mmc->ocr_avail |= MMC_VDD_31_32; - mmc->ocr_avail |= MMC_VDD_32_33; - mmc->ocr_avail |= MMC_VDD_33_34; - mmc->ocr_avail |= MMC_VDD_34_35; - mmc->ocr_avail |= MMC_VDD_35_36; - mmc->ops = &vub300_mmc_ops; - vub300 = mmc_priv(mmc); - vub300->mmc = mmc; - vub300->card_powered = 0; - vub300->bus_width = 0; - vub300->cmnd.head.block_size[0] = 0x00; - vub300->cmnd.head.block_size[1] = 0x00; - vub300->app_spec = 0; - mutex_init(&vub300->cmd_mutex); - mutex_init(&vub300->irq_mutex); - vub300->command_out_urb = command_out_urb; - vub300->command_res_urb = command_res_urb; - vub300->usb_timed_out = 0; - vub300->dynamic_register_count = 0; - - for (i = 0; i < ARRAY_SIZE(vub300->fn); i++) { - vub300->fn[i].offload_point = 0; - vub300->fn[i].offload_count = 0; - } - - vub300->total_offload_count = 0; - vub300->irq_enabled = 0; - vub300->irq_disabled = 0; - vub300->irqs_queued = 0; - - for (i = 0; i < ARRAY_SIZE(vub300->sdio_register); i++) - vub300->sdio_register[i++].activate = 0; - - vub300->udev = udev; - vub300->interface = interface; - vub300->cmnd_res_ep = 0; - vub300->cmnd_out_ep = 0; - vub300->data_inp_ep = 0; - vub300->data_out_ep = 0; - - for (i = 0; i < ARRAY_SIZE(vub300->fbs); i++) - vub300->fbs[i] = 512; - - /* - * set up the endpoint information - * - * use the first pair of bulk-in and bulk-out - * endpoints for Command/Response+Interrupt - * - * use the second pair of bulk-in and bulk-out - * endpoints for Data In/Out - */ - vub300->large_usb_packets = 0; - iface_desc = interface->cur_altsetting; - for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) { - struct usb_endpoint_descriptor *endpoint = - &iface_desc->endpoint[i].desc; - dev_info(&vub300->udev->dev, - "vub300 testing %s EndPoint(%d) %02X\n", - usb_endpoint_is_bulk_in(endpoint) ? "BULK IN" : - usb_endpoint_is_bulk_out(endpoint) ? "BULK OUT" : - "UNKNOWN", i, endpoint->bEndpointAddress); - if (endpoint->wMaxPacketSize > 64) - vub300->large_usb_packets = 1; - if (usb_endpoint_is_bulk_in(endpoint)) { - if (!vub300->cmnd_res_ep) { - vub300->cmnd_res_ep = - endpoint->bEndpointAddress; - } else if (!vub300->data_inp_ep) { - vub300->data_inp_ep = - endpoint->bEndpointAddress; - } else { - dev_warn(&vub300->udev->dev, - "ignoring" - " unexpected bulk_in endpoint"); - } - } else if (usb_endpoint_is_bulk_out(endpoint)) { - if (!vub300->cmnd_out_ep) { - vub300->cmnd_out_ep = - endpoint->bEndpointAddress; - } else if (!vub300->data_out_ep) { - vub300->data_out_ep = - endpoint->bEndpointAddress; - } else { - dev_warn(&vub300->udev->dev, - "ignoring" - " unexpected bulk_out endpoint"); - } - } else { - dev_warn(&vub300->udev->dev, - "vub300 ignoring EndPoint(%d) %02X", i, - endpoint->bEndpointAddress); - } - } - if (vub300->cmnd_res_ep && vub300->cmnd_out_ep && - vub300->data_inp_ep && vub300->data_out_ep) { - dev_info(&vub300->udev->dev, - "vub300 %s packets" - " using EndPoints %02X %02X %02X %02X\n", - vub300->large_usb_packets ? "LARGE" : "SMALL", - vub300->cmnd_out_ep, vub300->cmnd_res_ep, - vub300->data_out_ep, vub300->data_inp_ep); - /* we have the expected EndPoints */ - } else { - dev_err(&vub300->udev->dev, - "Could not find two sets of bulk-in/out endpoint pairs\n"); - retval = -EINVAL; - goto err_free_host; - } - retval = - usb_control_msg(vub300->udev, usb_rcvctrlpipe(vub300->udev, 0), - GET_HC_INF0, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0000, 0x0000, &vub300->hc_info, - sizeof(vub300->hc_info), 1000); - if (retval < 0) - goto err_free_host; - retval = - usb_control_msg(vub300->udev, usb_sndctrlpipe(vub300->udev, 0), - SET_ROM_WAIT_STATES, - USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - firmware_rom_wait_states, 0x0000, NULL, 0, 1000); - if (retval < 0) - goto err_free_host; - dev_info(&vub300->udev->dev, - "operating_mode = %s %s %d MHz %s %d byte USB packets\n", - (mmc->caps & MMC_CAP_SDIO_IRQ) ? "IRQs" : "POLL", - (mmc->caps & MMC_CAP_4_BIT_DATA) ? "4-bit" : "1-bit", - mmc->f_max / 1000000, - pad_input_to_usb_pkt ? "padding input data to" : "with", - vub300->large_usb_packets ? 512 : 64); - retval = - usb_control_msg(vub300->udev, usb_rcvctrlpipe(vub300->udev, 0), - GET_SYSTEM_PORT_STATUS, - USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, - 0x0000, 0x0000, &vub300->system_port_status, - sizeof(vub300->system_port_status), 1000); - if (retval < 0) { - goto err_free_host; - } else if (sizeof(vub300->system_port_status) == retval) { - vub300->card_present = - (0x0001 & vub300->system_port_status.port_flags) ? 1 : 0; - vub300->read_only = - (0x0010 & vub300->system_port_status.port_flags) ? 1 : 0; - } else { - retval = -EINVAL; - goto err_free_host; - } - usb_set_intfdata(interface, vub300); - INIT_DELAYED_WORK(&vub300->pollwork, vub300_pollwork_thread); - INIT_WORK(&vub300->cmndwork, vub300_cmndwork_thread); - INIT_WORK(&vub300->deadwork, vub300_deadwork_thread); - kref_init(&vub300->kref); - timer_setup(&vub300->sg_transfer_timer, vub300_sg_timed_out, 0); - kref_get(&vub300->kref); - timer_setup(&vub300->inactivity_timer, - vub300_inactivity_timer_expired, 0); - vub300->inactivity_timer.expires = jiffies + HZ; - add_timer(&vub300->inactivity_timer); - if (vub300->card_present) - dev_info(&vub300->udev->dev, - "USB vub300 remote SDIO host controller[%d]" - "connected with SD/SDIO card inserted\n", - interface_to_InterfaceNumber(interface)); - else - dev_info(&vub300->udev->dev, - "USB vub300 remote SDIO host controller[%d]" - "connected with no SD/SDIO card inserted\n", - interface_to_InterfaceNumber(interface)); - retval = mmc_add_host(mmc); - if (retval) - goto err_stop_io; - - return 0; - -err_stop_io: - vub300->interface = NULL; - kref_put(&vub300->kref, vub300_delete); - - return retval; - -err_free_host: - mmc_free_host(mmc); - /* - * and hence also frees vub300 - * which is contained at the end of struct mmc - */ -err_free_res_urb: - usb_free_urb(command_res_urb); -err_free_out_urb: - usb_free_urb(command_out_urb); -err_put_udev: - usb_put_dev(udev); - - return retval; -} - -static void vub300_disconnect(struct usb_interface *interface) -{ /* NOT irq */ - struct vub300_mmc_host *vub300 = usb_get_intfdata(interface); - if (!vub300 || !vub300->mmc) { - return; - } else { - struct mmc_host *mmc = vub300->mmc; - if (!vub300->mmc) { - return; - } else { - int ifnum = interface_to_InterfaceNumber(interface); - usb_set_intfdata(interface, NULL); - /* prevent more I/O from starting */ - vub300->interface = NULL; - mmc_remove_host(mmc); - kref_put(&vub300->kref, vub300_delete); - pr_info("USB vub300 remote SDIO host controller[%d]" - " now disconnected", ifnum); - return; - } - } -} - -#ifdef CONFIG_PM -static int vub300_suspend(struct usb_interface *intf, pm_message_t message) -{ - return 0; -} - -static int vub300_resume(struct usb_interface *intf) -{ - return 0; -} -#else -#define vub300_suspend NULL -#define vub300_resume NULL -#endif -static int vub300_pre_reset(struct usb_interface *intf) -{ /* NOT irq */ - struct vub300_mmc_host *vub300 = usb_get_intfdata(intf); - mutex_lock(&vub300->cmd_mutex); - return 0; -} - -static int vub300_post_reset(struct usb_interface *intf) -{ /* NOT irq */ - struct vub300_mmc_host *vub300 = usb_get_intfdata(intf); - /* we are sure no URBs are active - no locking needed */ - vub300->errors = -EPIPE; - mutex_unlock(&vub300->cmd_mutex); - return 0; -} - -static struct usb_driver vub300_driver = { - .name = "vub300", - .probe = vub300_probe, - .disconnect = vub300_disconnect, - .suspend = vub300_suspend, - .resume = vub300_resume, - .pre_reset = vub300_pre_reset, - .post_reset = vub300_post_reset, - .id_table = vub300_table, - .supports_autosuspend = 1, -}; - -static int __init vub300_init(void) -{ /* NOT irq */ - int result; - - pr_info("VUB300 Driver rom wait states = %02X irqpoll timeout = %04X", - firmware_rom_wait_states, 0x0FFFF & firmware_irqpoll_timeout); - - cmndworkqueue = create_singlethread_workqueue("kvub300c"); - if (!cmndworkqueue) - return -ENOMEM; - - pollworkqueue = create_singlethread_workqueue("kvub300p"); - if (!pollworkqueue) { - result = -ENOMEM; - goto err_destroy_cmdwq; - } - - deadworkqueue = create_singlethread_workqueue("kvub300d"); - if (!deadworkqueue) { - result = -ENOMEM; - goto err_destroy_pollwq; - } - - result = usb_register(&vub300_driver); - if (result) - goto err_destroy_deadwq; - - return 0; - -err_destroy_deadwq: - destroy_workqueue(deadworkqueue); -err_destroy_pollwq: - destroy_workqueue(pollworkqueue); -err_destroy_cmdwq: - destroy_workqueue(cmndworkqueue); - - return result; -} - -static void __exit vub300_exit(void) -{ - usb_deregister(&vub300_driver); - flush_workqueue(cmndworkqueue); - flush_workqueue(pollworkqueue); - flush_workqueue(deadworkqueue); - destroy_workqueue(cmndworkqueue); - destroy_workqueue(pollworkqueue); - destroy_workqueue(deadworkqueue); -} - -module_init(vub300_init); -module_exit(vub300_exit); - -MODULE_AUTHOR("Tony Olech <tony.olech@elandigitalsystems.com>"); -MODULE_DESCRIPTION("VUB300 USB to SD/MMC/SDIO adapter driver"); -MODULE_LICENSE("GPL");
diff --git a/drivers/pinctrl/freescale/pinctrl-imx.c b/drivers/pinctrl/freescale/pinctrl-imx.c index 9a45b37..f08ef52 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx.c +++ b/drivers/pinctrl/freescale/pinctrl-imx.c
@@ -21,6 +21,7 @@ #include <linux/pinctrl/machine.h> #include <linux/pinctrl/pinconf.h> +#include <linux/pinctrl/pinconf-generic.h> #include <linux/pinctrl/pinctrl.h> #include <linux/pinctrl/pinmux.h> @@ -291,8 +292,8 @@ struct pinmux_ops imx_pmx_ops = { .set_mux = imx_pmx_set, }; -static int imx_pinconf_get_mmio(struct pinctrl_dev *pctldev, unsigned pin_id, - unsigned long *config) +static int imx_pinconf_get_raw_mmio(struct pinctrl_dev *pctldev, + unsigned int pin_id, unsigned long *config) { struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); const struct imx_pinctrl_soc_info *info = ipctl->info; @@ -312,6 +313,39 @@ static int imx_pinconf_get_mmio(struct pinctrl_dev *pctldev, unsigned pin_id, return 0; } +static int imx_pinconf_get_mmio(struct pinctrl_dev *pctldev, + unsigned int pin_id, unsigned long *config) +{ + struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); + const struct imx_pinctrl_soc_info *info = ipctl->info; + const struct imx_pin_reg *pin_reg = &ipctl->pin_regs[pin_id]; + enum pin_config_param param = pinconf_to_config_param(*config); + unsigned int mask; + u32 raw; + + switch (param) { + case PIN_CONFIG_OUTPUT_ENABLE: + mask = info->obe_mask; + break; + case PIN_CONFIG_INPUT_ENABLE: + mask = info->ibe_mask; + break; + default: + mask = 0; + break; + } + + if (!mask) + return -ENOTSUPP; + if (pin_reg->conf_reg == -1) + return -EINVAL; + + raw = readl(ipctl->base + pin_reg->conf_reg); + *config = pinconf_to_config_packed(param, !!(raw & mask)); + + return 0; +} + static int imx_pinconf_get(struct pinctrl_dev *pctldev, unsigned pin_id, unsigned long *config) { @@ -319,9 +353,21 @@ static int imx_pinconf_get(struct pinctrl_dev *pctldev, const struct imx_pinctrl_soc_info *info = ipctl->info; if (info->flags & IMX_USE_SCU) + return -ENOTSUPP; + + return imx_pinconf_get_mmio(pctldev, pin_id, config); +} + +static int imx_pinconf_get_raw(struct pinctrl_dev *pctldev, + unsigned int pin_id, unsigned long *config) +{ + struct imx_pinctrl *ipctl = pinctrl_dev_get_drvdata(pctldev); + const struct imx_pinctrl_soc_info *info = ipctl->info; + + if (info->flags & IMX_USE_SCU) return info->imx_pinconf_get(pctldev, pin_id, config); else - return imx_pinconf_get_mmio(pctldev, pin_id, config); + return imx_pinconf_get_raw_mmio(pctldev, pin_id, config); } static int imx_pinconf_set_mmio(struct pinctrl_dev *pctldev, @@ -426,7 +472,7 @@ static void imx_pinconf_group_dbg_show(struct pinctrl_dev *pctldev, struct imx_pin *pin = &((struct imx_pin *)(grp->data))[i]; name = pin_get_name(pctldev, pin->pin); - ret = imx_pinconf_get(pctldev, pin->pin, &config); + ret = imx_pinconf_get_raw(pctldev, pin->pin, &config); if (ret) return; seq_printf(s, " %s: 0x%lx\n", name, config);
diff --git a/drivers/pinctrl/freescale/pinctrl-imx.h b/drivers/pinctrl/freescale/pinctrl-imx.h index f65ff45b..8fa7e1e 100644 --- a/drivers/pinctrl/freescale/pinctrl-imx.h +++ b/drivers/pinctrl/freescale/pinctrl-imx.h
@@ -91,6 +91,10 @@ struct imx_pinctrl_soc_info { unsigned int mux_mask; u8 mux_shift; + /* OBE/IBE bits in the conf register, 0 if the pad does not have them */ + unsigned int obe_mask; + unsigned int ibe_mask; + int (*gpio_set_direction)(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned offset,
diff --git a/drivers/pinctrl/freescale/pinctrl-vf610.c b/drivers/pinctrl/freescale/pinctrl-vf610.c index 76a4bc0..77d0776 100644 --- a/drivers/pinctrl/freescale/pinctrl-vf610.c +++ b/drivers/pinctrl/freescale/pinctrl-vf610.c
@@ -319,6 +319,8 @@ static const struct imx_pinctrl_soc_info vf610_pinctrl_info = { .gpio_set_direction = vf610_pmx_gpio_set_direction, .mux_mask = 0x700000, .mux_shift = 20, + .obe_mask = 0x2, + .ibe_mask = 0x1, }; static const struct of_device_id vf610_pinctrl_of_match[] = {
diff --git a/drivers/platform/cznic/turris-omnia-mcu-base.c b/drivers/platform/cznic/turris-omnia-mcu-base.c index e8fc0d7..f041630 100644 --- a/drivers/platform/cznic/turris-omnia-mcu-base.c +++ b/drivers/platform/cznic/turris-omnia-mcu-base.c
@@ -403,6 +403,7 @@ static const struct of_device_id of_omnia_mcu_match[] = { { .compatible = "cznic,turris-omnia-mcu" }, {} }; +MODULE_DEVICE_TABLE(of, of_omnia_mcu_match); static struct i2c_driver omnia_mcu_driver = { .probe = omnia_mcu_probe,
diff --git a/drivers/platform/cznic/turris-omnia-mcu-gpio.c b/drivers/platform/cznic/turris-omnia-mcu-gpio.c index 4e430d6..8f43bfa 100644 --- a/drivers/platform/cznic/turris-omnia-mcu-gpio.c +++ b/drivers/platform/cznic/turris-omnia-mcu-gpio.c
@@ -11,7 +11,6 @@ #include <linux/bug.h> #include <linux/cleanup.h> #include <linux/device.h> -#include <linux/devm-helpers.h> #include <linux/errno.h> #include <linux/gpio/consumer.h> #include <linux/gpio/driver.h> @@ -841,6 +840,18 @@ static void button_release_emul_fn(struct work_struct *work) generic_handle_irq_safe(mcu->client->irq); } +static void omnia_disable_button_release_work(void *data) +{ + struct delayed_work *work = data; + + /* + * The IRQ thread may requeue this work while the IRQ remains active. + * Disable and drain it before releasing the IRQ action and the MCU + * state used by the worker. + */ + disable_delayed_work_sync(work); +} + static void fill_int_from_sts(unsigned long *rising, unsigned long *falling, unsigned long rising_sts, unsigned long falling_sts, @@ -1082,21 +1093,9 @@ int omnia_mcu_register_gpiochip(struct omnia_mcu *mcu) return dev_err_probe(dev, err, "Cannot request IRQ\n"); if (!new_api) { - /* - * The button_release_emul_work has to be initialized before the - * thread is requested, and on driver remove it needs to be - * canceled before the thread is freed. Therefore we can't use - * devm_delayed_work_autocancel() directly, because the order - * devm_delayed_work_autocancel(); - * devm_request_threaded_irq(); - * would cause improper release order: - * free_irq(); - * cancel_delayed_work_sync(); - * Instead we first initialize the work above, and only now - * after IRQ is requested we add the work devm action. - */ - err = devm_add_action(dev, devm_delayed_work_drop, - &mcu->button_release_emul_work); + err = devm_add_action_or_reset(dev, + omnia_disable_button_release_work, + &mcu->button_release_emul_work); if (err) return err; }
diff --git a/drivers/pmdomain/Kconfig b/drivers/pmdomain/Kconfig index 23076ae..5341dff 100644 --- a/drivers/pmdomain/Kconfig +++ b/drivers/pmdomain/Kconfig
@@ -11,6 +11,7 @@ source "drivers/pmdomain/mediatek/Kconfig" source "drivers/pmdomain/qcom/Kconfig" source "drivers/pmdomain/renesas/Kconfig" +source "drivers/pmdomain/riscv/Kconfig" source "drivers/pmdomain/rockchip/Kconfig" source "drivers/pmdomain/samsung/Kconfig" source "drivers/pmdomain/st/Kconfig"
diff --git a/drivers/pmdomain/Makefile b/drivers/pmdomain/Makefile index ebc802f..d7aee13 100644 --- a/drivers/pmdomain/Makefile +++ b/drivers/pmdomain/Makefile
@@ -9,6 +9,7 @@ obj-y += mediatek/ obj-y += qcom/ obj-y += renesas/ +obj-y += riscv/ obj-y += rockchip/ obj-y += samsung/ obj-y += st/
diff --git a/drivers/pmdomain/core.c b/drivers/pmdomain/core.c index 052ec47..964e44c 100644 --- a/drivers/pmdomain/core.c +++ b/drivers/pmdomain/core.c
@@ -10,6 +10,7 @@ #include <linux/idr.h> #include <linux/kernel.h> #include <linux/io.h> +#include <linux/iopoll.h> #include <linux/platform_device.h> #include <linux/pm_opp.h> #include <linux/pm_runtime.h> @@ -19,11 +20,15 @@ #include <linux/slab.h> #include <linux/err.h> #include <linux/sched.h> +#include <linux/smp.h> #include <linux/suspend.h> #include <linux/export.h> #include <linux/cpu.h> #include <linux/debugfs.h> +#include <trace/events/ipi.h> +#include "core.h" + /* Provides a unique ID for each genpd device */ static DEFINE_IDA(genpd_ida); @@ -32,7 +37,9 @@ static const struct bus_type genpd_provider_bus_type = { .name = "genpd_provider", }; -#define GENPD_RETRY_MAX_MS 250 /* Approximate */ +#define GENPD_RETRY_MAX_MS 250 /* Approximate */ +#define GENPD_CPU_ON_POLL_PERIOD_US 100 /* 100us */ +#define GENPD_CPU_ON_TIMEOUT_US 300000 /* 300ms */ #define GENPD_DEV_CALLBACK(genpd, type, callback, dev) \ ({ \ @@ -173,7 +180,7 @@ static const struct genpd_lock_ops genpd_raw_spin_ops = { #define genpd_lock_interruptible(p) p->lock_ops->lock_interruptible(p) #define genpd_unlock(p) p->lock_ops->unlock(p) -#define genpd_status_on(genpd) (genpd->status == GENPD_STATE_ON) +#define genpd_status_on_unlocked(genpd) (genpd->status == GENPD_STATE_ON) #define genpd_is_irq_safe(genpd) (genpd->flags & GENPD_FLAG_IRQ_SAFE) #define genpd_is_always_on(genpd) (genpd->flags & GENPD_FLAG_ALWAYS_ON) #define genpd_is_active_wakeup(genpd) (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP) @@ -183,6 +190,7 @@ static const struct genpd_lock_ops genpd_raw_spin_ops = { #define genpd_is_dev_name_fw(genpd) (genpd->flags & GENPD_FLAG_DEV_NAME_FW) #define genpd_is_no_sync_state(genpd) (genpd->flags & GENPD_FLAG_NO_SYNC_STATE) #define genpd_is_no_stay_on(genpd) (genpd->flags & GENPD_FLAG_NO_STAY_ON) +#define genpd_is_power_unknown(genpd) (genpd->flags & GENPD_FLAG_POWER_UNKNOWN) static inline bool irq_safe_dev_in_sleep_domain(struct device *dev, const struct generic_pm_domain *genpd) @@ -276,6 +284,49 @@ static void genpd_sd_counter_inc(struct generic_pm_domain *genpd) smp_mb__after_atomic(); } +/** + * genpd_for_each_child - Recursively iterate over all devices + * in a PM domain and its subdomains. + * @genpd: PM domain to iterate over. + * @fn: Callback function to invoke for each device. + * @data: Data to pass to the callback function. + * + * This function recursively walks through all devices in the given PM domain + * and all devices in its child PM domains (subdomains). For each device found, + * the callback function @fn is invoked with the device and @data as arguments. + * + * Note: this function is inteded for use by the core and governors, + * not for pmdomain providers. + * + * Returns: 0 on success, or the first non-zero value returned by @fn. + */ +int genpd_for_each_child(struct generic_pm_domain *genpd, + int (*fn)(struct device *dev, void *data), + void *data) +{ + struct pm_domain_data *pdd; + struct gpd_link *link; + int ret; + + /* First, iterate over all devices in this domain */ + list_for_each_entry(pdd, &genpd->dev_list, list_node) { + ret = fn(pdd->dev, data); + if (ret) + return ret; + } + + /* Then, recursively iterate over all child domains (subdomains) */ + list_for_each_entry(link, &genpd->parent_links, parent_node) { + struct generic_pm_domain *child_pd = link->child; + + ret = genpd_for_each_child(child_pd, fn, data); + if (ret) + return ret; + } + + return 0; +} + #ifdef CONFIG_DEBUG_FS static struct dentry *genpd_debugfs_dir; @@ -771,8 +822,7 @@ EXPORT_SYMBOL_GPL(dev_pm_genpd_rpm_always_on); * @dev: Device to get the current power status * * This function checks whether the generic power domain associated with the - * given device is on or not by verifying if genpd_status_on equals - * GENPD_STATE_ON. + * given device is on or not by checking if genpd->status equals GENPD_STATE_ON. * * Note: this function returns the power status of the genpd at the time of the * call. The power status may change after due to activity from other devices @@ -791,7 +841,7 @@ bool dev_pm_genpd_is_on(struct device *dev) return false; genpd_lock(genpd); - is_on = genpd_status_on(genpd); + is_on = genpd_status_on_unlocked(genpd); genpd_unlock(genpd); return is_on; @@ -940,7 +990,7 @@ static void genpd_queue_power_off_work(struct generic_pm_domain *genpd) * genpd_power_off - Remove power from a given PM domain. * @genpd: PM domain to power down. * @one_dev_on: If invoked from genpd's ->runtime_suspend|resume() callback, the - * RPM status of the releated device is in an intermediate state, not yet turned + * RPM status of the related device is in an intermediate state, not yet turned * into RPM_SUSPENDED. This means genpd_power_off() must allow one device to not * be RPM_SUSPENDED, while it tries to power off the PM domain. * @depth: nesting count for lockdep. @@ -963,7 +1013,7 @@ static void genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, * The domain was on at boot and still need to stay on. * The domain has a subdomain being powered on. */ - if (!genpd_status_on(genpd) || genpd->prepared_count > 0 || + if (!genpd_status_on_unlocked(genpd) || genpd->prepared_count > 0 || genpd_is_always_on(genpd) || genpd_is_rpm_always_on(genpd) || genpd->stay_on || atomic_read(&genpd->sd_count) > 0) return; @@ -1027,22 +1077,86 @@ static void genpd_power_off(struct generic_pm_domain *genpd, bool one_dev_on, } } +static bool genpd_status_on(struct generic_pm_domain *genpd) +{ + bool is_on; + + genpd_lock(genpd); + is_on = genpd_status_on_unlocked(genpd); + genpd_unlock(genpd); + + return is_on; +} + +static int genpd_wakeup_cpu(struct generic_pm_domain *genpd) +{ + unsigned int cpu; + bool is_on; + int ret; + + /* Find the first online CPU in the genpd's cpumask. */ + cpu = cpumask_first_and(genpd->cpus, cpu_online_mask); + if (cpu >= nr_cpu_ids) + return -EAGAIN; + + genpd_unlock(genpd); + + /* Send a IPI to wakeup the selected CPU. */ + smp_send_reschedule(cpu); + + /* Poll to wait for it to complete the power on sequence. */ + ret = readx_poll_timeout_atomic(genpd_status_on, genpd, is_on, is_on, + GENPD_CPU_ON_POLL_PERIOD_US, + GENPD_CPU_ON_TIMEOUT_US); + + genpd_lock(genpd); + + /* Re-check the status as we have released the lock in between. */ + if (ret || !genpd_status_on_unlocked(genpd)) + return -EAGAIN; + + return 0; +} + +static bool genpd_need_alive_cpu(struct generic_pm_domain *genpd, + struct device *dev) +{ + if (!genpd_is_cpu_domain(genpd)) + return false; + + /* This is not for CPU devices as those are managed differently. */ + if (to_gpd_data(dev->power.subsys_data->domain_data)->cpu >= 0) + return false; + + /* + * If the current CPU doesn't belong to the genpd's cpumask, we need to + * wake up one of those idle CPUs to power on the CPU domain correctly. + */ + return !cpumask_test_cpu(smp_processor_id(), genpd->cpus); +} + /** * genpd_power_on - Restore power to a given PM domain and its parents. * @genpd: PM domain to power up. + * @dev: The device that needs the PM domain to power on. * @depth: nesting count for lockdep. * * Restore power to @genpd and all of its parents so that it is possible to * resume a device belonging to it. */ -static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth) +static int genpd_power_on(struct generic_pm_domain *genpd, struct device *dev, + unsigned int depth) { struct gpd_link *link; int ret = 0; - if (genpd_status_on(genpd)) + if (genpd_status_on_unlocked(genpd)) return 0; + /* Special case for a device attached to a CPU domain. */ + if (genpd_need_alive_cpu(genpd, dev)) + return genpd_wakeup_cpu(genpd); + /* Reflect over the entered idle-states residency for debugfs. */ genpd_reflect_residency(genpd); @@ -1057,7 +1171,7 @@ static int genpd_power_on(struct generic_pm_domain *genpd, unsigned int depth) genpd_sd_counter_inc(parent); genpd_lock_nested(parent, depth + 1); - ret = genpd_power_on(parent, depth + 1); + ret = genpd_power_on(parent, dev, depth + 1); genpd_unlock(parent); if (ret) { @@ -1307,7 +1421,7 @@ static int genpd_runtime_resume(struct device *dev) genpd_lock(genpd); genpd_restore_performance_state(dev, gpd_data->rpm_pstate); - ret = genpd_power_on(genpd, 0); + ret = genpd_power_on(genpd, dev, 0); genpd_unlock(genpd); if (ret) @@ -1406,7 +1520,7 @@ static void genpd_sync_power_off(struct generic_pm_domain *genpd, bool use_lock, { struct gpd_link *link; - if (!genpd_status_on(genpd) || genpd_is_always_on(genpd)) + if (!genpd_status_on_unlocked(genpd) || genpd_is_always_on(genpd)) return; if (genpd->suspended_count != genpd->device_count @@ -1472,7 +1586,7 @@ static void genpd_sync_power_on(struct generic_pm_domain *genpd, bool use_lock, { struct gpd_link *link; - if (genpd_status_on(genpd)) + if (genpd_status_on_unlocked(genpd)) return; list_for_each_entry(link, &genpd->child_links, child_node) { @@ -2170,7 +2284,8 @@ static int genpd_add_subdomain(struct generic_pm_domain *genpd, genpd_lock(subdomain); genpd_lock_nested(genpd, SINGLE_DEPTH_NESTING); - if (!genpd_status_on(genpd) && genpd_status_on(subdomain)) { + if (!genpd_status_on_unlocked(genpd) && + genpd_status_on_unlocked(subdomain)) { ret = -EINVAL; goto out; } @@ -2186,7 +2301,7 @@ static int genpd_add_subdomain(struct generic_pm_domain *genpd, list_add_tail(&link->parent_node, &genpd->parent_links); link->child = subdomain; list_add_tail(&link->child_node, &subdomain->child_links); - if (genpd_status_on(subdomain)) + if (genpd_status_on_unlocked(subdomain)) genpd_sd_counter_inc(genpd); out: @@ -2246,7 +2361,7 @@ int pm_genpd_remove_subdomain(struct generic_pm_domain *genpd, list_del(&link->parent_node); list_del(&link->child_node); kfree(link); - if (genpd_status_on(subdomain)) + if (genpd_status_on_unlocked(subdomain)) genpd_sd_counter_dec(genpd); ret = 0; @@ -2375,7 +2490,10 @@ static void genpd_lock_init(struct generic_pm_domain *genpd) #ifdef CONFIG_PM_GENERIC_DOMAINS_OF static void genpd_set_stay_on(struct generic_pm_domain *genpd, bool is_off) { - genpd->stay_on = !genpd_is_no_stay_on(genpd) && !is_off; + if (genpd_is_power_unknown(genpd)) + genpd->stay_on = is_off; + else + genpd->stay_on = !genpd_is_no_stay_on(genpd) && !is_off; } #else static void genpd_set_stay_on(struct generic_pm_domain *genpd, bool is_off) @@ -2441,7 +2559,7 @@ int pm_genpd_init(struct generic_pm_domain *genpd, /* Always-on domains must be powered on at initialization. */ if ((genpd_is_always_on(genpd) || genpd_is_rpm_always_on(genpd)) && - !genpd_status_on(genpd)) { + !genpd_status_on_unlocked(genpd)) { pr_err("always-on PM domain %s is not on\n", genpd->name); return -EINVAL; } @@ -3410,7 +3528,7 @@ static int __genpd_dev_pm_attach(struct device *dev, struct device *base_dev, if (power_on) { genpd_lock(pd); - ret = genpd_power_on(pd, 0); + ret = genpd_power_on(pd, dev, 0); genpd_unlock(pd); } @@ -3583,7 +3701,10 @@ static int genpd_parse_state(struct genpd_power_state *genpd_state, if (!err) genpd_state->residency_ns = 1000LL * residency; - of_property_read_string(state_node, "idle-state-name", &genpd_state->name); + err = of_property_read_string(state_node, "idle-state-name", + &genpd_state->name); + if (err) + genpd_state->name = state_node->name; genpd_state->power_on_latency_ns = 1000LL * exit_latency; genpd_state->power_off_latency_ns = 1000LL * entry_latency; @@ -3839,7 +3960,7 @@ static int genpd_summary_one(struct seq_file *s, if (WARN_ON(genpd->status >= ARRAY_SIZE(status_lookup))) goto exit; - if (!genpd_status_on(genpd)) + if (!genpd_status_on_unlocked(genpd)) snprintf(state, sizeof(state), "%s-%u", status_lookup[genpd->status], genpd->state_idx); else
diff --git a/drivers/pmdomain/core.h b/drivers/pmdomain/core.h new file mode 100644 index 0000000..d1df535 --- /dev/null +++ b/drivers/pmdomain/core.h
@@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Internal header for PM domain core + * + * Copyright (C) 2026 Kevin Hilman <khilman@baylibre.com>, Texas Instruments + */ + +#ifndef __PM_DOMAIN_CORE_H__ +#define __PM_DOMAIN_CORE_H__ + +struct device; +struct generic_pm_domain; + +int genpd_for_each_child(struct generic_pm_domain *genpd, + int (*fn)(struct device *dev, void *data), + void *data); + +#endif /* __PM_DOMAIN_CORE_H__ */
diff --git a/drivers/pmdomain/governor.c b/drivers/pmdomain/governor.c index 96737ab..38bba24 100644 --- a/drivers/pmdomain/governor.c +++ b/drivers/pmdomain/governor.c
@@ -13,6 +13,8 @@ #include <linux/cpumask.h> #include <linux/ktime.h> +#include "core.h" + static int dev_update_qos_constraint(struct device *dev, void *data) { s64 *constraint_ns_p = data; @@ -425,17 +427,60 @@ static bool cpu_power_down_ok(struct dev_pm_domain *pd) return true; } +/** + * check_device_qos_latency - Callback to check device QoS latency constraints + * @dev: Device to check + * @data: Pointer to s32 variable holding minimum latency found so far + * + * This callback checks if the device has a system-wide resume latency QoS + * constraint and updates the minimum latency if this device has a stricter + * constraint. + * + * The system-wide flag is checked first so that devices that have not opted + * in only incur a single lockless read. + * + * Returns: 0 to continue iteration. + */ +static int check_device_qos_latency(struct device *dev, void *data) +{ + s32 *min_dev_latency = data; + s32 dev_latency; + + if (!(dev_pm_qos_raw_flags(dev) & PM_QOS_FLAG_LATENCY_SYS)) + return 0; + + dev_latency = dev_pm_qos_raw_resume_latency(dev); + if (dev_latency != PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) { + if (dev_latency < *min_dev_latency) + *min_dev_latency = dev_latency; + } + + return 0; +} + static bool cpu_system_power_down_ok(struct dev_pm_domain *pd) { s64 constraint_ns = cpu_wakeup_latency_qos_limit() * NSEC_PER_USEC; struct generic_pm_domain *genpd = pd_to_genpd(pd); int state_idx = genpd->state_count - 1; + s32 min_dev_latency = PM_QOS_RESUME_LATENCY_NO_CONSTRAINT; + s64 min_dev_latency_ns; if (!(genpd->flags & GENPD_FLAG_CPU_DOMAIN)) { genpd->state_idx = state_idx; return true; } + genpd_for_each_child(genpd, check_device_qos_latency, + &min_dev_latency); + + /* If device latency < CPU wakeup latency, use it instead */ + if (min_dev_latency != PM_QOS_RESUME_LATENCY_NO_CONSTRAINT) { + min_dev_latency_ns = (s64)min_dev_latency * NSEC_PER_USEC; + if (min_dev_latency_ns < constraint_ns) + constraint_ns = min_dev_latency_ns; + } + /* Find the deepest state for the latency constraint. */ while (state_idx >= 0) { s64 latency_ns = genpd->states[state_idx].power_off_latency_ns +
diff --git a/drivers/pmdomain/imx/gpcv2.c b/drivers/pmdomain/imx/gpcv2.c index a829f8d..6a54ee7 100644 --- a/drivers/pmdomain/imx/gpcv2.c +++ b/drivers/pmdomain/imx/gpcv2.c
@@ -317,11 +317,9 @@ static int imx_pgc_power_up(struct generic_pm_domain *genpd) u32 reg_val, pgc; int ret; - ret = pm_runtime_get_sync(domain->dev); - if (ret < 0) { - pm_runtime_put_noidle(domain->dev); + ret = pm_runtime_resume_and_get(domain->dev); + if (ret < 0) return ret; - } if (!IS_ERR(domain->regulator)) { ret = regulator_enable(domain->regulator); @@ -1397,21 +1395,13 @@ static void imx_pgc_domain_remove(struct platform_device *pdev) #ifdef CONFIG_PM_SLEEP static int imx_pgc_domain_suspend(struct device *dev) { - int ret; - /* * This may look strange, but is done so the generic PM_SLEEP code * can power down our domain and more importantly power it up again * after resume, without tripping over our usage of runtime PM to * power up/down the nested domains. */ - ret = pm_runtime_get_sync(dev); - if (ret < 0) { - pm_runtime_put_noidle(dev); - return ret; - } - - return 0; + return pm_runtime_resume_and_get(dev); } static int imx_pgc_domain_resume(struct device *dev)
diff --git a/drivers/pmdomain/imx/imx8m-blk-ctrl.c b/drivers/pmdomain/imx/imx8m-blk-ctrl.c index f8105e8..14fb969 100644 --- a/drivers/pmdomain/imx/imx8m-blk-ctrl.c +++ b/drivers/pmdomain/imx/imx8m-blk-ctrl.c
@@ -108,9 +108,8 @@ static int imx8m_blk_ctrl_power_on(struct generic_pm_domain *genpd) guard(mutex)(&bc->power_lock); /* make sure bus domain is awake */ - ret = pm_runtime_get_sync(bc->bus_power_dev); + ret = pm_runtime_resume_and_get(bc->bus_power_dev); if (ret < 0) { - pm_runtime_put_noidle(bc->bus_power_dev); dev_err(bc->dev, "failed to power up bus domain\n"); return ret; } @@ -397,20 +396,16 @@ static int imx8m_blk_ctrl_suspend(struct device *dev) * in the system suspend/resume paths due to the device parent/child * hierarchy. */ - ret = pm_runtime_get_sync(bc->bus_power_dev); - if (ret < 0) { - pm_runtime_put_noidle(bc->bus_power_dev); + ret = pm_runtime_resume_and_get(bc->bus_power_dev); + if (ret < 0) return ret; - } for (i = 0; i < bc->onecell_data.num_domains; i++) { struct imx8m_blk_ctrl_domain *domain = &bc->domains[i]; - ret = pm_runtime_get_sync(domain->power_dev); - if (ret < 0) { - pm_runtime_put_noidle(domain->power_dev); + ret = pm_runtime_resume_and_get(domain->power_dev); + if (ret < 0) goto out_fail; - } } return 0;
diff --git a/drivers/pmdomain/imx/imx93-blk-ctrl.c b/drivers/pmdomain/imx/imx93-blk-ctrl.c index 243ce93..6d4c55a 100644 --- a/drivers/pmdomain/imx/imx93-blk-ctrl.c +++ b/drivers/pmdomain/imx/imx93-blk-ctrl.c
@@ -152,9 +152,8 @@ static int imx93_blk_ctrl_power_on(struct generic_pm_domain *genpd) return ret; } - ret = pm_runtime_get_sync(bc->dev); + ret = pm_runtime_resume_and_get(bc->dev); if (ret < 0) { - pm_runtime_put_noidle(bc->dev); dev_err(bc->dev, "failed to power up domain\n"); goto disable_clk; }
diff --git a/drivers/pmdomain/imx/scu-pd.c b/drivers/pmdomain/imx/scu-pd.c index e3f9e74..05d4364 100644 --- a/drivers/pmdomain/imx/scu-pd.c +++ b/drivers/pmdomain/imx/scu-pd.c
@@ -474,7 +474,7 @@ static int imx_scu_init_pm_domains(struct device *dev, struct genpd_onecell_data *pd_data; struct imx_sc_pm_domain *sc_pd; u32 count = 0; - int i, j; + int i, j, ret; for (i = 0; i < pd_soc->num_ranges; i++) count += pd_ranges[i].num; @@ -503,7 +503,13 @@ static int imx_scu_init_pm_domains(struct device *dev, pd_data->num_domains = count; pd_data->xlate = imx_scu_pd_xlate; - of_genpd_add_provider_onecell(dev->of_node, pd_data); + ret = of_genpd_add_provider_onecell(dev->of_node, pd_data); + if (ret) { + while (count) + pm_genpd_remove(domains[--count]); + + return ret; + } return 0; }
diff --git a/drivers/pmdomain/qcom/rpmhpd.c b/drivers/pmdomain/qcom/rpmhpd.c index 9074327..fa8fed5 100644 --- a/drivers/pmdomain/qcom/rpmhpd.c +++ b/drivers/pmdomain/qcom/rpmhpd.c
@@ -198,6 +198,11 @@ static struct rpmhpd mxc_ao = { .res_name = "mxc.lvl", }; +static struct rpmhpd nmxc = { + .pd = { .name = "nmxc", }, + .res_name = "nmxc.lvl", +}; + static struct rpmhpd nsp = { .pd = { .name = "nsp", }, .res_name = "nsp.lvl", @@ -327,6 +332,7 @@ static struct rpmhpd *nord_rpmhpds[] = { [RPMHPD_MX_AO] = &mx_ao, [RPMHPD_MXC] = &mxc, [RPMHPD_MXC_AO] = &mxc_ao, + [RPMHPD_NMXC] = &nmxc, [RPMHPD_NSP0] = &nsp0, [RPMHPD_NSP1] = &nsp1, [RPMHPD_NSP2] = &nsp2, @@ -486,6 +492,24 @@ static const struct rpmhpd_desc sm7150_desc = { .num_pds = ARRAY_SIZE(sm7150_rpmhpds), }; +/* SM7250 RPMH powerdomains */ +static struct rpmhpd *sm7250_rpmhpds[] = { + [RPMHPD_CX] = &cx_w_mx_parent, + [RPMHPD_CX_AO] = &cx_ao_w_mx_parent, + [RPMHPD_EBI] = &ebi, + [RPMHPD_GFX] = &gfx, + [RPMHPD_LCX] = &lcx, + [RPMHPD_LMX] = &lmx, + [RPMHPD_MSS] = &mss, + [RPMHPD_MX] = &mx, + [RPMHPD_MX_AO] = &mx_ao, +}; + +static const struct rpmhpd_desc sm7250_desc = { + .rpmhpds = sm7250_rpmhpds, + .num_pds = ARRAY_SIZE(sm7250_rpmhpds), +}; + /* SM8150 RPMH powerdomains */ static struct rpmhpd *sm8150_rpmhpds[] = { [SM8150_CX] = &cx_w_mx_parent, @@ -681,6 +705,21 @@ static const struct rpmhpd_desc kaanapali_desc = { .num_pds = ARRAY_SIZE(kaanapali_rpmhpds), }; +/* Kuno RPMH power domains */ +static struct rpmhpd *kuno_rpmhpds[] = { + [RPMHPD_CX] = &cx, + [RPMHPD_CX_AO] = &cx_ao, + [RPMHPD_MX] = &mx, + [RPMHPD_MX_AO] = &mx_ao, + [RPMHPD_MXC] = &mxc, + [RPMHPD_MXC_AO] = &mxc_ao, +}; + +static const struct rpmhpd_desc kuno_desc = { + .rpmhpds = kuno_rpmhpds, + .num_pds = ARRAY_SIZE(kuno_rpmhpds), +}; + /* Hawi RPMH powerdomains */ static struct rpmhpd *hawi_rpmhpds[] = { [RPMHPD_CX] = &cx, @@ -885,6 +924,7 @@ static const struct of_device_id rpmhpd_match_table[] = { { .compatible = "qcom,glymur-rpmhpd", .data = &glymur_desc }, { .compatible = "qcom,hawi-rpmhpd", .data = &hawi_desc }, { .compatible = "qcom,kaanapali-rpmhpd", .data = &kaanapali_desc }, + { .compatible = "qcom,kuno-rpmhpd", .data = &kuno_desc }, { .compatible = "qcom,milos-rpmhpd", .data = &milos_desc }, { .compatible = "qcom,nord-rpmhpd", .data = &nord_desc }, { .compatible = "qcom,qcs615-rpmhpd", .data = &qcs615_desc }, @@ -906,6 +946,7 @@ static const struct of_device_id rpmhpd_match_table[] = { { .compatible = "qcom,sm4450-rpmhpd", .data = &sm4450_desc }, { .compatible = "qcom,sm6350-rpmhpd", .data = &sm6350_desc }, { .compatible = "qcom,sm7150-rpmhpd", .data = &sm7150_desc }, + { .compatible = "qcom,sm7250-rpmhpd", .data = &sm7250_desc }, { .compatible = "qcom,sm8150-rpmhpd", .data = &sm8150_desc }, { .compatible = "qcom,sm8250-rpmhpd", .data = &sm8250_desc }, { .compatible = "qcom,sm8350-rpmhpd", .data = &sm8350_desc },
diff --git a/drivers/pmdomain/renesas/Kconfig b/drivers/pmdomain/renesas/Kconfig index f2f52d3..df19b95 100644 --- a/drivers/pmdomain/renesas/Kconfig +++ b/drivers/pmdomain/renesas/Kconfig
@@ -37,6 +37,10 @@ bool "System Controller support for R8A774A1 (RZ/G2M)" if COMPILE_TEST select SYSC_RCAR +config SYSC_R8A774A3 + bool "System Controller support for R8A774A3 (RZ/G2M v3.0)" if COMPILE_TEST + select SYSC_RCAR + config SYSC_R8A774B1 bool "System Controller support for R8A774B1 (RZ/G2N)" if COMPILE_TEST select SYSC_RCAR
diff --git a/drivers/pmdomain/renesas/Makefile b/drivers/pmdomain/renesas/Makefile index 17849aad3..8eda820 100644 --- a/drivers/pmdomain/renesas/Makefile +++ b/drivers/pmdomain/renesas/Makefile
@@ -6,6 +6,7 @@ obj-$(CONFIG_SYSC_R8A7745) += r8a7745-sysc.o obj-$(CONFIG_SYSC_R8A77470) += r8a77470-sysc.o obj-$(CONFIG_SYSC_R8A774A1) += r8a774a1-sysc.o +obj-$(CONFIG_SYSC_R8A774A3) += r8a774a3-sysc.o obj-$(CONFIG_SYSC_R8A774B1) += r8a774b1-sysc.o obj-$(CONFIG_SYSC_R8A774C0) += r8a774c0-sysc.o obj-$(CONFIG_SYSC_R8A774E1) += r8a774e1-sysc.o
diff --git a/drivers/pmdomain/renesas/r8a774a3-sysc.c b/drivers/pmdomain/renesas/r8a774a3-sysc.c new file mode 100644 index 0000000..58c9870 --- /dev/null +++ b/drivers/pmdomain/renesas/r8a774a3-sysc.c
@@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Renesas RZ/G2M v3.0 System Controller + * Copyright (C) 2026 Renesas Electronics Corp. + * + * Based on Renesas R-Car M3-W System Controller + * Copyright (C) 2016 Glider bvba + */ + +#include <linux/kernel.h> + +#include <dt-bindings/power/renesas,r8a774a3-sysc.h> + +#include "rcar-sysc.h" + +static const struct rcar_sysc_area r8a774a3_areas[] __initconst = { + { "always-on", 0, 0, R8A774A3_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, + { "ca57-scu", 0x1c0, 0, R8A774A3_PD_CA57_SCU, R8A774A3_PD_ALWAYS_ON, + PD_SCU }, + { "ca57-cpu0", 0x80, 0, R8A774A3_PD_CA57_CPU0, R8A774A3_PD_CA57_SCU, + PD_CPU_NOCR }, + { "ca57-cpu1", 0x80, 1, R8A774A3_PD_CA57_CPU1, R8A774A3_PD_CA57_SCU, + PD_CPU_NOCR }, + { "ca53-scu", 0x140, 0, R8A774A3_PD_CA53_SCU, R8A774A3_PD_ALWAYS_ON, + PD_SCU }, + { "ca53-cpu0", 0x200, 0, R8A774A3_PD_CA53_CPU0, R8A774A3_PD_CA53_SCU, + PD_CPU_NOCR }, + { "ca53-cpu1", 0x200, 1, R8A774A3_PD_CA53_CPU1, R8A774A3_PD_CA53_SCU, + PD_CPU_NOCR }, + { "ca53-cpu2", 0x200, 2, R8A774A3_PD_CA53_CPU2, R8A774A3_PD_CA53_SCU, + PD_CPU_NOCR }, + { "ca53-cpu3", 0x200, 3, R8A774A3_PD_CA53_CPU3, R8A774A3_PD_CA53_SCU, + PD_CPU_NOCR }, + { "a3vc", 0x380, 0, R8A774A3_PD_A3VC, R8A774A3_PD_ALWAYS_ON }, + { "a2vc1", 0x3c0, 1, R8A774A3_PD_A2VC1, R8A774A3_PD_A3VC }, + { "3dg-a", 0x100, 0, R8A774A3_PD_3DG_A, R8A774A3_PD_ALWAYS_ON }, + { "3dg-b", 0x100, 1, R8A774A3_PD_3DG_B, R8A774A3_PD_3DG_A }, +}; + +const struct rcar_sysc_info r8a774a3_sysc_info __initconst = { + .areas = r8a774a3_areas, + .num_areas = ARRAY_SIZE(r8a774a3_areas), + .extmask_offs = 0x2f8, + .extmask_val = BIT(0), +};
diff --git a/drivers/pmdomain/renesas/r8a7795-sysc.c b/drivers/pmdomain/renesas/r8a7795-sysc.c index cbe1ff0..2ed377b 100644 --- a/drivers/pmdomain/renesas/r8a7795-sysc.c +++ b/drivers/pmdomain/renesas/r8a7795-sysc.c
@@ -13,7 +13,7 @@ #include "rcar-sysc.h" -static struct rcar_sysc_area r8a7795_areas[] __initdata = { +static const struct rcar_sysc_area r8a7795_areas[] __initconst = { { "always-on", 0, 0, R8A7795_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, { "ca57-scu", 0x1c0, 0, R8A7795_PD_CA57_SCU, R8A7795_PD_ALWAYS_ON, PD_SCU },
diff --git a/drivers/pmdomain/renesas/r8a779a0-sysc.c b/drivers/pmdomain/renesas/r8a779a0-sysc.c index 54cdf25..5f84b8d 100644 --- a/drivers/pmdomain/renesas/r8a779a0-sysc.c +++ b/drivers/pmdomain/renesas/r8a779a0-sysc.c
@@ -11,7 +11,7 @@ #include "rcar-gen4-sysc.h" -static struct rcar_gen4_sysc_area r8a779a0_areas[] __initdata = { +static const struct rcar_gen4_sysc_area r8a779a0_areas[] __initconst = { { "always-on", R8A779A0_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, { "a3e0", R8A779A0_PD_A3E0, R8A779A0_PD_ALWAYS_ON, PD_SCU }, { "a3e1", R8A779A0_PD_A3E1, R8A779A0_PD_ALWAYS_ON, PD_SCU },
diff --git a/drivers/pmdomain/renesas/r8a779f0-sysc.c b/drivers/pmdomain/renesas/r8a779f0-sysc.c index 6ed13cd..d22cbc3 100644 --- a/drivers/pmdomain/renesas/r8a779f0-sysc.c +++ b/drivers/pmdomain/renesas/r8a779f0-sysc.c
@@ -11,7 +11,7 @@ #include "rcar-gen4-sysc.h" -static struct rcar_gen4_sysc_area r8a779f0_areas[] __initdata = { +static const struct rcar_gen4_sysc_area r8a779f0_areas[] __initconst = { { "always-on", R8A779F0_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, { "a3e0", R8A779F0_PD_A3E0, R8A779F0_PD_ALWAYS_ON, PD_SCU }, { "a3e1", R8A779F0_PD_A3E1, R8A779F0_PD_ALWAYS_ON, PD_SCU },
diff --git a/drivers/pmdomain/renesas/r8a779g0-sysc.c b/drivers/pmdomain/renesas/r8a779g0-sysc.c index 249cf43..96d39a3 100644 --- a/drivers/pmdomain/renesas/r8a779g0-sysc.c +++ b/drivers/pmdomain/renesas/r8a779g0-sysc.c
@@ -11,7 +11,7 @@ #include "rcar-gen4-sysc.h" -static struct rcar_gen4_sysc_area r8a779g0_areas[] __initdata = { +static const struct rcar_gen4_sysc_area r8a779g0_areas[] __initconst = { { "always-on", R8A779G0_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, { "a3e0", R8A779G0_PD_A3E0, R8A779G0_PD_ALWAYS_ON, PD_SCU }, { "a2e0d0", R8A779G0_PD_A2E0D0, R8A779G0_PD_A3E0, PD_SCU },
diff --git a/drivers/pmdomain/renesas/r8a779h0-sysc.c b/drivers/pmdomain/renesas/r8a779h0-sysc.c index e13372c..3775735 100644 --- a/drivers/pmdomain/renesas/r8a779h0-sysc.c +++ b/drivers/pmdomain/renesas/r8a779h0-sysc.c
@@ -11,7 +11,7 @@ #include "rcar-gen4-sysc.h" -static struct rcar_gen4_sysc_area r8a779h0_areas[] __initdata = { +static const struct rcar_gen4_sysc_area r8a779h0_areas[] __initconst = { { "always-on", R8A779H0_PD_ALWAYS_ON, -1, PD_ALWAYS_ON }, { "c4", R8A779H0_PD_C4, R8A779H0_PD_ALWAYS_ON }, { "a2e0d0", R8A779H0_PD_A2E0D0, R8A779H0_PD_C4, PD_SCU },
diff --git a/drivers/pmdomain/renesas/r8a78000-mdlc.c b/drivers/pmdomain/renesas/r8a78000-mdlc.c index 2668fc2..1fd71bb 100644 --- a/drivers/pmdomain/renesas/r8a78000-mdlc.c +++ b/drivers/pmdomain/renesas/r8a78000-mdlc.c
@@ -45,8 +45,9 @@ struct r8a78000_mdlc_priv { }; static struct generic_pm_domain *r8a78000_genpd_always_on; + static HLIST_HEAD(r8a78000_mdlc_list); -static DEFINE_MUTEX(r8a78000_mdlc_lock); /* protects the two above */ +static DEFINE_MUTEX(r8a78000_mdlc_lock); /* protects the list above */ static struct generic_pm_domain *r8a78000_genpd_xlate( const struct of_phandle_args *spec, void *data) @@ -191,10 +192,11 @@ static void r8a78000_genpd_del_provider(void *data) static int r8a78000_genpd_always_on_singleton(struct device *dev) { + static DEFINE_MUTEX(singleton_lock); struct generic_pm_domain *genpd; int ret; - guard(mutex)(&r8a78000_mdlc_lock); + guard(mutex)(&singleton_lock); if (r8a78000_genpd_always_on) return 0;
diff --git a/drivers/pmdomain/renesas/rcar-sysc.c b/drivers/pmdomain/renesas/rcar-sysc.c index bd7bb9c..3c8a44c 100644 --- a/drivers/pmdomain/renesas/rcar-sysc.c +++ b/drivers/pmdomain/renesas/rcar-sysc.c
@@ -284,6 +284,9 @@ static const struct of_device_id rcar_sysc_matches[] __initconst = { #ifdef CONFIG_SYSC_R8A774A1 { .compatible = "renesas,r8a774a1-sysc", .data = &r8a774a1_sysc_info }, #endif +#ifdef CONFIG_SYSC_R8A774A3 + { .compatible = "renesas,r8a774a3-sysc", .data = &r8a774a3_sysc_info }, +#endif #ifdef CONFIG_SYSC_R8A774B1 { .compatible = "renesas,r8a774b1-sysc", .data = &r8a774b1_sysc_info }, #endif
diff --git a/drivers/pmdomain/renesas/rcar-sysc.h b/drivers/pmdomain/renesas/rcar-sysc.h index 07ffce3..b264e72 100644 --- a/drivers/pmdomain/renesas/rcar-sysc.h +++ b/drivers/pmdomain/renesas/rcar-sysc.h
@@ -29,9 +29,15 @@ struct rcar_sysc_area { const char *name; - u16 chan_offs; /* Offset of PWRSR register for this area */ - u8 chan_bit; /* Bit in PWR* (except for PWRUP in PWRSR) */ - u8 isr_bit; /* Bit in SYSCI*R */ + u16 chan_offs; /* + * PWRSR register offset; or 0 if area is + * always on + */ + u8 chan_bit; /* + * Bit in PWR* (except for PWRUP in PWRSR); + * 0 if area is always on + */ + u8 isr_bit; /* Bit in SYSCI*R; 0 if area is always on */ s8 parent; /* -1 if none */ u8 flags; /* See PD_* */ }; @@ -55,6 +61,7 @@ extern const struct rcar_sysc_info r8a7743_sysc_info; extern const struct rcar_sysc_info r8a7745_sysc_info; extern const struct rcar_sysc_info r8a77470_sysc_info; extern const struct rcar_sysc_info r8a774a1_sysc_info; +extern const struct rcar_sysc_info r8a774a3_sysc_info; extern const struct rcar_sysc_info r8a774b1_sysc_info; extern const struct rcar_sysc_info r8a774c0_sysc_info; extern const struct rcar_sysc_info r8a774e1_sysc_info;
diff --git a/drivers/pmdomain/riscv/Kconfig b/drivers/pmdomain/riscv/Kconfig new file mode 100644 index 0000000..97232ed --- /dev/null +++ b/drivers/pmdomain/riscv/Kconfig
@@ -0,0 +1,15 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config RISCV_RPMI_DEVICE_POWER + bool "RISC-V RPMI Based Device Power driver" + depends on RISCV || COMPILE_TEST + depends on MAILBOX + depends on PM + default RISCV + select PM_GENERIC_DOMAINS + help + Support for device power domains based on the device power service + group defined by the RISC-V platform management interface (RPMI) + specification. The power domains advertised by the platform + microcontroller are registered as generic power domains, so that + devices can reference them through the "power-domains" property.
diff --git a/drivers/pmdomain/riscv/Makefile b/drivers/pmdomain/riscv/Makefile new file mode 100644 index 0000000..2cb0ee8 --- /dev/null +++ b/drivers/pmdomain/riscv/Makefile
@@ -0,0 +1,3 @@ +# SPDX-License-Identifier: GPL-2.0-only + +obj-$(CONFIG_RISCV_RPMI_DEVICE_POWER) += riscv-rpmi-device-power.o
diff --git a/drivers/pmdomain/riscv/riscv-rpmi-device-power.c b/drivers/pmdomain/riscv/riscv-rpmi-device-power.c new file mode 100644 index 0000000..c7c4671 --- /dev/null +++ b/drivers/pmdomain/riscv/riscv-rpmi-device-power.c
@@ -0,0 +1,485 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * RISC-V RPMI Based Device Power Driver through SBI MPXY + * + * Copyright (C) 2026 Shanghai StarFive Technology Co., Ltd. + * + * Implements a Device Power driver on top of SBI RPMI Message Proxy Extension (MPXY) + * + * Each SBI MPXY Device Power instance is associated, through the means of a proper DT + * entry description, to a specific Transport ID. + */ + +#include <linux/bitfield.h> +#include <linux/mailbox/riscv-rpmi-message.h> +#include <linux/mutex.h> +#include <linux/platform_device.h> +#include <linux/pm_domain.h> + +#define RPMI_PM_DOMAIN_NAME_LEN 16 + +/* power state for device power domains */ +#define RPMI_POWER_STATE_CONTEXT_MASK GENMASK(16, 16) +#define RPMI_POWER_STATE_CONTEXT_PRESERVED 0 +#define RPMI_POWER_STATE_CONTEXT_LOST 1 +#define RPMI_POWER_STATE_VALUE_MASK GENMASK(15, 0) +#define RPMI_POWER_STATE_VALUE_ON 0 +#define RPMI_POWER_STATE_VALUE_OFF 3 + +#define RPMI_POWER_STATE_PARAM(context_type, state_value) \ + ((FIELD_PREP(RPMI_POWER_STATE_CONTEXT_MASK, context_type)) | \ + (FIELD_PREP(RPMI_POWER_STATE_VALUE_MASK, state_value))) + +#define RPMI_POWER_STATE_GENERIC_ON \ + RPMI_POWER_STATE_PARAM(RPMI_POWER_STATE_CONTEXT_PRESERVED, \ + RPMI_POWER_STATE_VALUE_ON) + +#define RPMI_POWER_STATE_GENERIC_OFF \ + RPMI_POWER_STATE_PARAM(RPMI_POWER_STATE_CONTEXT_PRESERVED, \ + RPMI_POWER_STATE_VALUE_OFF) + +/** + * struct rpmi_ctx - RPMI transport context shared by all power domains + * + * @chan: mailbox channel of the underlying SBI MPXY transport + * @client: mailbox client bound to @chan + * @lock: serialises RPMI transactions on @chan + */ +struct rpmi_ctx { + struct mbox_chan *chan; + struct mbox_client client; + /* serialises RPMI transactions on @chan */ + struct mutex lock; +}; + +/** + * struct rpmi_device_power_domain - describe one available MPXY Device Power Domain + * + * @id: the power domain ID as advertised by PuC + * @transition_latency: worst case transition latency of power domain from one state + * to another + * @dev: device associated with this power domain + * @mpxy_ctx: RPMI transport context used to reach the PuC + * @genpd: generic power domain registered with the genpd core + * @name: device power domain name assigned by PuC + */ +struct rpmi_device_power_domain { + u32 id; + u32 transition_latency; + struct device *dev; + struct rpmi_ctx *mpxy_ctx; + struct generic_pm_domain genpd; + char name[RPMI_PM_DOMAIN_NAME_LEN]; +}; + +#define to_rpmi_pd(gpd) container_of(gpd, struct rpmi_device_power_domain, genpd) + +/* Service: GET_POWER_DOMAINS */ +struct rpmi_pm_get_num_domain_rx { + __le32 status; + __le32 num_domains; +}; + +/* Service: GET_POWER_DOMAIN_ATTRS */ +struct rpmi_pm_get_domain_attrs_tx { + __le32 domain_id; +}; + +/* pm domain attributes response data */ +struct rpmi_pm_get_domain_attrs_rx { + __le32 status; + __le32 flags; + __le32 transition_latency; + char name[RPMI_PM_DOMAIN_NAME_LEN]; +}; + +/* Service: SET_POWER_DOMAIN_STATE */ +struct rpmi_pm_set_power_state_tx { + __le32 domain_id; + __le32 power_state; +}; + +struct rpmi_pm_set_power_state_rx { + __le32 status; +}; + +/* Service: GET_POWER_DOMAIN_STATE */ +struct rpmi_pm_get_power_state_tx { + __le32 domain_id; +}; + +struct rpmi_pm_get_power_state_rx { + __le32 status; + __le32 power_state; +}; + +static int rpmi_pm_send_message(struct rpmi_ctx *mpxy_ctx, + struct rpmi_mbox_message *msg) +{ + guard(mutex)(&mpxy_ctx->lock); + + return rpmi_mbox_send_message(mpxy_ctx->chan, msg); +} + +static int rpmi_power_state_get(struct rpmi_device_power_domain *mpxy_pm_domain, + u32 domain_id, u32 *state) +{ + struct rpmi_pm_get_power_state_rx rx = { }; + struct rpmi_pm_get_power_state_tx tx; + struct rpmi_mbox_message msg; + int ret; + + tx.domain_id = cpu_to_le32(domain_id); + + rpmi_mbox_init_send_with_response(&msg, RPMI_DP_SRV_GET_STATE, + &tx, sizeof(tx), &rx, sizeof(rx)); + + ret = rpmi_pm_send_message(mpxy_pm_domain->mpxy_ctx, &msg); + if (ret) + return ret; + + if (rx.status) + return rpmi_to_linux_error(le32_to_cpu(rx.status)); + + if (msg.data.out_response_len < sizeof(rx)) + return -EPROTO; + + *state = le32_to_cpu(rx.power_state); + + return 0; +} + +static int rpmi_power_state_set(struct rpmi_device_power_domain *mpxy_pm_domain, + u32 domain_id, u32 state) +{ + struct rpmi_pm_set_power_state_rx rx = { }; + struct rpmi_pm_set_power_state_tx tx; + struct rpmi_mbox_message msg; + int ret; + + tx.domain_id = cpu_to_le32(domain_id); + tx.power_state = cpu_to_le32(state); + + rpmi_mbox_init_send_with_response(&msg, RPMI_DP_SRV_SET_STATE, + &tx, sizeof(tx), &rx, sizeof(rx)); + ret = rpmi_pm_send_message(mpxy_pm_domain->mpxy_ctx, &msg); + if (ret) + return ret; + + if (rx.status) + return rpmi_to_linux_error(le32_to_cpu(rx.status)); + + if (msg.data.out_response_len < sizeof(rx)) + return -EPROTO; + + return 0; +} + +static int rpmi_pd_power(struct generic_pm_domain *domain, bool power_on) +{ + struct rpmi_device_power_domain *mpxy_pm_domain; + u32 state, ret_state, domain_id; + int ret; + + if (power_on) + state = RPMI_POWER_STATE_GENERIC_ON; + else + state = RPMI_POWER_STATE_GENERIC_OFF; + + mpxy_pm_domain = to_rpmi_pd(domain); + domain_id = mpxy_pm_domain->id; + + ret = rpmi_power_state_set(mpxy_pm_domain, domain_id, state); + if (ret) + return ret; + + ret = rpmi_power_state_get(mpxy_pm_domain, domain_id, &ret_state); + if (ret) + return ret; + + if (FIELD_GET(RPMI_POWER_STATE_VALUE_MASK, ret_state) != + FIELD_GET(RPMI_POWER_STATE_VALUE_MASK, state)) + return -EIO; + + return ret; +} + +static int rpmi_pd_power_on(struct generic_pm_domain *domain) +{ + return rpmi_pd_power(domain, true); +} + +static int rpmi_pd_power_off(struct generic_pm_domain *domain) +{ + return rpmi_pd_power(domain, false); +} + +static int rpmi_pm_get_num_domains(struct rpmi_ctx *mpxy_ctx, u32 *domain) +{ + struct rpmi_pm_get_num_domain_rx rx = { }; + struct rpmi_mbox_message msg; + int ret; + + rpmi_mbox_init_send_with_response(&msg, RPMI_DP_SRV_GET_NUM_DOMAINS, + NULL, 0, &rx, sizeof(rx)); + ret = rpmi_pm_send_message(mpxy_ctx, &msg); + if (ret) + return ret; + + if (rx.status) + return rpmi_to_linux_error(le32_to_cpu(rx.status)); + + if (msg.data.out_response_len < sizeof(rx)) + return -EPROTO; + + *domain = le32_to_cpu(rx.num_domains); + + return 0; +} + +/* obtain the MPXY device power domain attributes */ +static int rpmi_device_power_get_attrs(u32 domain_id, + struct rpmi_device_power_domain *mpxy_pm_domain) +{ + struct rpmi_pm_get_domain_attrs_rx rx = { }; + struct rpmi_pm_get_domain_attrs_tx tx; + struct rpmi_mbox_message msg; + int ret; + + tx.domain_id = cpu_to_le32(domain_id); + + rpmi_mbox_init_send_with_response(&msg, RPMI_DP_SRV_GET_ATTRS, + &tx, sizeof(tx), &rx, sizeof(rx)); + ret = rpmi_pm_send_message(mpxy_pm_domain->mpxy_ctx, &msg); + if (ret) + return ret; + + if (rx.status) + return rpmi_to_linux_error(le32_to_cpu(rx.status)); + + if (msg.data.out_response_len < sizeof(rx)) + return -EPROTO; + + mpxy_pm_domain->transition_latency = le32_to_cpu(rx.transition_latency); + strscpy(mpxy_pm_domain->name, rx.name, sizeof(mpxy_pm_domain->name)); + + return 0; +} + +static int rpmi_pm_attr_setup(struct device *dev, struct rpmi_ctx *mpxy_ctx) +{ + struct rpmi_mbox_message msg; + int ret; + + /* Validate RPMI specification version */ + rpmi_mbox_init_get_attribute(&msg, RPMI_MBOX_ATTR_SPEC_VERSION); + ret = rpmi_pm_send_message(mpxy_ctx, &msg); + if (ret) { + dev_dbg(dev, "Failed to get spec version\n"); + return ret; + } + + if (msg.attr.value < RPMI_MKVER(1, 0)) { + dev_dbg(dev, + "msg protocol version mismatch, expected 0x%x, found 0x%x\n", + RPMI_MKVER(1, 0), msg.attr.value); + return -EINVAL; + } + + /* Validate device power service group ID */ + rpmi_mbox_init_get_attribute(&msg, RPMI_MBOX_ATTR_SERVICEGROUP_ID); + ret = rpmi_pm_send_message(mpxy_ctx, &msg); + if (ret) { + dev_dbg(dev, "Failed to get service group ID\n"); + return ret; + } + + if (msg.attr.value != RPMI_SRVGRP_DEVICE_POWER) { + dev_dbg(dev, + "service group match failed, expected 0x%x, found 0x%x\n", + RPMI_SRVGRP_DEVICE_POWER, msg.attr.value); + return -EINVAL; + } + + /* Validate device power service group version */ + rpmi_mbox_init_get_attribute(&msg, RPMI_MBOX_ATTR_SERVICEGROUP_VERSION); + ret = rpmi_pm_send_message(mpxy_ctx, &msg); + if (ret) { + dev_dbg(dev, "Failed to get service group version\n"); + return ret; + } + + if (msg.attr.value < RPMI_MKVER(1, 0)) { + dev_dbg(dev, + "service group version failed, expected 0x%x, found 0x%x\n", + RPMI_MKVER(1, 0), msg.attr.value); + return -EINVAL; + } + + return 0; +} + +static void rpmi_pm_domain_mbox_chan_release(void *data) +{ + mbox_free_channel((struct mbox_chan *)data); +} + +static int rpmi_pm_domain_probe(struct platform_device *pdev) +{ + struct device_node *np = pdev->dev.of_node; + struct rpmi_device_power_domain *mpxy_pd; + struct genpd_onecell_data *mpxy_pd_data; + struct generic_pm_domain **domains; + struct device *dev = &pdev->dev; + struct rpmi_ctx *mpxy_ctx; + u32 num_domains = 0; + int ret; + u32 i; + + mpxy_ctx = devm_kzalloc(&pdev->dev, sizeof(*mpxy_ctx), GFP_KERNEL); + if (!mpxy_ctx) + return -ENOMEM; + + ret = devm_mutex_init(dev, &mpxy_ctx->lock); + if (ret) + return ret; + + /* Setup mailbox client */ + mpxy_ctx->client.dev = dev; + mpxy_ctx->client.rx_callback = NULL; + mpxy_ctx->client.tx_block = false; + mpxy_ctx->client.knows_txdone = true; + mpxy_ctx->client.tx_tout = 0; + + /* Request mailbox channel */ + mpxy_ctx->chan = mbox_request_channel(&mpxy_ctx->client, 0); + if (IS_ERR(mpxy_ctx->chan)) + return PTR_ERR(mpxy_ctx->chan); + + ret = devm_add_action_or_reset(dev, rpmi_pm_domain_mbox_chan_release, + mpxy_ctx->chan); + if (ret) + return dev_err_probe(dev, ret, + "failed to add rpmi mbox channel cleanup\n"); + + ret = rpmi_pm_attr_setup(dev, mpxy_ctx); + if (ret) + return dev_err_probe(dev, ret, + "failed to verify RPMI attribute\n"); + + /* Get number of device power domain */ + ret = rpmi_pm_get_num_domains(mpxy_ctx, &num_domains); + if (ret) + return dev_err_probe(dev, ret, + "failed to get number of pm domains\n"); + + if (!num_domains) + return dev_err_probe(dev, -EINVAL, "No PM domains found!\n"); + + dev_info(&pdev->dev, "%u MPXY PM domains are found\n", num_domains); + + mpxy_pd = devm_kcalloc(&pdev->dev, num_domains, sizeof(*mpxy_pd), GFP_KERNEL); + if (!mpxy_pd) + return -ENOMEM; + + domains = devm_kcalloc(&pdev->dev, num_domains, sizeof(*domains), GFP_KERNEL); + if (!domains) + return -ENOMEM; + + mpxy_pd_data = devm_kzalloc(&pdev->dev, sizeof(*mpxy_pd_data), GFP_KERNEL); + if (!mpxy_pd_data) + return -ENOMEM; + + for (i = 0; i < num_domains; i++, mpxy_pd++) { + u32 state; + + mpxy_pd->dev = &pdev->dev; + mpxy_pd->mpxy_ctx = mpxy_ctx; + mpxy_pd->id = i; + + ret = rpmi_device_power_get_attrs(i, mpxy_pd); + if (ret) { + dev_warn(mpxy_pd->dev, + "power domain %u initialization failed\n", + mpxy_pd->id); + domains[i] = NULL; + continue; + } + + ret = rpmi_power_state_get(mpxy_pd, i, &state); + if (ret) { + dev_warn(mpxy_pd->dev, + "failed to get state for power domain %u\n", + mpxy_pd->id); + domains[i] = NULL; + continue; + } + + state = FIELD_GET(RPMI_POWER_STATE_VALUE_MASK, state); + if (state != RPMI_POWER_STATE_VALUE_OFF && + state != RPMI_POWER_STATE_VALUE_ON) { + dev_warn(mpxy_pd->dev, + "unsupported state 0x%x for power domain %u\n", + state, mpxy_pd->id); + domains[i] = NULL; + continue; + } + + mpxy_pd->genpd.name = mpxy_pd->name; + mpxy_pd->genpd.power_off = rpmi_pd_power_off; + mpxy_pd->genpd.power_on = rpmi_pd_power_on; + /* + * Domain names come from the PuC and are not guaranteed to be + * unique or non-empty, so let genpd derive unique device names + * from them rather than using them verbatim. + */ + mpxy_pd->genpd.flags = GENPD_FLAG_DEV_NAME_FW; + + ret = pm_genpd_init(&mpxy_pd->genpd, NULL, + state == RPMI_POWER_STATE_VALUE_OFF); + if (ret) { + dev_warn(mpxy_pd->dev, + "failed to init power domain %u\n", + mpxy_pd->id); + domains[i] = NULL; + continue; + } + + domains[i] = &mpxy_pd->genpd; + } + + mpxy_pd_data->domains = domains; + mpxy_pd_data->num_domains = num_domains; + + ret = of_genpd_add_provider_onecell(np, mpxy_pd_data); + if (ret) { + while (i--) { + if (domains[i]) + pm_genpd_remove(domains[i]); + } + + return dev_err_probe(dev, ret, "failed to add genpd provider\n"); + } + + return 0; +} + +static const struct of_device_id rpmi_pm_domain_of_match[] = { + { .compatible = "riscv,rpmi-device-power" }, + {}, +}; + +static struct platform_driver rpmi_pm_domain_platdrv = { + .driver = { + .name = "riscv-rpmi-device-power", + .of_match_table = rpmi_pm_domain_of_match, + .suppress_bind_attrs = true, + }, + .probe = rpmi_pm_domain_probe, +}; + +builtin_platform_driver(rpmi_pm_domain_platdrv); + +MODULE_AUTHOR("Joshua Yeong <joshua.yeong@starfivetech.com>"); +MODULE_DESCRIPTION("Device Power Driver based on RPMI message protocol"); +MODULE_LICENSE("GPL");
diff --git a/drivers/pmdomain/rockchip/pm-domains.c b/drivers/pmdomain/rockchip/pm-domains.c index e193f97..db38798 100644 --- a/drivers/pmdomain/rockchip/pm-domains.c +++ b/drivers/pmdomain/rockchip/pm-domains.c
@@ -721,7 +721,7 @@ static int rockchip_pd_power_on(struct generic_pm_domain *domain) ret = rockchip_pd_regulator_enable(pd); if (ret) return dev_err_probe(pd->pmu->dev, ret, - "Failed to enable supply: %d\n", ret); + "Failed to enable supply\n"); ret = rockchip_pd_power(pd, true); if (ret) @@ -821,7 +821,7 @@ static int rockchip_pm_add_one_domain(struct rockchip_pmu *pmu, return 0; pd_info = &pmu->info->domain_info[id]; - if (!pd_info) { + if (!pd_info->pwr_mask && !pd_info->req_mask) { dev_err(pmu->dev, "%pOFn: undefined domain id %d\n", node, id); return -EINVAL;
diff --git a/drivers/pmdomain/st/ste-ux500-pm-domain.c b/drivers/pmdomain/st/ste-ux500-pm-domain.c index 6896cb4..c9129a3 100644 --- a/drivers/pmdomain/st/ste-ux500-pm-domain.c +++ b/drivers/pmdomain/st/ste-ux500-pm-domain.c
@@ -17,6 +17,8 @@ #include <dt-bindings/arm/ux500_pm_domains.h> +#define NR_DOMAINS (DOMAIN_VAPE + 1) + static int pd_power_off(struct generic_pm_domain *domain) { /*
diff --git a/drivers/power/sequencing/Kconfig b/drivers/power/sequencing/Kconfig index 226c627..b6a9f25 100644 --- a/drivers/power/sequencing/Kconfig +++ b/drivers/power/sequencing/Kconfig
@@ -27,6 +27,15 @@ this driver is needed for correct power control or else we'd risk not respecting the required delays between enabling Bluetooth and WLAN. +config POWER_SEQUENCING_RENESAS_PWRRDY + tristate "Renesas Power Ready sequencing driver" + depends on SYSC_RZ || COMPILE_TEST + select AUXILIARY_BUS + help + Say Y here to enable the power sequencing driver for the Renesas + Power Ready signals. This driver handles the power ready signals + required to power on the various IP's on RZ/G3L platform. + config POWER_SEQUENCING_TH1520_GPU tristate "T-HEAD TH1520 GPU power sequencing driver" depends on ARCH_THEAD || COMPILE_TEST @@ -47,4 +56,14 @@ connectors. This driver handles the power sequencing for the M.2 connectors exposing multiple interfaces like PCIe, SATA, UART, etc... +config POWER_SEQUENCING_KUNIT + tristate "Build power sequencing KUnit test cases" + depends on KUNIT + default KUNIT_ALL_TESTS + help + Say Y here to build the module containing KUnit test cases for the + power sequencing subsystem. + + If unsure, say N. + endif
diff --git a/drivers/power/sequencing/Makefile b/drivers/power/sequencing/Makefile index 0911d461..76a2775 100644 --- a/drivers/power/sequencing/Makefile +++ b/drivers/power/sequencing/Makefile
@@ -4,5 +4,7 @@ pwrseq-core-y := core.o obj-$(CONFIG_POWER_SEQUENCING_QCOM_WCN) += pwrseq-qcom-wcn.o +obj-$(CONFIG_POWER_SEQUENCING_RENESAS_PWRRDY) += pwrseq-renesas-pwrrdy.o obj-$(CONFIG_POWER_SEQUENCING_TH1520_GPU) += pwrseq-thead-gpu.o obj-$(CONFIG_POWER_SEQUENCING_PCIE_M2) += pwrseq-pcie-m2.o +obj-$(CONFIG_POWER_SEQUENCING_KUNIT) += pwrseq-kunit.o
diff --git a/drivers/power/sequencing/core.c b/drivers/power/sequencing/core.c index 3076b38..d7a545b 100644 --- a/drivers/power/sequencing/core.c +++ b/drivers/power/sequencing/core.c
@@ -183,12 +183,15 @@ static void pwrseq_unit_release(struct kref *ref) * the state lock has been released. It's useful for implementing * boot-up delays without blocking other users from powering up * using the same power sequencer. + * @is_controllable: Optional callback reporting whether enabling/disabling + * this target actually controls power. */ struct pwrseq_target { struct list_head list; const char *name; struct pwrseq_unit *unit; pwrseq_power_state_func post_enable; + pwrseq_is_controllable_func is_controllable; }; static struct pwrseq_target * @@ -207,6 +210,7 @@ pwrseq_target_new(const struct pwrseq_target_data *data) } target->post_enable = data->post_enable; + target->is_controllable = data->is_controllable; return target; } @@ -994,6 +998,51 @@ struct device *pwrseq_to_device(struct pwrseq_desc *desc) } EXPORT_SYMBOL_GPL(pwrseq_to_device); +/** + * pwrseq_is_controllable() - Check whether the target provides a + * host-controllable power actuator. + * @desc: Descriptor referencing the power sequencer. + * + * Some power sequencing targets provide no host-controllable enable for their + * function on a given board, for instance when the enable line is not wired up + * and is instead hardwired to an always-on level. For such targets a call to + * pwrseq_power_off() is still allowed, so that the consumer can drop its vote + * on the (possibly shared) resources, but the host cannot gate the function + * on its own. + * + * Returns: + * True if the target provides a host-controllable power actuator, false + * otherwise. Also returns false if @desc is NULL. + */ +bool pwrseq_is_controllable(struct pwrseq_desc *desc) +{ + struct pwrseq_device *pwrseq; + struct pwrseq_target *target; + struct pwrseq_unit *unit; + + might_sleep(); + + if (!desc) + return false; + + pwrseq = desc->pwrseq; + target = desc->target; + unit = target->unit; + + guard(rwsem_read)(&pwrseq->rw_lock); + if (!device_is_registered(&pwrseq->dev)) + return false; + + if (!unit->enable && !unit->disable) + return false; + + if (!target->is_controllable) + return true; + + return target->is_controllable(pwrseq); +} +EXPORT_SYMBOL_GPL(pwrseq_is_controllable); + #if IS_ENABLED(CONFIG_DEBUG_FS) struct pwrseq_debugfs_count_ctx {
diff --git a/drivers/power/sequencing/pwrseq-kunit.c b/drivers/power/sequencing/pwrseq-kunit.c new file mode 100644 index 0000000..c2899f3 --- /dev/null +++ b/drivers/power/sequencing/pwrseq-kunit.c
@@ -0,0 +1,1497 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2026 Qualcomm Technologies, Inc. and/or its subsidiaries + */ + +#include <linux/err.h> +#include <linux/fwnode.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/property.h> +#include <linux/pwrseq/consumer.h> +#include <linux/pwrseq/provider.h> + +#include <kunit/fwnode.h> +#include <kunit/platform_device.h> +#include <kunit/resource.h> +#include <kunit/test.h> + +#define PWRSEQ_TEST_PARENT "pwrseq-test-parent" +#define PWRSEQ_TEST_CONSUMER "pwrseq-test-consumer" + +#define PWRSEQ_SWNODE_TEST_PROVIDER "pwrseq-swnode-test-provider" +#define PWRSEQ_SWNODE_TEST_PROVIDER_2 "pwrseq-swnode-test-provider-2" +#define PWRSEQ_PROBE_ORDER_TEST_CONSUMER "pwrseq-probe-order-test-consumer" +#define PWRSEQ_PROBE_DEFER_TEST_CONSUMER "pwrseq-probe-defer-test-consumer" + +static const struct software_node pwrseq_test_provider_swnode = { + .name = "pwrseq-test-provider", +}; + +KUNIT_DEFINE_ACTION_WRAPPER(pwrseq_device_unregister_wrapper, + pwrseq_device_unregister, + struct pwrseq_device *); + +static struct pwrseq_device * +kunit_pwrseq_device_register(struct kunit *test, + const struct pwrseq_config *config) +{ + struct pwrseq_device *pwrseq; + int ret; + + pwrseq = pwrseq_device_register(config); + if (IS_ERR(pwrseq)) + return pwrseq; + + ret = kunit_add_action_or_reset(test, pwrseq_device_unregister_wrapper, + pwrseq); + if (ret) + return ERR_PTR(ret); + + return pwrseq; +} + +KUNIT_DEFINE_ACTION_WRAPPER(pwrseq_put_wrapper, pwrseq_put, + struct pwrseq_desc *); + +static struct pwrseq_desc * +kunit_pwrseq_get(struct kunit *test, struct device *dev, const char *target) +{ + struct pwrseq_desc *desc; + int ret; + + desc = pwrseq_get(dev, target); + if (IS_ERR(desc)) + return desc; + + ret = kunit_add_action_or_reset(test, pwrseq_put_wrapper, desc); + if (ret) + return ERR_PTR(ret); + + return desc; +} + +struct pwrseq_test_ctx { + const char *consumer_name; + int enable_count_a; + int enable_count_b; + int disable_count_a; + int disable_count_b; + int enable_calls_a; + int post_enable_calls; + bool enable_error_a; + bool enable_error_b; + bool post_enable_error; +}; + +static int pwrseq_test_no_match(struct pwrseq_device *pwrseq, + struct device *dev) +{ + return PWRSEQ_NO_MATCH; +} + +static int pwrseq_test_match_by_name(struct pwrseq_device *pwrseq, + struct device *dev) +{ + struct pwrseq_test_ctx *ctx = pwrseq_device_get_drvdata(pwrseq); + + return strcmp(dev_name(dev), ctx->consumer_name) == 0 ? + PWRSEQ_MATCH_OK : PWRSEQ_NO_MATCH; +} + +static int pwrseq_test_match_always(struct pwrseq_device *pwrseq, + struct device *dev) +{ + return PWRSEQ_MATCH_OK; +} + +static int pwrseq_test_enable_a(struct pwrseq_device *pwrseq) +{ + struct pwrseq_test_ctx *ctx = pwrseq_device_get_drvdata(pwrseq); + + ctx->enable_calls_a++; + + if (ctx->enable_error_a) + return -EIO; + + ctx->enable_count_a++; + + return 0; +} + +static int pwrseq_test_disable_a(struct pwrseq_device *pwrseq) +{ + struct pwrseq_test_ctx *ctx = pwrseq_device_get_drvdata(pwrseq); + + ctx->disable_count_a++; + + return 0; +} + +static int pwrseq_test_enable_b(struct pwrseq_device *pwrseq) +{ + struct pwrseq_test_ctx *ctx = pwrseq_device_get_drvdata(pwrseq); + + if (ctx->enable_error_b) + return -EIO; + + ctx->enable_count_b++; + + return 0; +} + +static int pwrseq_test_disable_b(struct pwrseq_device *pwrseq) +{ + struct pwrseq_test_ctx *ctx = pwrseq_device_get_drvdata(pwrseq); + + ctx->disable_count_b++; + + return 0; +} + +static int pwrseq_test_post_enable(struct pwrseq_device *pwrseq) +{ + struct pwrseq_test_ctx *ctx = pwrseq_device_get_drvdata(pwrseq); + + ctx->post_enable_calls++; + + return ctx->post_enable_error ? -EIO : 0; +} + +static int pwrseq_test_parent_probe(struct platform_device *pdev) +{ + return 0; +} + +static struct platform_driver pwrseq_test_parent_driver = { + .probe = pwrseq_test_parent_probe, + .driver = { + .name = PWRSEQ_TEST_PARENT, + }, +}; + +static int pwrseq_test_parent_init(struct kunit *test) +{ + static const struct platform_device_info pdevinfo = { + .name = PWRSEQ_TEST_PARENT, + .id = PLATFORM_DEVID_NONE, + }; + + struct platform_device *pdev; + bool bound; + int ret; + + ret = kunit_platform_driver_register(test, &pwrseq_test_parent_driver); + KUNIT_ASSERT_EQ(test, ret, 0); + + pdev = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); + + wait_for_device_probe(); + scoped_guard(device, &pdev->dev) + bound = device_is_bound(&pdev->dev); + + KUNIT_ASSERT_TRUE(test, bound); + + test->priv = pdev; + + return 0; +} + +/* + * Test that registering a power sequencer whose unit dependency graph + * contains a two-node cycle (A -> B -> A) is rejected with -EINVAL. + */ +static void pwrseq_circular_deps(struct kunit *test) +{ + const struct pwrseq_unit_data *unit_a_deps[2] = { }; + const struct pwrseq_unit_data *unit_b_deps[2] = { }; + const struct pwrseq_target_data *targets[2] = { }; + struct platform_device *pdev = test->priv; + struct pwrseq_unit_data unit_a, unit_b; + struct pwrseq_target_data target; + struct pwrseq_device *pwrseq; + struct pwrseq_config config; + + unit_a = (struct pwrseq_unit_data){ + .name = "unit-a", + .deps = unit_a_deps, + }; + + unit_b = (struct pwrseq_unit_data){ + .name = "unit-b", + .deps = unit_b_deps, + }; + + unit_a_deps[0] = &unit_b; + unit_b_deps[0] = &unit_a; + + target = (struct pwrseq_target_data){ + .name = "test-target", + .unit = &unit_a, + }; + + targets[0] = ⌖ + + config = (struct pwrseq_config){ + .parent = &pdev->dev, + .match = pwrseq_test_no_match, + .targets = targets, + }; + + kunit_warning_suppress(test) { + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1); + } + + KUNIT_EXPECT_TRUE(test, IS_ERR(pwrseq)); + KUNIT_EXPECT_EQ(test, PTR_ERR(pwrseq), -EINVAL); +} + +/* + * Test that a longer chain cycle (A -> B -> C -> D -> A) is also rejected + * with -EINVAL. + */ +static void pwrseq_circular_deps_chain(struct kunit *test) +{ + struct pwrseq_unit_data unit_a, unit_b, unit_c, unit_d; + const struct pwrseq_unit_data *unit_a_deps[2] = { }; + const struct pwrseq_unit_data *unit_b_deps[2] = { }; + const struct pwrseq_unit_data *unit_c_deps[2] = { }; + const struct pwrseq_unit_data *unit_d_deps[2] = { }; + const struct pwrseq_target_data *targets[2] = { }; + struct platform_device *pdev = test->priv; + struct pwrseq_target_data target; + struct pwrseq_device *pwrseq; + struct pwrseq_config config; + + unit_a = (struct pwrseq_unit_data){ + .name = "unit-a", + .deps = unit_a_deps, + }; + unit_b = (struct pwrseq_unit_data){ + .name = "unit-b", + .deps = unit_b_deps, + }; + unit_c = (struct pwrseq_unit_data){ + .name = "unit-c", + .deps = unit_c_deps, + }; + unit_d = (struct pwrseq_unit_data){ + .name = "unit-d", + .deps = unit_d_deps, + }; + + unit_a_deps[0] = &unit_b; + unit_b_deps[0] = &unit_c; + unit_c_deps[0] = &unit_d; + unit_d_deps[0] = &unit_a; + + target = (struct pwrseq_target_data){ + .name = "test-target", + .unit = &unit_a, + }; + + targets[0] = ⌖ + + config = (struct pwrseq_config){ + .parent = &pdev->dev, + .match = pwrseq_test_no_match, + .targets = targets, + }; + + kunit_warning_suppress(test) { + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1); + } + + KUNIT_EXPECT_TRUE(test, IS_ERR(pwrseq)); + KUNIT_EXPECT_EQ(test, PTR_ERR(pwrseq), -EINVAL); +} + +/* + * Test that a valid acyclic dependency graph (A -> B) registers successfully. + */ +static void pwrseq_register_valid(struct kunit *test) +{ + const struct pwrseq_unit_data *unit_a_deps[2] = { }; + const struct pwrseq_target_data *targets[2] = { }; + struct platform_device *pdev = test->priv; + struct pwrseq_unit_data unit_a, unit_b; + struct pwrseq_target_data target; + struct pwrseq_device *pwrseq; + struct pwrseq_config config; + + unit_b = (struct pwrseq_unit_data){ + .name = "unit-b", + }; + + unit_a_deps[0] = &unit_b; + unit_a = (struct pwrseq_unit_data){ + .name = "unit-a", + .deps = unit_a_deps, + }; + + target = (struct pwrseq_target_data){ + .name = "test-target", + .unit = &unit_a, + }; + + targets[0] = ⌖ + + config = (struct pwrseq_config){ + .parent = &pdev->dev, + .match = pwrseq_test_no_match, + .targets = targets, + }; + + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pwrseq); +} + +/* + * Test that registration is rejected with -EINVAL when .parent, .match or + * .targets is missing, or when .targets is a non-NULL but empty array. + */ +static void pwrseq_register_invalid_args(struct kunit *test) +{ + const struct pwrseq_target_data *empty_targets[1] = { }; + const struct pwrseq_target_data *targets[2] = { }; + struct platform_device *pdev = test->priv; + struct pwrseq_target_data target; + struct pwrseq_unit_data unit; + struct pwrseq_device *pwrseq; + struct pwrseq_config config; + + unit = (struct pwrseq_unit_data){ .name = "unit-a" }; + target = (struct pwrseq_target_data){ + .name = "test-target", + .unit = &unit, + }; + targets[0] = ⌖ + + config = (struct pwrseq_config){ + .parent = &pdev->dev, + .match = pwrseq_test_no_match, + .targets = targets, + }; + + config.parent = NULL; + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_EXPECT_TRUE(test, IS_ERR(pwrseq)); + KUNIT_EXPECT_EQ(test, PTR_ERR(pwrseq), -EINVAL); + config.parent = &pdev->dev; + + config.match = NULL; + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_EXPECT_TRUE(test, IS_ERR(pwrseq)); + KUNIT_EXPECT_EQ(test, PTR_ERR(pwrseq), -EINVAL); + config.match = pwrseq_test_no_match; + + config.targets = NULL; + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_EXPECT_TRUE(test, IS_ERR(pwrseq)); + KUNIT_EXPECT_EQ(test, PTR_ERR(pwrseq), -EINVAL); + + config.targets = empty_targets; + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_EXPECT_TRUE(test, IS_ERR(pwrseq)); + KUNIT_EXPECT_EQ(test, PTR_ERR(pwrseq), -EINVAL); +} + +/* + * Test that a target without a unit is rejected with -EINVAL. + */ +static void pwrseq_register_target_without_unit(struct kunit *test) +{ + const struct pwrseq_target_data *targets[2] = { }; + struct platform_device *pdev = test->priv; + struct pwrseq_target_data target; + struct pwrseq_device *pwrseq; + struct pwrseq_config config; + + target = (struct pwrseq_target_data){ + .name = "test-target", + .unit = NULL, + }; + targets[0] = ⌖ + + config = (struct pwrseq_config){ + .parent = &pdev->dev, + .match = pwrseq_test_no_match, + .targets = targets, + }; + + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_EXPECT_TRUE(test, IS_ERR(pwrseq)); + KUNIT_EXPECT_EQ(test, PTR_ERR(pwrseq), -EINVAL); +} + +/* + * Test that enabling and disabling a single-unit target increments and + * decrements enable_count correctly and fires the enable/disable callbacks + * exactly once. + */ +static void pwrseq_enable_disable(struct kunit *test) +{ + const struct pwrseq_target_data *targets[2] = { }; + struct platform_device *pdev = test->priv; + struct platform_device_info pdevinfo; + struct pwrseq_target_data target; + struct pwrseq_test_ctx *ctx; + struct pwrseq_unit_data unit; + struct pwrseq_device *pwrseq; + struct pwrseq_config config; + struct pwrseq_desc *desc; + int ret; + + ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + unit = (struct pwrseq_unit_data){ + .name = "unit-a", + .enable = pwrseq_test_enable_a, + .disable = pwrseq_test_disable_a, + }; + + target = (struct pwrseq_target_data){ + .name = "test-target", + .unit = &unit, + }; + + targets[0] = ⌖ + + ctx->consumer_name = PWRSEQ_TEST_CONSUMER; + + config = (struct pwrseq_config){ + .parent = &pdev->dev, + .drvdata = ctx, + .match = pwrseq_test_match_by_name, + .targets = targets, + }; + + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pwrseq); + + pdevinfo = (struct platform_device_info){ + .name = PWRSEQ_TEST_CONSUMER, + .id = PLATFORM_DEVID_NONE, + }; + + pdev = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); + + desc = kunit_pwrseq_get(test, &pdev->dev, "test-target"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, desc); + + ret = pwrseq_enable(desc); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, ctx->enable_count_a, 1); + KUNIT_EXPECT_EQ(test, ctx->disable_count_a, 0); + + ret = pwrseq_disable(desc); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, ctx->enable_count_a, 1); + KUNIT_EXPECT_EQ(test, ctx->disable_count_a, 1); +} + +/* + * Test that two consumers sharing a common dependency unit cause it to be + * enabled only once and disabled only once, while enable_count tracks each + * consumer correctly. + */ +static void pwrseq_shared_deps(struct kunit *test) +{ + const struct pwrseq_unit_data *unit_a_deps[2] = { }; + const struct pwrseq_unit_data *unit_b_deps[2] = { }; + const struct pwrseq_target_data *targets[3] = { }; + struct pwrseq_unit_data dep_unit, unit_a, unit_b; + struct pwrseq_target_data target_a, target_b; + struct platform_device *parent = test->priv; + struct platform_device *pdev_a, *pdev_b; + struct platform_device_info pdevinfo; + struct pwrseq_desc *desc_a, *desc_b; + struct pwrseq_device *pwrseq; + struct pwrseq_config config; + struct pwrseq_test_ctx *ctx; + int ret; + + ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + dep_unit = (struct pwrseq_unit_data){ + .name = "dep", + .enable = pwrseq_test_enable_a, + .disable = pwrseq_test_disable_a, + }; + + unit_a_deps[0] = &dep_unit; + unit_a = (struct pwrseq_unit_data){ + .name = "unit-a", + .deps = unit_a_deps, + .enable = pwrseq_test_enable_b, + .disable = pwrseq_test_disable_b, + }; + + unit_b_deps[0] = &dep_unit; + unit_b = (struct pwrseq_unit_data){ + .name = "unit-b", + .deps = unit_b_deps, + }; + + target_a = (struct pwrseq_target_data){ + .name = "target-a", + .unit = &unit_a, + }; + target_b = (struct pwrseq_target_data){ + .name = "target-b", + .unit = &unit_b, + }; + + targets[0] = &target_a; + targets[1] = &target_b; + + ctx->consumer_name = PWRSEQ_TEST_CONSUMER "-a"; + + config = (struct pwrseq_config){ + .parent = &parent->dev, + .drvdata = ctx, + .match = pwrseq_test_match_by_name, + .targets = targets, + }; + + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pwrseq); + + pdevinfo = (struct platform_device_info){ + .name = PWRSEQ_TEST_CONSUMER "-a", + .id = PLATFORM_DEVID_NONE, + }; + pdev_a = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev_a); + + pdevinfo = (struct platform_device_info){ + .name = PWRSEQ_TEST_CONSUMER "-b", + .id = PLATFORM_DEVID_NONE, + }; + pdev_b = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev_b); + + /* + * match_by_name() only matches one consumer name at a time, so + * reconfigure ctx->consumer_name between the two pwrseq_get() calls + * below to acquire descriptors for both consumer-a and consumer-b. + */ + desc_a = kunit_pwrseq_get(test, &pdev_a->dev, "target-a"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, desc_a); + + ctx->consumer_name = PWRSEQ_TEST_CONSUMER "-b"; + desc_b = kunit_pwrseq_get(test, &pdev_b->dev, "target-b"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, desc_b); + + ret = pwrseq_enable(desc_a); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, ctx->enable_count_a, 1); + KUNIT_EXPECT_EQ(test, ctx->enable_count_b, 1); + + ret = pwrseq_enable(desc_b); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, ctx->enable_count_a, 1); + + ret = pwrseq_disable(desc_a); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, ctx->disable_count_a, 0); + KUNIT_EXPECT_EQ(test, ctx->disable_count_b, 1); + + ret = pwrseq_disable(desc_b); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, ctx->disable_count_a, 1); +} + +/* + * Test that calling pwrseq_enable() twice on the same descriptor has no + * effect. + */ +static void pwrseq_enable_idempotent(struct kunit *test) +{ + const struct pwrseq_target_data *targets[2] = { }; + struct platform_device *pdev = test->priv; + struct platform_device_info pdevinfo; + struct pwrseq_target_data target; + struct pwrseq_device *pwrseq; + struct pwrseq_unit_data unit; + struct pwrseq_config config; + struct pwrseq_test_ctx *ctx; + struct pwrseq_desc *desc; + int ret; + + ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + unit = (struct pwrseq_unit_data){ + .name = "unit-a", + .enable = pwrseq_test_enable_a, + .disable = pwrseq_test_disable_a, + }; + + target = (struct pwrseq_target_data){ + .name = "test-target", + .unit = &unit, + }; + + targets[0] = ⌖ + + ctx->consumer_name = PWRSEQ_TEST_CONSUMER; + + config = (struct pwrseq_config){ + .parent = &pdev->dev, + .drvdata = ctx, + .match = pwrseq_test_match_by_name, + .targets = targets, + }; + + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pwrseq); + + pdevinfo = (struct platform_device_info){ + .name = PWRSEQ_TEST_CONSUMER, + .id = PLATFORM_DEVID_NONE, + }; + + pdev = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); + + desc = kunit_pwrseq_get(test, &pdev->dev, "test-target"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, desc); + + ret = pwrseq_enable(desc); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, ctx->enable_count_a, 1); + + /* Second power_on on same descriptor must be a no-op. */ + ret = pwrseq_enable(desc); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, ctx->enable_count_a, 1); + + ret = pwrseq_disable(desc); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, ctx->disable_count_a, 1); +} + +/* + * Test that when a dependency unit's enable() callback fails, the error + * propagates to the caller, the top unit's enable callback is never reached, + * and target->post_enable() is never invoked. + */ +static void pwrseq_enable_enable_error(struct kunit *test) +{ + const struct pwrseq_target_data *targets[2] = { }; + const struct pwrseq_unit_data *top_deps[2] = { }; + struct pwrseq_unit_data dep_unit, top_unit; + struct platform_device *pdev = test->priv; + struct platform_device_info pdevinfo; + struct pwrseq_target_data target; + struct pwrseq_device *pwrseq; + struct pwrseq_config config; + struct pwrseq_test_ctx *ctx; + struct pwrseq_desc *desc; + int ret; + + ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + dep_unit = (struct pwrseq_unit_data){ + .name = "dep", + .enable = pwrseq_test_enable_a, + }; + + top_deps[0] = &dep_unit; + top_unit = (struct pwrseq_unit_data){ + .name = "top", + .deps = top_deps, + .enable = pwrseq_test_enable_b, + }; + + target = (struct pwrseq_target_data){ + .name = "test-target", + .unit = &top_unit, + .post_enable = pwrseq_test_post_enable, + }; + + targets[0] = ⌖ + + ctx->consumer_name = PWRSEQ_TEST_CONSUMER; + ctx->enable_error_a = true; + + config = (struct pwrseq_config){ + .parent = &pdev->dev, + .drvdata = ctx, + .match = pwrseq_test_match_by_name, + .targets = targets, + }; + + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pwrseq); + + pdevinfo = (struct platform_device_info){ + .name = PWRSEQ_TEST_CONSUMER, + .id = PLATFORM_DEVID_NONE, + }; + + pdev = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); + + desc = kunit_pwrseq_get(test, &pdev->dev, "test-target"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, desc); + + ret = pwrseq_enable(desc); + KUNIT_EXPECT_EQ(test, ret, -EIO); + /* + * Dependency's enable() was attempted but failed, so it never + * incremented. + */ + KUNIT_EXPECT_EQ(test, ctx->enable_calls_a, 1); + KUNIT_EXPECT_EQ(test, ctx->enable_count_a, 0); + /* Target unit's enable() was never reached. */ + KUNIT_EXPECT_EQ(test, ctx->enable_count_b, 0); + /* Target's .post_enable() must not run on an unpowered sequencer. */ + KUNIT_EXPECT_EQ(test, ctx->post_enable_calls, 0); +} + +/* + * Test that when the top unit's own enable() callback fails after its + * dependency's enable() already succeeded, the dependency is rolled back. + */ +static void pwrseq_enable_rollback_on_top_failure(struct kunit *test) +{ + const struct pwrseq_target_data *targets[2] = { }; + const struct pwrseq_unit_data *top_deps[2] = { }; + struct pwrseq_unit_data dep_unit, top_unit; + struct platform_device *pdev = test->priv; + struct platform_device_info pdevinfo; + struct pwrseq_target_data target; + struct pwrseq_device *pwrseq; + struct pwrseq_config config; + struct pwrseq_test_ctx *ctx; + struct pwrseq_desc *desc; + int ret; + + ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + dep_unit = (struct pwrseq_unit_data){ + .name = "dep", + .enable = pwrseq_test_enable_a, + .disable = pwrseq_test_disable_a, + }; + + top_deps[0] = &dep_unit; + top_unit = (struct pwrseq_unit_data){ + .name = "top", + .deps = top_deps, + .enable = pwrseq_test_enable_b, + }; + + target = (struct pwrseq_target_data){ + .name = "test-target", + .unit = &top_unit, + }; + + targets[0] = ⌖ + + ctx->consumer_name = PWRSEQ_TEST_CONSUMER; + ctx->enable_error_b = true; + + config = (struct pwrseq_config){ + .parent = &pdev->dev, + .drvdata = ctx, + .match = pwrseq_test_match_by_name, + .targets = targets, + }; + + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pwrseq); + + pdevinfo = (struct platform_device_info){ + .name = PWRSEQ_TEST_CONSUMER, + .id = PLATFORM_DEVID_NONE, + }; + + pdev = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); + + desc = kunit_pwrseq_get(test, &pdev->dev, "test-target"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, desc); + + ret = pwrseq_enable(desc); + KUNIT_EXPECT_EQ(test, ret, -EIO); + /* + * Dependency was enabled, then rolled back once top's own enable + * failed. + */ + KUNIT_EXPECT_EQ(test, ctx->enable_count_a, 1); + KUNIT_EXPECT_EQ(test, ctx->disable_count_a, 1); + /* + * Target unit's own enable never incremented since it returned an + * error. + */ + KUNIT_EXPECT_EQ(test, ctx->enable_count_b, 0); +} + +/* + * Test target->post_enable() on both the success and failure paths: it must + * run exactly once per pwrseq_enable() call that actually powers the target + * unit on, and a failing post_enable() must roll the unit back and clear + * powered_on so a subsequent pwrseq_enable() is called again. + */ +static void pwrseq_enable_post_enable(struct kunit *test) +{ + const struct pwrseq_target_data *targets[2] = { }; + struct platform_device *pdev = test->priv; + struct platform_device_info pdevinfo; + struct pwrseq_target_data target; + struct pwrseq_unit_data unit; + struct pwrseq_device *pwrseq; + struct pwrseq_config config; + struct pwrseq_test_ctx *ctx; + struct pwrseq_desc *desc; + int ret; + + ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + unit = (struct pwrseq_unit_data){ + .name = "unit-a", + .enable = pwrseq_test_enable_a, + .disable = pwrseq_test_disable_a, + }; + + target = (struct pwrseq_target_data){ + .name = "test-target", + .unit = &unit, + .post_enable = pwrseq_test_post_enable, + }; + + targets[0] = ⌖ + + ctx->consumer_name = PWRSEQ_TEST_CONSUMER; + + config = (struct pwrseq_config){ + .parent = &pdev->dev, + .drvdata = ctx, + .match = pwrseq_test_match_by_name, + .targets = targets, + }; + + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pwrseq); + + pdevinfo = (struct platform_device_info){ + .name = PWRSEQ_TEST_CONSUMER, + .id = PLATFORM_DEVID_NONE, + }; + + pdev = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); + + desc = kunit_pwrseq_get(test, &pdev->dev, "test-target"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, desc); + + /* Success path: post_enable() runs once and reports success. */ + ret = pwrseq_enable(desc); + KUNIT_EXPECT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, ctx->post_enable_calls, 1); + KUNIT_EXPECT_EQ(test, ctx->enable_count_a, 1); + + ret = pwrseq_disable(desc); + KUNIT_ASSERT_EQ(test, ret, 0); + + /* Failure path: post_enable() fails, unit is rolled back. */ + ctx->post_enable_error = true; + ret = pwrseq_enable(desc); + KUNIT_EXPECT_EQ(test, ret, -EIO); + KUNIT_EXPECT_EQ(test, ctx->post_enable_calls, 2); + KUNIT_EXPECT_EQ(test, ctx->enable_count_a, 2); + KUNIT_EXPECT_EQ(test, ctx->disable_count_a, 2); + + /* powered_on must have been cleared. */ + ret = pwrseq_enable(desc); + KUNIT_EXPECT_EQ(test, ret, -EIO); + KUNIT_EXPECT_EQ(test, ctx->enable_count_a, 3); +} + +/* + * Test that pwrseq_get() returns -ENOENT when the matched provider does not + * have the requested target name. + */ +static void pwrseq_get_target_not_found(struct kunit *test) +{ + const struct pwrseq_target_data *targets[2] = { }; + struct platform_device *pdev = test->priv; + struct platform_device_info pdevinfo; + struct pwrseq_target_data target; + struct pwrseq_unit_data unit; + struct pwrseq_device *pwrseq; + struct pwrseq_config config; + struct pwrseq_desc *desc; + + unit = (struct pwrseq_unit_data){ + .name = "unit-a", + }; + + target = (struct pwrseq_target_data){ + .name = "real-target", + .unit = &unit, + }; + + targets[0] = ⌖ + + config = (struct pwrseq_config){ + .parent = &pdev->dev, + .match = pwrseq_test_match_always, + .targets = targets, + }; + + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pwrseq); + + pdevinfo = (struct platform_device_info){ + .name = PWRSEQ_TEST_CONSUMER, + .id = PLATFORM_DEVID_NONE, + }; + + pdev = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); + + desc = kunit_pwrseq_get(test, &pdev->dev, "nonexistent-target"); + KUNIT_EXPECT_TRUE(test, IS_ERR(desc)); + KUNIT_EXPECT_EQ(test, PTR_ERR(desc), -ENOENT); +} + +/* + * Test that pwrseq_put() on a descriptor that is still powered on disables + * it as part of tear-down, instead of leaking the power-on state. + */ +static void pwrseq_put_disables_powered_desc(struct kunit *test) +{ + const struct pwrseq_target_data *targets[2] = { }; + struct platform_device *pdev = test->priv; + struct platform_device_info pdevinfo; + struct pwrseq_target_data target; + struct pwrseq_unit_data unit; + struct pwrseq_device *pwrseq; + struct pwrseq_test_ctx *ctx; + struct pwrseq_config config; + struct pwrseq_desc *desc; + int ret; + + ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + unit = (struct pwrseq_unit_data){ + .name = "unit-a", + .enable = pwrseq_test_enable_a, + .disable = pwrseq_test_disable_a, + }; + + target = (struct pwrseq_target_data){ + .name = "test-target", + .unit = &unit, + }; + + targets[0] = ⌖ + + config = (struct pwrseq_config){ + .parent = &pdev->dev, + .drvdata = ctx, + .match = pwrseq_test_match_always, + .targets = targets, + }; + + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pwrseq); + + pdevinfo = (struct platform_device_info){ + .name = PWRSEQ_TEST_CONSUMER, + .id = PLATFORM_DEVID_NONE, + }; + + pdev = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); + + desc = kunit_pwrseq_get(test, &pdev->dev, "test-target"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, desc); + + ret = pwrseq_enable(desc); + KUNIT_ASSERT_EQ(test, ret, 0); + KUNIT_EXPECT_EQ(test, ctx->disable_count_a, 0); + + /* + * Run the deferred pwrseq_put() action now instead of at test + * teardown, so its effect can be asserted below. + */ + kunit_release_action(test, pwrseq_put_wrapper, desc); + KUNIT_EXPECT_EQ(test, ctx->disable_count_a, 1); +} + +/* + * Test that pwrseq_device_unregister() on a target with an active user + * triggers "REMOVING POWER SEQUENCER WITH ACTIVE USERS", and that both + * pwrseq_enable() and pwrseq_disable() start returning -ENODEV for + * previously acquired descriptors afterwards. + */ +static void pwrseq_unregister_with_active_user(struct kunit *test) +{ + struct platform_device *pdev = test->priv, *cons_a, *cons_b; + const struct pwrseq_target_data *targets[2] = { }; + struct platform_device_info pdevinfo; + struct pwrseq_desc *desc_a, *desc_b; + struct pwrseq_target_data target; + struct pwrseq_unit_data unit; + struct pwrseq_device *pwrseq; + struct pwrseq_test_ctx *ctx; + struct pwrseq_config config; + bool bound; + int ret; + + ctx = kunit_kzalloc(test, sizeof(*ctx), GFP_KERNEL); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); + + unit = (struct pwrseq_unit_data){ + .name = "unit-a", + .enable = pwrseq_test_enable_a, + .disable = pwrseq_test_disable_a, + }; + + target = (struct pwrseq_target_data){ + .name = "test-target", + .unit = &unit, + }; + + targets[0] = ⌖ + + config = (struct pwrseq_config){ + .parent = &pdev->dev, + .drvdata = ctx, + .match = pwrseq_test_match_always, + .targets = targets, + }; + + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pwrseq); + + pdevinfo = (struct platform_device_info){ + .name = PWRSEQ_TEST_CONSUMER, + .id = 0, + }; + cons_a = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cons_a); + + wait_for_device_probe(); + scoped_guard(device, &cons_a->dev) + bound = device_is_bound(&cons_a->dev); + + KUNIT_ASSERT_FALSE(test, bound); + + pdevinfo.id = 1; + cons_b = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cons_b); + + wait_for_device_probe(); + scoped_guard(device, &cons_b->dev) + bound = device_is_bound(&cons_b->dev); + + KUNIT_ASSERT_FALSE(test, bound); + + desc_a = kunit_pwrseq_get(test, &cons_a->dev, "test-target"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, desc_a); + desc_b = kunit_pwrseq_get(test, &cons_b->dev, "test-target"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, desc_b); + + ret = pwrseq_enable(desc_a); + KUNIT_ASSERT_EQ(test, ret, 0); + + kunit_warning_suppress(test) { + kunit_release_action(test, pwrseq_device_unregister_wrapper, pwrseq); + KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1); + } + + ret = pwrseq_enable(desc_b); + KUNIT_EXPECT_EQ(test, ret, -ENODEV); + + ret = pwrseq_disable(desc_a); + KUNIT_EXPECT_EQ(test, ret, -ENODEV); +} + +/* + * Test that pwrseq_to_device() returns the pwrseq provider's own device, + * and NULL for a NULL descriptor. + */ +static void pwrseq_to_device_test(struct kunit *test) +{ + struct platform_device *parent = test->priv, *cons; + const struct pwrseq_target_data *targets[2] = { }; + struct platform_device_info pdevinfo; + struct pwrseq_target_data target; + struct pwrseq_unit_data unit; + struct pwrseq_device *pwrseq; + struct pwrseq_config config; + struct pwrseq_desc *desc; + struct device *dev; + + unit = (struct pwrseq_unit_data){ .name = "unit-a" }; + target = (struct pwrseq_target_data){ + .name = "test-target", + .unit = &unit, + }; + targets[0] = ⌖ + + config = (struct pwrseq_config){ + .parent = &parent->dev, + .match = pwrseq_test_match_always, + .targets = targets, + }; + + pwrseq = kunit_pwrseq_device_register(test, &config); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pwrseq); + + pdevinfo = (struct platform_device_info){ + .name = PWRSEQ_TEST_CONSUMER, + .id = PLATFORM_DEVID_NONE, + }; + + cons = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cons); + + desc = kunit_pwrseq_get(test, &cons->dev, "test-target"); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, desc); + + dev = pwrseq_to_device(desc); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev); + KUNIT_EXPECT_PTR_EQ(test, dev->parent, &parent->dev); + KUNIT_EXPECT_TRUE(test, device_is_registered(dev)); + + KUNIT_EXPECT_PTR_EQ(test, pwrseq_to_device(NULL), NULL); +} + +static struct kunit_case pwrseq_tests[] = { + KUNIT_CASE(pwrseq_circular_deps), + KUNIT_CASE(pwrseq_circular_deps_chain), + KUNIT_CASE(pwrseq_register_valid), + KUNIT_CASE(pwrseq_register_invalid_args), + KUNIT_CASE(pwrseq_register_target_without_unit), + KUNIT_CASE(pwrseq_enable_disable), + KUNIT_CASE(pwrseq_shared_deps), + KUNIT_CASE(pwrseq_enable_idempotent), + KUNIT_CASE(pwrseq_enable_enable_error), + KUNIT_CASE(pwrseq_enable_rollback_on_top_failure), + KUNIT_CASE(pwrseq_enable_post_enable), + KUNIT_CASE(pwrseq_get_target_not_found), + KUNIT_CASE(pwrseq_put_disables_powered_desc), + KUNIT_CASE(pwrseq_unregister_with_active_user), + KUNIT_CASE(pwrseq_to_device_test), + { } +}; + +static struct kunit_suite pwrseq_test_suite = { + .name = "pwrseq", + .init = pwrseq_test_parent_init, + .test_cases = pwrseq_tests, +}; + +/* + * Match a consumer to this test provider by resolving its "pwrseq-provider" + * software-node reference and comparing it to the provider's own fwnode. + */ +static int pwrseq_test_match_by_swnode_ref(struct pwrseq_device *pwrseq, + struct device *dev) +{ + const struct software_node *provider_swnode; + struct fwnode_handle *provider_fwnode, *ref; + bool match; + + if (!dev_fwnode(dev)) + return PWRSEQ_NO_MATCH; + + ref = fwnode_find_reference(dev_fwnode(dev), "pwrseq-provider", 0); + if (IS_ERR_OR_NULL(ref)) + return PWRSEQ_NO_MATCH; + + provider_swnode = pwrseq_device_get_drvdata(pwrseq); + provider_fwnode = software_node_fwnode(provider_swnode); + match = (ref == provider_fwnode); + fwnode_handle_put(ref); + + return match ? PWRSEQ_MATCH_OK : PWRSEQ_NO_MATCH; +} + +static const struct pwrseq_unit_data pwrseq_swnode_test_unit = { + .name = "test-target", +}; + +static const struct pwrseq_target_data pwrseq_swnode_test_target = { + .name = "test-target", + .unit = &pwrseq_swnode_test_unit, +}; + +static const struct pwrseq_target_data *pwrseq_swnode_test_targets[] = { + &pwrseq_swnode_test_target, + NULL, +}; + +struct pwrseq_swnode_provider_pdata { + const struct software_node *provider_swnode; +}; + +static int pwrseq_swnode_provider_probe(struct platform_device *pdev) +{ + const struct pwrseq_swnode_provider_pdata *pdata = dev_get_platdata(&pdev->dev); + struct pwrseq_config config; + + config = (struct pwrseq_config){ + .parent = &pdev->dev, + .drvdata = (void *)pdata->provider_swnode, + .match = pwrseq_test_match_by_swnode_ref, + .targets = pwrseq_swnode_test_targets, + }; + + return PTR_ERR_OR_ZERO(devm_pwrseq_device_register(&pdev->dev, &config)); +} + +static struct platform_driver pwrseq_swnode_provider_driver = { + .probe = pwrseq_swnode_provider_probe, + .driver = { + .name = PWRSEQ_SWNODE_TEST_PROVIDER, + }, +}; + +static struct platform_driver pwrseq_swnode_provider_driver_2 = { + .probe = pwrseq_swnode_provider_probe, + .driver = { + .name = PWRSEQ_SWNODE_TEST_PROVIDER_2, + }, +}; + +struct pwrseq_probe_order_pdata { + unsigned int probe_count; + int pwrseq_err; +}; + +static const struct pwrseq_probe_order_pdata pwrseq_probe_order_pdata_template; + +static int pwrseq_probe_order_consumer_probe(struct platform_device *pdev) +{ + struct pwrseq_probe_order_pdata *pdata = dev_get_platdata(&pdev->dev); + struct pwrseq_desc *desc; + + pdata->probe_count++; + + desc = devm_pwrseq_get(&pdev->dev, "test-target"); + pdata->pwrseq_err = PTR_ERR_OR_ZERO(desc); + if (IS_ERR(desc)) + return PTR_ERR(desc); + + return 0; +} + +static struct platform_driver pwrseq_probe_order_consumer_driver = { + .probe = pwrseq_probe_order_consumer_probe, + .driver = { + .name = PWRSEQ_PROBE_ORDER_TEST_CONSUMER, + }, +}; + +static struct platform_driver pwrseq_probe_defer_consumer_driver = { + .probe = pwrseq_probe_order_consumer_probe, + .driver = { + .name = PWRSEQ_PROBE_DEFER_TEST_CONSUMER, + }, +}; + +/* + * Verify that driver core orders the probe of a pwrseq consumer after its + * provider. The consumer references the provider through a software node and + * is registered first and we rely on devlink for ordering. + */ +static void pwrseq_swnode_probe_order(struct kunit *test) +{ + struct property_entry properties[2] = { }; + struct pwrseq_probe_order_pdata *pdata; + struct platform_device_info pdevinfo; + struct platform_device *prvd, *cons; + struct fwnode_handle *fwnode; + bool bound = false; + int ret; + + ret = kunit_platform_driver_register(test, &pwrseq_swnode_provider_driver); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = kunit_platform_driver_register(test, &pwrseq_probe_order_consumer_driver); + KUNIT_ASSERT_EQ(test, ret, 0); + + fwnode = kunit_software_node_register(test, &pwrseq_test_provider_swnode); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode); + + properties[0] = PROPERTY_ENTRY_REF("pwrseq-provider", + &pwrseq_test_provider_swnode); + + pdevinfo = (struct platform_device_info){ + .name = PWRSEQ_PROBE_ORDER_TEST_CONSUMER, + .id = PLATFORM_DEVID_NONE, + .data = &pwrseq_probe_order_pdata_template, + .size_data = sizeof(pwrseq_probe_order_pdata_template), + .properties = properties, + }; + + cons = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cons); + + wait_for_device_probe(); + scoped_guard(device, &cons->dev) + bound = device_is_bound(&cons->dev); + + KUNIT_ASSERT_FALSE(test, bound); + + pdata = dev_get_platdata(&cons->dev); + KUNIT_ASSERT_EQ(test, pdata->probe_count, 0); + + pdevinfo = (struct platform_device_info){ + .name = PWRSEQ_SWNODE_TEST_PROVIDER, + .id = PLATFORM_DEVID_NONE, + .swnode = &pwrseq_test_provider_swnode, + .data = &(const struct pwrseq_swnode_provider_pdata){ + .provider_swnode = &pwrseq_test_provider_swnode, + }, + .size_data = sizeof(struct pwrseq_swnode_provider_pdata), + }; + + prvd = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, prvd); + + wait_for_device_probe(); + + scoped_guard(device, &prvd->dev) + bound = device_is_bound(&prvd->dev); + KUNIT_ASSERT_TRUE(test, bound); + + scoped_guard(device, &cons->dev) + bound = device_is_bound(&cons->dev); + KUNIT_ASSERT_TRUE(test, bound); + + pdata = dev_get_platdata(&cons->dev); + KUNIT_EXPECT_EQ(test, pdata->probe_count, 1); + KUNIT_EXPECT_EQ(test, pdata->pwrseq_err, 0); +} + +/* + * Verify that a pwrseq consumer referencing a provider whose software node is + * not registered yet, defers its probe instead of failing. + * + * The provider software node is deliberately left unregistered when the + * consumer is added. fw_devlink cannot resolve the reference, so it creates no + * supplier link and does not order the consumer - the consumer's probe() runs + * and calls pwrseq_get(), which finds no matching provider and returns + * -EPROBE_DEFER. Once the provider software node and device appear, the + * deferred consumer probes again and binds. + */ +static void pwrseq_swnode_probe_defer_on_unregistered(struct kunit *test) +{ + struct property_entry properties[2] = { }; + struct pwrseq_probe_order_pdata *pdata; + struct platform_device_info pdevinfo; + struct platform_device *prvd, *cons; + struct fwnode_handle *fwnode; + bool bound = false; + int ret; + + ret = kunit_platform_driver_register(test, &pwrseq_swnode_provider_driver_2); + KUNIT_ASSERT_EQ(test, ret, 0); + + ret = kunit_platform_driver_register(test, &pwrseq_probe_defer_consumer_driver); + KUNIT_ASSERT_EQ(test, ret, 0); + + properties[0] = PROPERTY_ENTRY_REF("pwrseq-provider", + &pwrseq_test_provider_swnode); + + pdevinfo = (struct platform_device_info){ + .name = PWRSEQ_PROBE_DEFER_TEST_CONSUMER, + .id = PLATFORM_DEVID_NONE, + .data = &pwrseq_probe_order_pdata_template, + .size_data = sizeof(pwrseq_probe_order_pdata_template), + .properties = properties, + }; + + cons = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, cons); + + wait_for_device_probe(); + scoped_guard(device, &cons->dev) + bound = device_is_bound(&cons->dev); + + KUNIT_ASSERT_FALSE(test, bound); + + pdata = dev_get_platdata(&cons->dev); + KUNIT_ASSERT_GT(test, pdata->probe_count, 0); + KUNIT_ASSERT_EQ(test, pdata->pwrseq_err, -EPROBE_DEFER); + + fwnode = kunit_software_node_register(test, &pwrseq_test_provider_swnode); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, fwnode); + + pdevinfo = (struct platform_device_info){ + .name = PWRSEQ_SWNODE_TEST_PROVIDER_2, + .id = PLATFORM_DEVID_NONE, + .swnode = &pwrseq_test_provider_swnode, + .data = &(const struct pwrseq_swnode_provider_pdata){ + .provider_swnode = &pwrseq_test_provider_swnode, + }, + .size_data = sizeof(struct pwrseq_swnode_provider_pdata), + }; + + prvd = kunit_platform_device_register_full(test, &pdevinfo); + KUNIT_ASSERT_NOT_ERR_OR_NULL(test, prvd); + + wait_for_device_probe(); + + scoped_guard(device, &prvd->dev) + bound = device_is_bound(&prvd->dev); + KUNIT_ASSERT_TRUE(test, bound); + + scoped_guard(device, &cons->dev) + bound = device_is_bound(&cons->dev); + KUNIT_ASSERT_TRUE(test, bound); + + pdata = dev_get_platdata(&cons->dev); + KUNIT_EXPECT_EQ(test, pdata->pwrseq_err, 0); +} + +static int pwrseq_swnode_test_init(struct kunit *test) +{ + /* + * A device link teardown from an earlier test case, or from this + * suite's previous module load, may still be queued on device_link_mq. + * Flush it so software_node_register() below doesn't spuriously see + * the about-to-be-reused node name as still taken. + */ + device_link_wait_removal(); + + return 0; +} + +static struct kunit_case pwrseq_swnode_probe_order_tests[] = { + KUNIT_CASE(pwrseq_swnode_probe_order), + KUNIT_CASE(pwrseq_swnode_probe_defer_on_unregistered), + { } +}; + +static struct kunit_suite pwrseq_swnode_probe_order_test_suite = { + .name = "pwrseq-swnode-probe-order", + .init = pwrseq_swnode_test_init, + .test_cases = pwrseq_swnode_probe_order_tests, +}; + +kunit_test_suites(&pwrseq_test_suite, + &pwrseq_swnode_probe_order_test_suite); + +MODULE_DESCRIPTION("KUnit test cases for the power sequencing subsystem"); +MODULE_AUTHOR("Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>"); +MODULE_LICENSE("GPL");
diff --git a/drivers/power/sequencing/pwrseq-pcie-m2.c b/drivers/power/sequencing/pwrseq-pcie-m2.c index e42e85f..56c5d51 100644 --- a/drivers/power/sequencing/pwrseq-pcie-m2.c +++ b/drivers/power/sequencing/pwrseq-pcie-m2.c
@@ -83,6 +83,18 @@ static int pwrseq_pci_m2_e_uart_disable(struct pwrseq_device *pwrseq) return gpiod_set_value_cansleep(ctx->w_disable2_gpio, 1); } +static bool pwrseq_pci_m2_e_uart_is_controllable(struct pwrseq_device *pwrseq) +{ + struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq); + + /* + * The UART enable is driven through the W_DISABLE2# line. When it is not + * wired up on this connector the enable/disable callbacks are no-ops, so + * the host cannot gate the Bluetooth function on its own. + */ + return !!ctx->w_disable2_gpio; +} + static const struct pwrseq_unit_data pwrseq_pcie_m2_e_uart_unit_data = { .name = "uart-enable", .deps = pwrseq_pcie_m2_unit_deps, @@ -104,6 +116,18 @@ static int pwrseq_pci_m2_e_pcie_disable(struct pwrseq_device *pwrseq) return gpiod_set_value_cansleep(ctx->w_disable1_gpio, 1); } +static bool pwrseq_pci_m2_e_pcie_is_controllable(struct pwrseq_device *pwrseq) +{ + struct pwrseq_pcie_m2_ctx *ctx = pwrseq_device_get_drvdata(pwrseq); + + /* + * The PCIe/WiFi enable is driven through the W_DISABLE1# line. When it + * is not wired up on this connector the enable/disable callbacks are + * no-ops, so the host cannot gate the PCIe/WiFi function on its own. + */ + return !!ctx->w_disable1_gpio; +} + static const struct pwrseq_unit_data pwrseq_pcie_m2_e_pcie_unit_data = { .name = "pcie-enable", .deps = pwrseq_pcie_m2_unit_deps, @@ -132,12 +156,14 @@ static const struct pwrseq_target_data pwrseq_pcie_m2_e_uart_target_data = { .name = "uart", .unit = &pwrseq_pcie_m2_e_uart_unit_data, .post_enable = pwrseq_pcie_m2_e_pwup_delay, + .is_controllable = pwrseq_pci_m2_e_uart_is_controllable, }; static const struct pwrseq_target_data pwrseq_pcie_m2_e_pcie_target_data = { .name = "pcie", .unit = &pwrseq_pcie_m2_e_pcie_unit_data, .post_enable = pwrseq_pcie_m2_e_pwup_delay, + .is_controllable = pwrseq_pci_m2_e_pcie_is_controllable, }; static const struct pwrseq_target_data pwrseq_pcie_m2_m_pcie_target_data = { @@ -199,6 +225,8 @@ static const struct pci_device_id pwrseq_m2_pci_ids[] = { .driver_data = (kernel_ulong_t)"qcom,wcn7850-bt" }, { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x1107, PCI_VENDOR_ID_LENOVO, 0xe0e9), .driver_data = (kernel_ulong_t)"qcom,wcn7850-bt" }, + { PCI_DEVICE_SUB(PCI_VENDOR_ID_QCOM, 0x1107, PCI_VENDOR_ID_FOXCONN, 0xe0ee), + .driver_data = (kernel_ulong_t)"qcom,wcn7850-bt" }, { } /* Sentinel */ }; @@ -378,6 +406,21 @@ static void pwrseq_pcie_m2_remove_serdev(struct pwrseq_pcie_m2_ctx *ctx, mutex_unlock(&ctx->list_lock); } +static bool pwrseq_pcie_m2_pci_parent_matches(struct pci_dev *pdev, + struct device_node *pci_parent) +{ + struct device *dev = pdev->dev.parent; + + while (dev) { + if (dev->of_node == pci_parent) + return true; + if (!dev_is_pci(dev)) + break; + dev = dev->parent; + } + return false; +} + static int pwrseq_pcie_m2_notify(struct notifier_block *nb, unsigned long action, void *data) { @@ -392,7 +435,7 @@ static int pwrseq_pcie_m2_notify(struct notifier_block *nb, unsigned long action */ struct device_node *pci_parent __free(device_node) = of_graph_get_remote_node(dev_of_node(ctx->dev), 0, 0); - if (!pci_parent || (pci_parent != pdev->dev.parent->of_node)) + if (!pci_parent || !pwrseq_pcie_m2_pci_parent_matches(pdev, pci_parent)) return NOTIFY_DONE; switch (action) { @@ -466,7 +509,7 @@ static int pwrseq_pcie_m2_create_serdev(struct pwrseq_pcie_m2_ctx *ctx) /* Create serdev for existing PCI devices if required */ for_each_pci_dev(pdev) { - if (!pdev->dev.parent || pci_parent != pdev->dev.parent->of_node) + if (!pwrseq_pcie_m2_pci_parent_matches(pdev, pci_parent)) continue; if (!pci_match_id(pwrseq_m2_pci_ids, pdev))
diff --git a/drivers/power/sequencing/pwrseq-qcom-wcn.c b/drivers/power/sequencing/pwrseq-qcom-wcn.c index 34146d6..636dd7e 100644 --- a/drivers/power/sequencing/pwrseq-qcom-wcn.c +++ b/drivers/power/sequencing/pwrseq-qcom-wcn.c
@@ -183,6 +183,19 @@ static int pwrseq_qcom_wcn_bt_disable(struct pwrseq_device *pwrseq) return 0; } +static bool pwrseq_qcom_wcn_bt_is_controllable(struct pwrseq_device *pwrseq) +{ + struct pwrseq_qcom_wcn_ctx *ctx = pwrseq_device_get_drvdata(pwrseq); + + /* + * The Bluetooth enable is driven through the BT_EN GPIO. When it is not + * wired up (e.g. hardwired to an always-on pull-up), the enable/disable + * callbacks are no-ops, so the host cannot gate the Bluetooth function + * on its own. + */ + return !!ctx->bt_gpio; +} + static const struct pwrseq_unit_data pwrseq_qcom_wcn_bt_unit_data = { .name = "bluetooth-enable", .deps = pwrseq_qcom_wcn_unit_deps, @@ -217,6 +230,19 @@ static int pwrseq_qcom_wcn_wlan_disable(struct pwrseq_device *pwrseq) return 0; } +static bool pwrseq_qcom_wcn_wlan_is_controllable(struct pwrseq_device *pwrseq) +{ + struct pwrseq_qcom_wcn_ctx *ctx = pwrseq_device_get_drvdata(pwrseq); + + /* + * The WLAN enable is driven through the WLAN_EN GPIO. When it is not + * wired up (e.g. hardwired to an always-on pull-up), the enable/disable + * callbacks are no-ops, so the host cannot gate the WLAN function on + * its own. + */ + return !!ctx->wlan_gpio; +} + static const struct pwrseq_unit_data pwrseq_qcom_wcn_wlan_unit_data = { .name = "wlan-enable", .deps = pwrseq_qcom_wcn_unit_deps, @@ -257,12 +283,14 @@ static const struct pwrseq_target_data pwrseq_qcom_wcn_bt_target_data = { .name = "bluetooth", .unit = &pwrseq_qcom_wcn_bt_unit_data, .post_enable = pwrseq_qcom_wcn_pwup_delay, + .is_controllable = pwrseq_qcom_wcn_bt_is_controllable, }; static const struct pwrseq_target_data pwrseq_qcom_wcn_wlan_target_data = { .name = "wlan", .unit = &pwrseq_qcom_wcn_wlan_unit_data, .post_enable = pwrseq_qcom_wcn_pwup_delay, + .is_controllable = pwrseq_qcom_wcn_wlan_is_controllable, }; /* There are no separate BT and WLAN enablement pins */ @@ -280,12 +308,14 @@ static const struct pwrseq_target_data pwrseq_qcom_wcn6855_bt_target_data = { .name = "bluetooth", .unit = &pwrseq_qcom_wcn6855_bt_unit_data, .post_enable = pwrseq_qcom_wcn6855_xo_clk_deassert, + .is_controllable = pwrseq_qcom_wcn_bt_is_controllable, }; static const struct pwrseq_target_data pwrseq_qcom_wcn6855_wlan_target_data = { .name = "wlan", .unit = &pwrseq_qcom_wcn6855_wlan_unit_data, .post_enable = pwrseq_qcom_wcn6855_xo_clk_deassert, + .is_controllable = pwrseq_qcom_wcn_wlan_is_controllable, }; static const struct pwrseq_target_data *pwrseq_qcom_wcn_targets[] = {
diff --git a/drivers/power/sequencing/pwrseq-renesas-pwrrdy.c b/drivers/power/sequencing/pwrseq-renesas-pwrrdy.c new file mode 100644 index 0000000..74385562 --- /dev/null +++ b/drivers/power/sequencing/pwrseq-renesas-pwrrdy.c
@@ -0,0 +1,142 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Renesas RZ/G3L Power Ready driver + * + */ + +#include <linux/auxiliary_bus.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/pwrseq/provider.h> +#include <linux/regmap.h> + +#define SYS_PWRRDY_N 0xd70 +#define SYS_PWRRDY_N_USB_MASK BIT(0) +#define SYS_PWRRDY_N_DSI_MASK BIT(1) +#define SYS_PWRRDY_N_CSI_MASK BIT(2) + +static int pwrseq_rzg3l_set_pwrrdy(struct pwrseq_device *pwrseq, u32 mask, + bool val) +{ + struct regmap *regmap = pwrseq_device_get_drvdata(pwrseq); + + return regmap_assign_bits(regmap, SYS_PWRRDY_N, mask, val); +} + +static int pwrseq_rzg3l_usb_pwrrdy_enable(struct pwrseq_device *pwrseq) +{ + return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_USB_MASK, 0); +} + +static int pwrseq_rzg3l_usb_pwrrdy_disable(struct pwrseq_device *pwrseq) +{ + return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_USB_MASK, 1); +} + +static const struct pwrseq_unit_data pwrseq_rzg3l_usb_pwrrdy_unit = { + .name = "usb-pwrrdy-power-sequence", + .enable = pwrseq_rzg3l_usb_pwrrdy_enable, + .disable = pwrseq_rzg3l_usb_pwrrdy_disable, +}; + +static int pwrseq_rzg3l_dsi_pwrrdy_enable(struct pwrseq_device *pwrseq) +{ + return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_DSI_MASK, 0); +} + +static int pwrseq_rzg3l_dsi_pwrrdy_disable(struct pwrseq_device *pwrseq) +{ + return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_DSI_MASK, 1); +} + +static const struct pwrseq_unit_data pwrseq_rzg3l_dsi_pwrrdy_unit = { + .name = "dsi-pwrrdy-sequence", + .enable = pwrseq_rzg3l_dsi_pwrrdy_enable, + .disable = pwrseq_rzg3l_dsi_pwrrdy_disable, +}; + +static int pwrseq_rzg3l_csi_pwrrdy_enable(struct pwrseq_device *pwrseq) +{ + return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_CSI_MASK, 0); +} + +static int pwrseq_rzg3l_csi_pwrrdy_disable(struct pwrseq_device *pwrseq) +{ + return pwrseq_rzg3l_set_pwrrdy(pwrseq, SYS_PWRRDY_N_CSI_MASK, 1); +} + +static const struct pwrseq_unit_data pwrseq_rzg3l_csi_pwrrdy_unit = { + .name = "csi-pwrrdy-power-sequence", + .enable = pwrseq_rzg3l_csi_pwrrdy_enable, + .disable = pwrseq_rzg3l_csi_pwrrdy_disable, +}; + +static const struct pwrseq_target_data pwrseq_rzg3l_usb_pwrrdy_target = { + .name = "usb-pwrrdy", + .unit = &pwrseq_rzg3l_usb_pwrrdy_unit, +}; + +static const struct pwrseq_target_data pwrseq_rzg3l_dsi_pwrrdy_target = { + .name = "dsi-pwrrdy", + .unit = &pwrseq_rzg3l_dsi_pwrrdy_unit, +}; + +static const struct pwrseq_target_data pwrseq_rzg3l_csi_pwrrdy_target = { + .name = "csi-pwrrdy", + .unit = &pwrseq_rzg3l_csi_pwrrdy_unit, +}; + +static const struct pwrseq_target_data *pwrseq_rzg3l_pwrrdy_targets[] = { + &pwrseq_rzg3l_usb_pwrrdy_target, + &pwrseq_rzg3l_dsi_pwrrdy_target, + &pwrseq_rzg3l_csi_pwrrdy_target, + NULL +}; + +static const char * const pwrseq_rzg3l_pwrrdy_compats[] = { + "renesas,r9a08g046-usbphy-ctrl", + "renesas,r9a08g046-mipi-dsi", + NULL +}; + +static int pwrseq_rzg3l_pwrrdy_match(struct pwrseq_device *pwrseq, + struct device *dev) +{ + if (of_device_compatible_match(dev->of_node, pwrseq_rzg3l_pwrrdy_compats)) + return PWRSEQ_MATCH_OK; + + return PWRSEQ_NO_MATCH; +} + +static int pwrseq_rzg3l_pwrrdy_probe(struct auxiliary_device *adev, + const struct auxiliary_device_id *id) +{ + struct pwrseq_config config = { + .parent = &adev->dev, + .owner = THIS_MODULE, + .drvdata = adev->dev.platform_data, + .match = pwrseq_rzg3l_pwrrdy_match, + .targets = pwrseq_rzg3l_pwrrdy_targets, + }; + + return PTR_ERR_OR_ZERO(devm_pwrseq_device_register(&adev->dev, &config)); +} + +static const struct auxiliary_device_id pwrseq_rzg3l_pwrrdy_id_table[] = { + { .name = "rz_sysc.pwrseq-pwrrdy" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(auxiliary, pwrseq_rzg3l_pwrrdy_id_table); + +static struct auxiliary_driver pwrseq_rzg3l_pwrrdy_driver = { + .driver = { + .name = "pwrseq-rzg3l-pwrrdy", + }, + .probe = pwrseq_rzg3l_pwrrdy_probe, + .id_table = pwrseq_rzg3l_pwrrdy_id_table, +}; +module_auxiliary_driver(pwrseq_rzg3l_pwrrdy_driver); + +MODULE_AUTHOR("Biju Das <biju.das.jz@bp.renesas.com>"); +MODULE_DESCRIPTION("Renesas RZ/G3L Power Ready Driver"); +MODULE_LICENSE("GPL");
diff --git a/drivers/pwm/core.c b/drivers/pwm/core.c index 2a050ff..4c6d716 100644 --- a/drivers/pwm/core.c +++ b/drivers/pwm/core.c
@@ -2389,6 +2389,7 @@ static const struct file_operations pwm_cdev_fileops = { .release = pwm_cdev_release, .owner = THIS_MODULE, .unlocked_ioctl = pwm_cdev_ioctl, + .compat_ioctl = compat_ptr_ioctl, }; static dev_t pwm_devt;
diff --git a/drivers/pwm/pwm-brcmstb.c b/drivers/pwm/pwm-brcmstb.c index 790ef7f..7837878 100644 --- a/drivers/pwm/pwm-brcmstb.c +++ b/drivers/pwm/pwm-brcmstb.c
@@ -101,7 +101,7 @@ static int brcmstb_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, u32 value; /* - * If asking for a duty_ns equal to period_ns, we need to substract + * If asking for a duty_ns equal to period_ns, we need to subtract * the period value by 1 to make it shorter than the "on" time and * produce a flat 100% duty cycle signal, and max out the "on" time */
diff --git a/drivers/pwm/pwm-ipq.c b/drivers/pwm/pwm-ipq.c index 6b7aec5..3e1231b 100644 --- a/drivers/pwm/pwm-ipq.c +++ b/drivers/pwm/pwm-ipq.c
@@ -186,7 +186,7 @@ static int ipq_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm, state->period = DIV64_U64_ROUND_UP(effective_div * NSEC_PER_SEC, ipq_chip->clk_rate); - hi_div = hi_dur * (pre_div + 1); + hi_div = (u64)hi_dur * (pre_div + 1); state->duty_cycle = DIV64_U64_ROUND_UP(hi_div * NSEC_PER_SEC, ipq_chip->clk_rate);
diff --git a/drivers/pwm/pwm-iqs620a.c b/drivers/pwm/pwm-iqs620a.c index 13e5e13..6c6caee 100644 --- a/drivers/pwm/pwm-iqs620a.c +++ b/drivers/pwm/pwm-iqs620a.c
@@ -173,18 +173,6 @@ static const struct pwm_ops iqs620_pwm_ops = { .get_state = iqs620_pwm_get_state, }; -static void iqs620_pwm_notifier_unregister(void *context) -{ - struct iqs620_pwm_private *iqs620_pwm = context; - int ret; - - ret = blocking_notifier_chain_unregister(&iqs620_pwm->iqs62x->nh, - &iqs620_pwm->notifier); - if (ret) - dev_err(iqs620_pwm->dev, - "Failed to unregister notifier: %d\n", ret); -} - static int iqs620_pwm_probe(struct platform_device *pdev) { struct iqs62x_core *iqs62x = dev_get_drvdata(pdev->dev.parent); @@ -218,19 +206,14 @@ static int iqs620_pwm_probe(struct platform_device *pdev) mutex_init(&iqs620_pwm->lock); iqs620_pwm->notifier.notifier_call = iqs620_pwm_notifier; - ret = blocking_notifier_chain_register(&iqs620_pwm->iqs62x->nh, - &iqs620_pwm->notifier); + ret = devm_blocking_notifier_chain_register(&pdev->dev, + &iqs620_pwm->iqs62x->nh, + &iqs620_pwm->notifier); if (ret) { dev_err(&pdev->dev, "Failed to register notifier: %d\n", ret); return ret; } - ret = devm_add_action_or_reset(&pdev->dev, - iqs620_pwm_notifier_unregister, - iqs620_pwm); - if (ret) - return ret; - ret = devm_pwmchip_add(&pdev->dev, chip); if (ret) dev_err(&pdev->dev, "Failed to add device: %d\n", ret);
diff --git a/drivers/pwm/pwm-loongson.c b/drivers/pwm/pwm-loongson.c index f2fb35b..98c809b 100644 --- a/drivers/pwm/pwm-loongson.c +++ b/drivers/pwm/pwm-loongson.c
@@ -99,6 +99,7 @@ static void pwm_loongson_disable(struct pwm_chip *chip, struct pwm_device *pwm) struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip); val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); + val |= LOONGSON_PWM_CTRL_REG_RST; val &= ~LOONGSON_PWM_CTRL_REG_EN; pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL); } @@ -109,6 +110,7 @@ static int pwm_loongson_enable(struct pwm_chip *chip, struct pwm_device *pwm) struct pwm_loongson_ddata *ddata = to_pwm_loongson_ddata(chip); val = pwm_loongson_readl(ddata, LOONGSON_PWM_REG_CTRL); + val &= ~LOONGSON_PWM_CTRL_REG_RST; val |= LOONGSON_PWM_CTRL_REG_EN; pwm_loongson_writel(ddata, val, LOONGSON_PWM_REG_CTRL);
diff --git a/drivers/pwm/pwm-lp3943.c b/drivers/pwm/pwm-lp3943.c index 10537e7..e42af90 100644 --- a/drivers/pwm/pwm-lp3943.c +++ b/drivers/pwm/pwm-lp3943.c
@@ -38,6 +38,9 @@ lp3943_pwm_request_map(struct lp3943_pwm *lp3943_pwm, int hwpwm) struct lp3943_pwm_map *pwm_map = &lp3943_pwm->pwm_map[hwpwm]; int i, offset; + if (!pdata->pwms[hwpwm]) + return ERR_PTR(-ENODEV); + pwm_map->output = pdata->pwms[hwpwm]->output; pwm_map->num_outputs = pdata->pwms[hwpwm]->num_outputs;
diff --git a/drivers/pwm/pwm-mtk-disp.c b/drivers/pwm/pwm-mtk-disp.c index b5409e1..56d10cd 100644 --- a/drivers/pwm/pwm-mtk-disp.c +++ b/drivers/pwm/pwm-mtk-disp.c
@@ -210,9 +210,9 @@ static int mtk_disp_pwm_get_state(struct pwm_chip *chip, period = FIELD_GET(PWM_PERIOD_MASK, con1); /* * period has 12 bits, clk_div 11 and NSEC_PER_SEC has 30, - * so period * (clk_div + 1) * NSEC_PER_SEC doesn't overflow. + * so (period + 1) * (clk_div + 1) * NSEC_PER_SEC doesn't overflow. */ - state->period = DIV64_U64_ROUND_UP(period * (clk_div + 1) * NSEC_PER_SEC, rate); + state->period = DIV64_U64_ROUND_UP((period + 1) * (clk_div + 1) * NSEC_PER_SEC, rate); high_width = FIELD_GET(PWM_HIGH_WIDTH_MASK, con1); state->duty_cycle = DIV64_U64_ROUND_UP(high_width * (clk_div + 1) * NSEC_PER_SEC, rate);
diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c index a2792b8..3374ed7 100644 --- a/drivers/pwm/pwm-pca9685.c +++ b/drivers/pwm/pwm-pca9685.c
@@ -54,7 +54,7 @@ /* * The time value of one counter tick. Note that NSEC_PER_SEC is an integer * multiple of PCA9685_OSC_CLOCK_HZ, so there is no rounding involved and we're - * not loosing precision due to the early division. + * not losing precision due to the early division. */ #define PCA9685_QUANTUM_NS(_prescale) ((NSEC_PER_SEC / PCA9685_OSC_CLOCK_HZ) * (_prescale + 1))
diff --git a/drivers/pwm/pwm-renesas-tpu.c b/drivers/pwm/pwm-renesas-tpu.c index 140fd0b..e35f2e1 100644 --- a/drivers/pwm/pwm-renesas-tpu.c +++ b/drivers/pwm/pwm-renesas-tpu.c
@@ -149,10 +149,14 @@ static int tpu_pwm_timer_start(struct tpu_pwm_device *tpd) if (!tpd->timer_on) { /* Wake up device and enable clock. */ - pm_runtime_get_sync(&tpd->tpu->pdev->dev); + ret = pm_runtime_resume_and_get(&tpd->tpu->pdev->dev); + if (ret < 0) + return ret; + ret = clk_prepare_enable(tpd->tpu->clk); if (ret) { dev_err(&tpd->tpu->pdev->dev, "cannot enable clock\n"); + pm_runtime_put(&tpd->tpu->pdev->dev); return ret; } tpd->timer_on = true; @@ -382,15 +386,21 @@ static int tpu_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm) return 0; } -static void tpu_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) +static int tpu_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) { struct tpu_device *tpu = to_tpu_device(chip); struct tpu_pwm_device *tpd = &tpu->tpd[pwm->hwpwm]; + int ret; /* The timer must be running to modify the pin output configuration. */ - tpu_pwm_timer_start(tpd); + ret = tpu_pwm_timer_start(tpd); + if (ret < 0) + return ret; + tpu_pwm_set_pin(tpd, TPU_PIN_INACTIVE); tpu_pwm_timer_stop(tpd); + + return 0; } static int tpu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, @@ -401,7 +411,10 @@ static int tpu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (state->polarity != pwm->state.polarity) { if (enabled) { - tpu_pwm_disable(chip, pwm); + err = tpu_pwm_disable(chip, pwm); + if (err) + return err; + enabled = false; } @@ -412,7 +425,7 @@ static int tpu_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm, if (!state->enabled) { if (enabled) - tpu_pwm_disable(chip, pwm); + return tpu_pwm_disable(chip, pwm); return 0; }
diff --git a/drivers/pwm/pwm-tiehrpwm.c b/drivers/pwm/pwm-tiehrpwm.c index 3a53489..e3407d0 100644 --- a/drivers/pwm/pwm-tiehrpwm.c +++ b/drivers/pwm/pwm-tiehrpwm.c
@@ -358,6 +358,9 @@ static void ehrpwm_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm) /* Disable clock on PWM disable */ pm_runtime_put_sync(pwmchip_parent(chip)); + + /* A disabled channel must not constrain the sibling's period */ + pc->period_cycles[pwm->hwpwm] = 0; } static void ehrpwm_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
diff --git a/drivers/regulator/88pm886-regulator.c b/drivers/regulator/88pm886-regulator.c index 7328cd1..1961a79 100644 --- a/drivers/regulator/88pm886-regulator.c +++ b/drivers/regulator/88pm886-regulator.c
@@ -337,6 +337,25 @@ static struct regulator_desc pm886_regulators[] = { }, }; +static const struct linear_range pm886_vbus_volt_ranges[] = { + REGULATOR_LINEAR_RANGE(3750000, 0, 7, 250000) +}; + +static struct regulator_desc pm886_vbus_regulator = { + .name = "vbus", + .regulators_node = "regulators", + .of_match = "vbus", + .ops = &pm886_buck_ops, + .type = REGULATOR_VOLTAGE, + .n_voltages = 8, + .linear_ranges = pm886_vbus_volt_ranges, + .n_linear_ranges = ARRAY_SIZE(pm886_vbus_volt_ranges), + .vsel_reg = PM886_REG_BOOST_CONFIG1, + .vsel_mask = PM886_REG_BOOST_MASK, + .enable_reg = PM886_REG_BATTERY_CONFIG1, + .enable_mask = PM886_REG_VBUS_EN, +}; + static int pm886_regulator_probe(struct platform_device *pdev) { struct pm886_chip *chip = dev_get_drvdata(pdev->dev.parent); @@ -369,6 +388,13 @@ static int pm886_regulator_probe(struct platform_device *pdev) "Failed to register %s\n", rdesc->name); } + rcfg.regmap = chip->regmap_battery; + rdesc = &pm886_vbus_regulator; + rdev = devm_regulator_register(dev, rdesc, &rcfg); + if (IS_ERR(rdev)) + return dev_err_probe(dev, PTR_ERR(rdev), + "Failed to register %s\n", rdesc->name); + return 0; }
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 89789ac..be6b72d 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig
@@ -241,12 +241,12 @@ will be called bd71815-regulator. config REGULATOR_BD71828 - tristate "ROHM BD71828, BD72720 and BD73900 Power Regulators" + tristate "ROHM BD71828, BD72720 and BD73[8/9]00 Power Regulators" depends on MFD_ROHM_BD71828 select REGULATOR_ROHM help This driver supports voltage regulators on ROHM BD71828, - BD71879, BD72720 and BD73900 PMICs. This will enable + BD71879, BD72720 and BD73[8/9]00 PMICs. This will enable support for the software controllable buck and LDO regulators. This driver can also be built as a module. If so, the module @@ -864,12 +864,23 @@ module. The module will be named "mp8859". config REGULATOR_MP886X - tristate "MPS MP8869 regulator driver" + tristate "MPS MP8864/MP8867/MP8869 regulator driver" depends on I2C && OF select REGMAP_I2C help This driver supports the MP8869 voltage regulator. +config REGULATOR_MPQ4210 + tristate "MPS MPQ4210 regulator driver" + depends on I2C && OF + select REGMAP_I2C + help + This driver supports the MPQ4210 synchronous buck-boost controller. + It supports get/set voltage, enable/disable and ramp rate selection + through the regulator interface. + Say M here if you want to include support for the regulator as a + module. The module will be named "mpq4210". + config REGULATOR_MPQ7920 tristate "Monolithic MPQ7920 PMIC" depends on I2C && OF @@ -1020,6 +1031,14 @@ of Mediatek. It allows for voting on regulator state between multiple users. +config REGULATOR_NEX10000UB + tristate "Nexperia NEX10000UB Dual Output Power regulators" + depends on I2C && GPIOLIB + select REGMAP_I2C + help + This driver supports the NEX10000UB single inductor - dual output + power supply specifically designed for display panels. + config REGULATOR_PALMAS tristate "TI Palmas PMIC Regulators" depends on MFD_PALMAS
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 5a764ce..6aabcc5 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile
@@ -104,6 +104,7 @@ obj-$(CONFIG_REGULATOR_MP5416) += mp5416.o obj-$(CONFIG_REGULATOR_MP8859) += mp8859.o obj-$(CONFIG_REGULATOR_MP886X) += mp886x.o +obj-$(CONFIG_REGULATOR_MPQ4210) += mpq4210.o obj-$(CONFIG_REGULATOR_MPQ7920) += mpq7920.o obj-$(CONFIG_REGULATOR_MT6311) += mt6311-regulator.o obj-$(CONFIG_REGULATOR_MT6315) += mt6315-regulator.o @@ -120,6 +121,7 @@ obj-$(CONFIG_REGULATOR_MT6380) += mt6380-regulator.o obj-$(CONFIG_REGULATOR_MT6397) += mt6397-regulator.o obj-$(CONFIG_REGULATOR_MTK_DVFSRC) += mtk-dvfsrc-regulator.o +obj-$(CONFIG_REGULATOR_NEX10000UB) += nex10000ub-regulator.o obj-$(CONFIG_REGULATOR_QCOM_LABIBB) += qcom-labibb-regulator.o obj-$(CONFIG_REGULATOR_QCOM_PM8008) += qcom-pm8008-regulator.o obj-$(CONFIG_REGULATOR_QCOM_REFGEN) += qcom-refgen-regulator.o
diff --git a/drivers/regulator/ab8500-ext.c b/drivers/regulator/ab8500-ext.c index b9955aa..c0657362 100644 --- a/drivers/regulator/ab8500-ext.c +++ b/drivers/regulator/ab8500-ext.c
@@ -88,7 +88,7 @@ static struct regulator_init_data ab8500_ext_regulators[] = { * @update_reg: register to control on/off * @update_mask: mask to enable/disable and set mode of regulator * @update_val: bits holding the regulator current mode - * @update_val_hp: bits to set EN pin active (LPn pin deactive) + * @update_val_hp: bits to set EN pin active (LPn pin deactivate) * normally this means high power mode * @update_val_lp: bits to set EN pin active and LPn pin active * normally this means low power mode
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c index 3705c98..3c1962a 100644 --- a/drivers/regulator/ab8500.c +++ b/drivers/regulator/ab8500.c
@@ -9,15 +9,18 @@ * AB8500 peripheral regulators * * AB8500 supports the following regulators: - * VAUX1/2/3, VINTCORE, VTVOUT, VUSB, VAUDIO, VAMIC1/2, VDMIC, VANA + * VSMPS1/2/3, VARM, VAPE, VMOD, VAUX1/2/3, VINTCORE, VTVOUT, + * VUSB, VAUDIO, VAMIC1/2, VDMIC, VANA * * AB8505 supports the following regulators: - * VAUX1/2/3/4/5/6, VINTCORE, VADC, VUSB, VAUDIO, VAMIC1/2, VDMIC, VANA + * VSMPSA/B/C/M, VSAFE, VARM, VAUX1/2/3/4/5/6, VINTCORE, + * VADC, VUSB, VAUDIO, VAMIC1/2, VDMIC, VANA */ #include <linux/init.h> #include <linux/kernel.h> #include <linux/module.h> #include <linux/err.h> +#include <linux/mutex.h> #include <linux/platform_device.h> #include <linux/mfd/abx500.h> #include <linux/mfd/abx500/ab8500.h> @@ -39,6 +42,12 @@ enum ab8500_regulator_id { AB8500_LDO_ANAMIC2, AB8500_LDO_DMIC, AB8500_LDO_ANA, + AB8500_BUCK_SMPS1, + AB8500_BUCK_SMPS2, + AB8500_BUCK_SMPS3, + AB8500_BUCK_ARM, + AB8500_BUCK_APE, + AB8500_BUCK_MOD, AB8500_NUM_REGULATORS, }; @@ -57,6 +66,12 @@ enum ab8505_regulator_id { AB8505_LDO_ANAMIC2, AB8505_LDO_AUX8, AB8505_LDO_ANA, + AB8505_BUCK_SMPSA, + AB8505_BUCK_SMPSB, + AB8505_BUCK_SAFE, + AB8505_BUCK_ARM, + AB8505_BUCK_SMPSC, + AB8505_BUCK_SMPSM, AB8505_NUM_REGULATORS, }; @@ -162,6 +177,7 @@ struct ab8500_shared_mode { * @update_bank: bank to control on/off * @update_reg: register to control on/off * @update_mask: mask to enable/disable and set mode of regulator + * @enable_mask: optional mask for an enable bit separate from the mode bit * @update_val: bits holding the regulator current mode * @update_val_idle: bits to enable the regulator in idle (low power) mode * @update_val_normal: bits to enable the regulator in normal (high power) mode @@ -171,8 +187,17 @@ struct ab8500_shared_mode { * @mode_val_idle: mode setting for low power * @mode_val_normal: mode setting for normal power * @voltage_bank: bank to control regulator voltage - * @voltage_reg: register to control regulator voltage + * @voltage_reg: first register containing a selectable regulator voltage * @voltage_mask: mask to control regulator voltage + * @expand_register: additional register used to select an extra voltage + * @voltage_ctrl_bank: bank containing the voltage selector control + * @voltage_ctrl_reg: register containing the voltage selector control + * @voltage_ctrl_mask: mask selecting one of the first voltage registers + * @voltage_ext_ctrl_bank: bank containing the extended selector control + * @voltage_ext_ctrl_reg: register containing the extended selector control + * @voltage_ext_ctrl_mask: mask selecting one of the extended voltage registers + * @voltage_ext_reg: first extended voltage register + * @voltage_ext_regs: number of extended voltage registers */ struct ab8500_regulator_info { struct device *dev; @@ -182,6 +207,7 @@ struct ab8500_regulator_info { u8 update_bank; u8 update_reg; u8 update_mask; + u8 enable_mask; u8 update_val; u8 update_val_idle; u8 update_val_normal; @@ -193,6 +219,20 @@ struct ab8500_regulator_info { u8 voltage_bank; u8 voltage_reg; u8 voltage_mask; + struct { + u8 voltage_limit; + u8 voltage_bank; + u8 voltage_reg; + u8 voltage_mask; + } expand_register; + u8 voltage_ctrl_bank; + u8 voltage_ctrl_reg; + u8 voltage_ctrl_mask; + u8 voltage_ext_ctrl_bank; + u8 voltage_ext_ctrl_reg; + u8 voltage_ext_ctrl_mask; + u8 voltage_ext_reg; + u8 voltage_ext_regs; }; /* voltage tables for the vauxn/vintcore supplies */ @@ -226,6 +266,18 @@ static const unsigned int ldo_vaux3_voltages[] = { 2910000, }; +static const unsigned int ldo_vaux3_ab8505_voltages[] = { + 1200000, + 1500000, + 1800000, + 2100000, + 2500000, + 2750000, + 2790000, + 2910000, + 3050000, +}; + static const unsigned int ldo_vaux56_voltages[] = { 1800000, 1050000, @@ -237,14 +289,13 @@ static const unsigned int ldo_vaux56_voltages[] = { 2790000, }; -static const unsigned int ldo_vintcore_voltages[] = { - 1200000, - 1225000, - 1250000, - 1275000, - 1300000, - 1325000, - 1350000, +static const struct linear_range ldo_vintcore_ranges[] = { + REGULATOR_LINEAR_RANGE(1200000, 0, 6, 25000), +}; + +static const struct linear_range ldo_vintcore_ab8505_ranges[] = { + REGULATOR_LINEAR_RANGE(1200000, 0, 6, 25000), + REGULATOR_LINEAR_RANGE(1350000, 7, 7, 0), }; static const unsigned int fixed_1200000_voltage[] = { @@ -264,25 +315,54 @@ static const unsigned int fixed_2050000_voltage[] = { }; static const unsigned int ldo_vana_voltages[] = { + 1200000, 1050000, 1075000, 1100000, 1125000, 1150000, 1175000, - 1200000, 1225000, }; -static const unsigned int ldo_vaudio_voltages[] = { - 2000000, - 2100000, - 2200000, - 2300000, - 2400000, - 2500000, - 2600000, - 2600000, /* Duplicated in Vaudio and IsoUicc Control register. */ +static const struct linear_range ldo_vaudio_ranges[] = { + REGULATOR_LINEAR_RANGE(2000000, 0, 6, 100000), + /* Duplicated in Vaudio and IsoUicc Control register. */ + REGULATOR_LINEAR_RANGE(2600000, 7, 7, 0), +}; + +/* + * AB8505 buck ranges except VARM are selected by OTP. The supported + * platforms use the AB8500-compatible profiles for VSMPSA/B and the low + * profiles for VSAFE, VSMPSC and VSMPSM. + */ +static const struct linear_range buck_low_voltages[] = { + REGULATOR_LINEAR_RANGE(700000, 0, 53, 12500), + REGULATOR_LINEAR_RANGE(1362500, 54, 63, 0), +}; + +/* VSMPS3 and VSAFE have a 7-bit selector, but the same low range. */ +static const struct linear_range buck_low_7bit_voltages[] = { + REGULATOR_LINEAR_RANGE(700000, 0, 53, 12500), + REGULATOR_LINEAR_RANGE(1362500, 54, 127, 0), +}; + +/* AB8505 VARM uses a separate 0.6 V to 1.39375 V selector range. */ +static const struct linear_range ab8505_buck_arm_voltages[] = { + REGULATOR_LINEAR_RANGE(600000, 0, 127, 6250), +}; + +/* VSMPS1 and the VSMPSA AB8500-compatible profile clamp to this range. */ +static const struct linear_range buck_smps1_voltages[] = { + REGULATOR_LINEAR_RANGE(1100000, 0, 32, 0), + REGULATOR_LINEAR_RANGE(1112500, 33, 48, 12500), + REGULATOR_LINEAR_RANGE(1300000, 49, 63, 0), +}; + +/* VSMPS2 and the VSMPSB AB8500-compatible profile clamp to this range. */ +static const struct linear_range buck_smps2_voltages[] = { + REGULATOR_LINEAR_RANGE(1800000, 0, 57, 0), + REGULATOR_LINEAR_RANGE(1812500, 58, 63, 12500), }; static DEFINE_MUTEX(shared_mode_mutex); @@ -343,7 +423,7 @@ static int ab8500_regulator_disable(struct regulator_dev *rdev) return ret; } -static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) +static int ab8500_regulator_get_enable_value(struct regulator_dev *rdev) { int ret; struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); @@ -368,10 +448,65 @@ static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) info->desc.name, info->update_bank, info->update_reg, info->update_mask, regval); - if (regval & info->update_mask) - return 1; + return regval & info->update_mask; +} + +static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) +{ + struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); + u8 enable_mask; + int ret; + + ret = ab8500_regulator_get_enable_value(rdev); + if (ret < 0) + return ret; + + enable_mask = info->enable_mask ? info->enable_mask : info->update_mask; + + return !!(ret & enable_mask); +} + +static int ab8500_buck_enable(struct regulator_dev *rdev) +{ + int ret; + + /* Keep an OTP-selected hardware or low-power mode intact. */ + ret = ab8500_regulator_is_enabled(rdev); + if (ret) + return ret < 0 ? ret : 0; + + return ab8500_regulator_enable(rdev); +} + +static int ab8500_buck_init(struct regulator_dev *rdev, + struct regulator_config *config) +{ + struct ab8500_regulator_info *info = config->driver_data; + int ret; + + ret = ab8500_regulator_get_enable_value(rdev); + if (ret <= 0) + return ret; + + /* Report forced LP accurately; HP and hardware control are normal mode. */ + if (ret == info->update_val_idle) + info->update_val = info->update_val_idle; else - return 0; + info->update_val = info->update_val_normal; + + /* + * The SMPS enable state is selected by OTP. An enabled rail may + * supply discrete board components which are not represented as + * regulator consumers, so keep it out of the unused-regulator sweep. + */ + rdev->constraints->boot_on = true; + rdev->constraints->always_on = true; + rdev->constraints->valid_ops_mask &= ~REGULATOR_CHANGE_STATUS; + + dev_dbg(config->dev, "%s: preserving OTP-enabled state\n", + info->desc.name); + + return 0; } static unsigned int ab8500_regulator_get_optimum_mode( @@ -398,7 +533,7 @@ static unsigned int ab8500_regulator_get_optimum_mode( static int ab8500_regulator_set_mode(struct regulator_dev *rdev, unsigned int mode) { - int ret = 0; + int enabled, ret = 0; u8 bank, reg, mask, val; bool lp_mode_req = false; struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); @@ -408,6 +543,8 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev, return -EINVAL; } + guard(mutex)(&shared_mode_mutex); + if (info->mode_mask) { bank = info->mode_bank; reg = info->mode_reg; @@ -418,9 +555,6 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev, mask = info->update_mask; } - if (info->shared_mode) - mutex_lock(&shared_mode_mutex); - switch (mode) { case REGULATOR_MODE_NORMAL: if (info->shared_mode) @@ -439,7 +573,7 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev, if (!shared_regulator->shared_mode->lp_mode_req) { /* Other regulator prevent LP mode */ info->shared_mode->lp_mode_req = true; - goto out_unlock; + return 0; } lp_mode_req = true; @@ -451,17 +585,24 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev, val = info->update_val_idle; break; default: - ret = -EINVAL; - goto out_unlock; + return -EINVAL; } - if (info->mode_mask || ab8500_regulator_is_enabled(rdev)) { + if (info->mode_mask) { + enabled = 1; + } else { + enabled = ab8500_regulator_is_enabled(rdev); + if (enabled < 0) + return enabled; + } + + if (enabled) { ret = abx500_mask_and_set_register_interruptible(info->dev, bank, reg, mask, val); if (ret < 0) { dev_err(rdev_get_dev(rdev), "couldn't set regulator mode\n"); - goto out_unlock; + return ret; } dev_vdbg(rdev_get_dev(rdev), @@ -477,10 +618,6 @@ static int ab8500_regulator_set_mode(struct regulator_dev *rdev, if (info->shared_mode) info->shared_mode->lp_mode_req = lp_mode_req; -out_unlock: - if (info->shared_mode) - mutex_unlock(&shared_mode_mutex); - return ret; } @@ -530,11 +667,67 @@ static unsigned int ab8500_regulator_get_mode(struct regulator_dev *rdev) return ret; } +static int ab8500_regulator_get_voltage_reg(struct regulator_dev *rdev, + u8 *voltage_reg) +{ + struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); + u8 regval; + unsigned int selector; + int ret; + + if (info->voltage_ext_ctrl_mask) { + ret = abx500_get_register_interruptible(info->dev, + info->voltage_ext_ctrl_bank, + info->voltage_ext_ctrl_reg, ®val); + if (ret < 0) + return ret; + + selector = (regval & info->voltage_ext_ctrl_mask) >> + (ffs(info->voltage_ext_ctrl_mask) - 1); + if (selector) { + selector = min_t(unsigned int, selector, + info->voltage_ext_regs); + *voltage_reg = info->voltage_ext_reg + selector - 1; + return 0; + } + } + + if (!info->voltage_ctrl_mask) { + *voltage_reg = info->voltage_reg; + return 0; + } + + ret = abx500_get_register_interruptible(info->dev, + info->voltage_ctrl_bank, + info->voltage_ctrl_reg, ®val); + if (ret < 0) + return ret; + + /* The three hardware selector layouts all use consecutive registers. */ + switch (info->voltage_ctrl_mask) { + case 0x0c: + selector = min((unsigned int)((regval & 0x0c) >> 2), 2U); + break; + case 0x24: + selector = regval & BIT(5) ? 2 : !!(regval & BIT(2)); + break; + case 0x04: + selector = !!(regval & BIT(2)); + break; + default: + return -EINVAL; + } + + *voltage_reg = info->voltage_reg + selector; + + return 0; +} + static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev) { int ret, voltage_shift; struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); - u8 regval; + u8 regval, voltage_reg; if (info == NULL) { dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); @@ -543,8 +736,15 @@ static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev) voltage_shift = ffs(info->voltage_mask) - 1; + ret = ab8500_regulator_get_voltage_reg(rdev, &voltage_reg); + if (ret < 0) { + dev_err(rdev_get_dev(rdev), + "couldn't read voltage selector control\n"); + return ret; + } + ret = abx500_get_register_interruptible(info->dev, - info->voltage_bank, info->voltage_reg, ®val); + info->voltage_bank, voltage_reg, ®val); if (ret < 0) { dev_err(rdev_get_dev(rdev), "couldn't read voltage reg for regulator\n"); @@ -555,7 +755,7 @@ static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev) "%s-get_voltage (bank, reg, mask, shift, value): " "0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n", info->desc.name, info->voltage_bank, - info->voltage_reg, info->voltage_mask, + voltage_reg, info->voltage_mask, voltage_shift, regval); return (regval & info->voltage_mask) >> voltage_shift; @@ -566,7 +766,7 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev, { int ret, voltage_shift; struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); - u8 regval; + u8 regval, voltage_reg; if (info == NULL) { dev_err(rdev_get_dev(rdev), "regulator info null pointer\n"); @@ -575,10 +775,17 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev, voltage_shift = ffs(info->voltage_mask) - 1; + ret = ab8500_regulator_get_voltage_reg(rdev, &voltage_reg); + if (ret < 0) { + dev_err(rdev_get_dev(rdev), + "couldn't read voltage selector control\n"); + return ret; + } + /* set the registers for the request */ regval = (u8)selector << voltage_shift; ret = abx500_mask_and_set_register_interruptible(info->dev, - info->voltage_bank, info->voltage_reg, + info->voltage_bank, voltage_reg, info->voltage_mask, regval); if (ret < 0) dev_err(rdev_get_dev(rdev), @@ -587,12 +794,70 @@ static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev, dev_vdbg(rdev_get_dev(rdev), "%s-set_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x," " 0x%x\n", - info->desc.name, info->voltage_bank, info->voltage_reg, + info->desc.name, info->voltage_bank, voltage_reg, info->voltage_mask, regval); return ret; } +static int ab8500_regulator_get_voltage_sel_expand(struct regulator_dev *rdev) +{ + struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); + u8 regval; + int ret; + + if (!info) + return -EINVAL; + + ret = abx500_get_register_interruptible(info->dev, + info->expand_register.voltage_bank, + info->expand_register.voltage_reg, ®val); + if (ret < 0) { + dev_err(rdev_get_dev(rdev), + "couldn't read voltage expand reg for regulator\n"); + return ret; + } + + if (regval & info->expand_register.voltage_mask) + return info->expand_register.voltage_limit; + + return ab8500_regulator_get_voltage_sel(rdev); +} + +static int ab8500_regulator_set_voltage_sel_expand(struct regulator_dev *rdev, + unsigned int selector) +{ + struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); + u8 regval; + int ret; + + if (!info) + return -EINVAL; + + if (selector > info->expand_register.voltage_limit) + return -EINVAL; + + if (selector < info->expand_register.voltage_limit) { + ret = ab8500_regulator_set_voltage_sel(rdev, selector); + if (ret < 0) + return ret; + + regval = 0; + } else { + regval = info->expand_register.voltage_mask; + } + + ret = abx500_mask_and_set_register_interruptible(info->dev, + info->expand_register.voltage_bank, + info->expand_register.voltage_reg, + info->expand_register.voltage_mask, regval); + if (ret < 0) + dev_err(rdev_get_dev(rdev), + "couldn't set voltage expand reg for regulator\n"); + + return ret; +} + static const struct regulator_ops ab8500_regulator_volt_mode_ops = { .enable = ab8500_regulator_enable, .disable = ab8500_regulator_disable, @@ -605,13 +870,59 @@ static const struct regulator_ops ab8500_regulator_volt_mode_ops = { .list_voltage = regulator_list_voltage_table, }; -static const struct regulator_ops ab8500_regulator_volt_ops = { +static const struct regulator_ops ab8500_regulator_volt_mode_expand_ops = { + .enable = ab8500_regulator_enable, + .disable = ab8500_regulator_disable, + .is_enabled = ab8500_regulator_is_enabled, + .get_optimum_mode = ab8500_regulator_get_optimum_mode, + .set_mode = ab8500_regulator_set_mode, + .get_mode = ab8500_regulator_get_mode, + .get_voltage_sel = ab8500_regulator_get_voltage_sel_expand, + .set_voltage_sel = ab8500_regulator_set_voltage_sel_expand, + .list_voltage = regulator_list_voltage_table, +}; + +static const struct regulator_ops ab8500_regulator_linear_range_volt_mode_ops = { + .enable = ab8500_regulator_enable, + .disable = ab8500_regulator_disable, + .is_enabled = ab8500_regulator_is_enabled, + .get_optimum_mode = ab8500_regulator_get_optimum_mode, + .set_mode = ab8500_regulator_set_mode, + .get_mode = ab8500_regulator_get_mode, + .get_voltage_sel = ab8500_regulator_get_voltage_sel, + .set_voltage_sel = ab8500_regulator_set_voltage_sel, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, +}; + +static const struct regulator_ops ab8500_regulator_linear_range_volt_ops = { .enable = ab8500_regulator_enable, .disable = ab8500_regulator_disable, .is_enabled = ab8500_regulator_is_enabled, .get_voltage_sel = ab8500_regulator_get_voltage_sel, .set_voltage_sel = ab8500_regulator_set_voltage_sel, - .list_voltage = regulator_list_voltage_table, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, +}; + +static const struct regulator_ops ab8500_buck_ops = { + .enable = ab8500_buck_enable, + .disable = ab8500_regulator_disable, + .is_enabled = ab8500_regulator_is_enabled, + .get_optimum_mode = ab8500_regulator_get_optimum_mode, + .set_mode = ab8500_regulator_set_mode, + .get_mode = ab8500_regulator_get_mode, + .get_voltage_sel = ab8500_regulator_get_voltage_sel, + .set_voltage_sel = ab8500_regulator_set_voltage_sel, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, +}; + +static const struct regulator_ops ab8500_buck_voltage_ops = { + .get_voltage_sel = ab8500_regulator_get_voltage_sel, + .set_voltage_sel = ab8500_regulator_set_voltage_sel, + .list_voltage = regulator_list_voltage_linear_range, + .map_voltage = regulator_map_voltage_linear_range, }; static const struct regulator_ops ab8500_regulator_mode_ops = { @@ -721,18 +1032,20 @@ static struct ab8500_regulator_info [AB8500_LDO_INTCORE] = { .desc = { .name = "LDO-INTCORE", - .ops = &ab8500_regulator_volt_mode_ops, + .ops = &ab8500_regulator_linear_range_volt_mode_ops, .type = REGULATOR_VOLTAGE, .id = AB8500_LDO_INTCORE, .owner = THIS_MODULE, - .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages), - .volt_table = ldo_vintcore_voltages, + .n_voltages = 7, + .linear_ranges = ldo_vintcore_ranges, + .n_linear_ranges = ARRAY_SIZE(ldo_vintcore_ranges), .enable_time = 750, }, .load_lp_uA = 5000, .update_bank = 0x03, .update_reg = 0x80, .update_mask = 0x44, + .enable_mask = 0x04, .update_val = 0x44, .update_val_idle = 0x44, .update_val_normal = 0x04, @@ -761,6 +1074,7 @@ static struct ab8500_regulator_info .update_bank = 0x03, .update_reg = 0x80, .update_mask = 0x82, + .enable_mask = 0x02, .update_val = 0x02, .update_val_idle = 0x82, .update_val_normal = 0x02, @@ -852,6 +1166,140 @@ static struct ab8500_regulator_info .update_val_idle = 0x0c, .update_val_normal = 0x04, }, + + /* Buck converters */ + [AB8500_BUCK_SMPS1] = { + .desc = { + .name = "BUCK-SMPS1", + .ops = &ab8500_buck_ops, + .init_cb = ab8500_buck_init, + .type = REGULATOR_VOLTAGE, + .id = AB8500_BUCK_SMPS1, + .owner = THIS_MODULE, + .n_voltages = 64, + .linear_ranges = buck_smps1_voltages, + .n_linear_ranges = ARRAY_SIZE(buck_smps1_voltages), + }, + .load_lp_uA = 20000, + .update_bank = 0x04, + .update_reg = 0x03, + .update_mask = 0x03, + .update_val = 0x01, + .update_val_idle = 0x03, + .update_val_normal = 0x01, + .voltage_bank = 0x04, + .voltage_reg = 0x13, + .voltage_mask = 0x3f, + .voltage_ctrl_bank = 0x04, + .voltage_ctrl_reg = 0x03, + .voltage_ctrl_mask = 0x0c, + }, + [AB8500_BUCK_SMPS2] = { + .desc = { + .name = "BUCK-SMPS2", + .ops = &ab8500_buck_ops, + .init_cb = ab8500_buck_init, + .type = REGULATOR_VOLTAGE, + .id = AB8500_BUCK_SMPS2, + .owner = THIS_MODULE, + .n_voltages = 64, + .linear_ranges = buck_smps2_voltages, + .n_linear_ranges = ARRAY_SIZE(buck_smps2_voltages), + }, + .load_lp_uA = 20000, + .update_bank = 0x04, + .update_reg = 0x04, + .update_mask = 0x03, + .update_val = 0x01, + .update_val_idle = 0x03, + .update_val_normal = 0x01, + .voltage_bank = 0x04, + .voltage_reg = 0x17, + .voltage_mask = 0x3f, + .voltage_ctrl_bank = 0x04, + .voltage_ctrl_reg = 0x04, + .voltage_ctrl_mask = 0x0c, + }, + [AB8500_BUCK_SMPS3] = { + .desc = { + .name = "BUCK-SMPS3", + .ops = &ab8500_buck_ops, + .init_cb = ab8500_buck_init, + .type = REGULATOR_VOLTAGE, + .id = AB8500_BUCK_SMPS3, + .owner = THIS_MODULE, + .n_voltages = 128, + .linear_ranges = buck_low_7bit_voltages, + .n_linear_ranges = ARRAY_SIZE(buck_low_7bit_voltages), + }, + .load_lp_uA = 50000, + .update_bank = 0x04, + .update_reg = 0x05, + .update_mask = 0x03, + .update_val = 0x01, + .update_val_idle = 0x03, + .update_val_normal = 0x01, + .voltage_bank = 0x04, + .voltage_reg = 0x1b, + .voltage_mask = 0x7f, + .voltage_ctrl_bank = 0x04, + .voltage_ctrl_reg = 0x05, + .voltage_ctrl_mask = 0x0c, + }, + [AB8500_BUCK_ARM] = { + .desc = { + .name = "BUCK-ARM", + .ops = &ab8500_buck_voltage_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_BUCK_ARM, + .owner = THIS_MODULE, + .n_voltages = 64, + .linear_ranges = buck_low_voltages, + .n_linear_ranges = ARRAY_SIZE(buck_low_voltages), + }, + .voltage_bank = 0x04, + .voltage_reg = 0x0b, + .voltage_mask = 0x3f, + .voltage_ctrl_bank = 0x04, + .voltage_ctrl_reg = 0x00, + .voltage_ctrl_mask = 0x0c, + }, + [AB8500_BUCK_APE] = { + .desc = { + .name = "BUCK-APE", + .ops = &ab8500_buck_voltage_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_BUCK_APE, + .owner = THIS_MODULE, + .n_voltages = 64, + .linear_ranges = buck_low_voltages, + .n_linear_ranges = ARRAY_SIZE(buck_low_voltages), + }, + .voltage_bank = 0x04, + .voltage_reg = 0x0e, + .voltage_mask = 0x3f, + .voltage_ctrl_bank = 0x04, + .voltage_ctrl_reg = 0x02, + .voltage_ctrl_mask = 0x24, + }, + [AB8500_BUCK_MOD] = { + .desc = { + .name = "BUCK-MOD", + .ops = &ab8500_buck_voltage_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8500_BUCK_MOD, + .owner = THIS_MODULE, + .n_voltages = 64, + .linear_ranges = buck_low_voltages, + .n_linear_ranges = ARRAY_SIZE(buck_low_voltages), + }, + .voltage_bank = 0x04, + .voltage_reg = 0x41, + .voltage_mask = 0x3f, + .voltage_ctrl_bank = 0x04, + .voltage_ctrl_reg = 0x40, + .voltage_ctrl_mask = 0x04, + }, }; /* AB8505 regulator information */ @@ -908,12 +1356,12 @@ static struct ab8500_regulator_info [AB8505_LDO_AUX3] = { .desc = { .name = "LDO-AUX3", - .ops = &ab8500_regulator_volt_mode_ops, + .ops = &ab8500_regulator_volt_mode_expand_ops, .type = REGULATOR_VOLTAGE, .id = AB8505_LDO_AUX3, .owner = THIS_MODULE, - .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages), - .volt_table = ldo_vaux3_voltages, + .n_voltages = ARRAY_SIZE(ldo_vaux3_ab8505_voltages), + .volt_table = ldo_vaux3_ab8505_voltages, }, .load_lp_uA = 5000, .update_bank = 0x04, @@ -925,6 +1373,12 @@ static struct ab8500_regulator_info .voltage_bank = 0x04, .voltage_reg = 0x21, .voltage_mask = 0x07, + .expand_register = { + .voltage_limit = 8, + .voltage_bank = 0x04, + .voltage_reg = 0x01, + .voltage_mask = 0x10, + }, }, [AB8505_LDO_AUX4] = { .desc = { @@ -964,6 +1418,7 @@ static struct ab8500_regulator_info .update_bank = 0x01, .update_reg = 0x55, .update_mask = 0x18, + .enable_mask = 0x10, .update_val = 0x10, .update_val_idle = 0x18, .update_val_normal = 0x10, @@ -986,6 +1441,7 @@ static struct ab8500_regulator_info .update_bank = 0x01, .update_reg = 0x56, .update_mask = 0x18, + .enable_mask = 0x10, .update_val = 0x10, .update_val_idle = 0x18, .update_val_normal = 0x10, @@ -996,17 +1452,19 @@ static struct ab8500_regulator_info [AB8505_LDO_INTCORE] = { .desc = { .name = "LDO-INTCORE", - .ops = &ab8500_regulator_volt_mode_ops, + .ops = &ab8500_regulator_linear_range_volt_mode_ops, .type = REGULATOR_VOLTAGE, .id = AB8505_LDO_INTCORE, .owner = THIS_MODULE, - .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages), - .volt_table = ldo_vintcore_voltages, + .n_voltages = 8, + .linear_ranges = ldo_vintcore_ab8505_ranges, + .n_linear_ranges = ARRAY_SIZE(ldo_vintcore_ab8505_ranges), }, .load_lp_uA = 5000, .update_bank = 0x03, .update_reg = 0x80, .update_mask = 0x44, + .enable_mask = 0x04, .update_val = 0x04, .update_val_idle = 0x44, .update_val_normal = 0x04, @@ -1035,6 +1493,7 @@ static struct ab8500_regulator_info .update_bank = 0x03, .update_reg = 0x80, .update_mask = 0x82, + .enable_mask = 0x02, .update_val = 0x02, .update_val_idle = 0x82, .update_val_normal = 0x02, @@ -1042,12 +1501,13 @@ static struct ab8500_regulator_info [AB8505_LDO_AUDIO] = { .desc = { .name = "LDO-AUDIO", - .ops = &ab8500_regulator_volt_ops, + .ops = &ab8500_regulator_linear_range_volt_ops, .type = REGULATOR_VOLTAGE, .id = AB8505_LDO_AUDIO, .owner = THIS_MODULE, - .n_voltages = ARRAY_SIZE(ldo_vaudio_voltages), - .volt_table = ldo_vaudio_voltages, + .n_voltages = 8, + .linear_ranges = ldo_vaudio_ranges, + .n_linear_ranges = ARRAY_SIZE(ldo_vaudio_ranges), }, .update_bank = 0x03, .update_reg = 0x83, @@ -1138,6 +1598,155 @@ static struct ab8500_regulator_info .voltage_reg = 0x29, .voltage_mask = 0x7, }, + + /* Buck converters */ + [AB8505_BUCK_SMPSA] = { + .desc = { + .name = "BUCK-SMPSA", + .ops = &ab8500_buck_ops, + .init_cb = ab8500_buck_init, + .type = REGULATOR_VOLTAGE, + .id = AB8505_BUCK_SMPSA, + .owner = THIS_MODULE, + .n_voltages = 64, + .linear_ranges = buck_smps1_voltages, + .n_linear_ranges = ARRAY_SIZE(buck_smps1_voltages), + }, + .load_lp_uA = 20000, + .update_bank = 0x04, + .update_reg = 0x03, + .update_mask = 0x03, + .update_val = 0x01, + .update_val_idle = 0x03, + .update_val_normal = 0x01, + .voltage_bank = 0x04, + .voltage_reg = 0x13, + .voltage_mask = 0x3f, + .voltage_ctrl_bank = 0x04, + .voltage_ctrl_reg = 0x03, + .voltage_ctrl_mask = 0x0c, + }, + [AB8505_BUCK_SMPSB] = { + .desc = { + .name = "BUCK-SMPSB", + .ops = &ab8500_buck_ops, + .init_cb = ab8500_buck_init, + .type = REGULATOR_VOLTAGE, + .id = AB8505_BUCK_SMPSB, + .owner = THIS_MODULE, + .n_voltages = 64, + .linear_ranges = buck_smps2_voltages, + .n_linear_ranges = ARRAY_SIZE(buck_smps2_voltages), + }, + .load_lp_uA = 20000, + .update_bank = 0x04, + .update_reg = 0x04, + .update_mask = 0x03, + .update_val = 0x01, + .update_val_idle = 0x03, + .update_val_normal = 0x01, + .voltage_bank = 0x04, + .voltage_reg = 0x17, + .voltage_mask = 0x3f, + .voltage_ctrl_bank = 0x04, + .voltage_ctrl_reg = 0x04, + .voltage_ctrl_mask = 0x0c, + }, + [AB8505_BUCK_SAFE] = { + .desc = { + .name = "BUCK-SAFE", + .ops = &ab8500_buck_ops, + .init_cb = ab8500_buck_init, + .type = REGULATOR_VOLTAGE, + .id = AB8505_BUCK_SAFE, + .owner = THIS_MODULE, + .n_voltages = 128, + .linear_ranges = buck_low_7bit_voltages, + .n_linear_ranges = ARRAY_SIZE(buck_low_7bit_voltages), + }, + .load_lp_uA = 50000, + .update_bank = 0x04, + .update_reg = 0x05, + .update_mask = 0x03, + .update_val = 0x01, + .update_val_idle = 0x03, + .update_val_normal = 0x01, + .voltage_bank = 0x04, + .voltage_reg = 0x1b, + .voltage_mask = 0x7f, + .voltage_ctrl_bank = 0x04, + .voltage_ctrl_reg = 0x05, + .voltage_ctrl_mask = 0x0c, + }, + [AB8505_BUCK_ARM] = { + .desc = { + .name = "BUCK-ARM", + .ops = &ab8500_buck_voltage_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8505_BUCK_ARM, + .owner = THIS_MODULE, + .n_voltages = 128, + .linear_ranges = ab8505_buck_arm_voltages, + .n_linear_ranges = ARRAY_SIZE(ab8505_buck_arm_voltages), + }, + .voltage_bank = 0x04, + .voltage_reg = 0x0b, + .voltage_mask = 0x7f, + .voltage_ctrl_bank = 0x04, + .voltage_ctrl_reg = 0x00, + .voltage_ctrl_mask = 0x0c, + .voltage_ext_ctrl_bank = 0x04, + .voltage_ext_ctrl_reg = 0x28, + .voltage_ext_ctrl_mask = 0x07, + .voltage_ext_reg = 0x24, + .voltage_ext_regs = 4, + }, + [AB8505_BUCK_SMPSC] = { + .desc = { + .name = "BUCK-SMPSC", + .ops = &ab8500_buck_voltage_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8505_BUCK_SMPSC, + .owner = THIS_MODULE, + .n_voltages = 64, + .linear_ranges = buck_low_voltages, + .n_linear_ranges = ARRAY_SIZE(buck_low_voltages), + }, + .voltage_bank = 0x04, + .voltage_reg = 0x0e, + .voltage_mask = 0x3f, + .voltage_ctrl_bank = 0x04, + .voltage_ctrl_reg = 0x02, + .voltage_ctrl_mask = 0x24, + .voltage_ext_ctrl_bank = 0x04, + .voltage_ext_ctrl_reg = 0x2a, + .voltage_ext_ctrl_mask = 0x03, + .voltage_ext_reg = 0x2b, + .voltage_ext_regs = 2, + }, + [AB8505_BUCK_SMPSM] = { + .desc = { + .name = "BUCK-SMPSM", + .ops = &ab8500_buck_voltage_ops, + .type = REGULATOR_VOLTAGE, + .id = AB8505_BUCK_SMPSM, + .owner = THIS_MODULE, + .n_voltages = 64, + .linear_ranges = buck_low_voltages, + .n_linear_ranges = ARRAY_SIZE(buck_low_voltages), + }, + .voltage_bank = 0x04, + .voltage_reg = 0x41, + .voltage_mask = 0x3f, + .voltage_ctrl_bank = 0x04, + .voltage_ctrl_reg = 0x40, + .voltage_ctrl_mask = 0x04, + .voltage_ext_ctrl_bank = 0x04, + .voltage_ext_ctrl_reg = 0x47, + .voltage_ext_ctrl_mask = 0x03, + .voltage_ext_reg = 0x45, + .voltage_ext_regs = 2, + }, }; static struct ab8500_shared_mode ldo_anamic1_shared = { @@ -1613,6 +2222,12 @@ static struct of_regulator_match ab8500_regulator_match[] = { { .name = "ab8500_ldo_anamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, }, { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, }, { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, }, + { .name = "ab8500_buck_smps1", .driver_data = (void *)AB8500_BUCK_SMPS1, }, + { .name = "ab8500_buck_smps2", .driver_data = (void *)AB8500_BUCK_SMPS2, }, + { .name = "ab8500_buck_smps3", .driver_data = (void *)AB8500_BUCK_SMPS3, }, + { .name = "ab8500_buck_arm", .driver_data = (void *)AB8500_BUCK_ARM, }, + { .name = "ab8500_buck_ape", .driver_data = (void *)AB8500_BUCK_APE, }, + { .name = "ab8500_buck_mod", .driver_data = (void *)AB8500_BUCK_MOD, }, }; static struct of_regulator_match ab8505_regulator_match[] = { @@ -1629,6 +2244,12 @@ static struct of_regulator_match ab8505_regulator_match[] = { { .name = "ab8500_ldo_anamic2", .driver_data = (void *) AB8505_LDO_ANAMIC2, }, { .name = "ab8500_ldo_aux8", .driver_data = (void *) AB8505_LDO_AUX8, }, { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8505_LDO_ANA, }, + { .name = "ab8505_buck_smpsa", .driver_data = (void *)AB8505_BUCK_SMPSA, }, + { .name = "ab8505_buck_smpsb", .driver_data = (void *)AB8505_BUCK_SMPSB, }, + { .name = "ab8505_buck_safe", .driver_data = (void *)AB8505_BUCK_SAFE, }, + { .name = "ab8505_buck_arm", .driver_data = (void *)AB8505_BUCK_ARM, }, + { .name = "ab8505_buck_smpsc", .driver_data = (void *)AB8505_BUCK_SMPSC, }, + { .name = "ab8505_buck_smpsm", .driver_data = (void *)AB8505_BUCK_SMPSM, }, }; static struct { @@ -1677,9 +2298,14 @@ static int ab8500_regulator_register(struct platform_device *pdev, config.driver_data = info; config.of_node = np; - /* fix for hardware before ab8500v2.0 */ - if (is_ab8500_1p1_or_earlier(ab8500)) { - if (info->desc.id == AB8500_LDO_AUX3) { + /* Handle the different VAUX3 implementations in early AB8500 cuts. */ + if (info->desc.id == AB8500_LDO_AUX3) { + if (is_ab8500_1p0_or_earlier(ab8500)) { + info->desc.ops = &ab8500_regulator_mode_ops; + info->desc.n_voltages = 1; + info->desc.volt_table = fixed_1200000_voltage; + info->voltage_mask = 0; + } else if (is_ab8500_1p1_or_earlier(ab8500)) { info->desc.n_voltages = ARRAY_SIZE(ldo_vauxn_voltages); info->desc.volt_table = ldo_vauxn_voltages;
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c index da89141..ec6ec07 100644 --- a/drivers/regulator/axp20x-regulator.c +++ b/drivers/regulator/axp20x-regulator.c
@@ -1652,7 +1652,7 @@ static int axp20x_regulator_probe(struct platform_device *pdev) (regulators == axp803_regulators && i == AXP803_DC1SW) || (regulators == axp809_regulators && i == AXP809_DC1SW) || (regulators == axp15060_regulators && i == AXP15060_SW)) { - new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc), + new_desc = devm_kzalloc(&pdev->dev, sizeof(*new_desc), GFP_KERNEL); if (!new_desc) return -ENOMEM; @@ -1665,7 +1665,7 @@ static int axp20x_regulator_probe(struct platform_device *pdev) if ((regulators == axp22x_regulators && i == AXP22X_DC5LDO) || (regulators == axp809_regulators && i == AXP809_DC5LDO) || (regulators == axp15060_regulators && i == AXP15060_CPUSLDO)) { - new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc), + new_desc = devm_kzalloc(&pdev->dev, sizeof(*new_desc), GFP_KERNEL); if (!new_desc) return -ENOMEM; @@ -1677,7 +1677,7 @@ static int axp20x_regulator_probe(struct platform_device *pdev) if (regulators == axp15060_regulators && i == AXP15060_RTC_LDO) { - new_desc = devm_kzalloc(&pdev->dev, sizeof(*desc), + new_desc = devm_kzalloc(&pdev->dev, sizeof(*new_desc), GFP_KERNEL); if (!new_desc) return -ENOMEM;
diff --git a/drivers/regulator/bd71828-regulator.c b/drivers/regulator/bd71828-regulator.c index 2ced81d..dea551c 100644 --- a/drivers/regulator/bd71828-regulator.c +++ b/drivers/regulator/bd71828-regulator.c
@@ -1,7 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only // Copyright (C) 2019 ROHM Semiconductors // bd71828-regulator.c ROHM BD71828GW-DS1 regulator driver -// #include <linux/cleanup.h> #include <linux/delay.h> @@ -10,6 +9,7 @@ #include <linux/kernel.h> #include <linux/mfd/rohm-bd71828.h> #include <linux/mfd/rohm-bd72720.h> +#include <linux/mfd/rohm-bd73800.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> @@ -31,6 +31,13 @@ struct bd71828_regulator_data { int reg_init_amnt; }; +/* + * LDO1 and LDO3 node names are used also in the driver to find OTP setting for + * the used voltage range. + */ +#define LDO1_NODE_NAME "ldo1" +#define LDO3_NODE_NAME "ldo3" + static const struct reg_init bd71828_buck1_inits[] = { /* * DVS Buck voltages can be changed by register values or via GPIO. @@ -172,6 +179,55 @@ static const struct linear_range bd72720_ldo6_volts[] = { REGULATOR_LINEAR_RANGE(1800000, 0x79, 0x7f, 0), }; +static const struct linear_range bd73800_buck12348_volts[] = { + REGULATOR_LINEAR_RANGE(500000, 0x00, 0x50, 10000), + REGULATOR_LINEAR_RANGE(1300000, 0x51, 0xff, 0), +}; + +static const unsigned int bd73800_buck5_volt_range_sel[] = { + 0x0, 0x0, 0x1, 0x1, +}; + +static const struct linear_range bd73800_buck5_volts[] = { + /* range selector 0 */ + REGULATOR_LINEAR_RANGE(500000, 0x00, 0x50, 10000), + REGULATOR_LINEAR_RANGE(1300000, 0x51, 0x7f, 0), + /* range selector 1 */ + REGULATOR_LINEAR_RANGE(300000, 0x00, 0x46, 10000), + REGULATOR_LINEAR_RANGE(1000000, 0x47, 0x7f, 0), +}; + +/* + * BUCK5 has two different pickable ranges, each having voltages matching + * selectors 0x0 to 0x7f. This gives 0x7f + 1 different voltages for each of + * the ranges. + */ +#define BD73800_NUM_BUCK5_VOLTS ((0x7f + 1) * 2) + +static const struct linear_range bd73800_buck67_volts[] = { + REGULATOR_LINEAR_RANGE(1500000, 0x00, 0xc8, 10000), + REGULATOR_LINEAR_RANGE(3500000, 0xc9, 0xff, 0), +}; + +/* + * On the BD73800 the LDO1 and LDO3 support two different voltage areas. + * Whether to use 'high' or 'low' ranges is configured by OTP. There seems + * to be no register to read the configured area so it must be given via + * device-tree properties. + */ +static const struct linear_range bd73800_ldo13_low_volts[] = { + REGULATOR_LINEAR_RANGE(600000, 0x00, 0x78, 10000), + REGULATOR_LINEAR_RANGE(1800000, 0x79, 0xff, 0), +}; + +static const struct linear_range bd73800_ldo13_high_volts[] = { + REGULATOR_LINEAR_RANGE(750000, 0x00, 0xff, 10000), +}; + +static const struct linear_range bd73800_ldo24_volts[] = { + REGULATOR_LINEAR_RANGE(750000, 0x00, 0xff, 10000), +}; + static const unsigned int bd71828_ramp_delay[] = { 2500, 5000, 10000, 20000 }; /* @@ -225,6 +281,36 @@ static int bd71828_ldo6_parse_dt(struct device_node *np, return 0; } +/* Operations for all other BUCKs but BUCK 5 */ +static const struct regulator_ops bd73800_buck_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_ramp_delay = regulator_set_ramp_delay_regmap, +}; + +static const struct regulator_ops bd73800_buck5_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .list_voltage = regulator_list_voltage_pickable_linear_range, + .set_voltage_sel = regulator_set_voltage_sel_pickable_regmap, + .get_voltage_sel = regulator_get_voltage_sel_pickable_regmap, + .set_ramp_delay = regulator_set_ramp_delay_regmap, +}; + +static const struct regulator_ops bd73800_ldo_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, +}; + static const struct regulator_ops bd71828_buck_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, @@ -1565,6 +1651,412 @@ static const struct bd71828_regulator_data bd72720_rdata[] = { }, }; +static const struct bd71828_regulator_data bd73800_rdata[] = { + { + .desc = { + .name = "buck1", + .of_match = of_match_ptr("buck1"), + .regulators_node = of_match_ptr("regulators"), + .id = BD73800_BUCK1, + .ops = &bd73800_buck_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd73800_buck12348_volts, + .n_linear_ranges = ARRAY_SIZE(bd73800_buck12348_volts), + .n_voltages = BD73800_NUM_VOLTS, + .enable_reg = BD73800_REG_BUCK1_ON, + .enable_mask = BD73800_MASK_RUN_EN, + .vsel_reg = BD73800_REG_BUCK1_VOLT_RUN, + .vsel_mask = BD73800_MASK_VOLT, + .ramp_delay_table = bd71828_ramp_delay, + .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay), + .ramp_reg = BD73800_REG_BUCK1_MODE, + .ramp_mask = BD73800_MASK_RAMP_DELAY, + .owner = THIS_MODULE, + .of_parse_cb = buck_set_hw_dvs_levels, + }, + .dvs = { + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | + ROHM_DVS_LEVEL_SUSPEND, + .run_reg = BD73800_REG_BUCK1_VOLT_RUN, + .run_mask = BD73800_MASK_VOLT, + .idle_reg = BD73800_REG_BUCK1_VOLT_IDLE, + .idle_mask = BD73800_MASK_VOLT, + .idle_on_mask = BD73800_MASK_IDLE_EN, + .suspend_reg = BD73800_REG_BUCK1_VOLT_SUSP, + .suspend_mask = BD73800_MASK_VOLT, + .suspend_on_mask = BD73800_MASK_SUSP_EN, + }, + }, { + .desc = { + .name = "buck2", + .of_match = of_match_ptr("buck2"), + .regulators_node = of_match_ptr("regulators"), + .id = BD73800_BUCK2, + .ops = &bd73800_buck_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd73800_buck12348_volts, + .n_linear_ranges = ARRAY_SIZE(bd73800_buck12348_volts), + .n_voltages = BD73800_NUM_VOLTS, + .enable_reg = BD73800_REG_BUCK2_ON, + .enable_mask = BD73800_MASK_RUN_EN, + .vsel_reg = BD73800_REG_BUCK2_VOLT_RUN, + .vsel_mask = BD73800_MASK_VOLT, + .ramp_delay_table = bd71828_ramp_delay, + .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay), + .ramp_reg = BD73800_REG_BUCK2_MODE, + .ramp_mask = BD73800_MASK_RAMP_DELAY, + .owner = THIS_MODULE, + .of_parse_cb = buck_set_hw_dvs_levels, + }, + .dvs = { + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | + ROHM_DVS_LEVEL_SUSPEND, + .run_reg = BD73800_REG_BUCK2_VOLT_RUN, + .run_mask = BD73800_MASK_VOLT, + .idle_reg = BD73800_REG_BUCK2_VOLT_IDLE, + .idle_mask = BD73800_MASK_VOLT, + .idle_on_mask = BD73800_MASK_IDLE_EN, + .suspend_reg = BD73800_REG_BUCK2_VOLT_SUSP, + .suspend_mask = BD73800_MASK_VOLT, + .suspend_on_mask = BD73800_MASK_SUSP_EN, + }, + }, { + .desc = { + .name = "buck3", + .of_match = of_match_ptr("buck3"), + .regulators_node = of_match_ptr("regulators"), + .id = BD73800_BUCK3, + .ops = &bd73800_buck_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd73800_buck12348_volts, + .n_linear_ranges = ARRAY_SIZE(bd73800_buck12348_volts), + .n_voltages = BD73800_NUM_VOLTS, + .enable_reg = BD73800_REG_BUCK3_ON, + .enable_mask = BD73800_MASK_RUN_EN, + .vsel_reg = BD73800_REG_BUCK3_VOLT_RUN, + .vsel_mask = BD73800_MASK_VOLT, + .ramp_delay_table = bd71828_ramp_delay, + .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay), + .ramp_reg = BD73800_REG_BUCK3_MODE, + .ramp_mask = BD73800_MASK_RAMP_DELAY, + .owner = THIS_MODULE, + .of_parse_cb = buck_set_hw_dvs_levels, + }, + .dvs = { + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | + ROHM_DVS_LEVEL_SUSPEND, + .run_reg = BD73800_REG_BUCK3_VOLT_RUN, + .run_mask = BD73800_MASK_VOLT, + .idle_reg = BD73800_REG_BUCK3_VOLT_IDLE, + .idle_mask = BD73800_MASK_VOLT, + .idle_on_mask = BD73800_MASK_IDLE_EN, + .suspend_reg = BD73800_REG_BUCK3_VOLT_SUSP, + .suspend_mask = BD73800_MASK_VOLT, + .suspend_on_mask = BD73800_MASK_SUSP_EN, + }, + + }, { + .desc = { + .name = "buck4", + .of_match = of_match_ptr("buck4"), + .regulators_node = of_match_ptr("regulators"), + .id = BD73800_BUCK4, + .ops = &bd73800_buck_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd73800_buck12348_volts, + .n_linear_ranges = ARRAY_SIZE(bd73800_buck12348_volts), + .n_voltages = BD73800_NUM_VOLTS, + .enable_reg = BD73800_REG_BUCK4_ON, + .enable_mask = BD73800_MASK_RUN_EN, + .vsel_reg = BD73800_REG_BUCK4_VOLT_RUN, + .vsel_mask = BD73800_MASK_VOLT, + .ramp_delay_table = bd71828_ramp_delay, + .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay), + .ramp_reg = BD73800_REG_BUCK4_MODE, + .ramp_mask = BD73800_MASK_RAMP_DELAY, + .owner = THIS_MODULE, + .of_parse_cb = buck_set_hw_dvs_levels, + }, + .dvs = { + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | + ROHM_DVS_LEVEL_SUSPEND, + .run_reg = BD73800_REG_BUCK4_VOLT_RUN, + .run_mask = BD73800_MASK_VOLT, + .idle_reg = BD73800_REG_BUCK4_VOLT_IDLE, + .idle_mask = BD73800_MASK_VOLT, + .idle_on_mask = BD73800_MASK_IDLE_EN, + .suspend_reg = BD73800_REG_BUCK4_VOLT_SUSP, + .suspend_mask = BD73800_MASK_VOLT, + .suspend_on_mask = BD73800_MASK_SUSP_EN, + }, + }, { + .desc = { + .name = "buck5", + .of_match = of_match_ptr("buck5"), + .regulators_node = of_match_ptr("regulators"), + .id = BD73800_BUCK5, + .ops = &bd73800_buck5_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd73800_buck5_volts, + .n_linear_ranges = ARRAY_SIZE(bd73800_buck5_volts), + .linear_range_selectors_bitfield = + bd73800_buck5_volt_range_sel, + .n_voltages = BD73800_NUM_BUCK5_VOLTS, + .enable_reg = BD73800_REG_BUCK5_ON, + .enable_mask = BD73800_MASK_RUN_EN, + .vsel_reg = BD73800_REG_BUCK5_VOLT_RUN, + .vsel_mask = BD73800_MASK_BUCK5_VOLT, + .vsel_range_reg = BD73800_REG_BUCK5_MODE, + .vsel_range_mask = BD73800_BUCK5_RANGE_MASK, + .range_applied_by_vsel = true, + .ramp_delay_table = bd71828_ramp_delay, + .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay), + .ramp_reg = BD73800_REG_BUCK5_MODE, + .ramp_mask = BD73800_MASK_RAMP_DELAY, + .owner = THIS_MODULE, + }, + .dvs = { + /* + * We don't support setting the IDLE / SUSPEND voltages + * for the BUCK 5 for now. Reason is that the pickable + * range selector bit is common for all states (RUN, + * SUSPEND and IDLE), and toggling it for one impacts + * also others. + * Furthermore, writing the BD73800 range selector does + * not impact the RUN voltage until a new voltage value + * is also written to the vsel register. Hence the + * voltage change can be done without any 'intermediate + * voltages', even when the range is changed when the + * BUCK is enabled. + * It, however, is not documented how the IDLE / SUSPEND + * states work in this regard. I expect the full + * combination of the range selector and vsel is taken + * into account at the state change, no matter when they + * have been written to. + */ + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | + ROHM_DVS_LEVEL_SUSPEND, + .run_reg = BD73800_REG_BUCK5_VOLT_RUN, + .run_mask = BD73800_MASK_VOLT, + .idle_on_mask = BD73800_MASK_IDLE_EN, + .suspend_on_mask = BD73800_MASK_SUSP_EN, + }, + + }, { + .desc = { + .name = "buck6", + .of_match = of_match_ptr("buck6"), + .regulators_node = of_match_ptr("regulators"), + .id = BD73800_BUCK6, + .ops = &bd73800_buck_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd73800_buck67_volts, + .n_linear_ranges = ARRAY_SIZE(bd73800_buck67_volts), + .n_voltages = BD73800_NUM_VOLTS, + .enable_reg = BD73800_REG_BUCK6_ON, + .enable_mask = BD73800_MASK_RUN_EN, + .vsel_reg = BD73800_REG_BUCK6_VOLT_RUN, + .vsel_mask = BD73800_MASK_VOLT, + .ramp_delay_table = bd71828_ramp_delay, + .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay), + .ramp_reg = BD73800_REG_BUCK6_MODE, + .ramp_mask = BD73800_MASK_RAMP_DELAY, + .owner = THIS_MODULE, + .of_parse_cb = buck_set_hw_dvs_levels, + }, + .dvs = { + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | + ROHM_DVS_LEVEL_SUSPEND, + .run_reg = BD73800_REG_BUCK6_VOLT_RUN, + .run_mask = BD73800_MASK_VOLT, + .idle_reg = BD73800_REG_BUCK6_VOLT_IDLE, + .idle_mask = BD73800_MASK_VOLT, + .idle_on_mask = BD73800_MASK_IDLE_EN, + .suspend_reg = BD73800_REG_BUCK6_VOLT_SUSP, + .suspend_mask = BD73800_MASK_VOLT, + .suspend_on_mask = BD73800_MASK_SUSP_EN, + }, + }, { + .desc = { + .name = "buck7", + .of_match = of_match_ptr("buck7"), + .regulators_node = of_match_ptr("regulators"), + .id = BD73800_BUCK7, + .ops = &bd73800_buck_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd73800_buck67_volts, + .n_linear_ranges = ARRAY_SIZE(bd73800_buck67_volts), + .n_voltages = BD73800_NUM_VOLTS, + .enable_reg = BD73800_REG_BUCK7_ON, + .enable_mask = BD73800_MASK_RUN_EN, + .vsel_reg = BD73800_REG_BUCK7_VOLT_RUN, + .vsel_mask = BD73800_MASK_VOLT, + .ramp_delay_table = bd71828_ramp_delay, + .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay), + .ramp_reg = BD73800_REG_BUCK7_MODE, + .ramp_mask = BD73800_MASK_RAMP_DELAY, + .owner = THIS_MODULE, + .of_parse_cb = buck_set_hw_dvs_levels, + }, + .dvs = { + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | + ROHM_DVS_LEVEL_SUSPEND, + .run_reg = BD73800_REG_BUCK7_VOLT_RUN, + .run_mask = BD73800_MASK_VOLT, + .idle_reg = BD73800_REG_BUCK7_VOLT_IDLE, + .idle_mask = BD73800_MASK_VOLT, + .idle_on_mask = BD73800_MASK_IDLE_EN, + .suspend_reg = BD73800_REG_BUCK7_VOLT_SUSP, + .suspend_mask = BD73800_MASK_VOLT, + .suspend_on_mask = BD73800_MASK_SUSP_EN, + }, + }, { + .desc = { + .name = "buck8", + .of_match = of_match_ptr("buck8"), + .regulators_node = of_match_ptr("regulators"), + .id = BD73800_BUCK8, + .ops = &bd73800_buck_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd73800_buck12348_volts, + .n_linear_ranges = ARRAY_SIZE(bd73800_buck12348_volts), + .n_voltages = BD73800_NUM_VOLTS, + .enable_reg = BD73800_REG_BUCK8_ON, + .enable_mask = BD73800_MASK_RUN_EN, + .vsel_reg = BD73800_REG_BUCK8_VOLT_RUN, + .vsel_mask = BD73800_MASK_VOLT, + .ramp_delay_table = bd71828_ramp_delay, + .n_ramp_values = ARRAY_SIZE(bd71828_ramp_delay), + .ramp_reg = BD73800_REG_BUCK8_MODE, + .ramp_mask = BD73800_MASK_RAMP_DELAY, + .owner = THIS_MODULE, + .of_parse_cb = buck_set_hw_dvs_levels, + }, + .dvs = { + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | + ROHM_DVS_LEVEL_SUSPEND, + .run_reg = BD73800_REG_BUCK8_VOLT_RUN, + .run_mask = BD73800_MASK_VOLT, + .idle_reg = BD73800_REG_BUCK8_VOLT_IDLE, + .idle_mask = BD73800_MASK_VOLT, + .idle_on_mask = BD73800_MASK_IDLE_EN, + .suspend_reg = BD73800_REG_BUCK8_VOLT_SUSP, + .suspend_mask = BD73800_MASK_VOLT, + .suspend_on_mask = BD73800_MASK_SUSP_EN, + }, + }, { + .desc = { + .name = "ldo1", + .of_match = of_match_ptr(LDO1_NODE_NAME), + .regulators_node = of_match_ptr("regulators"), + .id = BD73800_LDO1, + .ops = &bd73800_ldo_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd73800_ldo13_low_volts, + .n_linear_ranges = ARRAY_SIZE(bd73800_ldo13_low_volts), + .n_voltages = BD73800_NUM_VOLTS, + .enable_reg = BD73800_REG_LDO1_ON, + .enable_mask = BD73800_MASK_RUN_EN, + .vsel_reg = BD73800_REG_LDO1_VOLT, + .vsel_mask = BD73800_MASK_VOLT, + .owner = THIS_MODULE, + .of_parse_cb = buck_set_hw_dvs_levels, + }, + .dvs = { + /* + * LDOs support only single voltage for all states. + * Voltage can be individually enabled for each state + * though. Allow setting enable/disable config by + * setting the <state>_on_mask for all supported states. + */ + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | + ROHM_DVS_LEVEL_SUSPEND, + .run_reg = BD73800_REG_LDO1_VOLT, + .run_mask = BD73800_MASK_VOLT, + .idle_on_mask = BD73800_MASK_IDLE_EN, + .suspend_on_mask = BD73800_MASK_SUSP_EN, + }, + }, { + .desc = { + .name = "ldo2", + .of_match = of_match_ptr("ldo2"), + .regulators_node = of_match_ptr("regulators"), + .id = BD73800_LDO2, + .ops = &bd73800_ldo_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd73800_ldo24_volts, + .n_linear_ranges = ARRAY_SIZE(bd73800_ldo24_volts), + .n_voltages = BD73800_NUM_VOLTS, + .enable_reg = BD73800_REG_LDO2_ON, + .enable_mask = BD73800_MASK_RUN_EN, + .vsel_reg = BD73800_REG_LDO2_VOLT, + .vsel_mask = BD73800_MASK_VOLT, + .owner = THIS_MODULE, + .of_parse_cb = buck_set_hw_dvs_levels, + }, + .dvs = { + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | + ROHM_DVS_LEVEL_SUSPEND, + .run_reg = BD73800_REG_LDO2_VOLT, + .run_mask = BD73800_MASK_VOLT, + .idle_on_mask = BD73800_MASK_IDLE_EN, + .suspend_on_mask = BD73800_MASK_SUSP_EN, + }, + }, { + .desc = { + .name = "ldo3", + .of_match = of_match_ptr(LDO3_NODE_NAME), + .regulators_node = of_match_ptr("regulators"), + .id = BD73800_LDO3, + .ops = &bd73800_ldo_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd73800_ldo13_low_volts, + .n_linear_ranges = ARRAY_SIZE(bd73800_ldo13_low_volts), + .n_voltages = BD73800_NUM_VOLTS, + .enable_reg = BD73800_REG_LDO3_ON, + .enable_mask = BD73800_MASK_RUN_EN, + .vsel_reg = BD73800_REG_LDO3_VOLT, + .vsel_mask = BD73800_MASK_VOLT, + .owner = THIS_MODULE, + .of_parse_cb = buck_set_hw_dvs_levels, + }, + .dvs = { + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | + ROHM_DVS_LEVEL_SUSPEND, + .run_reg = BD73800_REG_LDO3_VOLT, + .run_mask = BD73800_MASK_VOLT, + .idle_on_mask = BD73800_MASK_IDLE_EN, + .suspend_on_mask = BD73800_MASK_SUSP_EN, + }, + }, { + .desc = { + .name = "ldo4", + .of_match = of_match_ptr("ldo4"), + .regulators_node = of_match_ptr("regulators"), + .id = BD73800_LDO4, + .ops = &bd73800_ldo_ops, + .type = REGULATOR_VOLTAGE, + .linear_ranges = bd73800_ldo24_volts, + .n_linear_ranges = ARRAY_SIZE(bd73800_ldo24_volts), + .n_voltages = BD73800_NUM_VOLTS, + .enable_reg = BD73800_REG_LDO4_ON, + .enable_mask = BD73800_MASK_RUN_EN, + .vsel_reg = BD73800_REG_LDO4_VOLT, + .vsel_mask = BD73800_MASK_VOLT, + .owner = THIS_MODULE, + .of_parse_cb = buck_set_hw_dvs_levels, + }, + .dvs = { + .level_map = ROHM_DVS_LEVEL_RUN | ROHM_DVS_LEVEL_IDLE | + ROHM_DVS_LEVEL_SUSPEND, + .run_reg = BD73800_REG_LDO4_VOLT, + .run_mask = BD73800_MASK_VOLT, + .idle_on_mask = BD73800_MASK_IDLE_EN, + .suspend_on_mask = BD73800_MASK_SUSP_EN, + }, + }, +}; + static int bd72720_buck10_ldon_head_mode(struct device *dev, struct device_node *npreg, struct regmap *regmap, @@ -1619,6 +2111,52 @@ static int bd72720_dt_parse(struct device *dev, return bd72720_buck10_ldon_head_mode(dev, nproot, regmap, buck10_desc); } +static bool bd73800_use_ldo_high_range(struct device_node *nproot, + const char *ldo_node) +{ + struct device_node *np __free(device_node) = + of_get_child_by_name(nproot, ldo_node); + + if (!np) + return false; + + return of_property_read_bool(np, "rohm,ldo-range-high"); +} + +static int bd73800_check_ldo_otp_options(struct device *dev, + struct bd71828_regulator_data *d, + unsigned int num_reg_data) +{ + struct device_node *nproot __free(device_node) = + of_get_child_by_name(dev->parent->of_node, "regulators"); + + /* + * The code assumes regulator IDs to start from 0 and to match the + * indexing of regulator data arrays. WARN if someone changes this. + */ + WARN_ON(d[BD73800_LDO1].desc.id != BD73800_LDO1); + WARN_ON(d[BD73800_LDO3].desc.id != BD73800_LDO3); + + if (!nproot) { + dev_err(dev, "failed to find regulators node\n"); + return -ENODEV; + } + + if (bd73800_use_ldo_high_range(nproot, LDO1_NODE_NAME)) { + d[BD73800_LDO1].desc.linear_ranges = bd73800_ldo13_high_volts; + d[BD73800_LDO1].desc.n_linear_ranges = + ARRAY_SIZE(bd73800_ldo13_high_volts); + } + + if (bd73800_use_ldo_high_range(nproot, LDO3_NODE_NAME)) { + d[BD73800_LDO3].desc.linear_ranges = bd73800_ldo13_high_volts; + d[BD73800_LDO3].desc.n_linear_ranges = + ARRAY_SIZE(bd73800_ldo13_high_volts); + } + + return 0; +} + static int bd71828_probe(struct platform_device *pdev) { int i, j, ret, num_regulators; @@ -1656,6 +2194,23 @@ static int bd71828_probe(struct platform_device *pdev) num_regulators = ARRAY_SIZE(bd71828_rdata); break; + + case ROHM_CHIP_TYPE_BD73800: + { + rdata = devm_kmemdup(&pdev->dev, bd73800_rdata, + sizeof(bd73800_rdata), GFP_KERNEL); + if (!rdata) + return -ENOMEM; + + num_regulators = ARRAY_SIZE(bd73800_rdata); + + ret = bd73800_check_ldo_otp_options(&pdev->dev, rdata, + num_regulators); + if (ret) + return ret; + + break; + } default: return dev_err_probe(&pdev->dev, -EINVAL, "Unsupported device\n"); @@ -1692,6 +2247,7 @@ static int bd71828_probe(struct platform_device *pdev) static const struct platform_device_id bd71828_pmic_id[] = { { .name = "bd71828-pmic", .driver_data = ROHM_CHIP_TYPE_BD71828 }, { .name = "bd72720-pmic", .driver_data = ROHM_CHIP_TYPE_BD72720 }, + { .name = "bd73800-pmic", .driver_data = ROHM_CHIP_TYPE_BD73800 }, { } }; MODULE_DEVICE_TABLE(platform, bd71828_pmic_id);
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 6a4008f..14422cf 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c
@@ -462,6 +462,7 @@ int regulator_check_voltage(struct regulator_dev *rdev, return 0; } +EXPORT_SYMBOL_GPL(regulator_check_voltage); /* return 0 if the state is valid */ static int regulator_check_states(suspend_state_t state) @@ -502,6 +503,7 @@ int regulator_check_consumers(struct regulator_dev *rdev, return 0; } +EXPORT_SYMBOL_GPL(regulator_check_consumers); /* current constraint check */ static int regulator_check_current_limit(struct regulator_dev *rdev, @@ -2239,6 +2241,7 @@ static int regulator_resolve_supply(struct regulator_dev *rdev) if (r == rdev) { dev_err(dev, "Supply for %s (%s) resolved to itself\n", rdev->desc->name, rdev->supply_name); + put_device(&rdev->dev); if (!have_full_constraints()) { ret = -EINVAL; goto out; @@ -3029,7 +3032,7 @@ static int _regulator_do_enable(struct regulator_dev *rdev) */ trace_regulator_enable_delay(rdev_get_name(rdev)); - /* If poll_enabled_time is set, poll upto the delay calculated + /* If poll_enabled_time is set, poll up to the delay calculated * above, delaying poll_enabled_time uS to check if the regulator * actually got enabled. * If the regulator isn't enabled after our delay helper has expired, @@ -4468,6 +4471,7 @@ int regulator_do_balance_voltage(struct regulator_dev *rdev, out: return ret; } +EXPORT_SYMBOL_GPL(regulator_do_balance_voltage); static int regulator_balance_voltage(struct regulator_dev *rdev, suspend_state_t state) @@ -5797,6 +5801,7 @@ int regulator_coupler_register(struct regulator_coupler *coupler) return 0; } +EXPORT_SYMBOL_GPL(regulator_coupler_register); static struct regulator_coupler * regulator_find_coupler(struct regulator_dev *rdev) @@ -5861,6 +5866,7 @@ static void regulator_resolve_coupling(struct regulator_dev *rdev) if (c_rdev->coupling_desc.coupler != coupler) { rdev_err(rdev, "coupler mismatch with %s\n", rdev_get_name(c_rdev)); + put_device(&c_rdev->dev); return; } @@ -5907,6 +5913,8 @@ static void regulator_remove_coupling(struct regulator_dev *rdev) c_desc->coupled_rdevs[i] = NULL; c_desc->n_resolved--; + + put_device(&c_rdev->dev); } if (coupler && coupler->detach_regulator) {
diff --git a/drivers/regulator/fixed.c b/drivers/regulator/fixed.c index 417d282..faa82f3 100644 --- a/drivers/regulator/fixed.c +++ b/drivers/regulator/fixed.c
@@ -28,6 +28,7 @@ #include <linux/regulator/of_regulator.h> #include <linux/regulator/machine.h> #include <linux/clk.h> +#include <linux/string.h> struct fixed_voltage_data { struct regulator_desc desc; @@ -225,6 +226,9 @@ static int reg_fixed_voltage_probe(struct platform_device *pdev) enum gpiod_flags gflags; int ret; + if (!pdev->dev.of_node && strcmp(pdev->name, "reg-fixed-voltage")) + return -ENODEV; + drvdata = devm_kzalloc(&pdev->dev, sizeof(struct fixed_voltage_data), GFP_KERNEL); if (!drvdata)
diff --git a/drivers/regulator/lp872x.c b/drivers/regulator/lp872x.c index 5b2fadd..8b95c2c 100644 --- a/drivers/regulator/lp872x.c +++ b/drivers/regulator/lp872x.c
@@ -12,10 +12,10 @@ #include <linux/err.h> #include <linux/gpio/consumer.h> #include <linux/delay.h> -#include <linux/regulator/lp872x.h> #include <linux/regulator/driver.h> #include <linux/platform_device.h> -#include <linux/of.h> +#include <linux/property.h> +#include <linux/regulator/machine.h> #include <linux/regulator/of_regulator.h> /* Registers : LP8720/8725 shared */ @@ -92,17 +92,58 @@ /* dump registers in regmap-debugfs */ #define MAX_REGISTERS 0x0F +#define LP8720_ENABLE_DELAY 200 +#define LP8725_ENABLE_DELAY 30000 + enum lp872x_id { LP8720, LP8725, }; +enum lp872x_regulator_id { + LP8720_ID_BASE, + LP8720_ID_LDO1 = LP8720_ID_BASE, + LP8720_ID_LDO2, + LP8720_ID_LDO3, + LP8720_ID_LDO4, + LP8720_ID_LDO5, + LP8720_ID_BUCK, + + LP8725_ID_BASE, + LP8725_ID_LDO1 = LP8725_ID_BASE, + LP8725_ID_LDO2, + LP8725_ID_LDO3, + LP8725_ID_LDO4, + LP8725_ID_LDO5, + LP8725_ID_LILO1, + LP8725_ID_LILO2, + LP8725_ID_BUCK1, + LP8725_ID_BUCK2, + + LP872X_ID_MAX, +}; + +enum lp872x_dvs_sel { + SEL_V1, + SEL_V2, +}; + +struct lp872x_chip_info { + const struct regulator_desc *rdesc; + int num_regulators; + enum lp872x_id chipid; +}; + struct lp872x { struct regmap *regmap; struct device *dev; - enum lp872x_id chipid; - struct lp872x_platform_data *pdata; - int num_regulators; + + struct gpio_desc *enable_gpio; + struct gpio_desc *dvs_gpio; + + const struct lp872x_chip_info *info; + + enum lp872x_dvs_sel vsel; enum gpiod_flags dvs_pin; }; @@ -152,36 +193,10 @@ static const unsigned int lp8725_buck_uA[] = { 460000, 780000, 1050000, 1370000, }; -static int lp872x_read_byte(struct lp872x *lp, u8 addr, u8 *data) -{ - int ret; - unsigned int val; - - ret = regmap_read(lp->regmap, addr, &val); - if (ret < 0) { - dev_err(lp->dev, "failed to read 0x%.2x\n", addr); - return ret; - } - - *data = (u8)val; - return 0; -} - -static inline int lp872x_write_byte(struct lp872x *lp, u8 addr, u8 data) -{ - return regmap_write(lp->regmap, addr, data); -} - -static inline int lp872x_update_bits(struct lp872x *lp, u8 addr, - unsigned int mask, u8 data) -{ - return regmap_update_bits(lp->regmap, addr, mask, data); -} - static int lp872x_get_timestep_usec(struct lp872x *lp) { - enum lp872x_id chip = lp->chipid; - u8 val, mask, shift; + enum lp872x_id chip = lp->info->chipid; + u32 val, mask, shift; int *time_usec, size, ret; int lp8720_time_usec[] = { 25, 50 }; int lp8725_time_usec[] = { 32, 64, 128, 256 }; @@ -203,7 +218,7 @@ static int lp872x_get_timestep_usec(struct lp872x *lp) return -EINVAL; } - ret = lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val); + ret = regmap_read(lp->regmap, LP872X_GENERAL_CFG, &val); if (ret) return ret; @@ -220,7 +235,7 @@ static int lp872x_regulator_enable_time(struct regulator_dev *rdev) enum lp872x_regulator_id rid = rdev_get_id(rdev); int time_step_us = lp872x_get_timestep_usec(lp); int ret; - u8 addr, val; + u32 addr, val; if (time_step_us < 0) return time_step_us; @@ -239,7 +254,7 @@ static int lp872x_regulator_enable_time(struct regulator_dev *rdev) return -EINVAL; } - ret = lp872x_read_byte(lp, addr, &val); + ret = regmap_read(lp->regmap, addr, &val); if (ret) return ret; @@ -261,9 +276,9 @@ static void lp872x_set_dvs(struct lp872x *lp, enum lp872x_dvs_sel dvs_sel, static u8 lp872x_select_buck_vout_addr(struct lp872x *lp, enum lp872x_regulator_id buck) { - u8 val, addr; + u32 val, addr; - if (lp872x_read_byte(lp, LP872X_GENERAL_CFG, &val)) + if (regmap_read(lp->regmap, LP872X_GENERAL_CFG, &val)) return 0; switch (buck) { @@ -272,7 +287,7 @@ static u8 lp872x_select_buck_vout_addr(struct lp872x *lp, addr = (lp->dvs_pin == GPIOD_OUT_HIGH) ? LP8720_BUCK_VOUT1 : LP8720_BUCK_VOUT2; } else { - if (lp872x_read_byte(lp, LP8720_ENABLE, &val)) + if (regmap_read(lp->regmap, LP8720_ENABLE, &val)) return 0; addr = val & LP8720_DVS_SEL_M ? @@ -317,31 +332,30 @@ static int lp872x_buck_set_voltage_sel(struct regulator_dev *rdev, { struct lp872x *lp = rdev_get_drvdata(rdev); enum lp872x_regulator_id buck = rdev_get_id(rdev); - u8 addr, mask = LP872X_VOUT_M; - struct lp872x_dvs *dvs = lp->pdata ? lp->pdata->dvs : NULL; + u32 addr, mask = LP872X_VOUT_M; - if (dvs && dvs->gpio) - lp872x_set_dvs(lp, dvs->vsel, dvs->gpio); + if (lp->dvs_gpio) + lp872x_set_dvs(lp, lp->vsel, lp->dvs_gpio); addr = lp872x_select_buck_vout_addr(lp, buck); if (!lp872x_is_valid_buck_addr(addr)) return -EINVAL; - return lp872x_update_bits(lp, addr, mask, selector); + return regmap_update_bits(lp->regmap, addr, mask, selector); } static int lp872x_buck_get_voltage_sel(struct regulator_dev *rdev) { struct lp872x *lp = rdev_get_drvdata(rdev); enum lp872x_regulator_id buck = rdev_get_id(rdev); - u8 addr, val; + u32 addr, val; int ret; addr = lp872x_select_buck_vout_addr(lp, buck); if (!lp872x_is_valid_buck_addr(addr)) return -EINVAL; - ret = lp872x_read_byte(lp, addr, &val); + ret = regmap_read(lp->regmap, addr, &val); if (ret) return ret; @@ -352,7 +366,7 @@ static int lp872x_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) { struct lp872x *lp = rdev_get_drvdata(rdev); enum lp872x_regulator_id buck = rdev_get_id(rdev); - u8 addr, mask, shift, val; + u32 addr, mask, shift, val; switch (buck) { case LP8720_ID_BUCK: @@ -381,14 +395,14 @@ static int lp872x_buck_set_mode(struct regulator_dev *rdev, unsigned int mode) else return -EINVAL; - return lp872x_update_bits(lp, addr, mask, val); + return regmap_update_bits(lp->regmap, addr, mask, val); } static unsigned int lp872x_buck_get_mode(struct regulator_dev *rdev) { struct lp872x *lp = rdev_get_drvdata(rdev); enum lp872x_regulator_id buck = rdev_get_id(rdev); - u8 addr, mask, val; + u32 addr, mask, val; int ret; switch (buck) { @@ -408,7 +422,7 @@ static unsigned int lp872x_buck_get_mode(struct regulator_dev *rdev) return -EINVAL; } - ret = lp872x_read_byte(lp, addr, &val); + ret = regmap_read(lp->regmap, addr, &val); if (ret) return ret; @@ -454,79 +468,62 @@ static const struct regulator_ops lp8725_buck_ops = { .get_current_limit = regulator_get_current_limit_regmap, }; +#define LP872X_LDO(_id, match, supply, _volt_table, _vsel_reg, \ + _enable_reg, _enable_mask) { \ + .name = (match), \ + .supply_name = (supply), \ + .of_match = (match), \ + .id = _id, \ + .ops = &lp872x_ldo_ops, \ + .n_voltages = ARRAY_SIZE(_volt_table), \ + .volt_table = _volt_table, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .vsel_reg = _vsel_reg, \ + .vsel_mask = LP872X_VOUT_M, \ + .enable_reg = _enable_reg, \ + .enable_mask = _enable_mask, \ +} + +#define LP8720_LDO(ids, match, supply, _volt_table) \ + LP872X_LDO(LP8720_ID_##ids, match, supply, _volt_table, \ + LP872X_##ids##_VOUT, LP8720_ENABLE, LP872X_EN_##ids##_M) + +#define LP8725_LDO(ids, match, supply) \ + LP872X_LDO(LP8725_ID_##ids, match, supply, lp872x_ldo_vtbl, \ + LP872X_##ids##_VOUT, LP8725_LDO_CTRL, LP872X_EN_##ids##_M) + +#define LP8725_LILO(ids, match, supply) \ + LP872X_LDO(LP8725_ID_##ids, match, supply, lp8725_lilo_vtbl, \ + LP8725_##ids##_VOUT, LP8725_LDO_CTRL, LP8725_EN_##ids##_M) + +#define LP8725_BUCK(ids, match) { \ + .name = (match), \ + .supply_name = "vinb", \ + .of_match = (match), \ + .id = LP8725_ID_##ids, \ + .ops = &lp8725_buck_ops, \ + .n_voltages = ARRAY_SIZE(lp8725_buck_vtbl), \ + .volt_table = lp8725_buck_vtbl, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + .enable_reg = LP872X_GENERAL_CFG, \ + .enable_mask = LP8725_##ids##_EN_M, \ + .curr_table = lp8725_buck_uA, \ + .n_current_limits = ARRAY_SIZE(lp8725_buck_uA), \ + .csel_reg = LP8725_##ids##_VOUT2, \ + .csel_mask = LP8725_BUCK_CL_M, \ +} + static const struct regulator_desc lp8720_regulator_desc[] = { - { - .name = "ldo1", - .of_match = of_match_ptr("ldo1"), - .id = LP8720_ID_LDO1, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO1_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8720_ENABLE, - .enable_mask = LP872X_EN_LDO1_M, - }, - { - .name = "ldo2", - .of_match = of_match_ptr("ldo2"), - .id = LP8720_ID_LDO2, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO2_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8720_ENABLE, - .enable_mask = LP872X_EN_LDO2_M, - }, - { - .name = "ldo3", - .of_match = of_match_ptr("ldo3"), - .id = LP8720_ID_LDO3, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO3_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8720_ENABLE, - .enable_mask = LP872X_EN_LDO3_M, - }, - { - .name = "ldo4", - .of_match = of_match_ptr("ldo4"), - .id = LP8720_ID_LDO4, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp8720_ldo4_vtbl), - .volt_table = lp8720_ldo4_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO4_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8720_ENABLE, - .enable_mask = LP872X_EN_LDO4_M, - }, - { - .name = "ldo5", - .of_match = of_match_ptr("ldo5"), - .id = LP8720_ID_LDO5, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO5_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8720_ENABLE, - .enable_mask = LP872X_EN_LDO5_M, - }, + LP8720_LDO(LDO1, "ldo1", "vbatt", lp872x_ldo_vtbl), + LP8720_LDO(LDO2, "ldo2", "vin1", lp872x_ldo_vtbl), + LP8720_LDO(LDO3, "ldo3", "vin1", lp872x_ldo_vtbl), + LP8720_LDO(LDO4, "ldo4", "vin2", lp8720_ldo4_vtbl), + LP8720_LDO(LDO5, "ldo5", "vin2", lp872x_ldo_vtbl), { .name = "buck", + .supply_name = "vinb", .of_match = of_match_ptr("buck"), .id = LP8720_ID_BUCK, .ops = &lp8720_buck_ops, @@ -540,244 +537,60 @@ static const struct regulator_desc lp8720_regulator_desc[] = { }; static const struct regulator_desc lp8725_regulator_desc[] = { - { - .name = "ldo1", - .of_match = of_match_ptr("ldo1"), - .id = LP8725_ID_LDO1, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO1_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8725_LDO_CTRL, - .enable_mask = LP872X_EN_LDO1_M, - }, - { - .name = "ldo2", - .of_match = of_match_ptr("ldo2"), - .id = LP8725_ID_LDO2, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO2_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8725_LDO_CTRL, - .enable_mask = LP872X_EN_LDO2_M, - }, - { - .name = "ldo3", - .of_match = of_match_ptr("ldo3"), - .id = LP8725_ID_LDO3, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO3_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8725_LDO_CTRL, - .enable_mask = LP872X_EN_LDO3_M, - }, - { - .name = "ldo4", - .of_match = of_match_ptr("ldo4"), - .id = LP8725_ID_LDO4, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO4_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8725_LDO_CTRL, - .enable_mask = LP872X_EN_LDO4_M, - }, - { - .name = "ldo5", - .of_match = of_match_ptr("ldo5"), - .id = LP8725_ID_LDO5, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp872x_ldo_vtbl), - .volt_table = lp872x_ldo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP872X_LDO5_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8725_LDO_CTRL, - .enable_mask = LP872X_EN_LDO5_M, - }, - { - .name = "lilo1", - .of_match = of_match_ptr("lilo1"), - .id = LP8725_ID_LILO1, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp8725_lilo_vtbl), - .volt_table = lp8725_lilo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8725_LILO1_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8725_LDO_CTRL, - .enable_mask = LP8725_EN_LILO1_M, - }, - { - .name = "lilo2", - .of_match = of_match_ptr("lilo2"), - .id = LP8725_ID_LILO2, - .ops = &lp872x_ldo_ops, - .n_voltages = ARRAY_SIZE(lp8725_lilo_vtbl), - .volt_table = lp8725_lilo_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .vsel_reg = LP8725_LILO2_VOUT, - .vsel_mask = LP872X_VOUT_M, - .enable_reg = LP8725_LDO_CTRL, - .enable_mask = LP8725_EN_LILO2_M, - }, - { - .name = "buck1", - .of_match = of_match_ptr("buck1"), - .id = LP8725_ID_BUCK1, - .ops = &lp8725_buck_ops, - .n_voltages = ARRAY_SIZE(lp8725_buck_vtbl), - .volt_table = lp8725_buck_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .enable_reg = LP872X_GENERAL_CFG, - .enable_mask = LP8725_BUCK1_EN_M, - .curr_table = lp8725_buck_uA, - .n_current_limits = ARRAY_SIZE(lp8725_buck_uA), - .csel_reg = LP8725_BUCK1_VOUT2, - .csel_mask = LP8725_BUCK_CL_M, - }, - { - .name = "buck2", - .of_match = of_match_ptr("buck2"), - .id = LP8725_ID_BUCK2, - .ops = &lp8725_buck_ops, - .n_voltages = ARRAY_SIZE(lp8725_buck_vtbl), - .volt_table = lp8725_buck_vtbl, - .type = REGULATOR_VOLTAGE, - .owner = THIS_MODULE, - .enable_reg = LP872X_GENERAL_CFG, - .enable_mask = LP8725_BUCK2_EN_M, - .curr_table = lp8725_buck_uA, - .n_current_limits = ARRAY_SIZE(lp8725_buck_uA), - .csel_reg = LP8725_BUCK2_VOUT2, - .csel_mask = LP8725_BUCK_CL_M, - }, + LP8725_LDO(LDO1, "ldo1", "vin1"), + LP8725_LDO(LDO2, "ldo2", "vin2"), + LP8725_LDO(LDO3, "ldo3", "vin2"), + LP8725_LDO(LDO4, "ldo4", "vin3"), + LP8725_LDO(LDO5, "ldo5", "vin3"), + LP8725_LILO(LILO1, "lilo1", "vinlilo1"), + LP8725_LILO(LILO2, "lilo2", "vinlilo2"), + LP8725_BUCK(BUCK1, "buck1"), + LP8725_BUCK(BUCK2, "buck2"), }; static int lp872x_init_dvs(struct lp872x *lp) { - struct lp872x_dvs *dvs = lp->pdata ? lp->pdata->dvs : NULL; - enum gpiod_flags pinstate; - u8 mask[] = { LP8720_EXT_DVS_M, LP8725_DVS1_M | LP8725_DVS2_M }; - u8 default_dvs_mode[] = { LP8720_DEFAULT_DVS, LP8725_DEFAULT_DVS }; + struct device *dev = lp->dev; + u32 mask[] = { LP8720_EXT_DVS_M, LP8725_DVS1_M | LP8725_DVS2_M }; + u32 default_dvs_mode[] = { LP8720_DEFAULT_DVS, LP8725_DEFAULT_DVS }; + u8 state = 1; + u8 vsel = SEL_V1; - if (!dvs) - goto set_default_dvs_mode; + device_property_read_u8(dev, "ti,dvs-vsel", &vsel); + lp->vsel = vsel; - if (!dvs->gpio) - goto set_default_dvs_mode; + device_property_read_u8(dev, "ti,dvs-state", &state); + lp->dvs_pin = state ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; - pinstate = dvs->init_state; - dvs->gpio = devm_gpiod_get_optional(lp->dev, "ti,dvs", pinstate); + lp->dvs_gpio = devm_gpiod_get_optional(dev, "dvs", lp->dvs_pin); + if (IS_ERR(lp->dvs_gpio)) + return dev_err_probe(dev, PTR_ERR(lp->dvs_gpio), + "Failed to request DVS GPIO\n"); - if (IS_ERR(dvs->gpio)) { - dev_err(lp->dev, "gpio request err: %ld\n", PTR_ERR(dvs->gpio)); - return PTR_ERR(dvs->gpio); - } - - lp->dvs_pin = pinstate; + if (!lp->dvs_gpio) + return regmap_update_bits(lp->regmap, LP872X_GENERAL_CFG, + mask[lp->info->chipid], + default_dvs_mode[lp->info->chipid]); return 0; - -set_default_dvs_mode: - return lp872x_update_bits(lp, LP872X_GENERAL_CFG, mask[lp->chipid], - default_dvs_mode[lp->chipid]); -} - -static int lp872x_hw_enable(struct lp872x *lp) -{ - if (!lp->pdata) - return -EINVAL; - - if (!lp->pdata->enable_gpio) - return 0; - - /* Always set enable GPIO high. */ - lp->pdata->enable_gpio = devm_gpiod_get_optional(lp->dev, "enable", GPIOD_OUT_HIGH); - if (IS_ERR(lp->pdata->enable_gpio)) { - dev_err(lp->dev, "gpio request err: %ld\n", PTR_ERR(lp->pdata->enable_gpio)); - return PTR_ERR(lp->pdata->enable_gpio); - } - - /* Each chip has a different enable delay. */ - if (lp->chipid == LP8720) - usleep_range(LP8720_ENABLE_DELAY, 1.5 * LP8720_ENABLE_DELAY); - else - usleep_range(LP8725_ENABLE_DELAY, 1.5 * LP8725_ENABLE_DELAY); - - return 0; -} - -static int lp872x_config(struct lp872x *lp) -{ - struct lp872x_platform_data *pdata = lp->pdata; - int ret; - - if (!pdata || !pdata->update_config) - goto init_dvs; - - ret = lp872x_write_byte(lp, LP872X_GENERAL_CFG, pdata->general_config); - if (ret) - return ret; - -init_dvs: - return lp872x_init_dvs(lp); -} - -static struct regulator_init_data -*lp872x_find_regulator_init_data(int id, struct lp872x *lp) -{ - struct lp872x_platform_data *pdata = lp->pdata; - int i; - - if (!pdata) - return NULL; - - for (i = 0; i < lp->num_regulators; i++) { - if (pdata->regulator_data[i].id == id) - return pdata->regulator_data[i].init_data; - } - - return NULL; } static int lp872x_regulator_register(struct lp872x *lp) { - const struct regulator_desc *desc; + const struct regulator_desc *desc = lp->info->rdesc; + int num_regulators = lp->info->num_regulators; struct regulator_config cfg = { }; + struct device *dev = lp->dev; struct regulator_dev *rdev; - int i; - for (i = 0; i < lp->num_regulators; i++) { - desc = (lp->chipid == LP8720) ? &lp8720_regulator_desc[i] : - &lp8725_regulator_desc[i]; + cfg.dev = dev; + cfg.driver_data = lp; + cfg.regmap = lp->regmap; - cfg.dev = lp->dev; - cfg.init_data = lp872x_find_regulator_init_data(desc->id, lp); - cfg.driver_data = lp; - cfg.regmap = lp->regmap; - - rdev = devm_regulator_register(lp->dev, desc, &cfg); + for (int i = 0; i < num_regulators; i++) { + rdev = devm_regulator_register(dev, &desc[i], &cfg); if (IS_ERR(rdev)) { - dev_err(lp->dev, "regulator register err"); + dev_err(dev, "regulator register err"); return PTR_ERR(rdev); } } @@ -791,152 +604,89 @@ static const struct regmap_config lp872x_regmap_config = { .max_register = MAX_REGISTERS, }; -#ifdef CONFIG_OF - -#define LP872X_VALID_OPMODE (REGULATOR_MODE_FAST | REGULATOR_MODE_NORMAL) - -static struct of_regulator_match lp8720_matches[] = { - { .name = "ldo1", .driver_data = (void *)LP8720_ID_LDO1, }, - { .name = "ldo2", .driver_data = (void *)LP8720_ID_LDO2, }, - { .name = "ldo3", .driver_data = (void *)LP8720_ID_LDO3, }, - { .name = "ldo4", .driver_data = (void *)LP8720_ID_LDO4, }, - { .name = "ldo5", .driver_data = (void *)LP8720_ID_LDO5, }, - { .name = "buck", .driver_data = (void *)LP8720_ID_BUCK, }, -}; - -static struct of_regulator_match lp8725_matches[] = { - { .name = "ldo1", .driver_data = (void *)LP8725_ID_LDO1, }, - { .name = "ldo2", .driver_data = (void *)LP8725_ID_LDO2, }, - { .name = "ldo3", .driver_data = (void *)LP8725_ID_LDO3, }, - { .name = "ldo4", .driver_data = (void *)LP8725_ID_LDO4, }, - { .name = "ldo5", .driver_data = (void *)LP8725_ID_LDO5, }, - { .name = "lilo1", .driver_data = (void *)LP8725_ID_LILO1, }, - { .name = "lilo2", .driver_data = (void *)LP8725_ID_LILO2, }, - { .name = "buck1", .driver_data = (void *)LP8725_ID_BUCK1, }, - { .name = "buck2", .driver_data = (void *)LP8725_ID_BUCK2, }, -}; - -static struct lp872x_platform_data -*lp872x_populate_pdata_from_dt(struct device *dev, enum lp872x_id which) -{ - struct device_node *np = dev->of_node; - struct lp872x_platform_data *pdata; - struct of_regulator_match *match; - int num_matches; - int count; - int i; - u8 dvs_state; - - pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); - if (!pdata) - return ERR_PTR(-ENOMEM); - - of_property_read_u8(np, "ti,general-config", &pdata->general_config); - pdata->update_config = of_property_read_bool(np, "ti,update-config"); - - pdata->dvs = devm_kzalloc(dev, sizeof(struct lp872x_dvs), GFP_KERNEL); - if (!pdata->dvs) - return ERR_PTR(-ENOMEM); - - of_property_read_u8(np, "ti,dvs-vsel", (u8 *)&pdata->dvs->vsel); - of_property_read_u8(np, "ti,dvs-state", &dvs_state); - pdata->dvs->init_state = dvs_state ? GPIOD_OUT_HIGH : GPIOD_OUT_LOW; - - if (of_get_child_count(np) == 0) - goto out; - - switch (which) { - case LP8720: - match = lp8720_matches; - num_matches = ARRAY_SIZE(lp8720_matches); - break; - case LP8725: - match = lp8725_matches; - num_matches = ARRAY_SIZE(lp8725_matches); - break; - default: - goto out; - } - - count = of_regulator_match(dev, np, match, num_matches); - if (count <= 0) - goto out; - - for (i = 0; i < num_matches; i++) { - pdata->regulator_data[i].id = - (uintptr_t)match[i].driver_data; - pdata->regulator_data[i].init_data = match[i].init_data; - } -out: - return pdata; -} -#else -static struct lp872x_platform_data -*lp872x_populate_pdata_from_dt(struct device *dev, enum lp872x_id which) -{ - return NULL; -} -#endif - static int lp872x_probe(struct i2c_client *cl) { - const struct i2c_device_id *id = i2c_client_get_device_id(cl); + struct device *dev = &cl->dev; + const char *in_supply_name; struct lp872x *lp; - struct lp872x_platform_data *pdata; int ret; - static const int lp872x_num_regulators[] = { - [LP8720] = LP8720_NUM_REGULATORS, - [LP8725] = LP8725_NUM_REGULATORS, - }; - if (cl->dev.of_node) { - pdata = lp872x_populate_pdata_from_dt(&cl->dev, - (enum lp872x_id)id->driver_data); - if (IS_ERR(pdata)) - return PTR_ERR(pdata); - } else { - pdata = dev_get_platdata(&cl->dev); - } - - lp = devm_kzalloc(&cl->dev, sizeof(struct lp872x), GFP_KERNEL); + lp = devm_kzalloc(dev, sizeof(*lp), GFP_KERNEL); if (!lp) return -ENOMEM; - lp->num_regulators = lp872x_num_regulators[id->driver_data]; + lp->info = i2c_get_match_data(cl); + if (!lp->info) + return -ENODEV; lp->regmap = devm_regmap_init_i2c(cl, &lp872x_regmap_config); - if (IS_ERR(lp->regmap)) { - ret = PTR_ERR(lp->regmap); - dev_err(&cl->dev, "regmap init i2c err: %d\n", ret); - return ret; - } + if (IS_ERR(lp->regmap)) + return dev_err_probe(dev, PTR_ERR(lp->regmap), + "Failed to init regmap\n"); - lp->dev = &cl->dev; - lp->pdata = pdata; - lp->chipid = id->driver_data; + /* LDO0 parent supplies chip itself */ + in_supply_name = lp->info->rdesc[0].supply_name; + ret = devm_regulator_get_enable(dev, in_supply_name); + if (ret) + return dev_err_probe(dev, ret, "Failed to enable supply regulator\n"); + + lp->dev = dev; i2c_set_clientdata(cl, lp); - ret = lp872x_hw_enable(lp); - if (ret) - return ret; + /* Always set enable GPIO high. */ + lp->enable_gpio = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH); + if (IS_ERR(lp->enable_gpio)) + return dev_err_probe(dev, PTR_ERR(lp->enable_gpio), + "Failed to request gpio\n"); - ret = lp872x_config(lp); + /* Each chip has a different enable delay. */ + if (lp->info->chipid == LP8720) + usleep_range(LP8720_ENABLE_DELAY, 1.5 * LP8720_ENABLE_DELAY); + else + usleep_range(LP8725_ENABLE_DELAY, 1.5 * LP8725_ENABLE_DELAY); + + if (device_property_present(dev, "ti,general-config")) { + u8 general_config; + + ret = device_property_read_u8(dev, "ti,general-config", + &general_config); + if (ret) + return dev_err_probe(dev, ret, "Failed to read general config\n"); + + ret = regmap_write(lp->regmap, LP872X_GENERAL_CFG, general_config); + if (ret) + return ret; + } + + ret = lp872x_init_dvs(lp); if (ret) return ret; return lp872x_regulator_register(lp); } -static const struct of_device_id lp872x_dt_ids[] __maybe_unused = { - { .compatible = "ti,lp8720", }, - { .compatible = "ti,lp8725", }, +static const struct lp872x_chip_info lp8720_data = { + .rdesc = lp8720_regulator_desc, + .num_regulators = LP8720_NUM_REGULATORS, + .chipid = LP8720, +}; + +static const struct lp872x_chip_info lp8725_data = { + .rdesc = lp8725_regulator_desc, + .num_regulators = LP8725_NUM_REGULATORS, + .chipid = LP8725, +}; + +static const struct of_device_id lp872x_dt_ids[] = { + { .compatible = "ti,lp8720", .data = &lp8720_data }, + { .compatible = "ti,lp8725", .data = &lp8725_data }, { } }; MODULE_DEVICE_TABLE(of, lp872x_dt_ids); static const struct i2c_device_id lp872x_ids[] = { - { .name = "lp8720", .driver_data = LP8720 }, - { .name = "lp8725", .driver_data = LP8725 }, + { .name = "lp8720", .driver_data = (kernel_ulong_t)&lp8720_data }, + { .name = "lp8725", .driver_data = (kernel_ulong_t)&lp8725_data }, { } }; MODULE_DEVICE_TABLE(i2c, lp872x_ids); @@ -945,7 +695,7 @@ static struct i2c_driver lp872x_driver = { .driver = { .name = "lp872x", .probe_type = PROBE_PREFER_ASYNCHRONOUS, - .of_match_table = of_match_ptr(lp872x_dt_ids), + .of_match_table = lp872x_dt_ids, }, .probe = lp872x_probe, .id_table = lp872x_ids,
diff --git a/drivers/regulator/mp886x.c b/drivers/regulator/mp886x.c index e0b62bc..e483e9d7 100644 --- a/drivers/regulator/mp886x.c +++ b/drivers/regulator/mp886x.c
@@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 // -// MP8867/MP8869 regulator driver +// MP8864/MP8867/MP8869 regulator driver // // Copyright (C) 2020 Synaptics Incorporated // @@ -229,6 +229,23 @@ static const struct regulator_ops mp8867_regulator_ops = { .set_ramp_delay = regulator_set_ramp_delay_regmap, }; +static const struct mp886x_cfg_info mp8864_ci = { + .rops = &mp8867_regulator_ops, + .slew_rates = { + 64000, + 32000, + 16000, + 8000, + 4000, + 2000, + 1000, + 500, + }, + .switch_freq = { 600000, 850000, 1100000, 1600000 }, + .fs_reg = MP886X_SYSCNTLREG1, + .fs_shift = 1, +}; + static const struct mp886x_cfg_info mp8867_ci = { .rops = &mp8867_regulator_ops, .slew_rates = { @@ -256,6 +273,7 @@ static int mp886x_regulator_register(struct mp886x_device_info *di, { struct regulator_desc *rdesc = &di->desc; struct regulator_dev *rdev; + int sel; rdesc->name = "mp886x-reg"; rdesc->supply_name = "vin"; @@ -267,7 +285,7 @@ static int mp886x_regulator_register(struct mp886x_device_info *di, rdesc->min_uV = 600000; rdesc->uV_step = 10000; rdesc->vsel_reg = MP886X_VSEL; - rdesc->vsel_mask = 0x3f; + rdesc->vsel_mask = 0x7f; rdesc->ramp_reg = MP886X_SYSCNTLREG1; rdesc->ramp_mask = MP886X_SLEW_MASK; rdesc->ramp_delay_table = di->ci->slew_rates; @@ -277,7 +295,12 @@ static int mp886x_regulator_register(struct mp886x_device_info *di, rdev = devm_regulator_register(di->dev, &di->desc, config); if (IS_ERR(rdev)) return PTR_ERR(rdev); - di->sel = rdesc->ops->get_voltage_sel(rdev); + + sel = rdesc->ops->get_voltage_sel(rdev); + if (sel < 0) + return sel; + di->sel = sel; + return 0; } @@ -311,6 +334,9 @@ static int mp886x_i2c_probe(struct i2c_client *client) if (ret) return ret; + if (di->r[1] == 0) + return -EINVAL; + di->en_gpio = devm_gpiod_get(dev, "enable", GPIOD_OUT_HIGH); if (IS_ERR(di->en_gpio)) return PTR_ERR(di->en_gpio); @@ -341,6 +367,7 @@ static int mp886x_i2c_probe(struct i2c_client *client) } static const struct of_device_id mp886x_dt_ids[] = { + { .compatible = "mps,mp8864", .data = &mp8864_ci }, { .compatible = "mps,mp8867", .data = &mp8867_ci }, { .compatible = "mps,mp8869", .data = &mp8869_ci }, { } @@ -348,6 +375,7 @@ static const struct of_device_id mp886x_dt_ids[] = { MODULE_DEVICE_TABLE(of, mp886x_dt_ids); static const struct i2c_device_id mp886x_id[] = { + { .name = "mp8864", .driver_data = (kernel_ulong_t)&mp8864_ci }, { .name = "mp8867", .driver_data = (kernel_ulong_t)&mp8867_ci }, { .name = "mp8869", .driver_data = (kernel_ulong_t)&mp8869_ci }, { }
diff --git a/drivers/regulator/mpq4210.c b/drivers/regulator/mpq4210.c new file mode 100644 index 0000000..293e7b2 --- /dev/null +++ b/drivers/regulator/mpq4210.c
@@ -0,0 +1,243 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Monolithic Power Systems MPQ4210 buck-boost regulator + * + * Copyright (c) 2026 Vaisala Oyj + */ + +#include <linux/bitfield.h> +#include <linux/delay.h> +#include <linux/gpio/consumer.h> +#include <linux/i2c.h> +#include <linux/math.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/regmap.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/of_regulator.h> + +#define MPQ4210_REF_LSB 0x00 +#define MPQ4210_REF_LSB_MASK GENMASK(2, 0) +#define MPQ4210_REF_LSB_BITS 3 +#define MPQ4210_REF_MSB 0x01 +#define MPQ4210_CONTROL1 0x02 +#define MPQ4210_CONTROL1_SR GENMASK(7, 6) +#define MPQ4210_CONTROL1_RESERVED BIT(2) +#define MPQ4210_CONTROL1_GO BIT(1) +#define MPQ4210_CONTROL1_ENPWR BIT(0) +#define MPQ4210_INT_MASK 0x06 + +/* + * The feedback reference is an 11 bit value with a 1mV step. The datasheet + * specifies no reference below 0.3V, so those selectors are not offered. + */ +#define MPQ4210_REF_MIN 0x12c +#define MPQ4210_REF_MAX 0x7ff +#define MPQ4210_REF_STEP_UV 1000 + +#define MPQ4210_ENPWR_DELAY_MS 200 + +/* Feedback reference slew rate per MPQ4210_CONTROL1_SR value, in uV/us. */ +static const unsigned int mpq4210_ref_slew_rate[] = { 38, 50, 75, 150 }; + +static const struct regmap_config mpq4210_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = MPQ4210_INT_MASK, +}; + +/* Scale a feedback reference value by the output voltage divider ratio. */ +static unsigned int mpq4210_scale(unsigned int val, u32 r1, u32 r2) +{ + u64 tmp = (u64)val * (r1 + r2); + + do_div(tmp, r2); + + return tmp; +} + +static int mpq4210_set_voltage_sel(struct regulator_dev *rdev, unsigned int sel) +{ + int ret; + + ret = regmap_write(rdev->regmap, MPQ4210_REF_LSB, + sel & MPQ4210_REF_LSB_MASK); + if (ret) + return ret; + + ret = regmap_write(rdev->regmap, MPQ4210_REF_MSB, + sel >> MPQ4210_REF_LSB_BITS); + if (ret) + return ret; + + return regmap_set_bits(rdev->regmap, MPQ4210_CONTROL1, + MPQ4210_CONTROL1_GO); +} + +static int mpq4210_get_voltage_sel(struct regulator_dev *rdev) +{ + unsigned int lsb, msb; + int ret; + + ret = regmap_read(rdev->regmap, MPQ4210_REF_MSB, &msb); + if (ret) + return ret; + + ret = regmap_read(rdev->regmap, MPQ4210_REF_LSB, &lsb); + if (ret) + return ret; + + return (msb << MPQ4210_REF_LSB_BITS) | (lsb & MPQ4210_REF_LSB_MASK); +} + +static int mpq4210_enable(struct regulator_dev *rdev) +{ + int ret; + + ret = regmap_set_bits(rdev->regmap, MPQ4210_CONTROL1, + MPQ4210_CONTROL1_GO); + if (ret) + return ret; + + /* The reference has to settle before power switching may start. */ + msleep(MPQ4210_ENPWR_DELAY_MS); + + return regmap_set_bits(rdev->regmap, MPQ4210_CONTROL1, + MPQ4210_CONTROL1_ENPWR); +} + +static const struct regulator_ops mpq4210_regulator_ops = { + .set_voltage_sel = mpq4210_set_voltage_sel, + .get_voltage_sel = mpq4210_get_voltage_sel, + .list_voltage = regulator_list_voltage_linear, + .set_ramp_delay = regulator_set_ramp_delay_regmap, + .enable = mpq4210_enable, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, +}; + +static const struct regulator_desc mpq4210_regulator = { + .name = "mpq4210", + .type = REGULATOR_VOLTAGE, + .owner = THIS_MODULE, + .ops = &mpq4210_regulator_ops, + .n_voltages = MPQ4210_REF_MAX + 1, + .linear_min_sel = MPQ4210_REF_MIN, + .enable_reg = MPQ4210_CONTROL1, + .enable_mask = MPQ4210_CONTROL1_ENPWR, + .ramp_reg = MPQ4210_CONTROL1, + .ramp_mask = MPQ4210_CONTROL1_SR, + .n_ramp_values = ARRAY_SIZE(mpq4210_ref_slew_rate), +}; + +static int mpq4210_i2c_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct regulator_config config = { }; + struct regulator_desc *desc; + struct regulator_dev *rdev; + struct gpio_desc *enable; + struct regmap *regmap; + unsigned int *slew; + unsigned int i, val; + u32 r[2]; + int ret; + + ret = of_property_read_u32_array(dev->of_node, + "mps,fb-voltage-divider-ohms", + r, ARRAY_SIZE(r)); + if (ret) + return dev_err_probe(dev, ret, + "failed to read mps,fb-voltage-divider-ohms\n"); + + if (!r[1]) + return dev_err_probe(dev, -EINVAL, + "feedback divider R2 must not be zero\n"); + + /* The controller does not answer on the bus while EN is deasserted. */ + enable = devm_gpiod_get_optional(dev, "enable", GPIOD_OUT_HIGH); + if (IS_ERR(enable)) + return dev_err_probe(dev, PTR_ERR(enable), + "failed to get enable GPIO\n"); + + regmap = devm_regmap_init_i2c(client, &mpq4210_regmap_config); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "failed to init regmap\n"); + + desc = devm_kmemdup(dev, &mpq4210_regulator, sizeof(*desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + + desc->min_uV = mpq4210_scale(MPQ4210_REF_MIN * MPQ4210_REF_STEP_UV, + r[0], r[1]); + desc->uV_step = mpq4210_scale(MPQ4210_REF_STEP_UV, r[0], r[1]); + + slew = devm_kcalloc(dev, ARRAY_SIZE(mpq4210_ref_slew_rate), + sizeof(*slew), GFP_KERNEL); + if (!slew) + return -ENOMEM; + + for (i = 0; i < ARRAY_SIZE(mpq4210_ref_slew_rate); i++) + slew[i] = mpq4210_scale(mpq4210_ref_slew_rate[i], r[0], r[1]); + + desc->ramp_delay_table = slew; + + ret = regmap_read(regmap, MPQ4210_CONTROL1, &val); + if (ret) + return dev_err_probe(dev, ret, "failed to read control 1\n"); + + /* The core overrides this if the board sets regulator-ramp-delay. */ + desc->ramp_delay = slew[FIELD_GET(MPQ4210_CONTROL1_SR, val)]; + + /* + * Documented as reserved, but the datasheet requires it to be set + * before the controller starts up. + */ + ret = regmap_set_bits(regmap, MPQ4210_CONTROL1, + MPQ4210_CONTROL1_RESERVED); + if (ret) + return dev_err_probe(dev, ret, "failed to write control 1\n"); + + config.dev = dev; + config.regmap = regmap; + config.of_node = dev->of_node; + config.init_data = of_get_regulator_init_data(dev, dev->of_node, desc); + if (!config.init_data) + return -ENOMEM; + + rdev = devm_regulator_register(dev, desc, &config); + if (IS_ERR(rdev)) + return dev_err_probe(dev, PTR_ERR(rdev), + "failed to register regulator\n"); + + return 0; +} + +static const struct of_device_id mpq4210_of_match[] = { + { .compatible = "mps,mpq4210" }, + { } +}; +MODULE_DEVICE_TABLE(of, mpq4210_of_match); + +static const struct i2c_device_id mpq4210_i2c_id[] = { + { .name = "mpq4210" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, mpq4210_i2c_id); + +static struct i2c_driver mpq4210_regulator_driver = { + .driver = { + .name = "mpq4210", + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + .of_match_table = mpq4210_of_match, + }, + .probe = mpq4210_i2c_probe, + .id_table = mpq4210_i2c_id, +}; + +module_i2c_driver(mpq4210_regulator_driver); + +MODULE_DESCRIPTION("Monolithic Power Systems MPQ4210 voltage regulator driver"); +MODULE_AUTHOR("Tapio Reijonen <tapio.reijonen@vaisala.com>"); +MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/nex10000ub-regulator.c b/drivers/regulator/nex10000ub-regulator.c new file mode 100644 index 0000000..f44b8b7 --- /dev/null +++ b/drivers/regulator/nex10000ub-regulator.c
@@ -0,0 +1,147 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Nexperia NEX10000UB Regulator driver + * + * Copyright (C) 2026 Linaro Limited. + */ + +#include <linux/delay.h> +#include <linux/err.h> +#include <linux/gpio/consumer.h> +#include <linux/i2c.h> +#include <linux/module.h> +#include <linux/regmap.h> +#include <linux/regulator/driver.h> +#include <linux/regulator/machine.h> + +#define NEX10000UB_REG_VPOS 0x00 +#define NEX10000UB_REG_VNEG 0x01 +#define NEX10000UB_REG_ID 0x02 + +#define NEX10000UB_VOUT_MASK 0x1F +#define NEX10000UB_VOUT_N_VOLTAGE 0x15 +#define NEX10000UB_VOUT_VMIN 4000000 +#define NEX10000UB_VOUT_VMAX 6000000 +#define NEX10000UB_VOUT_STEP 100000 + +#define NEX10000UB_REGULATOR_ID_VPOS 0 +#define NEX10000UB_REGULATOR_ID_VNEG 1 +#define NEX10000UB_MAX_REGULATORS 2 + +static const struct regulator_ops nex10000ub_regulator_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .list_voltage = regulator_list_voltage_linear, + .map_voltage = regulator_map_voltage_linear, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_voltage_sel = regulator_set_voltage_sel_regmap, +}; + +static int nex10000ub_of_parse_cb(struct device_node *np, + const struct regulator_desc *desc, + struct regulator_config *config) +{ + struct gpio_desc *ena_gpiod; + + ena_gpiod = fwnode_gpiod_get_index(of_fwnode_handle(np), "enable", 0, + GPIOD_OUT_LOW, desc->name); + if (IS_ERR(ena_gpiod)) + return PTR_ERR(ena_gpiod); + + config->ena_gpiod = ena_gpiod; + + return 0; +} + +#define NEX10000UB_REGULATOR_DESC(_id, _name) \ + [NEX10000UB_REGULATOR_ID_##_id] = { \ + .name = "nex10000ub-"#_name, \ + .supply_name = "vin", \ + .id = NEX10000UB_REGULATOR_ID_##_id, \ + .of_match = of_match_ptr(#_name), \ + .of_parse_cb = nex10000ub_of_parse_cb, \ + .ops = &nex10000ub_regulator_ops, \ + .n_voltages = NEX10000UB_VOUT_N_VOLTAGE, \ + .min_uV = NEX10000UB_VOUT_VMIN, \ + .uV_step = NEX10000UB_VOUT_STEP, \ + .enable_time = 2000, \ + .vsel_mask = NEX10000UB_VOUT_MASK, \ + .vsel_reg = NEX10000UB_REG_##_id, \ + .type = REGULATOR_VOLTAGE, \ + .owner = THIS_MODULE, \ + } + +static const struct regulator_desc nex10000_regs_desc[NEX10000UB_MAX_REGULATORS] = { + NEX10000UB_REGULATOR_DESC(VPOS, vpos), + NEX10000UB_REGULATOR_DESC(VNEG, vneg), +}; + +static const struct regmap_config nex10000ub_regmap_config = { + .reg_bits = 8, + .val_bits = 8, + .max_register = NEX10000UB_REG_ID, + .cache_type = REGCACHE_NONE, +}; + +static int nex10000ub_probe(struct i2c_client *client) +{ + struct device *dev = &client->dev; + struct regmap *map; + int id; + int ret; + + map = devm_regmap_init_i2c(client, &nex10000ub_regmap_config); + if (IS_ERR(map)) { + ret = PTR_ERR(map); + dev_err(dev, "regmap init failed: %d\n", ret); + return ret; + } + + for (id = 0; id < NEX10000UB_MAX_REGULATORS; ++id) { + struct regulator_config config = { }; + struct regulator_dev *rdev; + + config.regmap = map; + config.dev = dev; + + rdev = devm_regulator_register(dev, &nex10000_regs_desc[id], + &config); + if (IS_ERR(rdev)) { + ret = PTR_ERR(rdev); + dev_err(dev, "regulator %s register failed: %d\n", + nex10000_regs_desc[id].name, ret); + return ret; + } + } + + return 0; +} + +static const struct i2c_device_id nex10000ub_id[] = { + { .name = "nex10000ub" }, + { } +}; +MODULE_DEVICE_TABLE(i2c, nex10000ub_id); + +static const struct of_device_id __maybe_unused nex10000ub_of_match[] = { + { .compatible = "nexperia,nex10000ub" }, + {}, +}; +MODULE_DEVICE_TABLE(of, nex10000ub_of_match); + +static struct i2c_driver nex10000ub_i2c_driver = { + .driver = { + .name = "nex10000ub", + .probe_type = PROBE_PREFER_ASYNCHRONOUS, + .of_match_table = of_match_ptr(nex10000ub_of_match), + }, + .probe = nex10000ub_probe, + .id_table = nex10000ub_id, +}; + +module_i2c_driver(nex10000ub_i2c_driver); + +MODULE_DESCRIPTION("NEX10000UB regulator driver"); +MODULE_AUTHOR("Neil Armstrong <neil.armstrong@linaro.org>"); +MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/pca9450-regulator.c b/drivers/regulator/pca9450-regulator.c index c41db70..613bce4 100644 --- a/drivers/regulator/pca9450-regulator.c +++ b/drivers/regulator/pca9450-regulator.c
@@ -77,10 +77,56 @@ static const unsigned int pca9450_dvs_buck_ramp_table[] = { 25000, 12500, 6250, 3125 }; +static int pca9450_regulator_is_enabled(struct regulator_dev *rdev) +{ + unsigned int val; + int ret; + + ret = regmap_read(rdev->regmap, rdev->desc->enable_reg, &val); + if (ret) + return ret; + + /* All valid nonzero ENMODE values enable the regulator in RUN mode. */ + return !!(val & rdev->desc->enable_mask); +} + +static int pca9450_set_suspend_disable(struct regulator_dev *rdev, + unsigned int suspend_val) +{ + int ret; + + /* Do not enable a runtime-disabled regulator when returning to RUN. */ + ret = pca9450_regulator_is_enabled(rdev); + if (ret < 0) + return ret; + if (!ret) + return 0; + + return regmap_update_bits(rdev->regmap, rdev->desc->enable_reg, + rdev->desc->enable_mask, + suspend_val); +} + +/* + * ENMODE = 10b keeps the regulator enabled in RUN mode and disables it + * while PMIC_STBY_REQ is asserted. + */ +static int pca9450_buck_set_suspend_disable(struct regulator_dev *rdev) +{ + return pca9450_set_suspend_disable(rdev, + BUCK_ENMODE_ONREQ_STBYREQ); +} + +static int pca9450_ldo_set_suspend_disable(struct regulator_dev *rdev) +{ + return pca9450_set_suspend_disable(rdev, + LDO_ENMODE_ONREQ_STBYREQ); +} + static const struct regulator_ops pca9450_dvs_buck_regulator_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, + .is_enabled = pca9450_regulator_is_enabled, .list_voltage = regulator_list_voltage_linear_range, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, @@ -88,18 +134,20 @@ static const struct regulator_ops pca9450_dvs_buck_regulator_ops = { .set_ramp_delay = regulator_set_ramp_delay_regmap, .set_mode = pca9450_buck_set_mode, .get_mode = pca9450_buck_get_mode, + .set_suspend_disable = pca9450_buck_set_suspend_disable, }; static const struct regulator_ops pca9450_buck_regulator_ops = { .enable = regulator_enable_regmap, .disable = regulator_disable_regmap, - .is_enabled = regulator_is_enabled_regmap, + .is_enabled = pca9450_regulator_is_enabled, .list_voltage = regulator_list_voltage_linear_range, .set_voltage_sel = regulator_set_voltage_sel_regmap, .get_voltage_sel = regulator_get_voltage_sel_regmap, .set_voltage_time_sel = regulator_set_voltage_time_sel, .set_mode = pca9450_buck_set_mode, .get_mode = pca9450_buck_get_mode, + .set_suspend_disable = pca9450_buck_set_suspend_disable, }; static const struct regulator_ops pca9450_ldo_regulator_ops = { @@ -111,6 +159,16 @@ static const struct regulator_ops pca9450_ldo_regulator_ops = { .get_voltage_sel = regulator_get_voltage_sel_regmap, }; +static const struct regulator_ops pca9450_ldo_suspend_regulator_ops = { + .enable = regulator_enable_regmap, + .disable = regulator_disable_regmap, + .is_enabled = regulator_is_enabled_regmap, + .list_voltage = regulator_list_voltage_linear_range, + .set_voltage_sel = regulator_set_voltage_sel_regmap, + .get_voltage_sel = regulator_get_voltage_sel_regmap, + .set_suspend_disable = pca9450_ldo_set_suspend_disable, +}; + static unsigned int pca9450_ldo5_get_reg_voltage_sel(struct regulator_dev *rdev) { struct pca9450 *pca9450 = rdev_get_drvdata(rdev); @@ -164,6 +222,7 @@ static const struct regulator_ops pca9450_ldo5_regulator_ops = { .list_voltage = regulator_list_voltage_linear_range, .set_voltage_sel = pca9450_ldo5_set_voltage_sel_regmap, .get_voltage_sel = pca9450_ldo5_get_voltage_sel_regmap, + .set_suspend_disable = pca9450_ldo_set_suspend_disable, }; /* @@ -575,7 +634,7 @@ static struct pca9450_regulator_desc pca9450a_regulators[] = { .of_match = of_match_ptr("LDO3"), .regulators_node = of_match_ptr("regulators"), .id = PCA9450_LDO3, - .ops = &pca9450_ldo_regulator_ops, + .ops = &pca9450_ldo_suspend_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = PCA9450_LDO3_VOLTAGE_NUM, .linear_ranges = pca9450_ldo34_volts, @@ -594,7 +653,7 @@ static struct pca9450_regulator_desc pca9450a_regulators[] = { .of_match = of_match_ptr("LDO4"), .regulators_node = of_match_ptr("regulators"), .id = PCA9450_LDO4, - .ops = &pca9450_ldo_regulator_ops, + .ops = &pca9450_ldo_suspend_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = PCA9450_LDO4_VOLTAGE_NUM, .linear_ranges = pca9450_ldo34_volts, @@ -621,7 +680,7 @@ static struct pca9450_regulator_desc pca9450a_regulators[] = { .vsel_reg = PCA9450_REG_LDO5CTRL_H, .vsel_mask = LDO5HOUT_MASK, .enable_reg = PCA9450_REG_LDO5CTRL_L, - .enable_mask = LDO5H_EN_MASK, + .enable_mask = LDO5L_EN_MASK, .owner = THIS_MODULE, }, }, @@ -820,7 +879,7 @@ static struct pca9450_regulator_desc pca9450bc_regulators[] = { .of_match = of_match_ptr("LDO3"), .regulators_node = of_match_ptr("regulators"), .id = PCA9450_LDO3, - .ops = &pca9450_ldo_regulator_ops, + .ops = &pca9450_ldo_suspend_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = PCA9450_LDO3_VOLTAGE_NUM, .linear_ranges = pca9450_ldo34_volts, @@ -839,7 +898,7 @@ static struct pca9450_regulator_desc pca9450bc_regulators[] = { .of_match = of_match_ptr("LDO4"), .regulators_node = of_match_ptr("regulators"), .id = PCA9450_LDO4, - .ops = &pca9450_ldo_regulator_ops, + .ops = &pca9450_ldo_suspend_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = PCA9450_LDO4_VOLTAGE_NUM, .linear_ranges = pca9450_ldo34_volts, @@ -866,7 +925,7 @@ static struct pca9450_regulator_desc pca9450bc_regulators[] = { .vsel_reg = PCA9450_REG_LDO5CTRL_H, .vsel_mask = LDO5HOUT_MASK, .enable_reg = PCA9450_REG_LDO5CTRL_L, - .enable_mask = LDO5H_EN_MASK, + .enable_mask = LDO5L_EN_MASK, .owner = THIS_MODULE, }, }, @@ -1040,7 +1099,7 @@ static struct pca9450_regulator_desc pca9451a_regulators[] = { .of_match = of_match_ptr("LDO3"), .regulators_node = of_match_ptr("regulators"), .id = PCA9450_LDO3, - .ops = &pca9450_ldo_regulator_ops, + .ops = &pca9450_ldo_suspend_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = PCA9450_LDO3_VOLTAGE_NUM, .linear_ranges = pca9450_ldo34_volts, @@ -1059,7 +1118,7 @@ static struct pca9450_regulator_desc pca9451a_regulators[] = { .of_match = of_match_ptr("LDO4"), .regulators_node = of_match_ptr("regulators"), .id = PCA9450_LDO4, - .ops = &pca9450_ldo_regulator_ops, + .ops = &pca9450_ldo_suspend_regulator_ops, .type = REGULATOR_VOLTAGE, .n_voltages = PCA9450_LDO4_VOLTAGE_NUM, .linear_ranges = pca9450_ldo34_volts, @@ -1086,7 +1145,7 @@ static struct pca9450_regulator_desc pca9451a_regulators[] = { .vsel_reg = PCA9450_REG_LDO5CTRL_H, .vsel_mask = LDO5HOUT_MASK, .enable_reg = PCA9450_REG_LDO5CTRL_L, - .enable_mask = LDO5H_EN_MASK, + .enable_mask = LDO5L_EN_MASK, .owner = THIS_MODULE, }, },
diff --git a/drivers/regulator/pf1550-regulator.c b/drivers/regulator/pf1550-regulator.c index ceee553..84f8b18 100644 --- a/drivers/regulator/pf1550-regulator.c +++ b/drivers/regulator/pf1550-regulator.c
@@ -49,17 +49,26 @@ static const int pf1550_ldo13_volts[] = { static int pf1550_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay) { int id = rdev_get_id(rdev); - unsigned int ramp_bits = 0; + unsigned int ramp_bits; int ret; if (id > PF1550_VREFDDR) return -EACCES; - if (ramp_delay < 0 || ramp_delay > 6250) + switch (ramp_delay) { + case 0: + /* Ramp control is disabled, so use the fastest rate. */ + ramp_bits = 0; + break; + case 1 ... 3125: + ramp_bits = 1; + break; + case 3126 ... 6250: + ramp_bits = 0; + break; + default: return -EINVAL; - - ramp_delay = 6250 / ramp_delay; - ramp_bits = ramp_delay >> 1; + } ret = regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg + 4, 0x10, ramp_bits << 4);
diff --git a/drivers/regulator/pv88080-regulator.c b/drivers/regulator/pv88080-regulator.c index b96afbf..1f2c405 100644 --- a/drivers/regulator/pv88080-regulator.c +++ b/drivers/regulator/pv88080-regulator.c
@@ -432,7 +432,7 @@ static int pv88080_i2c_probe(struct i2c_client *i2c) config.dev = chip->dev; config.regmap = chip->regmap; - /* Registeration for BUCK1, 2, 3 */ + /* Registration for BUCK1, 2, 3 */ for (i = 0; i < PV88080_MAX_REGULATORS-1; i++) { if (init_data) config.init_data = &init_data[i]; @@ -498,7 +498,7 @@ static int pv88080_i2c_probe(struct i2c_client *i2c) pv88080_regulator_info[PV88080_ID_HVBUCK].desc.vsel_mask = regmap_config->hvbuck_vsel_mask; - /* Registeration for HVBUCK */ + /* Registration for HVBUCK */ if (init_data) config.init_data = &init_data[PV88080_ID_HVBUCK];
diff --git a/drivers/regulator/qcom-rpmh-regulator.c b/drivers/regulator/qcom-rpmh-regulator.c index 25c14de..4c90d20 100644 --- a/drivers/regulator/qcom-rpmh-regulator.c +++ b/drivers/regulator/qcom-rpmh-regulator.c
@@ -400,7 +400,7 @@ static unsigned int rpmh_regulator_vrm_get_mode(struct regulator_dev *rdev) * This function is used in the regulator_ops for VRM type RPMh regulator * devices. * - * Return: 0 on success, or a negative error number on failure + * Return: the regulator mode to use for the load */ static unsigned int rpmh_regulator_vrm_get_optimum_mode( struct regulator_dev *rdev, int input_uV, int output_uV, int load_uA) @@ -1589,31 +1589,34 @@ static const struct rpmh_vreg_init_data pm6150l_vreg_data[] = { }; static const struct rpmh_vreg_init_data pm6350_vreg_data[] = { - RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps510, NULL), - RPMH_VREG("smps2", SMPS, 2, &pmic5_hfsmps510, NULL), - /* smps3 - smps5 not configured */ - RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, NULL), - RPMH_VREG("ldo2", LDO, 2, &pmic5_pldo, NULL), - RPMH_VREG("ldo3", LDO, 3, &pmic5_pldo, NULL), - RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo, NULL), - RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo, NULL), - RPMH_VREG("ldo6", LDO, 6, &pmic5_pldo, NULL), - RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo, NULL), - RPMH_VREG("ldo8", LDO, 8, &pmic5_pldo, NULL), - RPMH_VREG("ldo9", LDO, 9, &pmic5_pldo, NULL), - RPMH_VREG("ldo10", LDO, 10, &pmic5_pldo, NULL), - RPMH_VREG("ldo11", LDO, 11, &pmic5_pldo, NULL), - RPMH_VREG("ldo12", LDO, 12, &pmic5_pldo, NULL), - RPMH_VREG("ldo13", LDO, 13, &pmic5_nldo, NULL), - RPMH_VREG("ldo14", LDO, 14, &pmic5_pldo, NULL), - RPMH_VREG("ldo15", LDO, 15, &pmic5_nldo, NULL), - RPMH_VREG("ldo16", LDO, 16, &pmic5_nldo, NULL), - /* ldo17 not configured */ - RPMH_VREG("ldo18", LDO, 18, &pmic5_nldo, NULL), - RPMH_VREG("ldo19", LDO, 19, &pmic5_nldo, NULL), - RPMH_VREG("ldo20", LDO, 20, &pmic5_nldo, NULL), - RPMH_VREG("ldo21", LDO, 21, &pmic5_nldo, NULL), - RPMH_VREG("ldo22", LDO, 22, &pmic5_nldo, NULL), + RPMH_VREG("smps1", SMPS, 1, &pmic5_ftsmps510, "vdd-s1"), + RPMH_VREG("smps2", SMPS, 2, &pmic5_hfsmps510, "vdd-s2"), + RPMH_VREG("smps3", SMPS, 3, &pmic5_ftsmps510, "vdd-s3"), + RPMH_VREG("smps4", SMPS, 4, &pmic5_ftsmps510, "vdd-s4"), + RPMH_VREG("smps5", SMPS, 5, &pmic5_ftsmps510, "vdd-s5"), + RPMH_VREG("smps6", SMPS, 6, &pmic5_hfsmps510, "vdd-s6"), + RPMH_VREG("ldo1", LDO, 1, &pmic5_nldo, "vdd-l1"), + RPMH_VREG("ldo2", LDO, 2, &pmic5_pldo, "vdd-l2-l5-l7"), + RPMH_VREG("ldo3", LDO, 3, &pmic5_pldo, "vdd-l3-l6-l8-l9-l10"), + RPMH_VREG("ldo4", LDO, 4, &pmic5_nldo, "vdd-l4"), + RPMH_VREG("ldo5", LDO, 5, &pmic5_pldo, "vdd-l2-l5-l7"), + RPMH_VREG("ldo6", LDO, 6, &pmic5_pldo, "vdd-l3-l6-l8-l9-l10"), + RPMH_VREG("ldo7", LDO, 7, &pmic5_pldo, "vdd-l2-l5-l7"), + RPMH_VREG("ldo8", LDO, 8, &pmic5_pldo, "vdd-l3-l6-l8-l9-l10"), + RPMH_VREG("ldo9", LDO, 9, &pmic5_pldo, "vdd-l3-l6-l8-l9-l10"), + RPMH_VREG("ldo10", LDO, 10, &pmic5_pldo, "vdd-l3-l6-l8-l9-l10"), + RPMH_VREG("ldo11", LDO, 11, &pmic5_pldo, "vdd-l11"), + RPMH_VREG("ldo12", LDO, 12, &pmic5_pldo, "vdd-l12-l14"), + RPMH_VREG("ldo13", LDO, 13, &pmic5_nldo, "vdd-l13"), + RPMH_VREG("ldo14", LDO, 14, &pmic5_pldo, "vdd-l12-l14"), + RPMH_VREG("ldo15", LDO, 15, &pmic5_nldo, "vdd-l15-l19-l22"), + RPMH_VREG("ldo16", LDO, 16, &pmic5_nldo, "vdd-l16"), + RPMH_VREG("ldo17", LDO, 17, &pmic5_nldo, "vdd-l17"), + RPMH_VREG("ldo18", LDO, 18, &pmic5_nldo, "vdd-l18-l20-l21"), + RPMH_VREG("ldo19", LDO, 19, &pmic5_nldo, "vdd-l15-l19-l22"), + RPMH_VREG("ldo20", LDO, 20, &pmic5_nldo, "vdd-l18-l20-l21"), + RPMH_VREG("ldo21", LDO, 21, &pmic5_nldo, "vdd-l18-l20-l21"), + RPMH_VREG("ldo22", LDO, 22, &pmic5_nldo, "vdd-l15-l19-l22"), }; static const struct rpmh_vreg_init_data pmcx0102_vreg_data[] = {
diff --git a/drivers/regulator/rpi-panel-attiny-regulator.c b/drivers/regulator/rpi-panel-attiny-regulator.c index 3020839..77da916 100644 --- a/drivers/regulator/rpi-panel-attiny-regulator.c +++ b/drivers/regulator/rpi-panel-attiny-regulator.c
@@ -249,8 +249,14 @@ static int attiny_i2c_read(struct i2c_client *client, u8 reg, unsigned int *buf) msgs[0].len = ARRAY_SIZE(addr_buf); msgs[0].buf = addr_buf; + /* + * The first transfer after a power-up of the host usually fails on + * (at least) some TI boards, so retry the transfer on failure. + */ ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); if (ret != ARRAY_SIZE(msgs)) + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); + if (ret != ARRAY_SIZE(msgs)) return -EIO; usleep_range(5000, 10000);
diff --git a/drivers/regulator/rt6190-regulator.c b/drivers/regulator/rt6190-regulator.c index f2cd954..21ced34 100644 --- a/drivers/regulator/rt6190-regulator.c +++ b/drivers/regulator/rt6190-regulator.c
@@ -108,19 +108,27 @@ static int rt6190_out_enable(struct regulator_dev *rdev) ret = regmap_raw_read(regmap, RT6190_REG_OUTV, out_cfg, sizeof(out_cfg)); if (ret) - return ret; + goto err_pm_put; ret = regulator_enable_regmap(rdev); if (ret) - return ret; + goto err_pm_put; ret = regmap_raw_write(regmap, RT6190_REG_OUTV, out_cfg, sizeof(out_cfg)); if (ret) - return ret; + goto err_pm_put; - return regmap_update_bits(regmap, RT6190_REG_SET5, RT6190_ENGCP_MASK, - RT6190_ENGCP_MASK); + ret = regmap_update_bits(regmap, RT6190_REG_SET5, RT6190_ENGCP_MASK, + RT6190_ENGCP_MASK); + if (ret) + goto err_pm_put; + + return 0; + +err_pm_put: + pm_runtime_put(data->dev); + return ret; } static int rt6190_out_disable(struct regulator_dev *rdev)
diff --git a/drivers/regulator/tps6105x-regulator.c b/drivers/regulator/tps6105x-regulator.c index a09c6ae..7f99f3e 100644 --- a/drivers/regulator/tps6105x-regulator.c +++ b/drivers/regulator/tps6105x-regulator.c
@@ -65,7 +65,7 @@ static int tps6105x_regulator_probe(struct platform_device *pdev) /* This instance is not set for regulator mode so bail out */ if (pdata->mode != TPS6105X_MODE_VOLTAGE) { dev_info(&pdev->dev, - "chip not in voltage mode mode, exit probe\n"); + "chip not in voltage mode, exit probe\n"); return 0; }
diff --git a/drivers/regulator/tps65185.c b/drivers/regulator/tps65185.c index 6a31301..4865227 100644 --- a/drivers/regulator/tps65185.c +++ b/drivers/regulator/tps65185.c
@@ -392,8 +392,7 @@ static int tps65185_probe(struct i2c_client *client) IRQF_TRIGGER_RISING | IRQF_ONESHOT, "PGOOD", data); if (ret) - return dev_err_probe(&client->dev, ret, - "failed to request power good irq\n"); + return ret; if (client->irq) { ret = devm_request_threaded_irq(&client->dev, client->irq, @@ -401,8 +400,7 @@ static int tps65185_probe(struct i2c_client *client) IRQF_TRIGGER_LOW | IRQF_ONESHOT, "tps65185", data); if (ret) - return dev_err_probe(&client->dev, ret, - "failed to request irq\n"); + return ret; } ret = regmap_update_bits(data->regmap, TPS65185_REG_INT_EN2, BIT(0), BIT(0));
diff --git a/drivers/rtc/rtc-bd70528.c b/drivers/rtc/rtc-bd70528.c index 482810b..fd415e3 100644 --- a/drivers/rtc/rtc-bd70528.c +++ b/drivers/rtc/rtc-bd70528.c
@@ -8,6 +8,7 @@ #include <linux/mfd/rohm-bd71815.h> #include <linux/mfd/rohm-bd71828.h> #include <linux/mfd/rohm-bd72720.h> +#include <linux/mfd/rohm-bd73800.h> #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> @@ -284,6 +285,12 @@ static int bd70528_probe(struct platform_device *pdev) bd_rtc->bd718xx_alm_block_start = BD72720_REG_RTC_ALM_START; hour_reg = BD72720_REG_RTC_HOUR; break; + case ROHM_CHIP_TYPE_BD73800: + bd_rtc->reg_time_start = BD73800_REG_RTC_START; + bd_rtc->bd718xx_alm_block_start = BD73800_REG_RTC_ALM_START; + hour_reg = BD73800_REG_RTC_HOUR; + break; + default: dev_err(&pdev->dev, "Unknown chip\n"); return -ENOENT; @@ -344,6 +351,7 @@ static const struct platform_device_id bd718x7_rtc_id[] = { { .name = "bd71828-rtc", .driver_data = ROHM_CHIP_TYPE_BD71828 }, { .name = "bd71815-rtc", .driver_data = ROHM_CHIP_TYPE_BD71815 }, { .name = "bd72720-rtc", .driver_data = ROHM_CHIP_TYPE_BD72720 }, + { .name = "bd73800-rtc", .driver_data = ROHM_CHIP_TYPE_BD73800 }, { } }; MODULE_DEVICE_TABLE(platform, bd718x7_rtc_id);
diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index a2d65ad..483cbdc 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig
@@ -24,6 +24,8 @@ source "drivers/soc/rockchip/Kconfig" source "drivers/soc/samsung/Kconfig" source "drivers/soc/sophgo/Kconfig" +source "drivers/soc/st/Kconfig" +source "drivers/soc/starfive/Kconfig" source "drivers/soc/sunxi/Kconfig" source "drivers/soc/tegra/Kconfig" source "drivers/soc/ti/Kconfig"
diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index c9e6890..5a3efd6 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile
@@ -30,6 +30,8 @@ obj-y += rockchip/ obj-$(CONFIG_SOC_SAMSUNG) += samsung/ obj-y += sophgo/ +obj-y += st/ +obj-y += starfive/ obj-y += sunxi/ obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-y += ti/
diff --git a/drivers/soc/amlogic/meson-clk-measure.c b/drivers/soc/amlogic/meson-clk-measure.c index 8a1a9fe..33767f0 100644 --- a/drivers/soc/amlogic/meson-clk-measure.c +++ b/drivers/soc/amlogic/meson-clk-measure.c
@@ -20,7 +20,7 @@ static DEFINE_MUTEX(measure_lock); #define MSR_CONT BIT(17) /* continuous measurement */ #define MSR_INTR BIT(18) /* interrupts */ #define MSR_RUN BIT(19) -#define MSR_CLK_SRC GENMASK(26, 20) +#define MSR_CLK_SRC GENMASK(27, 20) #define MSR_BUSY BIT(31) #define MSR_VAL_MASK GENMASK(15, 0) @@ -55,7 +55,7 @@ struct meson_msr { }; #define CLK_MSR_ID(__id, __name) \ - [__id] = {.id = __id, .name = __name,} + {.id = __id, .name = __name,} static const struct meson_msr_id clk_msr_m8[] = { CLK_MSR_ID(0, "ring_osc_out_ee0"), @@ -1041,6 +1041,843 @@ static const struct meson_msr_id clk_msr_t7[] = { CLK_MSR_ID(222, "enc0") }; +static const struct meson_msr_id clk_msr_a4[] = { + CLK_MSR_ID(0, "sys_clk"), + CLK_MSR_ID(1, "axi_clk"), + CLK_MSR_ID(2, "rtc_clk"), + CLK_MSR_ID(3, "p22_usb2_ckout"), + CLK_MSR_ID(4, "p21_usb2_ckout"), + CLK_MSR_ID(5, "p20_usb2_ckout"), + CLK_MSR_ID(6, "cpu_clk_div16"), + CLK_MSR_ID(8, "eth_mpll_test"), + CLK_MSR_ID(10, "fclk_div5"), + CLK_MSR_ID(15, "fclk_50m"), + CLK_MSR_ID(16, "sys_oscin32k_i"), + CLK_MSR_ID(17, "rtc_pll"), + CLK_MSR_ID(19, "hifi_pll"), + CLK_MSR_ID(20, "gp0_pll"), + CLK_MSR_ID(21, "gp1_pll"), + CLK_MSR_ID(22, "eth_mppll_50m_ckout"), + CLK_MSR_ID(23, "sys_pll_div16"), + CLK_MSR_ID(24, "ddr_dpll_pt_clk"), + CLK_MSR_ID(27, "rtc_sec_pulse_out"), + CLK_MSR_ID(28, "rtc_osc_clk_out"), + CLK_MSR_ID(30, "mod_eth_phy_ref_clk"), + CLK_MSR_ID(31, "mod_eth_tx_clk"), + CLK_MSR_ID(32, "eth_125m"), + CLK_MSR_ID(33, "eth_rmii"), + CLK_MSR_ID(34, "co_clkin_to_mac"), + CLK_MSR_ID(35, "mod_eth_rx_clk_rmii"), + CLK_MSR_ID(36, "co_rx_clk"), + CLK_MSR_ID(37, "co_tx_clk"), + CLK_MSR_ID(38, "eth_phy_rxclk"), + CLK_MSR_ID(39, "eth_phy_plltxclk"), + CLK_MSR_ID(40, "ephy_test_clk"), + CLK_MSR_ID(41, "audio_core"), + CLK_MSR_ID(51, "cts_vout_venc_clk_ph"), + CLK_MSR_ID(52, "cts_vout_venc_clk"), + CLK_MSR_ID(106, "deskew_pll_test_clk"), + CLK_MSR_ID(111, "sar_adc"), + CLK_MSR_ID(112, "ts"), + CLK_MSR_ID(113, "sd_emmc_c"), + CLK_MSR_ID(115, "sd_emmc_a"), + CLK_MSR_ID(116, "gpio_msr_clk"), + CLK_MSR_ID(117, "spicc1"), + CLK_MSR_ID(118, "spicc0"), + CLK_MSR_ID(119, "o_mst_sclk_vad"), + CLK_MSR_ID(120, "o_mst_mclk_vad"), + CLK_MSR_ID(121, "o_pdm_sysclk"), + CLK_MSR_ID(122, "mod_audio_pdm_dclk_o"), + CLK_MSR_ID(123, "o_vad_clk"), + CLK_MSR_ID(124, "earcrx_dmac_clk"), + CLK_MSR_ID(125, "earcrx_cmdc_clk"), + CLK_MSR_ID(126, "earctx_dmac_clk"), + CLK_MSR_ID(127, "earctx_cmdc_clk"), + CLK_MSR_ID(128, "tohdmitx_bclk"), + CLK_MSR_ID(129, "tohdmitx_mclk"), + CLK_MSR_ID(130, "tohdmitx_spdif_clk"), + CLK_MSR_ID(131, "toacodec_bclk"), + CLK_MSR_ID(132, "toacodec_mclk"), + CLK_MSR_ID(133, "spdifout_b_mst_clk"), + CLK_MSR_ID(134, "spdifout_mst_clk"), + CLK_MSR_ID(135, "spdifin_mst_clk"), + CLK_MSR_ID(136, "audio_mclk"), + CLK_MSR_ID(137, "vad_clk"), + CLK_MSR_ID(138, "tdmout_d_sclk"), + CLK_MSR_ID(139, "tdmout_c_sclk"), + CLK_MSR_ID(140, "tdmout_b_sclk"), + CLK_MSR_ID(141, "tdmout_a_sclk"), + CLK_MSR_ID(142, "tdminb_lb_sclk"), + CLK_MSR_ID(143, "tdmin_lb_sclk"), + CLK_MSR_ID(144, "tdmin_d_sclk"), + CLK_MSR_ID(145, "tdmin_c_sclk"), + CLK_MSR_ID(146, "tdmin_b_sclk"), + CLK_MSR_ID(147, "tdmin_a_sclk"), + CLK_MSR_ID(148, "resampleb_clk"), + CLK_MSR_ID(149, "resamplea_clk"), + CLK_MSR_ID(150, "pdmb_sysclk"), + CLK_MSR_ID(151, "pdmb_dclk"), + CLK_MSR_ID(152, "pdm_sysclk"), + CLK_MSR_ID(153, "pdm_dclk"), + CLK_MSR_ID(154, "alockerb_out_clk"), + CLK_MSR_ID(155, "alockerb_in_clk"), + CLK_MSR_ID(156, "alocker_out_clk"), + CLK_MSR_ID(157, "alocker_in_clk"), + CLK_MSR_ID(158, "audio_mst_clk[34]"), + CLK_MSR_ID(159, "audio_mst_clk[35]"), + CLK_MSR_ID(162, "pwm_h"), + CLK_MSR_ID(163, "pwm_g"), + CLK_MSR_ID(164, "pwm_f"), + CLK_MSR_ID(165, "pwm_e"), + CLK_MSR_ID(166, "pwm_d"), + CLK_MSR_ID(167, "pwm_c"), + CLK_MSR_ID(168, "pwm_b"), + CLK_MSR_ID(169, "pwm_a"), + CLK_MSR_ID(170, "AU_ADC_CLK_G128X"), + CLK_MSR_ID(171, "AU_ADC_CLK_TO_GPIO"), + CLK_MSR_ID(172, "AU_DAC1_CLK_G128X"), + CLK_MSR_ID(173, "AU_DAC1_CLK_TO_GPIO"), + CLK_MSR_ID(176, "rng_ring_osc_clk[0]"), + CLK_MSR_ID(177, "rng_ring_osc_clk[1]"), + CLK_MSR_ID(178, "rng_ring_osc_clk[2]"), + CLK_MSR_ID(179, "rng_ring_osc_clk[3]"), + CLK_MSR_ID(180, "sys_cpu_osc_ring[0](ULVT16)"), + CLK_MSR_ID(181, "sys_cpu_osc_ring[1](ULVT20)"), + CLK_MSR_ID(182, "sys_cpu_osc_ring[2](ULVT16)"), + CLK_MSR_ID(183, "sys_cpu_osc_ring[3](ULVT16)"), + CLK_MSR_ID(184, "sys_cpu_osc_ring[4](ULVT16)"), + CLK_MSR_ID(185, "am_ring_osc_clk_out_top[0](SVT16)"), + CLK_MSR_ID(186, "am_ring_osc_clk_out_top[1](LVT20)"), +}; + +static const struct meson_msr_id clk_msr_a5[] = { + CLK_MSR_ID(0, "sys_clk"), + CLK_MSR_ID(1, "axi_clk"), + CLK_MSR_ID(2, "rtc_clk"), + CLK_MSR_ID(3, "dspa"), + CLK_MSR_ID(6, "cpu_clk_div16"), + CLK_MSR_ID(10, "fclk_div5"), + CLK_MSR_ID(11, "mpll0"), + CLK_MSR_ID(12, "mpll1"), + CLK_MSR_ID(13, "mpll2"), + CLK_MSR_ID(14, "mpll3"), + CLK_MSR_ID(15, "fclk_50m"), + CLK_MSR_ID(16, "sys_oscin32k_i"), + CLK_MSR_ID(17, "rtc_pll"), + CLK_MSR_ID(18, "mpll_clk_test_out"), + CLK_MSR_ID(19, "hifi_pll"), + CLK_MSR_ID(20, "gp0_pll"), + CLK_MSR_ID(21, "gp1_pll"), + CLK_MSR_ID(23, "sys_pll_div16"), + CLK_MSR_ID(24, "ddr_dpll_pt_clk"), + CLK_MSR_ID(25, "nna_axi"), + CLK_MSR_ID(26, "nna_core"), + CLK_MSR_ID(27, "rtc_sec_pulse_out"), + CLK_MSR_ID(28, "rtc_osc_clk_out"), + CLK_MSR_ID(30, "mod_eth_phy_ref_clk"), + CLK_MSR_ID(31, "mod_eth_tx_clk"), + CLK_MSR_ID(35, "mod_eth_rx_clk_rmii"), + CLK_MSR_ID(79, "rama_clk"), + CLK_MSR_ID(106, "deskew_pll_clk_div32_out"), + CLK_MSR_ID(111, "sar_adc"), + CLK_MSR_ID(112, "ts"), + CLK_MSR_ID(113, "sd_emmc_c"), + CLK_MSR_ID(115, "sd_emmc_a"), + CLK_MSR_ID(116, "gpio_msr_clk"), + CLK_MSR_ID(117, "spicc1"), + CLK_MSR_ID(118, "spicc0"), + CLK_MSR_ID(119, "o_mst_sclk_vad"), + CLK_MSR_ID(120, "o_mst_mclk_vad"), + CLK_MSR_ID(121, "o_pdm_sysclk"), + CLK_MSR_ID(122, "mod_audio_pdm_dclk_o"), + CLK_MSR_ID(123, "o_vad_clk"), + CLK_MSR_ID(124, "earcrx_dmac_clk"), + CLK_MSR_ID(125, "earcrx_cmdc_clk"), + CLK_MSR_ID(126, "earctx_dmac_clk"), + CLK_MSR_ID(127, "earctx_cmdc_clk"), + CLK_MSR_ID(128, "tohdmitx_bclk"), + CLK_MSR_ID(129, "tohdmitx_mclk"), + CLK_MSR_ID(130, "tohdmitx_spdif_clk"), + CLK_MSR_ID(131, "toacodec_bclk"), + CLK_MSR_ID(132, "toacodec_mclk"), + CLK_MSR_ID(133, "spdifout_b_mst_clk"), + CLK_MSR_ID(134, "spdifout_mst_clk"), + CLK_MSR_ID(135, "spdifin_mst_clk"), + CLK_MSR_ID(136, "audio_mclk"), + CLK_MSR_ID(137, "vad_clk"), + CLK_MSR_ID(138, "tdmout_d_sclk"), + CLK_MSR_ID(139, "tdmout_c_sclk"), + CLK_MSR_ID(140, "tdmout_b_sclk"), + CLK_MSR_ID(141, "tdmout_a_sclk"), + CLK_MSR_ID(142, "tdminb_lb_sclk"), + CLK_MSR_ID(143, "tdmin_lb_sclk"), + CLK_MSR_ID(144, "tdmin_d_sclk"), + CLK_MSR_ID(145, "tdmin_c_sclk"), + CLK_MSR_ID(146, "tdmin_b_sclk"), + CLK_MSR_ID(147, "tdmin_a_sclk"), + CLK_MSR_ID(148, "resampleb_clk"), + CLK_MSR_ID(149, "resamplea_clk"), + CLK_MSR_ID(150, "pdmb_sysclk"), + CLK_MSR_ID(151, "pdmb_dclk"), + CLK_MSR_ID(152, "pdm_sysclk"), + CLK_MSR_ID(153, "pdm_dclk"), + CLK_MSR_ID(154, "alockerb_out_clk"), + CLK_MSR_ID(155, "alockerb_in_clk"), + CLK_MSR_ID(156, "alocker_out_clk"), + CLK_MSR_ID(157, "alocker_in_clk"), + CLK_MSR_ID(158, "audio_mst_clk[34]"), + CLK_MSR_ID(159, "audio_mst_clk[35]"), + CLK_MSR_ID(162, "pwm_h"), + CLK_MSR_ID(163, "pwm_g"), + CLK_MSR_ID(164, "pwm_f"), + CLK_MSR_ID(165, "pwm_e"), + CLK_MSR_ID(166, "pwm_d"), + CLK_MSR_ID(167, "pwm_c"), + CLK_MSR_ID(168, "pwm_b"), + CLK_MSR_ID(169, "pwm_a"), + CLK_MSR_ID(176, "rng_ring_osc_clk[0]"), + CLK_MSR_ID(177, "rng_ring_osc_clk[1]"), + CLK_MSR_ID(178, "rng_ring_osc_clk[2]"), + CLK_MSR_ID(179, "rng_ring_osc_clk[3]"), + CLK_MSR_ID(180, "dmc_osc_ring(LVT16)"), + CLK_MSR_ID(181, "dsp_osc_ring(SVT16)"), + CLK_MSR_ID(182, "axi_srama_osc_ring(SVT16)"), + CLK_MSR_ID(183, "nna_osc_ring[0](ULVT20)"), + CLK_MSR_ID(184, "nna_osc_ring[1](LVT16)"), + CLK_MSR_ID(185, "sys_cpu_osc_ring[0](ULVT16)"), + CLK_MSR_ID(186, "sys_cpu_osc_ring[1](ULVT20)"), + CLK_MSR_ID(187, "sys_cpu_osc_ring[2](ULVT16)"), + CLK_MSR_ID(188, "sys_cpu_osc_ring[3](LVT16)"), + CLK_MSR_ID(189, "axi_sramb_osc_ring(SVT16)"), +}; + +static const struct meson_msr_id clk_msr_a9[] = { + CLK_MSR_ID(0, "sys_clk"), + CLK_MSR_ID(1, "axi_clk"), + CLK_MSR_ID(2, "rtc_clk"), + CLK_MSR_ID(3, "dspa"), + CLK_MSR_ID(4, "mali_stack"), + CLK_MSR_ID(5, "mali"), + CLK_MSR_ID(6, "cpu_clk_div16"), + CLK_MSR_ID(7, "a78_clk_div16"), + CLK_MSR_ID(8, "dsu_clk_div16"), + CLK_MSR_ID(9, "isp"), + CLK_MSR_ID(10, "gp2_pll"), + CLK_MSR_ID(11, "fclk_div5"), + CLK_MSR_ID(12, "u2drd_usb2_ckout"), + CLK_MSR_ID(13, "pre0_hdmirx_aud_pll_clk"), + CLK_MSR_ID(14, "hrx20_pll_clk_test"), + CLK_MSR_ID(15, "u2h_usb2_ckout"), + CLK_MSR_ID(16, "fclk_50m"), + CLK_MSR_ID(17, "u3drd_b_usb2_ckout"), + CLK_MSR_ID(18, "gp1_pll"), + CLK_MSR_ID(19, "hifi_pll"), + CLK_MSR_ID(20, "gp0_pll"), + CLK_MSR_ID(21, "hifi1_pll"), + CLK_MSR_ID(22, "csi_phy"), + CLK_MSR_ID(23, "sys_pll_div16"), + CLK_MSR_ID(24, "ddr_dpll_pt_clk"), + CLK_MSR_ID(25, "mod_Tsin_A_CLK_IN"), + CLK_MSR_ID(26, "ext_Tsin_B_CLK_IN"), + CLK_MSR_ID(27, "u3p2pll1_0_clk_div16"), + CLK_MSR_ID(28, "u3p2pll1_1_clk_div16"), + CLK_MSR_ID(29, "upcrx0_cdrclk"), + CLK_MSR_ID(30, "upcrx1_cdrclk"), + CLK_MSR_ID(31, "hdmirx_aud_sck"), + CLK_MSR_ID(32, "uptx0_clk_sync_b20"), + CLK_MSR_ID(33, "uptx1_clk_sync_b20"), + CLK_MSR_ID(34, "lp_pll_clk0"), + CLK_MSR_ID(35, "lp_pll_clk1"), + CLK_MSR_ID(36, "u3hsg_PCIE_PIPE_PCLK"), + CLK_MSR_ID(37, "u3hsg_upcrx_cdrclk"), + CLK_MSR_ID(38, "u3hsg_upctx_clk_sync_b20"), + CLK_MSR_ID(39, "u3hsg_upcrxpll_clk_test"), + CLK_MSR_ID(40, "hdmirx_acr_lclk"), + CLK_MSR_ID(41, "i3c"), + CLK_MSR_ID(42, "hdmirx_aud_pll"), + CLK_MSR_ID(43, "hdmirx_acr_ref"), + CLK_MSR_ID(44, "hdmirx_meter"), + CLK_MSR_ID(45, "hdmirx_hdcp2x"), + CLK_MSR_ID(46, "hdmirx_5m"), + CLK_MSR_ID(47, "hdmirx_2m"), + CLK_MSR_ID(48, "hdmirx_cfg"), + CLK_MSR_ID(49, "hdmi_vx1_pix_clk"), + CLK_MSR_ID(50, "vid_pll"), + CLK_MSR_ID(51, "encoder0_if_clk"), + CLK_MSR_ID(52, "encoder1"), + CLK_MSR_ID(53, "encoder0"), + CLK_MSR_ID(54, "vdac"), + CLK_MSR_ID(55, "mali_aclkm"), + CLK_MSR_ID(56, "vid1_pll"), + CLK_MSR_ID(57, "lcd_an_ph2"), + CLK_MSR_ID(58, "lcd_an_ph3"), + CLK_MSR_ID(59, "hdmitx_pixel"), + CLK_MSR_ID(60, "vdin_meas"), + CLK_MSR_ID(61, "vpu"), + CLK_MSR_ID(62, "vpu_clkb"), + CLK_MSR_ID(63, "vpu_clkb_tmp"), + CLK_MSR_ID(64, "u3p2_upcrxpll_fst_pll_clk"), + CLK_MSR_ID(65, "vid_lock"), + CLK_MSR_ID(66, "vapb"), + CLK_MSR_ID(67, "ge2d"), + CLK_MSR_ID(68, "cve"), + CLK_MSR_ID(69, "vge"), + CLK_MSR_ID(70, "dsi0_meas"), + CLK_MSR_ID(71, "dsi1_meas"), + CLK_MSR_ID(72, "mipi_csi_phy_clk_out[0]"), + CLK_MSR_ID(73, "mipi_csi_phy_clk_out[1]"), + CLK_MSR_ID(74, "mipi_csi_phy_clk_out[2]"), + CLK_MSR_ID(75, "mipi_csi_phy_clk_out[3]"), + CLK_MSR_ID(76, "hdmitx_tmds"), + CLK_MSR_ID(77, "hdmitx_sys"), + CLK_MSR_ID(78, "hdmitx_fe"), + CLK_MSR_ID(80, "hdmitx_prif"), + CLK_MSR_ID(81, "hdmitx_200m"), + CLK_MSR_ID(82, "hdmitx_aud"), + CLK_MSR_ID(83, "hdmitx1_pixel"), + CLK_MSR_ID(84, "hdmitx1_fe"), + CLK_MSR_ID(85, "gic"), + CLK_MSR_ID(86, "lvds0_fifo_clk"), + CLK_MSR_ID(87, "lvds1_fifo_clk"), + CLK_MSR_ID(88, "htx_aes_clk"), + CLK_MSR_ID(89, "amfc"), + CLK_MSR_ID(90, "a_clk_sync_dig"), + CLK_MSR_ID(91, "b_clk_sync_dig"), + CLK_MSR_ID(92, "u3dp_upcrx_cdrclk"), + CLK_MSR_ID(93, "u3dp_upctx_clk_sync_b20"), + CLK_MSR_ID(94, "u3dp_upcrxpll_clk_test"), + CLK_MSR_ID(95, "u3dp_upcrpll_fst_pll_clk"), + CLK_MSR_ID(96, "u3dp_usb2_ckout"), + CLK_MSR_ID(97, "hcodec"), + CLK_MSR_ID(99, "hevcf"), + CLK_MSR_ID(104, "spisg2"), + CLK_MSR_ID(105, "spisg1"), + CLK_MSR_ID(106, "deskew_pll_clk_div32_out"), + CLK_MSR_ID(108, "cmpr"), + CLK_MSR_ID(109, "dewarpa"), + CLK_MSR_ID(110, "sc"), + CLK_MSR_ID(111, "sar_adc"), + CLK_MSR_ID(112, "glb"), + CLK_MSR_ID(113, "sd_emmc_c"), + CLK_MSR_ID(114, "sd_emmc_b"), + CLK_MSR_ID(115, "sd_emmc_a"), + CLK_MSR_ID(116, "gpio_msr_clk"), + CLK_MSR_ID(117, "aux_clk_o"), + CLK_MSR_ID(118, "spisg0"), + CLK_MSR_ID(121, "ts"), + CLK_MSR_ID(122, "usb_48m"), + CLK_MSR_ID(123, "usb_250m"), + CLK_MSR_ID(124, "eth_125m"), + CLK_MSR_ID(125, "eth_rmii"), + CLK_MSR_ID(126, "hrx20_tmds20_clk"), + CLK_MSR_ID(127, "hrx20_cable_clk"), + CLK_MSR_ID(128, "hdmirx_vid_clk"), + CLK_MSR_ID(129, "hdmirx_aud_clk"), + CLK_MSR_ID(130, "dptx_apb2"), + CLK_MSR_ID(131, "dptx_aud"), + CLK_MSR_ID(132, "audio_todptx_bclk"), + CLK_MSR_ID(133, "audio_txhdmitx_bclk"), + CLK_MSR_ID(134, "audio_txhdmitx_mclk"), + CLK_MSR_ID(135, "audio_txhdmitx_spdif_clk"), + CLK_MSR_ID(136, "mclk_0_pre"), + CLK_MSR_ID(137, "mclk1_0_pre"), + CLK_MSR_ID(138, "pixel0_pll_clkout"), + CLK_MSR_ID(139, "pixel1_pll_clkout"), + CLK_MSR_ID(140, "tcon_clk_out0"), + CLK_MSR_ID(141, "tcon_clk_out1"), + CLK_MSR_ID(142, "audio_todptx_spdif_clk"), + CLK_MSR_ID(143, "audio_todptx_mclk"), + CLK_MSR_ID(144, "dptx_lnk_clk"), + CLK_MSR_ID(145, "edptx_lnk_clk_tx"), + CLK_MSR_ID(146, "mod_audio_pdm_dclk_o_ao"), + CLK_MSR_ID(147, "vid2_pll"), + CLK_MSR_ID(151, "can1_filter"), + CLK_MSR_ID(152, "can0_filter"), + CLK_MSR_ID(153, "can1_pe"), + CLK_MSR_ID(154, "can0_pe"), + CLK_MSR_ID(155, "o_sed_clk"), + CLK_MSR_ID(156, "pwm_n"), + CLK_MSR_ID(157, "pwm_m"), + CLK_MSR_ID(158, "pwm_l"), + CLK_MSR_ID(159, "pwm_k"), + CLK_MSR_ID(160, "pwm_j"), + CLK_MSR_ID(161, "pwm_i"), + CLK_MSR_ID(162, "pwm_h"), + CLK_MSR_ID(170, "rng_ring_osc_clk[0]"), + CLK_MSR_ID(171, "rng_ring_osc_clk[1]"), + CLK_MSR_ID(172, "rng_ring_osc_clk[2]"), + CLK_MSR_ID(173, "rng_ring_osc_clk[3]"), + CLK_MSR_ID(174, "rng_ring_osc_clk[4]"), + CLK_MSR_ID(175, "sys_cpu_osc_ring_clk[0]"), + CLK_MSR_ID(176, "sys_cpu_osc_ring_clk[1]"), + CLK_MSR_ID(177, "sys_cpu_osc_ring_clk[2]"), + CLK_MSR_ID(178, "sys_cpu_osc_ring_clk[3]"), + CLK_MSR_ID(179, "sys_cpu_osc_ring_clk[4]"), + CLK_MSR_ID(180, "sys_cpu_osc_ring_clk[5]"), + CLK_MSR_ID(181, "sys_cpu_osc_ring_clk[6]"), + CLK_MSR_ID(182, "sys_cpu_osc_ring_clk[7]"), + CLK_MSR_ID(183, "sys_cpu_osc_ring_clk[8]"), + CLK_MSR_ID(184, "sys_cpu_osc_ring_clk[9]"), + CLK_MSR_ID(185, "osc_ring_clk_gpu[0]"), + CLK_MSR_ID(186, "osc_ring_clk_gpu[1]"), + CLK_MSR_ID(187, "osc_ring_clk_vpu"), + CLK_MSR_ID(188, "osc_ring_clk_dos[0]"), + CLK_MSR_ID(189, "osc_ring_clk_dos[1]"), + CLK_MSR_ID(190, "osc_ring_clk_vge"), + CLK_MSR_ID(191, "osc_ring_clk_nna[0]"), + CLK_MSR_ID(192, "osc_ring_clk_nna[1]"), + CLK_MSR_ID(193, "osc_ring_clk_top[0]"), + CLK_MSR_ID(194, "osc_ring_clk_top[1]"), + CLK_MSR_ID(195, "nna"), + CLK_MSR_ID(200, "pcie1_tl"), + CLK_MSR_ID(201, "pcie0_tl"), + CLK_MSR_ID(202, "pp"), + CLK_MSR_ID(203, "pwm_a(ao)"), + CLK_MSR_ID(204, "pwm_b(ao)"), + CLK_MSR_ID(205, "pwm_c(ao)"), + CLK_MSR_ID(206, "pwm_d(ao)"), + CLK_MSR_ID(207, "pwm_e(ao)"), + CLK_MSR_ID(208, "pwm_f(ao)"), + CLK_MSR_ID(209, "pwm_g(ao)"), + CLK_MSR_ID(210, "ao_cec"), + CLK_MSR_ID(211, "sec_pulse_out"), + CLK_MSR_ID(212, "osc_clk_out"), + CLK_MSR_ID(213, "earcrx_pll_clk_out"), + CLK_MSR_ID(215, "o_pd_sysclk"), + CLK_MSR_ID(216, "o_earcrx_dmac_clk"), + CLK_MSR_ID(217, "o_earcrx_cmdc_clk"), + CLK_MSR_ID(218, "o_earctx_dmac_clk"), + CLK_MSR_ID(219, "o_earctx_cmdc_clk"), + CLK_MSR_ID(220, "o_earctx_ana_dmac_clk_a2d"), + CLK_MSR_ID(221, "o_tohdmi_dp_tx_a_bclk"), + CLK_MSR_ID(222, "o_tohdmi_dp_tx_a_mclk"), + CLK_MSR_ID(223, "o_tohdmi_dp_tx_a_spdif_clk"), + CLK_MSR_ID(224, "o_tohdmi_dp_tx_b_bclk"), + CLK_MSR_ID(225, "o_tohdmi_dp_tx_b_mclk"), + CLK_MSR_ID(226, "o_tohdmi_dp_tx_b_spdif_clk"), + CLK_MSR_ID(227, "o_toacodec_dac_bclk"), + CLK_MSR_ID(228, "o_toacodec_dac_mclk"), + CLK_MSR_ID(229, "o_spdifout_b_mst_clk"), + CLK_MSR_ID(230, "o_spdifout_mst_clk"), + CLK_MSR_ID(231, "o_spdifin_mst_clk"), + CLK_MSR_ID(232, "o_audio_mclk"), + CLK_MSR_ID(233, "o_vad_clk"), + CLK_MSR_ID(234, "o_tdmout_d_sclk"), + CLK_MSR_ID(235, "o_tdmout_c_sclk"), + CLK_MSR_ID(236, "o_tdmout_b_sclk"), + CLK_MSR_ID(237, "o_tdmout_a_sclk"), + CLK_MSR_ID(238, "o_tdminb_lb_sclk"), + CLK_MSR_ID(239, "o_tdmin_lb_sclk"), + CLK_MSR_ID(240, "o_tdmin_d_sclk"), + CLK_MSR_ID(241, "o_tdmin_c_sclk"), + CLK_MSR_ID(242, "o_tdmin_b_sclk"), + CLK_MSR_ID(243, "o_tdmin_a_sclk"), + CLK_MSR_ID(244, "o_resampleb_clk"), + CLK_MSR_ID(245, "o_resamplea_clk"), + CLK_MSR_ID(246, "o_pdmb_sysclk"), + CLK_MSR_ID(247, "o_pdmb_dclk"), + CLK_MSR_ID(248, "o_pdm_sysclk"), + CLK_MSR_ID(249, "o_pdm_dclk"), + CLK_MSR_ID(250, "c_alockerb_out_clk"), + CLK_MSR_ID(251, "c_alockerb_in_clk"), + CLK_MSR_ID(252, "c_alocker_out_clk"), + CLK_MSR_ID(253, "c_alocker_in_clk"), + CLK_MSR_ID(254, "o_resample_c_clk") +}; + +static const struct meson_msr_id clk_msr_s6[] = { + CLK_MSR_ID(0, "sys_clk"), + CLK_MSR_ID(1, "axi_clk"), + CLK_MSR_ID(2, "rtc_clk"), + CLK_MSR_ID(3, "dspa"), + CLK_MSR_ID(4, "mali_stack"), + CLK_MSR_ID(5, "mali"), + CLK_MSR_ID(6, "cpu_clk_div16"), + CLK_MSR_ID(7, "mali_aclkm"), + CLK_MSR_ID(8, "cecb"), + CLK_MSR_ID(9, "gp2_pll"), + CLK_MSR_ID(10, "fclk_div5"), + CLK_MSR_ID(11, "p21_usb2_ckout"), + CLK_MSR_ID(12, "p20_usb2_ckout"), + CLK_MSR_ID(13, "eth_mpll_test"), + CLK_MSR_ID(15, "fclk_50m"), + CLK_MSR_ID(18, "gp1_pll"), + CLK_MSR_ID(19, "hifi_pll"), + CLK_MSR_ID(20, "gp0_pll"), + CLK_MSR_ID(21, "hifi1_pll"), + CLK_MSR_ID(22, "eth_mppll_50m_ckout"), + CLK_MSR_ID(23, "sys_pll_div16"), + CLK_MSR_ID(24, "ddr_dpll_pt_clk"), + CLK_MSR_ID(25, "mod_Tsin_A_CLK_IN"), + CLK_MSR_ID(26, "ext_Tsin_B_CLK_IN"), + CLK_MSR_ID(27, "mod_Tsin_C_CLK_IN"), + CLK_MSR_ID(28, "mod_Tsin_D_CLK_IN"), + CLK_MSR_ID(29, "dsi_pll_div_clk_out"), + CLK_MSR_ID(30, "dsi_pll_clk"), + CLK_MSR_ID(32, "eth_125m"), + CLK_MSR_ID(33, "eth_rmii"), + CLK_MSR_ID(34, "co_clkin_to_mac"), + CLK_MSR_ID(36, "co_rx_clk"), + CLK_MSR_ID(37, "co_tx_clk"), + CLK_MSR_ID(38, "eth_phy_rxclk"), + CLK_MSR_ID(39, "eth_phy_plltxclk"), + CLK_MSR_ID(40, "ephy_test_clk"), + CLK_MSR_ID(49, "hdmi_vx1_pix_clk"), + CLK_MSR_ID(50, "vid_pll"), + CLK_MSR_ID(51, "enci"), + CLK_MSR_ID(52, "encp"), + CLK_MSR_ID(53, "encl"), + CLK_MSR_ID(54, "vdac"), + CLK_MSR_ID(55, "cdac"), + CLK_MSR_ID(57, "lcd_an_clk_ph2"), + CLK_MSR_ID(58, "lcd_an_clk_ph3"), + CLK_MSR_ID(59, "hdmitx_pixel"), + CLK_MSR_ID(60, "vdin_meas"), + CLK_MSR_ID(61, "vpu"), + CLK_MSR_ID(62, "vpu_clkb"), + CLK_MSR_ID(63, "vpu_clkb_tmp"), + CLK_MSR_ID(64, "vpu_clkc"), + CLK_MSR_ID(65, "vid_lock"), + CLK_MSR_ID(66, "vapb"), + CLK_MSR_ID(67, "ge2d"), + CLK_MSR_ID(70, "mipi_dsi_meas"), + CLK_MSR_ID(71, "mipi_dsi_phy"), + CLK_MSR_ID(72, "mipi_csi_phy"), + CLK_MSR_ID(73, "csi2_adapt"), + CLK_MSR_ID(74, "cts_csi2_data"), + CLK_MSR_ID(75, "mipi_csi_phy_out"), + CLK_MSR_ID(76, "hdmitx_tmds"), + CLK_MSR_ID(77, "hdmitx_sys"), + CLK_MSR_ID(78, "hdmitx_fe"), + CLK_MSR_ID(79, "rama_clk"), + CLK_MSR_ID(80, "hdmitx_prif"), + CLK_MSR_ID(81, "hdmitx_200m"), + CLK_MSR_ID(82, "hdmitx_aud"), + CLK_MSR_ID(84, "audio_tohdmitx_mclk"), + CLK_MSR_ID(85, "audio_tohdmitx_bclk"), + CLK_MSR_ID(86, "audio_tohdmitx_lrclk"), + CLK_MSR_ID(87, "audio_tohdmitx_spdif_clk"), + CLK_MSR_ID(88, "htx_aes_clk"), + CLK_MSR_ID(89, "amfc"), + CLK_MSR_ID(93, "vdec"), + CLK_MSR_ID(99, "hevcf"), + CLK_MSR_ID(106, "deskew_pll_clk_div32_out"), + CLK_MSR_ID(108, "cmpr"), + CLK_MSR_ID(109, "dewarpa"), + CLK_MSR_ID(110, "sc"), + CLK_MSR_ID(111, "sar_adc"), + CLK_MSR_ID(113, "sd_emmc_c"), + CLK_MSR_ID(114, "sd_emmc_b"), + CLK_MSR_ID(115, "sd_emmc_a"), + CLK_MSR_ID(116, "gpio_msr_clk"), + CLK_MSR_ID(117, "aux_clk_o"), + CLK_MSR_ID(118, "spicc"), + CLK_MSR_ID(121, "ts"), + CLK_MSR_ID(130, "o_vad_clk"), + CLK_MSR_ID(132, "audio_locker_in_clk"), + CLK_MSR_ID(133, "audio_locker_out_clk"), + CLK_MSR_ID(134, "audio_tdmout_c_sclk"), + CLK_MSR_ID(135, "audio_tdmout_b_sclk"), + CLK_MSR_ID(136, "audio_tdmout_a_sclk"), + CLK_MSR_ID(137, "audio_tdmin_lb_sclk"), + CLK_MSR_ID(138, "audio_tdmin_c_sclk"), + CLK_MSR_ID(139, "audio_tdmin_b_sclk"), + CLK_MSR_ID(140, "audio_tdmin_a_sclk"), + CLK_MSR_ID(141, "audio_resamplea_clk"), + CLK_MSR_ID(142, "audio_pdm_sysclk"), + CLK_MSR_ID(143, "audio_spdifout_b_mst_clk"), + CLK_MSR_ID(144, "audio_spdifout_mst_clk"), + CLK_MSR_ID(145, "audio_spdifin_mst_clk"), + CLK_MSR_ID(147, "audio_resampleb_clk"), + CLK_MSR_ID(148, "pcie_pipe_clk"), + CLK_MSR_ID(149, "pcie_ref_clk"), + CLK_MSR_ID(150, "pcie_upcrx_cdrclk"), + CLK_MSR_ID(151, "pcie_upcrx_clk_sync_b20"), + CLK_MSR_ID(152, "pcie_u3p2pll1_clk_div16"), + CLK_MSR_ID(153, "pcie_u3p2pll0_clkout"), + CLK_MSR_ID(154, "pcie_ref_clk_p"), + CLK_MSR_ID(160, "pwm_j"), + CLK_MSR_ID(161, "pwm_i"), + CLK_MSR_ID(162, "pwm_h"), + CLK_MSR_ID(163, "pwm_g"), + CLK_MSR_ID(164, "pwm_f"), + CLK_MSR_ID(165, "pwm_e"), + CLK_MSR_ID(166, "pwm_d"), + CLK_MSR_ID(167, "pwm_c"), + CLK_MSR_ID(168, "pwm_b"), + CLK_MSR_ID(169, "pwm_a"), + CLK_MSR_ID(175, "rng_ring_clk[0]"), + CLK_MSR_ID(176, "rng_ring_clk[1]"), + CLK_MSR_ID(177, "rng_ring_clk[2]"), + CLK_MSR_ID(178, "rng_ring_clk[3]"), + CLK_MSR_ID(179, "rng_ring_clk[4]"), + CLK_MSR_ID(180, "am_ring_osc_clk_out[0]"), + CLK_MSR_ID(181, "am_ring_osc_clk_out[1]"), + CLK_MSR_ID(182, "am_ring_osc_clk_out[2]"), + CLK_MSR_ID(183, "am_ring_osc_clk_out[3]"), + CLK_MSR_ID(184, "am_ring_osc_clk_out[4]"), + CLK_MSR_ID(185, "am_ring_osc_clk_out[5]"), + CLK_MSR_ID(186, "am_ring_osc_clk_out[6]"), + CLK_MSR_ID(187, "am_ring_osc_clk_out[7]"), + CLK_MSR_ID(188, "am_ring_osc_clk_out[8]"), + CLK_MSR_ID(189, "am_ring_osc_clk_out[9]"), + CLK_MSR_ID(190, "am_ring_osc_clk_out[10]"), + CLK_MSR_ID(191, "am_ring_osc_clk_out[11]"), + CLK_MSR_ID(192, "am_ring_osc_clk_out[12]"), + CLK_MSR_ID(193, "am_ring_osc_clk_out[13]"), + CLK_MSR_ID(194, "am_ring_osc_clk_out[14]"), + CLK_MSR_ID(195, "am_ring_osc_clk_out[15]"), + CLK_MSR_ID(196, "am_ring_osc_clk_out[16]"), + CLK_MSR_ID(197, "nna"), + CLK_MSR_ID(198, "vc9000e_axi"), + CLK_MSR_ID(199, "vc9000e_core"), + CLK_MSR_ID(201, "pcie_tl"), + CLK_MSR_ID(204, "u3p2pll1_clk_div16"), + CLK_MSR_ID(205, "u3p2pll0_clkout"), + CLK_MSR_ID(206, "upctx_clk_sync_b20"), + CLK_MSR_ID(207, "upcrx_carclk"), + CLK_MSR_ID(208, "usb_pipe_clk"), + CLK_MSR_ID(209, "earcrx_pll_out"), + CLK_MSR_ID(210, "mclk_pll_clk") +}; + +static const struct meson_msr_id clk_msr_s7[] = { + CLK_MSR_ID(0, "sys_clk"), + CLK_MSR_ID(1, "axi_clk"), + CLK_MSR_ID(2, "rtc_clk"), + CLK_MSR_ID(5, "mali"), + CLK_MSR_ID(6, "cpu_clk_div16"), + CLK_MSR_ID(8, "cecb"), + CLK_MSR_ID(10, "fclk_div5"), + CLK_MSR_ID(11, "p21_usb2_ckout"), + CLK_MSR_ID(12, "p20_usb2_ckout"), + CLK_MSR_ID(13, "eth_mpll_test"), + CLK_MSR_ID(15, "fclk_50m"), + CLK_MSR_ID(18, "gp1_pll"), + CLK_MSR_ID(19, "hifi_pll"), + CLK_MSR_ID(20, "gp0_pll"), + CLK_MSR_ID(21, "hifi1_pll"), + CLK_MSR_ID(22, "eth_mppll_50m_ckout"), + CLK_MSR_ID(23, "sys_pll_div16"), + CLK_MSR_ID(24, "ddr_dpll_pt_clk"), + CLK_MSR_ID(25, "mod_Tsin_A_CLK_IN"), + CLK_MSR_ID(32, "eth_125m"), + CLK_MSR_ID(33, "eth_rmii"), + CLK_MSR_ID(34, "co_clkin_to_mac"), + CLK_MSR_ID(36, "co_rx_clk"), + CLK_MSR_ID(37, "co_tx_clk"), + CLK_MSR_ID(38, "eth_phy_rxclk"), + CLK_MSR_ID(39, "eth_phy_plltxclk"), + CLK_MSR_ID(40, "ephy_test_clk"), + CLK_MSR_ID(49, "hdmi_vx1_pix_clk"), + CLK_MSR_ID(50, "vid_pll"), + CLK_MSR_ID(51, "enci"), + CLK_MSR_ID(52, "encp"), + CLK_MSR_ID(53, "encl"), + CLK_MSR_ID(54, "vdac"), + CLK_MSR_ID(55, "cdac"), + CLK_MSR_ID(57, "lcd_an_clk_ph2"), + CLK_MSR_ID(58, "lcd_an_clk_ph3"), + CLK_MSR_ID(59, "hdmitx_pixel"), + CLK_MSR_ID(60, "vdin_meas"), + CLK_MSR_ID(61, "vpu"), + CLK_MSR_ID(62, "vpu_clkb"), + CLK_MSR_ID(63, "vpu_clkb_tmp"), + CLK_MSR_ID(64, "vpu_clkc"), + CLK_MSR_ID(65, "vid_lock"), + CLK_MSR_ID(66, "vapb"), + CLK_MSR_ID(67, "ge2d"), + CLK_MSR_ID(76, "hdmitx_tmds"), + CLK_MSR_ID(77, "hdmitx_sys"), + CLK_MSR_ID(78, "hdmitx_fe"), + CLK_MSR_ID(80, "hdmitx_prif"), + CLK_MSR_ID(81, "hdmitx_200m"), + CLK_MSR_ID(82, "hdmitx_aud"), + CLK_MSR_ID(84, "audio_tohdmitx_mclk"), + CLK_MSR_ID(85, "audio_tohdmitx_bclk"), + CLK_MSR_ID(86, "audio_tohdmitx_lrclk"), + CLK_MSR_ID(87, "audio_tohdmitx_spdif_clk"), + CLK_MSR_ID(88, "htx_aes_clk"), + CLK_MSR_ID(93, "vdec"), + CLK_MSR_ID(99, "hevcf"), + CLK_MSR_ID(106, "deskew_pll_clk_div32_out"), + CLK_MSR_ID(110, "sc"), + CLK_MSR_ID(111, "sar_adc"), + CLK_MSR_ID(113, "sd_emmc_c"), + CLK_MSR_ID(114, "sd_emmc_b"), + CLK_MSR_ID(115, "sd_emmc_a"), + CLK_MSR_ID(116, "gpio_msr_clk"), + CLK_MSR_ID(118, "spicc"), + CLK_MSR_ID(121, "ts"), + CLK_MSR_ID(130, "o_vad_clk"), + CLK_MSR_ID(131, "au_dac_clk_x128"), + CLK_MSR_ID(132, "audio_locker_in_clk"), + CLK_MSR_ID(133, "audio_locker_out_clk"), + CLK_MSR_ID(134, "audio_tdmout_c_sclk"), + CLK_MSR_ID(135, "audio_tdmout_b_sclk"), + CLK_MSR_ID(136, "audio_tdmout_a_sclk"), + CLK_MSR_ID(137, "audio_tdmin_lb_sclk"), + CLK_MSR_ID(138, "audio_tdmin_c_sclk"), + CLK_MSR_ID(139, "audio_tdmin_b_sclk"), + CLK_MSR_ID(140, "audio_tdmin_a_sclk"), + CLK_MSR_ID(141, "audio_resamplea_clk"), + CLK_MSR_ID(142, "audio_pdm_sysclk"), + CLK_MSR_ID(143, "audio_spdifout_b_mst_clk"), + CLK_MSR_ID(144, "audio_spdifout_mst_clk"), + CLK_MSR_ID(145, "audio_spdifin_mst_clk"), + CLK_MSR_ID(147, "audio_resampleb_clk"), + CLK_MSR_ID(160, "pwm_j"), + CLK_MSR_ID(161, "pwm_i"), + CLK_MSR_ID(162, "pwm_h"), + CLK_MSR_ID(163, "pwm_g"), + CLK_MSR_ID(164, "pwm_f"), + CLK_MSR_ID(165, "pwm_e"), + CLK_MSR_ID(166, "pwm_d"), + CLK_MSR_ID(167, "pwm_c"), + CLK_MSR_ID(168, "pwm_b"), + CLK_MSR_ID(169, "pwm_a"), + CLK_MSR_ID(176, "rng_ring_clk[0]"), + CLK_MSR_ID(177, "rng_ring_clk[1]"), + CLK_MSR_ID(178, "rng_ring_clk[2]"), + CLK_MSR_ID(179, "rng_ring_clk[3]"), + CLK_MSR_ID(180, "osc_ring_clk[0](a55 core0 14_slvt)"), + CLK_MSR_ID(181, "osc_ring_clk[1](a55 core1 14_slvt)"), + CLK_MSR_ID(182, "osc_ring_clk[2](a55 core2 14_slvt)"), + CLK_MSR_ID(183, "osc_ring_clk[3](a55 core3 14_slvt)"), + CLK_MSR_ID(184, "osc_ring_clk[4](a55_pwr[0] 16_slvt)"), + CLK_MSR_ID(185, "osc_ring_clk[5](a55_pwr[1] 14_lvt)"), + CLK_MSR_ID(186, "osc_ring_clk[6](a55_pwr[2] 14_rvt)"), + CLK_MSR_ID(187, "osc_ring_clk[7](mali[1] 14_lvt)"), + CLK_MSR_ID(188, "osc_ring_clk[8](mali[1] 14_rvt)"), + CLK_MSR_ID(189, "osc_ring_clk[9](dos[0] 16_lvt)"), + CLK_MSR_ID(190, "osc_ring_clk[10](dos[1] 14_rvt)"), + CLK_MSR_ID(191, "osc_ring_clk[11](ddr[0] 9t_14_lvt)"), + CLK_MSR_ID(192, "osc_ring_clk[12](top[0] 16_rvt)"), +}; + +static const struct meson_msr_id clk_msr_s7d[] = { + CLK_MSR_ID(0, "sys_clk"), + CLK_MSR_ID(1, "axi_clk"), + CLK_MSR_ID(2, "rtc_clk"), + CLK_MSR_ID(4, "mali_stack"), + CLK_MSR_ID(5, "mali"), + CLK_MSR_ID(6, "cpu_clk_div16"), + CLK_MSR_ID(8, "cecb"), + CLK_MSR_ID(9, "mali_aclkm"), + CLK_MSR_ID(10, "fclk_div5"), + CLK_MSR_ID(11, "p21_usb2_ckout"), + CLK_MSR_ID(12, "p20_usb2_ckout"), + CLK_MSR_ID(13, "eth_mpll_test"), + CLK_MSR_ID(15, "fclk_50m"), + CLK_MSR_ID(18, "gp1_pll"), + CLK_MSR_ID(19, "hifi_pll"), + CLK_MSR_ID(20, "gp0_pll"), + CLK_MSR_ID(21, "hifi1_pll"), + CLK_MSR_ID(22, "eth_mppll_50m_ckout"), + CLK_MSR_ID(23, "sys_pll_div16"), + CLK_MSR_ID(24, "ddr_dpll_pt_clk"), + CLK_MSR_ID(25, "mod_Tsin_A_CLK_IN"), + CLK_MSR_ID(26, "mod_Tsin_B_CLK_IN"), + CLK_MSR_ID(31, "earcrx_pll_clk_out"), + CLK_MSR_ID(32, "eth_125m"), + CLK_MSR_ID(33, "eth_rmii"), + CLK_MSR_ID(34, "co_clkin_to_mac"), + CLK_MSR_ID(36, "co_rx_clk"), + CLK_MSR_ID(37, "co_tx_clk"), + CLK_MSR_ID(38, "eth_phy_rxclk"), + CLK_MSR_ID(39, "eth_phy_plltxclk"), + CLK_MSR_ID(40, "ephy_test_clk"), + CLK_MSR_ID(49, "hdmi_vx1_pix_clk"), + CLK_MSR_ID(50, "vid_pll"), + CLK_MSR_ID(51, "enci"), + CLK_MSR_ID(52, "encp"), + CLK_MSR_ID(53, "encl"), + CLK_MSR_ID(54, "vdac"), + CLK_MSR_ID(55, "cdac"), + CLK_MSR_ID(57, "lcd_an_clk_ph2"), + CLK_MSR_ID(58, "lcd_an_clk_ph3"), + CLK_MSR_ID(59, "hdmitx_pixel"), + CLK_MSR_ID(60, "vdin_meas"), + CLK_MSR_ID(61, "vpu"), + CLK_MSR_ID(62, "vpu_clkb"), + CLK_MSR_ID(63, "vpu_clkb_tmp"), + CLK_MSR_ID(64, "vpu_clkc"), + CLK_MSR_ID(65, "vid_lock"), + CLK_MSR_ID(66, "vapb"), + CLK_MSR_ID(67, "ge2d"), + CLK_MSR_ID(76, "hdmitx_tmds"), + CLK_MSR_ID(77, "hdmitx_sys"), + CLK_MSR_ID(78, "hdmitx_fe"), + CLK_MSR_ID(80, "hdmitx_prif"), + CLK_MSR_ID(81, "hdmitx_200m"), + CLK_MSR_ID(82, "hdmitx_aud"), + CLK_MSR_ID(84, "audio_tohdmitx_mclk"), + CLK_MSR_ID(85, "audio_tohdmitx_bclk"), + CLK_MSR_ID(86, "audio_tohdmitx_lrclk"), + CLK_MSR_ID(87, "audio_tohdmitx_spdif_clk"), + CLK_MSR_ID(88, "htx_aes_clk"), + CLK_MSR_ID(89, "amfc"), + CLK_MSR_ID(93, "vdec"), + CLK_MSR_ID(97, "hcodec"), + CLK_MSR_ID(99, "hevcf"), + CLK_MSR_ID(106, "deskew_pll_clk_div32_out"), + CLK_MSR_ID(110, "sc"), + CLK_MSR_ID(111, "sar_adc"), + CLK_MSR_ID(112, "aux_adc_clk_to_gpio"), + CLK_MSR_ID(113, "sd_emmc_c"), + CLK_MSR_ID(114, "sd_emmc_b"), + CLK_MSR_ID(115, "sd_emmc_a"), + CLK_MSR_ID(116, "gpio_msr_clk"), + CLK_MSR_ID(117, "aux_clk_o"), + CLK_MSR_ID(118, "spicc"), + CLK_MSR_ID(121, "ts"), + CLK_MSR_ID(130, "o_vad_clk"), + CLK_MSR_ID(131, "au_dac_clk_x128"), + CLK_MSR_ID(132, "audio_locker_in_clk"), + CLK_MSR_ID(133, "audio_locker_out_clk"), + CLK_MSR_ID(134, "audio_tdmout_c_sclk"), + CLK_MSR_ID(135, "audio_tdmout_b_sclk"), + CLK_MSR_ID(136, "audio_tdmout_a_sclk"), + CLK_MSR_ID(137, "audio_tdmin_lb_sclk"), + CLK_MSR_ID(138, "audio_tdmin_c_sclk"), + CLK_MSR_ID(139, "audio_tdmin_b_sclk"), + CLK_MSR_ID(140, "audio_tdmin_a_sclk"), + CLK_MSR_ID(141, "audio_resamplea_clk"), + CLK_MSR_ID(142, "audio_pdm_sysclk"), + CLK_MSR_ID(143, "audio_spdifout_b_mst_clk"), + CLK_MSR_ID(144, "audio_spdifout_mst_clk"), + CLK_MSR_ID(145, "audio_spdifin_mst_clk"), + CLK_MSR_ID(146, "mod_audio_pdm_dclk_o"), + CLK_MSR_ID(147, "audio_resampleb_clk"), + CLK_MSR_ID(160, "pwm_j"), + CLK_MSR_ID(161, "pwm_i"), + CLK_MSR_ID(162, "pwm_h"), + CLK_MSR_ID(163, "pwm_g"), + CLK_MSR_ID(164, "pwm_f"), + CLK_MSR_ID(165, "pwm_e"), + CLK_MSR_ID(166, "pwm_d"), + CLK_MSR_ID(167, "pwm_c"), + CLK_MSR_ID(168, "pwm_b"), + CLK_MSR_ID(169, "pwm_a"), + CLK_MSR_ID(176, "rng_ring_clk[0]"), + CLK_MSR_ID(177, "rng_ring_clk[1]"), + CLK_MSR_ID(178, "rng_ring_clk[2]"), + CLK_MSR_ID(179, "rng_ring_clk[3]"), + CLK_MSR_ID(180, "osc_ring_clk[0](a55 core0 14_slvt)"), + CLK_MSR_ID(181, "osc_ring_clk[1](a55 core1 14_slvt)"), + CLK_MSR_ID(182, "osc_ring_clk[2](a55 core2 14_slvt)"), + CLK_MSR_ID(183, "osc_ring_clk[3](a55 core3 14_slvt)"), + CLK_MSR_ID(184, "osc_ring_clk[4](a55_pwr[0] 16_slvt)"), + CLK_MSR_ID(185, "osc_ring_clk[5](a55_pwr[1] 14_lvt)"), + CLK_MSR_ID(186, "osc_ring_clk[6](a55_pwr[2] 14_rvt)"), + CLK_MSR_ID(187, "osc_ring_clk[7](mali[1] 14_lvt)"), + CLK_MSR_ID(188, "osc_ring_clk[8](mali[1] 14_rvt)"), + CLK_MSR_ID(189, "osc_ring_clk[9](dos[0] 16_lvt)"), + CLK_MSR_ID(190, "osc_ring_clk[10](dos[1] 14_rvt)"), + CLK_MSR_ID(191, "osc_ring_clk[11](ddr[0] 9t_14_lvt)"), + CLK_MSR_ID(192, "osc_ring_clk[12](top[0] 16_rvt)"), +}; + static int meson_measure_id(struct meson_msr_id *clk_msr_id, unsigned int duration) { @@ -1279,6 +2116,30 @@ static const struct msr_reg_offset msr_reg_offset_v2 = { .duty_val = 0x18, }; +static const struct meson_msr_data clk_msr_a1_data = { + .msr_table = (void *)clk_msr_a1, + .msr_count = ARRAY_SIZE(clk_msr_a1), + .reg = &msr_reg_offset_v2, +}; + +static const struct meson_msr_data clk_msr_a4_data = { + .msr_table = (void *)clk_msr_a4, + .msr_count = ARRAY_SIZE(clk_msr_a4), + .reg = &msr_reg_offset_v2, +}; + +static const struct meson_msr_data clk_msr_a5_data = { + .msr_table = (void *)clk_msr_a5, + .msr_count = ARRAY_SIZE(clk_msr_a5), + .reg = &msr_reg_offset_v2, +}; + +static const struct meson_msr_data clk_msr_a9_data = { + .msr_table = (void *)clk_msr_a9, + .msr_count = ARRAY_SIZE(clk_msr_a9), + .reg = &msr_reg_offset_v2, +}; + static const struct meson_msr_data clk_msr_c3_data = { .msr_table = (void *)clk_msr_c3, .msr_count = ARRAY_SIZE(clk_msr_c3), @@ -1291,9 +2152,21 @@ static const struct meson_msr_data clk_msr_s4_data = { .reg = &msr_reg_offset_v2, }; -static const struct meson_msr_data clk_msr_a1_data = { - .msr_table = (void *)clk_msr_a1, - .msr_count = ARRAY_SIZE(clk_msr_a1), +static const struct meson_msr_data clk_msr_s6_data = { + .msr_table = (void *)clk_msr_s6, + .msr_count = ARRAY_SIZE(clk_msr_s6), + .reg = &msr_reg_offset_v2, +}; + +static const struct meson_msr_data clk_msr_s7_data = { + .msr_table = (void *)clk_msr_s7, + .msr_count = ARRAY_SIZE(clk_msr_s7), + .reg = &msr_reg_offset_v2, +}; + +static const struct meson_msr_data clk_msr_s7d_data = { + .msr_table = (void *)clk_msr_s7d, + .msr_count = ARRAY_SIZE(clk_msr_s7d), .reg = &msr_reg_offset_v2, }; @@ -1305,16 +2178,24 @@ static const struct meson_msr_data clk_msr_t7_data = { static const struct of_device_id meson_msr_match_table[] = { { - .compatible = "amlogic,meson-gx-clk-measure", - .data = &clk_msr_gx_data, + .compatible = "amlogic,a1-clk-measure", + .data = &clk_msr_a1_data, }, { - .compatible = "amlogic,meson8-clk-measure", - .data = &clk_msr_m8_data, + .compatible = "amlogic,a4-clk-measure", + .data = &clk_msr_a4_data, }, { - .compatible = "amlogic,meson8b-clk-measure", - .data = &clk_msr_m8_data, + .compatible = "amlogic,a5-clk-measure", + .data = &clk_msr_a5_data, + }, + { + .compatible = "amlogic,a9-clk-measure", + .data = &clk_msr_a9_data, + }, + { + .compatible = "amlogic,c3-clk-measure", + .data = &clk_msr_c3_data, }, { .compatible = "amlogic,meson-axg-clk-measure", @@ -1325,20 +2206,36 @@ static const struct of_device_id meson_msr_match_table[] = { .data = &clk_msr_g12a_data, }, { + .compatible = "amlogic,meson-gx-clk-measure", + .data = &clk_msr_gx_data, + }, + { .compatible = "amlogic,meson-sm1-clk-measure", .data = &clk_msr_sm1_data, }, { - .compatible = "amlogic,c3-clk-measure", - .data = &clk_msr_c3_data, + .compatible = "amlogic,meson8-clk-measure", + .data = &clk_msr_m8_data, + }, + { + .compatible = "amlogic,meson8b-clk-measure", + .data = &clk_msr_m8_data, }, { .compatible = "amlogic,s4-clk-measure", .data = &clk_msr_s4_data, }, { - .compatible = "amlogic,a1-clk-measure", - .data = &clk_msr_a1_data, + .compatible = "amlogic,s6-clk-measure", + .data = &clk_msr_s6_data, + }, + { + .compatible = "amlogic,s7-clk-measure", + .data = &clk_msr_s7_data, + }, + { + .compatible = "amlogic,s7d-clk-measure", + .data = &clk_msr_s7d_data, }, { .compatible = "amlogic,t7-clk-measure",
diff --git a/drivers/soc/apple/rtkit-crashlog.c b/drivers/soc/apple/rtkit-crashlog.c index 8319e36..195b786 100644 --- a/drivers/soc/apple/rtkit-crashlog.c +++ b/drivers/soc/apple/rtkit-crashlog.c
@@ -13,7 +13,8 @@ #define APPLE_RTKIT_CRASHLOG_VERSION FOURCC('C', 'v', 'e', 'r') #define APPLE_RTKIT_CRASHLOG_MBOX FOURCC('C', 'm', 'b', 'x') #define APPLE_RTKIT_CRASHLOG_TIME FOURCC('C', 't', 'i', 'm') -#define APPLE_RTKIT_CRASHLOG_REGS FOURCC('C', 'r', 'g', '8') +#define APPLE_RTKIT_CRASHLOG_AARCH32 FOURCC('C', 'r', 'g', 'A') +#define APPLE_RTKIT_CRASHLOG_AARCH64 FOURCC('C', 'r', 'g', '8') /* For COMPILE_TEST on non-ARM64 architectures */ #ifndef PSR_MODE_EL0t @@ -25,6 +26,21 @@ #define PSR_MODE_MASK 0x0000000f #endif +/* + * AArch32 mode definitions: APPLE_RTKIT depends on APPLE_MAILBOX, which + * depends on 64BIT, so there is no need to care about COMPILE_TEST on ARM. + */ +#define USR_MODE 0x00000010 +#define FIQ_MODE 0x00000011 +#define IRQ_MODE 0x00000012 +#define SVC_MODE 0x00000013 +#define MON_MODE 0x00000016 +#define ABT_MODE 0x00000017 +#define HYP_MODE 0x0000001a +#define UND_MODE 0x0000001b +#define SYSTEM_MODE 0x0000001f +#define MODE_MASK_32 0x0000001f + struct apple_rtkit_crashlog_header { u32 fourcc; u32 version; @@ -42,7 +58,7 @@ struct apple_rtkit_crashlog_mbox_entry { }; static_assert(sizeof(struct apple_rtkit_crashlog_mbox_entry) == 0x18); -struct apple_rtkit_crashlog_regs { +struct apple_rtkit_crashlog_aarch64 { u32 unk_0; u32 unk_4; u64 regs[31]; @@ -58,7 +74,21 @@ struct apple_rtkit_crashlog_regs { u64 esr; u64 unk_Z; } __packed; -static_assert(sizeof(struct apple_rtkit_crashlog_regs) == 0x350); +static_assert(sizeof(struct apple_rtkit_crashlog_aarch64) == 0x350); + +struct apple_rtkit_crashlog_aarch32 { + u32 unk_0; + u32 unk_4; + u32 regs[16]; + u32 psr; + u32 unk_x1; + u8 stack[0x100]; + u32 unk_x2; + u32 unk_x3; + u32 unk_x4; + u32 unk_x5; +} __packed; +static_assert(sizeof(struct apple_rtkit_crashlog_aarch32) == 0x160); static void apple_rtkit_crashlog_dump_str(struct apple_rtkit *rtk, u8 *bfr, size_t size) @@ -123,21 +153,84 @@ static void apple_rtkit_crashlog_dump_mailbox(struct apple_rtkit *rtk, u8 *bfr, } } -static void apple_rtkit_crashlog_dump_regs(struct apple_rtkit *rtk, u8 *bfr, - size_t size) +static void apple_rtkit_crashlog_dump_aarch32(struct apple_rtkit *rtk, u8 *bfr, + size_t size) { - struct apple_rtkit_crashlog_regs *regs; - const char *el; + struct apple_rtkit_crashlog_aarch32 *state; + const char *mode; int i; - if (size < sizeof(*regs)) { - dev_warn(rtk->dev, "RTKit: Regs section too small: 0x%zx", size); + if (size < sizeof(*state)) { + dev_warn(rtk->dev, "RTKit: AArch32 section too small: 0x%zx", size); return; } - regs = (struct apple_rtkit_crashlog_regs *)bfr; + state = (struct apple_rtkit_crashlog_aarch32 *)bfr; - switch (regs->psr & PSR_MODE_MASK) { + switch (state->psr & MODE_MASK_32) { + case USR_MODE: + mode = "User"; + break; + case FIQ_MODE: + mode = "FIQ"; + break; + case IRQ_MODE: + mode = "IRQ"; + break; + case SVC_MODE: + mode = "Supervisor"; + break; + case MON_MODE: + mode = "Monitor"; + break; + case ABT_MODE: + mode = "Abort"; + break; + case HYP_MODE: + mode = "Hypervisor"; + break; + case UND_MODE: + mode = "Undefined"; + break; + case SYSTEM_MODE: + mode = "System"; + break; + default: + mode = "Unknown"; + break; + } + + dev_warn(rtk->dev, "RTKit: Exception dump:"); + dev_warn(rtk->dev, " == Exception taken from %s mode ==", mode); + dev_warn(rtk->dev, " PSR = 0x%x", state->psr); + dev_warn(rtk->dev, "\n"); + + for (i = 0; i < 16; i += 4) + dev_warn(rtk->dev, + " r%02d-r%02d = %08x %08x %08x %08x\n", + i, i + 3, + state->regs[i], state->regs[i + 1], + state->regs[i + 2], state->regs[i + 3]); + + dev_warn(rtk->dev, "\n"); +} + +static void apple_rtkit_crashlog_dump_aarch64(struct apple_rtkit *rtk, u8 *bfr, + size_t size) +{ + struct apple_rtkit_crashlog_aarch64 *state; + const char *el; + int i; + + if (size < sizeof(*state)) { + dev_warn(rtk->dev, "RTKit: AArch64 section too small: 0x%zx", + size); + return; + } + + state = (struct apple_rtkit_crashlog_aarch64 *)bfr; + + switch (state->psr & PSR_MODE_MASK) { case PSR_MODE_EL0t: el = "EL0t"; break; @@ -160,11 +253,11 @@ static void apple_rtkit_crashlog_dump_regs(struct apple_rtkit *rtk, u8 *bfr, dev_warn(rtk->dev, "RTKit: Exception dump:"); dev_warn(rtk->dev, " == Exception taken from %s ==", el); - dev_warn(rtk->dev, " PSR = 0x%llx", regs->psr); - dev_warn(rtk->dev, " PC = 0x%llx\n", regs->pc); - dev_warn(rtk->dev, " ESR = 0x%llx\n", regs->esr); - dev_warn(rtk->dev, " FAR = 0x%llx\n", regs->far); - dev_warn(rtk->dev, " SP = 0x%llx\n", regs->sp); + dev_warn(rtk->dev, " PSR = 0x%llx", state->psr); + dev_warn(rtk->dev, " PC = 0x%llx\n", state->pc); + dev_warn(rtk->dev, " ESR = 0x%llx\n", state->esr); + dev_warn(rtk->dev, " FAR = 0x%llx\n", state->far); + dev_warn(rtk->dev, " SP = 0x%llx\n", state->sp); dev_warn(rtk->dev, "\n"); for (i = 0; i < 31; i += 4) { @@ -172,12 +265,12 @@ static void apple_rtkit_crashlog_dump_regs(struct apple_rtkit *rtk, u8 *bfr, dev_warn(rtk->dev, " x%02d-x%02d = %016llx %016llx %016llx %016llx\n", i, i + 3, - regs->regs[i], regs->regs[i + 1], - regs->regs[i + 2], regs->regs[i + 3]); + state->regs[i], state->regs[i + 1], + state->regs[i + 2], state->regs[i + 3]); else dev_warn(rtk->dev, " x%02d-x%02d = %016llx %016llx %016llx\n", i, i + 3, - regs->regs[i], regs->regs[i + 1], regs->regs[i + 2]); + state->regs[i], state->regs[i + 1], state->regs[i + 2]); } dev_warn(rtk->dev, "\n"); @@ -229,9 +322,13 @@ void apple_rtkit_crashlog_dump(struct apple_rtkit *rtk, u8 *bfr, size_t size) apple_rtkit_crashlog_dump_time(rtk, bfr + offset + 16, section_size); break; - case APPLE_RTKIT_CRASHLOG_REGS: - apple_rtkit_crashlog_dump_regs(rtk, bfr + offset + 16, - section_size); + case APPLE_RTKIT_CRASHLOG_AARCH32: + apple_rtkit_crashlog_dump_aarch32(rtk, bfr + offset + 16, + section_size); + break; + case APPLE_RTKIT_CRASHLOG_AARCH64: + apple_rtkit_crashlog_dump_aarch64(rtk, bfr + offset + 16, + section_size); break; default: dev_warn(rtk->dev,
diff --git a/drivers/soc/atmel/soc.c b/drivers/soc/atmel/soc.c index d89f9dc..7e60c56 100644 --- a/drivers/soc/atmel/soc.c +++ b/drivers/soc/atmel/soc.c
@@ -404,9 +404,7 @@ static const struct of_device_id at91_soc_allowed_list[] __initconst = { static int __init atmel_soc_device_init(void) { - struct device_node *np __free(device_node) = of_find_node_by_path("/"); - - if (!of_match_node(at91_soc_allowed_list, np)) + if (!of_machine_device_match(at91_soc_allowed_list)) return 0; at91_soc_init(socs);
diff --git a/drivers/soc/fsl/dpio/dpio-driver.c b/drivers/soc/fsl/dpio/dpio-driver.c index d5198ff..d8f28fb 100644 --- a/drivers/soc/fsl/dpio/dpio-driver.c +++ b/drivers/soc/fsl/dpio/dpio-driver.c
@@ -88,6 +88,7 @@ static void unregister_dpio_irq_handlers(struct fsl_mc_device *dpio_dev) /* clear the affinity hint */ irq_set_affinity_hint(irq->virq, NULL); + devm_free_irq(&dpio_dev->dev, irq->virq, &dpio_dev->dev); } static int register_dpio_irq_handlers(struct fsl_mc_device *dpio_dev, int cpu) @@ -244,9 +245,9 @@ static int dpaa2_dpio_probe(struct fsl_mc_device *dpio_dev) return 0; -err_dpaa2_io_create: - unregister_dpio_irq_handlers(dpio_dev); err_register_dpio_irq: + dpaa2_io_down(priv->io); +err_dpaa2_io_create: fsl_mc_free_irqs(dpio_dev); err_allocate_irqs: dpio_disable(dpio_dev->mc_io, 0, dpio_dev->mc_handle); @@ -276,10 +277,10 @@ static void dpaa2_dpio_remove(struct fsl_mc_device *dpio_dev) priv = dev_get_drvdata(dev); cpu = dpaa2_io_get_cpu(priv->io); - dpaa2_io_down(priv->io); - dpio_teardown_irqs(dpio_dev); + dpaa2_io_down(priv->io); + cpumask_set_cpu(cpu, cpus_unused_mask); err = dpio_open(dpio_dev->mc_io, 0, dpio_dev->obj_desc.id,
diff --git a/drivers/soc/fsl/qe/gpio.c b/drivers/soc/fsl/qe/gpio.c index 5cd59cf..1b5a1b1 100644 --- a/drivers/soc/fsl/qe/gpio.c +++ b/drivers/soc/fsl/qe/gpio.c
@@ -32,8 +32,13 @@ struct qe_gpio_chip { /* shadowed data register to clear/set bits safely */ u32 cpdata; - /* saved_regs used to restore dedicated functions */ - struct qe_pio_regs saved_regs; + /* saved regs used to restore dedicated functions */ + u32 saved_cpodr; + u32 saved_cpdata; + u32 saved_cpdir1; + u32 saved_cpdir2; + u32 saved_cppar1; + u32 saved_cppar2; }; static void qe_gpio_save_regs(struct qe_gpio_chip *qe_gc) @@ -41,12 +46,12 @@ static void qe_gpio_save_regs(struct qe_gpio_chip *qe_gc) struct qe_pio_regs __iomem *regs = qe_gc->regs; qe_gc->cpdata = ioread32be(®s->cpdata); - qe_gc->saved_regs.cpdata = qe_gc->cpdata; - qe_gc->saved_regs.cpdir1 = ioread32be(®s->cpdir1); - qe_gc->saved_regs.cpdir2 = ioread32be(®s->cpdir2); - qe_gc->saved_regs.cppar1 = ioread32be(®s->cppar1); - qe_gc->saved_regs.cppar2 = ioread32be(®s->cppar2); - qe_gc->saved_regs.cpodr = ioread32be(®s->cpodr); + qe_gc->saved_cpdata = qe_gc->cpdata; + qe_gc->saved_cpdir1 = ioread32be(®s->cpdir1); + qe_gc->saved_cpdir2 = ioread32be(®s->cpdir2); + qe_gc->saved_cppar1 = ioread32be(®s->cppar1); + qe_gc->saved_cppar2 = ioread32be(®s->cppar2); + qe_gc->saved_cpodr = ioread32be(®s->cpodr); } static int qe_gpio_get(struct gpio_chip *gc, unsigned int gpio) @@ -196,18 +201,17 @@ struct qe_pin { /** * qe_pin_request - Request a QE pin * @dev: device to get the pin from - * @index: index of the pin in the device tree + * @gpiod: GPIO descriptor associated with this pin * Context: non-atomic * * This function return qe_pin so that you could use it with the rest of * the QE Pin Multiplexing API. */ -struct qe_pin *qe_pin_request(struct device *dev, int index) +struct qe_pin *qe_pin_request(struct device *dev, struct gpio_desc *gpiod) { + struct gpio_device *gdev; struct qe_pin *qe_pin; struct gpio_chip *gc; - struct gpio_desc *gpiod; - int gpio_num; int err; qe_pin = kzalloc_obj(*qe_pin); @@ -216,34 +220,20 @@ struct qe_pin *qe_pin_request(struct device *dev, int index) return ERR_PTR(-ENOMEM); } - /* - * Request gpio as nonexclusive as it was likely reserved by the - * caller, and we are not planning on controlling it, we only need - * the descriptor to the to the gpio chip structure. - */ - gpiod = gpiod_get_index(dev, NULL, index, - GPIOD_ASIS | GPIOD_FLAGS_BIT_NONEXCLUSIVE); - err = PTR_ERR_OR_ZERO(gpiod); - if (err) - goto err0; - - gc = gpiod_to_chip(gpiod); - gpio_num = desc_to_gpio(gpiod); - /* We no longer need this descriptor */ - gpiod_put(gpiod); - - if (WARN_ON(!gc)) { + gdev = gpiod_to_gpio_device(gpiod); + if (WARN_ON(!gdev)) { err = -ENODEV; goto err0; } + gc = gpio_device_get_chip(gdev); qe_pin->controller = gpiochip_get_data(gc); /* * FIXME: this gets the local offset on the gpio_chip so that the driver * can manipulate pin control settings through its custom API. The real * solution is to create a real pin control driver for this. */ - qe_pin->num = gpio_num - gc->base; + qe_pin->num = desc_to_gpio(gpiod) - gc->base; if (!fwnode_device_is_compatible(gc->fwnode, "fsl,mpc8323-qe-pario-bank")) { dev_dbg(dev, "%s: tried to get a non-qe pin\n", __func__); @@ -284,7 +274,6 @@ void qe_pin_set_dedicated(struct qe_pin *qe_pin) { struct qe_gpio_chip *qe_gc = qe_pin->controller; struct qe_pio_regs __iomem *regs = qe_gc->regs; - struct qe_pio_regs *sregs = &qe_gc->saved_regs; int pin = qe_pin->num; u32 mask1 = 1 << (QE_PIO_PINS - (pin + 1)); u32 mask2 = 0x3 << (QE_PIO_PINS - (pin % (QE_PIO_PINS / 2) + 1) * 2); @@ -294,24 +283,20 @@ void qe_pin_set_dedicated(struct qe_pin *qe_pin) spin_lock_irqsave(&qe_gc->lock, flags); if (second_reg) { - qe_clrsetbits_be32(®s->cpdir2, mask2, - sregs->cpdir2 & mask2); - qe_clrsetbits_be32(®s->cppar2, mask2, - sregs->cppar2 & mask2); + qe_clrsetbits_be32(®s->cpdir2, mask2, qe_gc->saved_cpdir2 & mask2); + qe_clrsetbits_be32(®s->cppar2, mask2, qe_gc->saved_cppar2 & mask2); } else { - qe_clrsetbits_be32(®s->cpdir1, mask2, - sregs->cpdir1 & mask2); - qe_clrsetbits_be32(®s->cppar1, mask2, - sregs->cppar1 & mask2); + qe_clrsetbits_be32(®s->cpdir1, mask2, qe_gc->saved_cpdir1 & mask2); + qe_clrsetbits_be32(®s->cppar1, mask2, qe_gc->saved_cppar1 & mask2); } - if (sregs->cpdata & mask1) + if (qe_gc->saved_cpdata & mask1) qe_gc->cpdata |= mask1; else qe_gc->cpdata &= ~mask1; iowrite32be(qe_gc->cpdata, ®s->cpdata); - qe_clrsetbits_be32(®s->cpodr, mask1, sregs->cpodr & mask1); + qe_clrsetbits_be32(®s->cpodr, mask1, qe_gc->saved_cpodr & mask1); spin_unlock_irqrestore(&qe_gc->lock, flags); } EXPORT_SYMBOL(qe_pin_set_dedicated);
diff --git a/drivers/soc/fsl/qe/tsa.c b/drivers/soc/fsl/qe/tsa.c index 4a88e54..502e2ff 100644 --- a/drivers/soc/fsl/qe/tsa.c +++ b/drivers/soc/fsl/qe/tsa.c
@@ -865,12 +865,12 @@ static int tsa_of_parse_tdms(struct tsa *tsa, struct device_node *np) clk_put(tsa->tdm[i].l1rclk_clk); } if (tsa->tdm[i].l1tsync_clk) { - clk_disable_unprepare(tsa->tdm[i].l1rsync_clk); - clk_put(tsa->tdm[i].l1rsync_clk); + clk_disable_unprepare(tsa->tdm[i].l1tsync_clk); + clk_put(tsa->tdm[i].l1tsync_clk); } if (tsa->tdm[i].l1tclk_clk) { - clk_disable_unprepare(tsa->tdm[i].l1rclk_clk); - clk_put(tsa->tdm[i].l1rclk_clk); + clk_disable_unprepare(tsa->tdm[i].l1tclk_clk); + clk_put(tsa->tdm[i].l1tclk_clk); } } return ret; @@ -1039,12 +1039,12 @@ static void tsa_remove(struct platform_device *pdev) clk_put(tsa->tdm[i].l1rclk_clk); } if (tsa->tdm[i].l1tsync_clk) { - clk_disable_unprepare(tsa->tdm[i].l1rsync_clk); - clk_put(tsa->tdm[i].l1rsync_clk); + clk_disable_unprepare(tsa->tdm[i].l1tsync_clk); + clk_put(tsa->tdm[i].l1tsync_clk); } if (tsa->tdm[i].l1tclk_clk) { - clk_disable_unprepare(tsa->tdm[i].l1rclk_clk); - clk_put(tsa->tdm[i].l1rclk_clk); + clk_disable_unprepare(tsa->tdm[i].l1tclk_clk); + clk_put(tsa->tdm[i].l1tclk_clk); } } }
diff --git a/drivers/soc/mediatek/mt8167-mmsys.h b/drivers/soc/mediatek/mt8167-mmsys.h index 0013793..858779a 100644 --- a/drivers/soc/mediatek/mt8167-mmsys.h +++ b/drivers/soc/mediatek/mt8167-mmsys.h
@@ -5,35 +5,200 @@ #define MT8167_DISP_REG_CONFIG_DISP_OVL0_MOUT_EN 0x030 #define MT8167_DISP_REG_CONFIG_DISP_DITHER_MOUT_EN 0x038 +#define MT8167_DISP_REG_CONFIG_DISP_UFOE_MOUT_EN 0x03c #define MT8167_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN 0x058 +#define MT8167_DISP_REG_CONFIG_DISP_WDMA0_SEL_IN 0x05c +#define MT8167_DISP_REG_CONFIG_DISP_UFOE_SEL_IN 0x060 #define MT8167_DISP_REG_CONFIG_DISP_DSI0_SEL_IN 0x064 +#define MT8167_DISP_REG_CONFIG_DISP_DPI0_SEL_IN 0x068 #define MT8167_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN 0x06c +#define MT8167_DISP_REG_CONFIG_DISP_RDMA1_SOUT_SEL_IN 0x070 +#define MT8167_DISP_REG_CONFIG_DISP_DPI1_SEL_IN 0x074 + +#define MT8167_OVL0_MOUT_EN_COLOR0 0x1 +#define MT8167_OVL0_MOUT_EN_WDMA0 0x2 +#define MT8167_OVL0_MOUT_EN_MASK 0x3 #define MT8167_DITHER_MOUT_EN_RDMA0 0x1 +#define MT8167_DITHER_MOUT_EN_UFOE 0x2 +#define MT8167_DITHER_MOUT_EN_WDMA0 0x4 #define MT8167_DITHER_MOUT_EN_MASK 0x7 -#define MT8167_RDMA0_SOUT_DSI0 0x2 -#define MT8167_RDMA0_SOUT_MASK 0x3 +#define MT8167_UFOE_MOUT_EN_DSI0 0x1 +#define MT8167_UFOE_MOUT_EN_DPI0 0x2 +/* + * For some reason Android sources and the data sheet don't agree here, + * the data sheet has UFOE_MOUT_EN_WDMA0 as 0x4 and does not mention DPI1. + */ +#define MT8167_UFOE_MOUT_EN_DPI1 0x4 +#define MT8167_UFOE_MOUT_EN_WDMA0 0x8 +#define MT8167_UFOE_MOUT_EN_MASK 0xF +#define MT8167_COLOR0_SEL_IN_RDMA0 0x0 +#define MT8167_COLOR0_SEL_IN_OVL0 0x1 +#define MT8167_COLOR0_SEL_IN_MASK 0x1 + +#define MT8167_WDMA0_SEL_IN_OVL0 0x0 +#define MT8167_WDMA0_SEL_IN_DITHER 0x1 +#define MT8167_WDMA0_SEL_IN_UFOE 0x2 +#define MT8167_WDMA0_SEL_IN_MASK 0x3 + +#define MT8167_UFOE_SEL_IN_RDMA0 0x0 +#define MT8167_UFOE_SEL_IN_DITHER 0x1 +#define MT8167_UFOE_SEL_IN_MASK 0x1 + +#define MT8167_DSI0_SEL_IN_UFOE 0x0 #define MT8167_DSI0_SEL_IN_RDMA0 0x1 +#define MT8167_DSI0_SEL_IN_RDMA1 0x2 #define MT8167_DSI0_SEL_IN_MASK 0x3 +#define MT8167_DPI0_SEL_IN_UFOE 0x0 +#define MT8167_DPI0_SEL_IN_RDMA0 0x1 +#define MT8167_DPI0_SEL_IN_RDMA1 0x2 +#define MT8167_DPI0_SEL_IN_MASK 0x3 + +#define MT8167_DPI1_SEL_IN_UFOE 0x0 +#define MT8167_DPI1_SEL_IN_RDMA0 0x1 +#define MT8167_DPI1_SEL_IN_RDMA1 0x2 +#define MT8167_DPI1_SEL_IN_MASK 0x3 + +#define MT8167_RDMA0_SOUT_UFOE 0x0 +#define MT8167_RDMA0_SOUT_COLOR0 0x1 +#define MT8167_RDMA0_SOUT_DSI0 0x2 +#define MT8167_RDMA0_SOUT_DPI0 0x3 +/* DPI1 is only defined in Android sources, not in the data sheet */ +#define MT8167_RDMA0_SOUT_DPI1 0x4 +#define MT8167_RDMA0_SOUT_MASK 0x7 + +#define MT8167_RDMA1_SOUT_DSI0 0x0 +#define MT8167_RDMA1_SOUT_DPI0 0x1 +/* DPI1 is only defined in Android sources, not in the data sheet */ +#define MT8167_RDMA1_SOUT_DPI1 0x2 +#define MT8167_RDMA1_SOUT_MASK 0x3 + static const struct mtk_mmsys_routes mt8167_mmsys_routing_table[] = { + /* OVL0<->COLOR0 */ MMSYS_ROUTE(OVL, 0, COLOR, 0, - MT8167_DISP_REG_CONFIG_DISP_OVL0_MOUT_EN, OVL0_MOUT_EN_COLOR0, - OVL0_MOUT_EN_COLOR0), + MT8167_DISP_REG_CONFIG_DISP_OVL0_MOUT_EN, MT8167_OVL0_MOUT_EN_MASK, + MT8167_OVL0_MOUT_EN_COLOR0), + MMSYS_ROUTE(OVL, 0, COLOR, 0, + MT8167_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN, MT8167_COLOR0_SEL_IN_MASK, + MT8167_COLOR0_SEL_IN_OVL0), + + /* OVL0<->WDMA0 */ + MMSYS_ROUTE(OVL, 0, WDMA, 0, + MT8167_DISP_REG_CONFIG_DISP_OVL0_MOUT_EN, MT8167_OVL0_MOUT_EN_MASK, + MT8167_OVL0_MOUT_EN_WDMA0), + MMSYS_ROUTE(OVL, 0, WDMA, 0, + MT8167_DISP_REG_CONFIG_DISP_WDMA0_SEL_IN, MT8167_COLOR0_SEL_IN_MASK, + MT8167_WDMA0_SEL_IN_OVL0), + + /* DITHER0 outputs */ MMSYS_ROUTE(DITHER, 0, RDMA, 0, MT8167_DISP_REG_CONFIG_DISP_DITHER_MOUT_EN, MT8167_DITHER_MOUT_EN_MASK, MT8167_DITHER_MOUT_EN_RDMA0), - MMSYS_ROUTE(OVL, 0, COLOR, 0, - MT8167_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN, COLOR0_SEL_IN_OVL0, - COLOR0_SEL_IN_OVL0), - MMSYS_ROUTE(RDMA, 0, DSI, 0, + MMSYS_ROUTE(DITHER, 0, UFOE, 0, + MT8167_DISP_REG_CONFIG_DISP_DITHER_MOUT_EN, MT8167_DITHER_MOUT_EN_MASK, + MT8167_DITHER_MOUT_EN_UFOE), + MMSYS_ROUTE(DITHER, 0, WDMA, 0, + MT8167_DISP_REG_CONFIG_DISP_DITHER_MOUT_EN, MT8167_DITHER_MOUT_EN_MASK, + MT8167_DITHER_MOUT_EN_WDMA0), + + /* UFOE<->DSI0 */ + MMSYS_ROUTE(UFOE, 0, DSI, 0, + MT8167_DISP_REG_CONFIG_DISP_UFOE_MOUT_EN, MT8167_UFOE_MOUT_EN_MASK, + MT8167_UFOE_MOUT_EN_DSI0), + MMSYS_ROUTE(UFOE, 0, DSI, 0, MT8167_DISP_REG_CONFIG_DISP_DSI0_SEL_IN, MT8167_DSI0_SEL_IN_MASK, - MT8167_DSI0_SEL_IN_RDMA0), + MT8167_DSI0_SEL_IN_UFOE), + + /* UFOE<->DPI0 */ + MMSYS_ROUTE(UFOE, 0, DPI, 0, + MT8167_DISP_REG_CONFIG_DISP_UFOE_MOUT_EN, MT8167_UFOE_MOUT_EN_MASK, + MT8167_UFOE_MOUT_EN_DPI0), + MMSYS_ROUTE(UFOE, 0, DPI, 0, + MT8167_DISP_REG_CONFIG_DISP_DPI0_SEL_IN, MT8167_DPI0_SEL_IN_MASK, + MT8167_DPI0_SEL_IN_UFOE), + + /* UFOE<->DPI1 */ + MMSYS_ROUTE(UFOE, 0, DPI, 1, + MT8167_DISP_REG_CONFIG_DISP_UFOE_MOUT_EN, MT8167_UFOE_MOUT_EN_MASK, + MT8167_UFOE_MOUT_EN_DPI1), + MMSYS_ROUTE(UFOE, 0, DPI, 1, + MT8167_DISP_REG_CONFIG_DISP_DPI1_SEL_IN, MT8167_DPI1_SEL_IN_MASK, + MT8167_DPI1_SEL_IN_UFOE), + + /* UFOE<->WDMA0 */ + MMSYS_ROUTE(UFOE, 0, WDMA, 0, + MT8167_DISP_REG_CONFIG_DISP_UFOE_MOUT_EN, MT8167_UFOE_MOUT_EN_MASK, + MT8167_UFOE_MOUT_EN_WDMA0), + MMSYS_ROUTE(UFOE, 0, WDMA, 0, + MT8167_DISP_REG_CONFIG_DISP_WDMA0_SEL_IN, MT8167_WDMA0_SEL_IN_MASK, + MT8167_WDMA0_SEL_IN_UFOE), + + /* RDMA0<->UFOE */ + MMSYS_ROUTE(RDMA, 0, UFOE, 0, + MT8167_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN, MT8167_RDMA0_SOUT_MASK, + MT8167_RDMA0_SOUT_UFOE), + MMSYS_ROUTE(RDMA, 0, UFOE, 0, + MT8167_DISP_REG_CONFIG_DISP_UFOE_SEL_IN, MT8167_UFOE_SEL_IN_MASK, + MT8167_UFOE_SEL_IN_RDMA0), + + /* RDMA0->COLOR0 */ + MMSYS_ROUTE(RDMA, 0, COLOR, 0, + MT8167_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN, MT8167_RDMA0_SOUT_MASK, + MT8167_RDMA0_SOUT_COLOR0), + MMSYS_ROUTE(RDMA, 0, COLOR, 0, + MT8167_DISP_REG_CONFIG_DISP_COLOR0_SEL_IN, MT8167_COLOR0_SEL_IN_MASK, + MT8167_COLOR0_SEL_IN_RDMA0), + + /* RDMA0<->DSI0 */ MMSYS_ROUTE(RDMA, 0, DSI, 0, MT8167_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN, MT8167_RDMA0_SOUT_MASK, MT8167_RDMA0_SOUT_DSI0), + MMSYS_ROUTE(RDMA, 0, DSI, 0, + MT8167_DISP_REG_CONFIG_DISP_DSI0_SEL_IN, MT8167_DSI0_SEL_IN_MASK, + MT8167_DSI0_SEL_IN_RDMA0), + + /* RDMA0<->DPI0 */ + MMSYS_ROUTE(RDMA, 0, DPI, 0, + MT8167_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN, MT8167_RDMA0_SOUT_MASK, + MT8167_RDMA0_SOUT_DPI0), + MMSYS_ROUTE(RDMA, 0, DPI, 0, + MT8167_DISP_REG_CONFIG_DISP_DPI0_SEL_IN, MT8167_DPI0_SEL_IN_MASK, + MT8167_DPI0_SEL_IN_RDMA0), + + /* RDMA0<->DPI1 */ + MMSYS_ROUTE(RDMA, 0, DPI, 1, + MT8167_DISP_REG_CONFIG_DISP_RDMA0_SOUT_SEL_IN, MT8167_RDMA0_SOUT_MASK, + MT8167_RDMA0_SOUT_DPI1), + MMSYS_ROUTE(RDMA, 0, DPI, 1, + MT8167_DISP_REG_CONFIG_DISP_DPI1_SEL_IN, MT8167_DPI1_SEL_IN_MASK, + MT8167_DPI1_SEL_IN_RDMA0), + + /* RDMA1<->DSI0 */ + MMSYS_ROUTE(RDMA, 1, DSI, 0, + MT8167_DISP_REG_CONFIG_DISP_RDMA1_SOUT_SEL_IN, MT8167_RDMA1_SOUT_MASK, + MT8167_RDMA1_SOUT_DSI0), + MMSYS_ROUTE(RDMA, 1, DSI, 0, + MT8167_DISP_REG_CONFIG_DISP_DSI0_SEL_IN, MT8167_DSI0_SEL_IN_MASK, + MT8167_DSI0_SEL_IN_RDMA1), + + /* RDMA1<->DPI0 */ + MMSYS_ROUTE(RDMA, 1, DPI, 0, + MT8167_DISP_REG_CONFIG_DISP_RDMA1_SOUT_SEL_IN, MT8167_RDMA1_SOUT_MASK, + MT8167_RDMA1_SOUT_DPI0), + MMSYS_ROUTE(RDMA, 1, DPI, 0, + MT8167_DISP_REG_CONFIG_DISP_DPI0_SEL_IN, MT8167_DPI0_SEL_IN_MASK, + MT8167_DPI0_SEL_IN_RDMA1), + + /* RDMA1<->DPI1 */ + MMSYS_ROUTE(RDMA, 1, DPI, 1, + MT8167_DISP_REG_CONFIG_DISP_RDMA1_SOUT_SEL_IN, MT8167_RDMA1_SOUT_MASK, + MT8167_RDMA1_SOUT_DPI1), + MMSYS_ROUTE(RDMA, 1, DPI, 1, + MT8167_DISP_REG_CONFIG_DISP_DPI1_SEL_IN, MT8167_DPI1_SEL_IN_MASK, + MT8167_DPI1_SEL_IN_RDMA1), }; #endif /* __SOC_MEDIATEK_MT8167_MMSYS_H */
diff --git a/drivers/soc/mediatek/mtk-regulator-coupler.c b/drivers/soc/mediatek/mtk-regulator-coupler.c index 0b6a288..1109e3d 100644 --- a/drivers/soc/mediatek/mtk-regulator-coupler.c +++ b/drivers/soc/mediatek/mtk-regulator-coupler.c
@@ -148,6 +148,7 @@ static int mediatek_regulator_coupler_init(void) if (!of_machine_is_compatible("mediatek,mt8183") && !of_machine_is_compatible("mediatek,mt8186") && !of_machine_is_compatible("mediatek,mt8188") && + !of_machine_is_compatible("mediatek,mt8189") && !of_machine_is_compatible("mediatek,mt8192")) return 0;
diff --git a/drivers/soc/microchip/mpfs-sys-controller.c b/drivers/soc/microchip/mpfs-sys-controller.c index 0400a01..ef27e10 100644 --- a/drivers/soc/microchip/mpfs-sys-controller.c +++ b/drivers/soc/microchip/mpfs-sys-controller.c
@@ -159,7 +159,7 @@ static int mpfs_sys_controller_probe(struct platform_device *pdev) of_data = (struct mpfs_syscon_config *) device_get_match_data(dev); if (!of_data) { ret = dev_err_probe(dev, -EINVAL, "Error getting match data\n"); - goto out_free_channel; + goto out_put; } for (i = 0; i < of_data->nb_subdevs; i++) { @@ -173,8 +173,9 @@ static int mpfs_sys_controller_probe(struct platform_device *pdev) return 0; -out_free_channel: - mbox_free_channel(sys_controller->chan); +out_put: + mpfs_sys_controller_put(sys_controller); + return ret; out_free: kfree(sys_controller); return ret;
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 2b52415..9f70326 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig
@@ -39,7 +39,6 @@ config QCOM_GENI_SE tristate "Qualcomm GENI Serial Engine Driver" - depends on ARM64 || COMPILE_TEST default ARCH_QCOM help This driver is used to manage Generic Interface (GENI) firmware based
diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c index ea7f839..2d5645f 100644 --- a/drivers/soc/qcom/apr.c +++ b/drivers/soc/qcom/apr.c
@@ -338,29 +338,6 @@ static void apr_rxwq(struct work_struct *work) } } -static int apr_device_match(struct device *dev, const struct device_driver *drv) -{ - struct apr_device *adev = to_apr_device(dev); - const struct apr_driver *adrv = to_apr_driver(drv); - const struct apr_device_id *id = adrv->id_table; - - /* Attempt an OF style match first */ - if (of_driver_match_device(dev, drv)) - return 1; - - if (!id) - return 0; - - while (id->domain_id != 0 || id->svc_id != 0) { - if (id->domain_id == adev->domain_id && - id->svc_id == adev->svc.id) - return 1; - id++; - } - - return 0; -} - static int apr_device_probe(struct device *dev) { struct apr_device *adev = to_apr_device(dev); @@ -401,7 +378,7 @@ static int apr_uevent(const struct device *dev, struct kobj_uevent_env *env) const struct bus_type aprbus = { .name = "aprbus", - .match = apr_device_match, + .match = of_driver_match_device, .probe = apr_device_probe, .uevent = apr_uevent, .remove = apr_device_remove, @@ -434,31 +411,35 @@ static int apr_add_device(struct device *dev, struct device_node *np, if (np) snprintf(adev->name, APR_NAME_SIZE, "%pOFn", np); - switch (apr->type) { - case PR_TYPE_APR: - dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name, - domain_id, svc_id); - break; - case PR_TYPE_GPR: - dev_set_name(&adev->dev, "gprsvc:%s:%x:%x", adev->name, - domain_id, svc_id); - break; - default: - break; - } - adev->dev.bus = &aprbus; adev->dev.parent = dev; adev->dev.of_node = np; adev->dev.release = apr_dev_release; adev->dev.driver = NULL; + device_initialize(&adev->dev); + + switch (apr->type) { + case PR_TYPE_APR: + ret = dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name, + domain_id, svc_id); + break; + case PR_TYPE_GPR: + ret = dev_set_name(&adev->dev, "gprsvc:%s:%x:%x", adev->name, + domain_id, svc_id); + break; + default: + ret = -EINVAL; + break; + } + if (ret) + goto out_put_device; spin_lock(&apr->svcs_lock); ret = idr_alloc(&apr->svcs_idr, svc, svc_id, svc_id + 1, GFP_ATOMIC); spin_unlock(&apr->svcs_lock); if (ret < 0) { dev_err(dev, "idr_alloc failed: %d\n", ret); - goto out; + goto out_put_device; } /* Protection domain is optional, it does not exist on older platforms */ @@ -466,18 +447,26 @@ static int apr_add_device(struct device *dev, struct device_node *np, 1, &adev->service_path); if (ret < 0 && ret != -EINVAL) { dev_err(dev, "Failed to read second value of qcom,protection-domain\n"); - goto out; + goto out_remove_idr; } dev_info(dev, "Adding APR/GPR dev: %s\n", dev_name(&adev->dev)); - ret = device_register(&adev->dev); + ret = device_add(&adev->dev); if (ret) { - dev_err(dev, "device_register failed: %d\n", ret); - put_device(&adev->dev); + dev_err(dev, "device_add failed: %d\n", ret); + goto out_remove_idr; } -out: + return 0; + +out_remove_idr: + spin_lock(&apr->svcs_lock); + idr_remove(&apr->svcs_idr, svc_id); + spin_unlock(&apr->svcs_lock); + flush_workqueue(apr->rxwq); +out_put_device: + put_device(&adev->dev); return ret; }
diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c index 7339998..d7a42a8 100644 --- a/drivers/soc/qcom/llcc-qcom.c +++ b/drivers/soc/qcom/llcc-qcom.c
@@ -626,11 +626,11 @@ static const struct llcc_slice_config glymur_data[] = { static const struct llcc_slice_config ipq5424_data[] = { { - .usecase_id = LLCC_CPUSS, + .usecase_id = LLCC_PPE_RXDESC, .slice_id = 1, - .max_cap = 768, - .priority = 1, - .bonus_ways = 0xFFFF, + .max_cap = 128, + .priority = 3, + .bonus_ways = 0x0FFF, .retain_on_pc = true, .activate_on_init = true, .write_scid_cacheable_en = true, @@ -642,12 +642,52 @@ static const struct llcc_slice_config ipq5424_data[] = { .vict_prio = true, }, { - .usecase_id = LLCC_VIDSC0, + .usecase_id = LLCC_CPUSS, .slice_id = 2, - .max_cap = 256, - .priority = 2, + .max_cap = 768, + .priority = 1, .fixed_size = true, - .bonus_ways = 0xF000, + .bonus_ways = 0x0FFF, + .retain_on_pc = true, + .activate_on_init = true, + .write_scid_cacheable_en = true, + .stale_en = true, + .stale_cap_en = true, + }, + { + .usecase_id = LLCC_PPE_RXFILL, + .slice_id = 5, + .max_cap = 128, + .priority = 3, + .bonus_ways = 0x0FFF, + .retain_on_pc = true, + .activate_on_init = true, + .write_scid_cacheable_en = true, + .stale_en = true, + .stale_cap_en = true, + .alloc_oneway_en = true, + .ovcap_en = true, + .ovcap_prio = true, + .vict_prio = true, + }, + { + .usecase_id = LLCC_WLAN_5G, + .slice_id = 6, + .max_cap = 128, + .priority = 3, + .bonus_ways = 0xC000, + .retain_on_pc = true, + .activate_on_init = true, + .write_scid_cacheable_en = true, + .stale_en = true, + .stale_cap_en = true, + }, + { + .usecase_id = LLCC_WLAN_6G, + .slice_id = 7, + .max_cap = 128, + .priority = 3, + .bonus_ways = 0x3000, .retain_on_pc = true, .activate_on_init = true, .write_scid_cacheable_en = true, @@ -1014,6 +1054,128 @@ static const struct llcc_slice_config kaanapali_data[] = { }, }; +static const struct llcc_slice_config nord_data[] = { + { + .usecase_id = LLCC_CPUSS, + .slice_id = 1, + .max_cap = 3072, + .priority = 0, + .bonus_ways = 0xff, + .activate_on_init = true, + .write_scid_en = true, + .write_scid_cacheable_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_CMPT, + .slice_id = 34, + .max_cap = 0, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xff, + .vict_prio = true, + }, { + .usecase_id = LLCC_GPUHTW, + .slice_id = 11, + .max_cap = 512, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xff, + .vict_prio = true, + }, { + .usecase_id = LLCC_GPU, + .slice_id = 12, + .max_cap = 2048, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xff, + .write_scid_en = true, + .write_scid_cacheable_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_MMUHWT, + .slice_id = 13, + .max_cap = 1024, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xff, + .activate_on_init = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_CAMFW, + .slice_id = 20, + .max_cap = 512, + .priority = 2, + .fixed_size = true, + .bonus_ways = 0xff, + .vict_prio = true, + }, { + .usecase_id = LLCC_ECC, + .slice_id = 26, + .max_cap = 1536, + .priority = 3, + .fixed_size = true, + .bonus_ways = 0xff, + .activate_on_init = true, + .write_scid_en = true, + .write_scid_cacheable_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_WRCACHE, + .slice_id = 31, + .max_cap = 2048, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xff, + .activate_on_init = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_LCPDARE, + .slice_id = 30, + .max_cap = 512, + .priority = 3, + .fixed_size = true, + .bonus_ways = 0xff, + .activate_on_init = true, + .alloc_oneway_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_COMPUTE1, + .slice_id = 22, + .max_cap = 0, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xff, + .vict_prio = true, + }, { + .usecase_id = LLCC_PCIE_TCU, + .slice_id = 15, + .max_cap = 0, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xff, + .activate_on_init = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_GPU_LITTLE, + .slice_id = 9, + .max_cap = 2048, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xff, + .write_scid_en = true, + .write_scid_cacheable_en = true, + .vict_prio = true, + }, { + .usecase_id = LLCC_GPUHTW_LITTLE, + .slice_id = 14, + .max_cap = 512, + .priority = 1, + .fixed_size = true, + .bonus_ways = 0xff, + .vict_prio = true, + }, +}; + static const struct llcc_slice_config sa8775p_data[] = { { .usecase_id = LLCC_CPUSS, @@ -4444,6 +4606,17 @@ static const struct qcom_llcc_config glymur_cfg[] = { }, }; +static const struct qcom_llcc_config nord_cfg[] = { + { + .sct_data = nord_data, + .size = ARRAY_SIZE(nord_data), + .reg_offset = llcc_v6_reg_offset, + .edac_reg_offset = &llcc_v6_edac_reg_offset, + .num_banks = 16, + .no_edac = true, + }, +}; + static const struct qcom_llcc_config qcs615_cfg[] = { { .sct_data = qcs615_data, @@ -4711,6 +4884,11 @@ static const struct qcom_sct_config glymur_cfgs = { .num_config = ARRAY_SIZE(glymur_cfg), }; +static const struct qcom_sct_config nord_cfgs = { + .llcc_config = nord_cfg, + .num_config = ARRAY_SIZE(nord_cfg), +}; + static const struct qcom_sct_config qcs615_cfgs = { .llcc_config = qcs615_cfg, .num_config = ARRAY_SIZE(qcs615_cfg), @@ -5617,6 +5795,10 @@ static int qcom_llcc_probe(struct platform_device *pdev) } drv_data->ecc_irq = platform_get_irq_optional(pdev, 0); + if (drv_data->ecc_irq < 0 && drv_data->ecc_irq != -ENXIO) + return dev_err_probe(&pdev->dev, drv_data->ecc_irq, + "failed to get IRQ resource\n"); + drv_data->edac_reg_offset = cfg->edac_reg_offset; drv_data->ecc_irq_configured = cfg->irq_configured; drv_data->dev = dev; @@ -5649,6 +5831,7 @@ static const struct of_device_id qcom_llcc_of_match[] = { { .compatible = "qcom,hawi-llcc", .data = &hawi_sct_cfgs }, { .compatible = "qcom,ipq5424-llcc", .data = &ipq5424_cfgs}, { .compatible = "qcom,kaanapali-llcc", .data = &kaanapali_cfgs}, + { .compatible = "qcom,nord-llcc", .data = &nord_cfgs}, { .compatible = "qcom,qcs615-llcc", .data = &qcs615_cfgs}, { .compatible = "qcom,qcs8300-llcc", .data = &qcs8300_cfgs}, { .compatible = "qcom,qdu1000-llcc", .data = &qdu1000_cfgs},
diff --git a/drivers/soc/qcom/pmic_glink.c b/drivers/soc/qcom/pmic_glink.c index 3042261..84fd0c8 100644 --- a/drivers/soc/qcom/pmic_glink.c +++ b/drivers/soc/qcom/pmic_glink.c
@@ -250,7 +250,8 @@ static int pmic_glink_rpmsg_probe(struct rpmsg_device *rpdev) guard(mutex)(&__pmic_glink_lock); pg = __pmic_glink; if (!pg) - return dev_err_probe(&rpdev->dev, -ENODEV, "no pmic_glink device to attach to\n"); + return dev_err_probe(&rpdev->dev, -EPROBE_DEFER, + "no pmic_glink device to attach to\n"); dev_set_drvdata(&rpdev->dev, pg); pg->pdr_available = rpdev->id.driver_data;
diff --git a/drivers/soc/qcom/pmic_glink_altmode.c b/drivers/soc/qcom/pmic_glink_altmode.c index 13c434f..465e5d2 100644 --- a/drivers/soc/qcom/pmic_glink_altmode.c +++ b/drivers/soc/qcom/pmic_glink_altmode.c
@@ -451,7 +451,7 @@ static void pmic_glink_altmode_sc8180xp_notify(struct pmic_glink_altmode *altmod alt_port->mode = mode; alt_port->hpd_state = hpd_state; alt_port->hpd_irq = hpd_irq; - schedule_work(&alt_port->work); + queue_work(system_freezable_wq, &alt_port->work); } #define SC8280XP_DPAM_MASK 0x3f @@ -502,7 +502,7 @@ static void pmic_glink_altmode_sc8280xp_notify(struct pmic_glink_altmode *altmod alt_port->tbt_data = *tbt; } - schedule_work(&alt_port->work); + queue_work(system_freezable_wq, &alt_port->work); } static void pmic_glink_altmode_callback(const void *data, size_t len, void *priv)
diff --git a/drivers/soc/qcom/pmic_pdcharger_ulog.c b/drivers/soc/qcom/pmic_pdcharger_ulog.c index 39f412b..06cd9c4 100644 --- a/drivers/soc/qcom/pmic_pdcharger_ulog.c +++ b/drivers/soc/qcom/pmic_pdcharger_ulog.c
@@ -143,7 +143,7 @@ static void pmic_pdcharger_ulog_rpmsg_remove(struct rpmsg_device *rpdev) { struct pmic_pdcharger_ulog *pg = dev_get_drvdata(&rpdev->dev); - cancel_delayed_work_sync(&pg->ulog_work); + disable_delayed_work_sync(&pg->ulog_work); } static const struct rpmsg_device_id pmic_pdcharger_ulog_rpmsg_id_match[] = {
diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c index 873bfbd..074087c 100644 --- a/drivers/soc/qcom/qcom-geni-se.c +++ b/drivers/soc/qcom/qcom-geni-se.c
@@ -42,7 +42,7 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(geni_se_regs); * * GENI based QUP is a highly-flexible and programmable module for supporting * a wide range of serial interfaces like UART, SPI, I2C, I3C, etc. A single - * QUP module can provide upto 8 serial interfaces, using its internal + * QUP module can provide up to 8 serial interfaces, using its internal * serial engines. The actual configuration is determined by the target * platform configuration. The protocol supported by each interface is * determined by the firmware loaded to the serial engine. Each SE consists @@ -101,22 +101,26 @@ EXPORT_TRACEPOINT_SYMBOL_GPL(geni_se_regs); * @base: Base address of this instance of QUP wrapper core * @clks: Handle to the primary & optional secondary AHB clocks * @num_clks: Count of clocks + * @prog_ram_depth: Available CFG RAM depth for instance without SE_HW_PARAM_2 */ struct geni_wrapper { struct device *dev; void __iomem *base; struct clk_bulk_data clks[MAX_CLKS]; unsigned int num_clks; + unsigned int prog_ram_depth; }; /** * struct geni_se_desc - Data structure to represent the QUP Wrapper resources * @clks: Name of the primary & optional secondary AHB clocks * @num_clks: Count of clock names + * @prog_ram_depth: Available CFG RAM depth for instance without SE_HW_PARAM_2 */ struct geni_se_desc { unsigned int num_clks; const char * const *clks; + unsigned int prog_ram_depth; }; static const char * const icc_path_names[] = {"qup-core", "qup-config", @@ -920,7 +924,7 @@ void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len) } EXPORT_SYMBOL_GPL(geni_se_rx_dma_unprep); -int geni_icc_get(struct geni_se *se, const char *icc_ddr) +int geni_icc_get(struct geni_se *se) { struct geni_icc_path *icc_paths = se->icc_paths; @@ -1217,7 +1221,7 @@ int geni_se_resources_init(struct geni_se *se) se->has_opp = (ret == 0); - ret = geni_icc_get(se, "qup-memory"); + ret = geni_icc_get(se); if (ret) return ret; @@ -1230,25 +1234,29 @@ EXPORT_SYMBOL_GPL(geni_se_resources_init); * @se: Pointer to the serial engine structure. * @fw: Pointer to the firmware image. * @protocol: Expected serial engine protocol type. + * @fw_size_out: Non-NULL output parameter; receives the rounded, validated + * firmware word count on success. * * Identifies the appropriate firmware image or configuration required for a * specific communication protocol instance running on a Qualcomm GENI * controller. Validates the firmware size against the hardware PROG_RAM_DEPTH * read from SE_HW_PARAM_2. * - * Return: pointer to a valid 'struct se_fw_hdr' if found, or NULL otherwise. + * Return: pointer to a valid 'const struct se_fw_hdr' if found, or NULL otherwise. */ -static struct se_fw_hdr *geni_find_protocol_fw(struct geni_se *se, const struct firmware *fw, - enum geni_se_protocol_type protocol) +static const struct se_fw_hdr *geni_find_protocol_fw(struct geni_se *se, const struct firmware *fw, + enum geni_se_protocol_type protocol, + u32 *fw_size_out) { + struct geni_wrapper *wrapper = se->wrapper; struct device *dev = se->dev; const struct elf32_hdr *ehdr; const struct elf32_phdr *phdrs; const struct elf32_phdr *phdr; - struct se_fw_hdr *sefw; + const struct se_fw_hdr *sefw; u32 fw_end, cfg_idx_end, cfg_val_end; u32 prog_ram_depth; - u16 fw_size; + u32 fw_size; int i; if (!fw || fw->size < sizeof(struct elf32_hdr)) @@ -1287,27 +1295,29 @@ static struct se_fw_hdr *geni_find_protocol_fw(struct geni_se *se, const struct if (phdr->p_filesz < sizeof(struct se_fw_hdr)) continue; - sefw = (struct se_fw_hdr *)(fw->data + phdr->p_offset); + sefw = (const struct se_fw_hdr *)(fw->data + phdr->p_offset); fw_size = le16_to_cpu(sefw->fw_size_in_items); + + if (le32_to_cpu(sefw->magic) != SE_MAGIC_NUM || le32_to_cpu(sefw->version) != 1) + continue; + + if (le16_to_cpu(sefw->serial_protocol) != protocol) + continue; + + if (fw_size % 2 != 0) + fw_size++; + fw_end = le16_to_cpu(sefw->fw_offset) + fw_size * sizeof(u32); cfg_idx_end = le16_to_cpu(sefw->cfg_idx_offset) + le16_to_cpu(sefw->cfg_size_in_items) * sizeof(u8); cfg_val_end = le16_to_cpu(sefw->cfg_val_offset) + le16_to_cpu(sefw->cfg_size_in_items) * sizeof(u32); - if (le32_to_cpu(sefw->magic) != SE_MAGIC_NUM || le32_to_cpu(sefw->version) != 1) - continue; - - if (le32_to_cpu(sefw->serial_protocol) != protocol) - continue; - - if (fw_size % 2 != 0) { - fw_size++; - sefw->fw_size_in_items = cpu_to_le16(fw_size); - } - - prog_ram_depth = FIELD_GET(PROG_RAM_DEPTH_MSK, - readl_relaxed(se->base + SE_HW_PARAM_2)); + if (wrapper->prog_ram_depth) + prog_ram_depth = wrapper->prog_ram_depth; + else + prog_ram_depth = FIELD_GET(PROG_RAM_DEPTH_MSK, + readl_relaxed(se->base + SE_HW_PARAM_2)); if (fw_size >= prog_ram_depth) { dev_err(dev, "Firmware size (%u) exceeds RAM size (%u)\n", fw_size, prog_ram_depth); @@ -1320,6 +1330,7 @@ static struct se_fw_hdr *geni_find_protocol_fw(struct geni_se *se, const struct continue; } + *fw_size_out = fw_size; return sefw; } @@ -1430,17 +1441,17 @@ static int geni_load_se_fw(struct geni_se *se, const struct firmware *fw, { const u32 *fw_data, *cfg_val_arr; const u8 *cfg_idx_arr; - u32 i, reg_value; + u32 i, reg_value, fw_size_in_items; int ret; - struct se_fw_hdr *hdr; + const struct se_fw_hdr *hdr; - hdr = geni_find_protocol_fw(se, fw, protocol); + hdr = geni_find_protocol_fw(se, fw, protocol, &fw_size_in_items); if (!hdr) return -EINVAL; - fw_data = (const u32 *)((u8 *)hdr + le16_to_cpu(hdr->fw_offset)); + fw_data = (const u32 *)((const u8 *)hdr + le16_to_cpu(hdr->fw_offset)); cfg_idx_arr = (const u8 *)hdr + le16_to_cpu(hdr->cfg_idx_offset); - cfg_val_arr = (const u32 *)((u8 *)hdr + le16_to_cpu(hdr->cfg_val_offset)); + cfg_val_arr = (const u32 *)((const u8 *)hdr + le16_to_cpu(hdr->cfg_val_offset)); ret = geni_icc_set_bw(se); if (ret) @@ -1511,7 +1522,7 @@ static int geni_load_se_fw(struct geni_se *se, const struct firmware *fw, /* Program RAM address space. */ memcpy_toio(se->base + SE_GENI_CFG_RAMN, fw_data, - le16_to_cpu(hdr->fw_size_in_items) * sizeof(u32)); + fw_size_in_items * sizeof(u32)); /* Put default values on GENI's output pads. */ writel_relaxed(0x1, se->base + GENI_FORCE_DEFAULT_REG); @@ -1617,6 +1628,7 @@ static int geni_se_probe(struct platform_device *pdev) return PTR_ERR(wrapper->base); desc = device_get_match_data(&pdev->dev); + wrapper->prog_ram_depth = desc->prog_ram_depth; if (!has_acpi_companion(&pdev->dev) && desc->num_clks) { int i; @@ -1669,6 +1681,7 @@ static const char * const i2c_master_hub_clks[] = { static const struct geni_se_desc i2c_master_hub_desc = { .clks = i2c_master_hub_clks, .num_clks = ARRAY_SIZE(i2c_master_hub_clks), + .prog_ram_depth = 1020, }; static const struct of_device_id geni_se_dt_match[] = {
diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c index 259c41f0..a6b673c 100644 --- a/drivers/soc/qcom/qcom_aoss.c +++ b/drivers/soc/qcom/qcom_aoss.c
@@ -602,10 +602,8 @@ static int qmp_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); ret = devm_request_irq(&pdev->dev, irq, qmp_intr, 0, "aoss-qmp", qmp); - if (ret < 0) { - dev_err(&pdev->dev, "failed to request interrupt\n"); + if (ret < 0) goto err_free_mbox; - } ret = qmp_open(qmp); if (ret < 0)
diff --git a/drivers/soc/qcom/qcom_stats.c b/drivers/soc/qcom/qcom_stats.c index 0692340..3422d6d 100644 --- a/drivers/soc/qcom/qcom_stats.c +++ b/drivers/soc/qcom/qcom_stats.c
@@ -371,6 +371,14 @@ static const struct stats_config rpm_data_dba0 = { .subsystem_stats_in_smem = false, }; +static const struct stats_config rpm_data_shikra = { + .stats_offset = 0, + .num_records = 2, + .appended_stats_avail = true, + .dynamic_offset = true, + .subsystem_stats_in_smem = true, +}; + static const struct stats_config rpmh_data_sdm845 = { .stats_offset = 0x48, .num_records = 2, @@ -396,6 +404,7 @@ static const struct of_device_id qcom_stats_table[] = { { .compatible = "qcom,rpm-stats", .data = &rpm_data }, { .compatible = "qcom,rpmh-stats", .data = &rpmh_data }, { .compatible = "qcom,sdm845-rpmh-stats", .data = &rpmh_data_sdm845 }, + { .compatible = "qcom,shikra-rpm-stats", .data = &rpm_data_shikra }, { } }; MODULE_DEVICE_TABLE(of, qcom_stats_table);
diff --git a/drivers/soc/qcom/rpmh-internal.h b/drivers/soc/qcom/rpmh-internal.h index e3cf1bef..39441a2 100644 --- a/drivers/soc/qcom/rpmh-internal.h +++ b/drivers/soc/qcom/rpmh-internal.h
@@ -20,7 +20,7 @@ struct rsc_drv; /** - * struct tcs_group: group of Trigger Command Sets (TCS) to send state requests + * struct tcs_group - group of Trigger Command Sets (TCS) to send state requests * to the controller * * @drv: The controller. @@ -53,7 +53,7 @@ struct tcs_group { }; /** - * struct rpmh_request: the message to be sent to rpmh-rsc + * struct rpmh_request - the message to be sent to rpmh-rsc * * @msg: the request * @cmd: the payload that will be part of the @msg @@ -70,7 +70,7 @@ struct rpmh_request { }; /** - * struct rpmh_ctrlr: our representation of the controller + * struct rpmh_ctrlr - our representation of the controller * * @cache: the list of cached requests * @cache_lock: synchronize access to the cache data @@ -84,13 +84,19 @@ struct rpmh_ctrlr { struct list_head batch_cache; }; +/** + * struct rsc_ver - Hardware version of the RSC controller. + * + * @major: Major version number. + * @minor: Minor version number. + */ struct rsc_ver { u32 major; u32 minor; }; /** - * struct rsc_drv: the Direct Resource Voter (DRV) of the + * struct rsc_drv - the Direct Resource Voter (DRV) of the * Resource State Coordinator controller (RSC) * * @name: Controller identifier. @@ -116,6 +122,8 @@ struct rsc_ver { * slot * @client: Handle to the DRV's client. * @dev: RSC device. + * @ver: HW version of the RSC controller. + * @regs: Pointer to the register offset table for this version. */ struct rsc_drv { const char *name;
diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index f881af3..c454231 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c
@@ -842,7 +842,7 @@ void rpmh_rsc_write_next_wakeup(struct rsc_drv *drv) } /** - * rpmh_rsc_cpu_pm_callback() - Check if any of the AMCs are busy. + * rpmh_rsc_cpu_pm_callback() - CPU PM notifier to flush sleep/wake TCS data. * @nfb: Pointer to the notifier block in struct rsc_drv. * @action: CPU_PM_ENTER, CPU_PM_ENTER_FAILED, or CPU_PM_EXIT. * @v: Unused @@ -923,7 +923,7 @@ static int rpmh_rsc_cpu_pm_callback(struct notifier_block *nfb, } /** - * rpmh_rsc_pd_callback() - Check if any of the AMCs are busy. + * rpmh_rsc_pd_callback() - PM domain callback to flush sleep/wake TCS data. * @nfb: Pointer to the genpd notifier block in struct rsc_drv. * @action: GENPD_NOTIFY_PRE_OFF, GENPD_NOTIFY_OFF, GENPD_NOTIFY_PRE_ON or GENPD_NOTIFY_ON. * @v: Unused
diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c index f881c4c..360242a 100644 --- a/drivers/soc/qcom/rpmh.c +++ b/drivers/soc/qcom/rpmh.c
@@ -41,7 +41,7 @@ #define ctrlr_to_drv(ctrlr) container_of(ctrlr, struct rsc_drv, client) /** - * struct cache_req: the request object for caching + * struct cache_req - the request object for caching * * @addr: the address of the resource * @sleep_val: the sleep vote @@ -56,7 +56,7 @@ struct cache_req { }; /** - * struct batch_cache_req - An entry in our batch catch + * struct batch_cache_req - An entry in our batch cache * * @list: linked list obj * @count: number of messages @@ -76,6 +76,14 @@ static struct rpmh_ctrlr *get_rpmh_ctrlr(const struct device *dev) return &drv->client; } +/** + * rpmh_tx_done() - Signal the completion of a RPMH transfer. + * @msg: The request that was previously sent. + * + * Called by the RSC driver when an active-only transfer is complete. + * Signals any blocking waiter and frees the message if it was dynamically + * allocated. + */ void rpmh_tx_done(const struct tcs_request *msg) { struct rpmh_request *rpm_msg = container_of(msg, struct rpmh_request, @@ -157,7 +165,7 @@ static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr, } /** - * __rpmh_write: Cache and send the RPMH request + * __rpmh_write() - Cache and send the RPMH request. * * @dev: The device making the request * @state: Active/Sleep request type @@ -166,6 +174,8 @@ static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr, * Cache the RPMH request and send if the state is ACTIVE_ONLY. * SLEEP/WAKE_ONLY requests are not sent to the controller at * this time. Use rpmh_flush() to send them to the controller. + * + * Return: 0 on success, negative error code on failure. */ static int __rpmh_write(const struct device *dev, enum rpmh_state state, struct rpmh_request *rpm_msg) @@ -248,7 +258,7 @@ int rpmh_read(const struct device *dev, struct tcs_cmd *cmd) EXPORT_SYMBOL_GPL(rpmh_read); /** - * rpmh_write_async: Write a set of RPMH commands + * rpmh_write_async() - Write a set of RPMH commands. * * @dev: The device making the request * @state: Active/sleep set @@ -257,6 +267,8 @@ EXPORT_SYMBOL_GPL(rpmh_read); * * Write a set of RPMH commands, the order of commands is maintained * and will be sent as a single shot. + * + * Return: 0 on success, negative error code on failure. */ int rpmh_write_async(const struct device *dev, enum rpmh_state state, const struct tcs_cmd *cmd, u32 n) @@ -280,7 +292,7 @@ int rpmh_write_async(const struct device *dev, enum rpmh_state state, EXPORT_SYMBOL_GPL(rpmh_write_async); /** - * rpmh_write: Write a set of RPMH commands and block until response + * rpmh_write() - Write a set of RPMH commands and block until response * * @dev: The device making the request * @state: Active/sleep set @@ -288,6 +300,8 @@ EXPORT_SYMBOL_GPL(rpmh_write_async); * @n: The number of elements in @cmd * * May sleep. Do not call from atomic contexts. + * + * Return: 0 on success, negative error code on failure. */ int rpmh_write(const struct device *dev, enum rpmh_state state, const struct tcs_cmd *cmd, u32 n) @@ -342,7 +356,7 @@ static int flush_batch(struct rpmh_ctrlr *ctrlr) } /** - * rpmh_write_batch: Write multiple sets of RPMH commands and wait for the + * rpmh_write_batch() - Write multiple sets of RPMH commands and wait for the * batch to finish. * * @dev: the device making the request @@ -350,13 +364,15 @@ static int flush_batch(struct rpmh_ctrlr *ctrlr) * @cmd: The payload data * @n: The array of count of elements in each batch, 0 terminated. * - * Write a request to the RSC controller without caching. If the request - * state is ACTIVE, then the requests are treated as completion request - * and sent to the controller immediately. The function waits until all the - * commands are complete. If the request was to SLEEP or WAKE_ONLY, then the - * request is sent as fire-n-forget and no ack is expected. + * If the request state is ACTIVE_ONLY, the requests are sent to the + * controller immediately and the function waits until all commands are + * complete. If the state is SLEEP or WAKE_ONLY, the requests are cached + * and the function returns immediately; they are sent to the controller + * later by rpmh_flush(). * * May sleep. Do not call from atomic contexts for ACTIVE_ONLY requests. + * + * Return: 0 on success, negative error code on failure. */ int rpmh_write_batch(const struct device *dev, enum rpmh_state state, const struct tcs_cmd *cmd, u32 *n) @@ -519,7 +535,7 @@ int rpmh_flush(struct rpmh_ctrlr *ctrlr) } /** - * rpmh_invalidate: Invalidate sleep and wake sets in batch_cache + * rpmh_invalidate() - Invalidate sleep and wake sets in batch_cache * * @dev: The device making the request *
diff --git a/drivers/soc/qcom/smem_dramc.c b/drivers/soc/qcom/smem_dramc.c index 63ebe7f..497513c 100644 --- a/drivers/soc/qcom/smem_dramc.c +++ b/drivers/soc/qcom/smem_dramc.c
@@ -20,12 +20,22 @@ #define MAX_DDR_FREQ_NUM_V5 14 #define MAX_CHAN_NUM 8 +#define MAX_CHAN_NUM_V7_GLYMUR 16 #define MAX_RANK_NUM 2 #define DDR_HBB_MIN 13 #define DDR_HBB_MAX 19 #define MAX_SHUB_ENTRIES 8 +#define MAX_SHUB_ENTRIES_V7_GLYMUR 10 +#define MAX_DDR_REGIONS_V7_GLYMUR 4 + +/* + * Glymur's DRAM information entry has 256 bytes of trailing zeroes + * after its DDR details, four region slots, 10-entry SHUB frequency + * plan, and v6 misc information. + */ +#define DDR_V7_GLYMUR_RESERVED_SIZE 256 static struct smem_dram *__dram; @@ -39,6 +49,7 @@ enum ddr_info_version { INFO_V6, /* INFO_V6 seems to only have shipped with 6 DDR regions, unlike V7 */ INFO_V7, INFO_V7_WITH_6_REGIONS, + INFO_V7_GLYMUR, }; struct smem_dram { @@ -188,6 +199,37 @@ struct ddr_details_v7 { struct ddr_regions_v5 ddr_regions; }; +struct ddr_regions_v7_glymur { + __le32 ddr_region_num; + __le64 ddr_rank0_size; + __le64 ddr_rank1_size; + __le64 ddr_cs0_start_addr; + __le64 ddr_cs1_start_addr; + __le32 highest_bank_addr_bit; + struct ddr_region_v5 ddr_region[MAX_DDR_REGIONS_V7_GLYMUR]; +}; + +struct ddr_details_v7_glymur { + u8 manufacturer_id; + u8 device_type; + struct ddr_part_details ddr_params[MAX_CHAN_NUM_V7_GLYMUR]; + struct ddr_freq_plan_v5 ddr_freq_tbl; + u8 num_channels; + u8 sct_config; + struct ddr_regions_v7_glymur ddr_regions; +}; + +struct shub_freq_plan_entry_v7_glymur { + u8 num_shub_freqs; + struct shub_freq_table shub_freq[MAX_SHUB_ENTRIES_V7_GLYMUR]; +}; + +struct ddr_v7_glymur_tail { + struct shub_freq_plan_entry_v7_glymur shub_freq_plan; + struct ddr_misc_info_v6 misc_info; + u8 reserved[DDR_V7_GLYMUR_RESERVED_SIZE]; +}; + /** * qcom_smem_dram_get_hbb(): Get the Highest bank address bit * @@ -219,7 +261,7 @@ static void smem_dram_parse_v3_data(struct smem_dram *dram, void *data) if (freq_entry->freq_khz && freq_entry->enabled) { u32 freq_khz = le32_to_cpu(freq_entry->freq_khz); - dram->frequencies[dram->num_frequencies++] = 1000 * freq_khz; + dram->frequencies[dram->num_frequencies++] = 1000UL * freq_khz; } } } @@ -231,8 +273,11 @@ static void smem_dram_parse_v3_14freqs_data(struct smem_dram *dram, void *data) for (int i = 0; i < MAX_DDR_FREQ_NUM_V3 + 1; i++) { struct ddr_freq_table *freq_entry = &details->ddr_freq_tbl.ddr_freq[i]; - if (freq_entry->freq_khz && freq_entry->enabled) - dram->frequencies[dram->num_frequencies++] = 1000 * freq_entry->freq_khz; + if (freq_entry->freq_khz && freq_entry->enabled) { + u32 freq_khz = le32_to_cpu(freq_entry->freq_khz); + + dram->frequencies[dram->num_frequencies++] = 1000UL * freq_khz; + } } } @@ -248,7 +293,7 @@ static void smem_dram_parse_v4_data(struct smem_dram *dram, void *data) if (freq_entry->freq_khz && freq_entry->enabled) { u32 freq_khz = le32_to_cpu(freq_entry->freq_khz); - dram->frequencies[dram->num_frequencies++] = 1000 * freq_khz; + dram->frequencies[dram->num_frequencies++] = 1000UL * freq_khz; } } } @@ -265,7 +310,7 @@ static void smem_dram_parse_v5_data(struct smem_dram *dram, void *data) if (freq_entry->freq_khz && freq_entry->enabled) { u32 freq_khz = le32_to_cpu(freq_entry->freq_khz); - dram->frequencies[dram->num_frequencies++] = 1000 * freq_khz; + dram->frequencies[dram->num_frequencies++] = 1000UL * freq_khz; } } } @@ -282,6 +327,23 @@ static void smem_dram_parse_v7_data(struct smem_dram *dram, void *data) if (freq_entry->freq_khz && freq_entry->enabled) { u32 freq_khz = le32_to_cpu(freq_entry->freq_khz); + dram->frequencies[dram->num_frequencies++] = 1000UL * freq_khz; + } + } +} + +static void smem_dram_parse_v7_glymur_data(struct smem_dram *dram, void *data) +{ + struct ddr_details_v7_glymur *details = data; + + dram->hbb = le32_to_cpu(details->ddr_regions.highest_bank_addr_bit); + + for (int i = 0; i < MAX_DDR_FREQ_NUM_V5; i++) { + struct ddr_freq_table *freq_entry = &details->ddr_freq_tbl.ddr_freq[i]; + + if (freq_entry->freq_khz && freq_entry->enabled) { + u32 freq_khz = le32_to_cpu(freq_entry->freq_khz); + dram->frequencies[dram->num_frequencies++] = 1000 * freq_khz; } } @@ -341,6 +403,10 @@ static int smem_dram_infer_struct_version(size_t size) sizeof(struct shub_freq_plan_entry)) return INFO_V7_WITH_6_REGIONS; + if (size == sizeof(struct ddr_details_v7_glymur) + + sizeof(struct ddr_v7_glymur_tail)) + return INFO_V7_GLYMUR; + return INFO_UNKNOWN; } @@ -382,7 +448,7 @@ struct dentry *smem_dram_parse(struct qcom_smem *smem, struct device *dev) return ERR_PTR(-ENODATA); ver = smem_dram_infer_struct_version(actual_size); - if (ver < 0) { + if ((int)ver < 0) { /* Some SoCs don't provide data that's useful for us */ return ERR_PTR(-ENODATA); } else if (ver == INFO_UNKNOWN) { @@ -415,6 +481,9 @@ struct dentry *smem_dram_parse(struct qcom_smem *smem, struct device *dev) case INFO_V7_WITH_6_REGIONS: smem_dram_parse_v7_data(dram, data); break; + case INFO_V7_GLYMUR: + smem_dram_parse_v7_glymur_data(dram, data); + break; default: return ERR_PTR(-EINVAL); }
diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index af0ceea..01b8580 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c
@@ -102,7 +102,7 @@ struct smp2p_entry { struct qcom_smp2p *smp2p; const char *name; - u32 *value; + u32 __iomem *value; u32 last_value; struct irq_domain *domain; @@ -276,7 +276,7 @@ static void qcom_smp2p_start_in(struct qcom_smp2p *smp2p) list_for_each_entry(entry, &smp2p->inbound, node) { memcpy(buf, in->entries[i].name, sizeof(buf)); if (!strcmp(buf, entry->name)) { - entry->value = &in->entries[i].value; + entry->value = (u32 __iomem *)&in->entries[i].value; entry->last_value = readl(entry->value); break; } @@ -302,7 +302,7 @@ static void qcom_smp2p_notify_in(struct qcom_smp2p *smp2p) list_for_each_entry(entry, &smp2p->inbound, node) { memcpy(buf, in->entries[i].name, sizeof(buf)); if (!strcmp(buf, entry->name)) { - entry->value = &in->entries[i].value; + entry->value = (u32 __iomem *)&in->entries[i].value; break; } } @@ -411,15 +411,9 @@ static int smp2p_set_irq_type(struct irq_data *irqd, unsigned int type) if (!(type & IRQ_TYPE_EDGE_BOTH)) return -EINVAL; - if (type & IRQ_TYPE_EDGE_RISING) - set_bit(irq, entry->irq_rising); - else - clear_bit(irq, entry->irq_rising); + assign_bit(irq, entry->irq_rising, type & IRQ_TYPE_EDGE_RISING); - if (type & IRQ_TYPE_EDGE_FALLING) - set_bit(irq, entry->irq_falling); - else - clear_bit(irq, entry->irq_falling); + assign_bit(irq, entry->irq_falling, type & IRQ_TYPE_EDGE_FALLING); return 0; } @@ -528,7 +522,7 @@ static int qcom_smp2p_outbound_entry(struct qcom_smp2p *smp2p, memcpy(out->entries[out->valid_entries].name, buf, SMP2P_MAX_ENTRY_NAME); /* Make the logical entry reference the physical value */ - entry->value = &out->entries[out->valid_entries].value; + entry->value = (u32 __iomem *)&out->entries[out->valid_entries].value; out->valid_entries++; @@ -720,10 +714,8 @@ static int qcom_smp2p_probe(struct platform_device *pdev) NULL, qcom_smp2p_intr, IRQF_ONESHOT, NULL, (void *)smp2p); - if (ret) { - dev_err(&pdev->dev, "failed to request interrupt\n"); + if (ret) goto unwind_interfaces; - } /* * Treat smp2p interrupt as wakeup source, but keep it disabled
diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c index 021e9d1..bb487bf 100644 --- a/drivers/soc/qcom/smsm.c +++ b/drivers/soc/qcom/smsm.c
@@ -82,8 +82,8 @@ struct qcom_smsm { u32 num_hosts; u32 num_entries; - u32 *local_state; - u32 *subscription; + u32 __iomem *local_state; + u32 __iomem *subscription; struct qcom_smem_state *state; spinlock_t lock; @@ -115,8 +115,8 @@ struct smsm_entry { DECLARE_BITMAP(irq_falling, 32); unsigned long last_value; - u32 *remote_state; - u32 *subscription; + u32 __iomem *remote_state; + u32 __iomem *subscription; }; /** @@ -277,10 +277,8 @@ static void smsm_unmask_irq(struct irq_data *irqd) u32 val; /* Make sure our last cached state is up-to-date */ - if (readl(entry->remote_state) & BIT(irq)) - set_bit(irq, &entry->last_value); - else - clear_bit(irq, &entry->last_value); + assign_bit(irq, &entry->last_value, + readl(entry->remote_state) & BIT(irq)); set_bit(irq, entry->irq_enabled); @@ -304,15 +302,9 @@ static int smsm_set_irq_type(struct irq_data *irqd, unsigned int type) if (!(type & IRQ_TYPE_EDGE_BOTH)) return -EINVAL; - if (type & IRQ_TYPE_EDGE_RISING) - set_bit(irq, entry->irq_rising); - else - clear_bit(irq, entry->irq_rising); + assign_bit(irq, entry->irq_rising, type & IRQ_TYPE_EDGE_RISING); - if (type & IRQ_TYPE_EDGE_FALLING) - set_bit(irq, entry->irq_falling); - else - clear_bit(irq, entry->irq_falling); + assign_bit(irq, entry->irq_falling, type & IRQ_TYPE_EDGE_FALLING); return 0; } @@ -451,10 +443,8 @@ static int smsm_inbound_entry(struct qcom_smsm *smsm, NULL, smsm_intr, IRQF_ONESHOT, "smsm", (void *)entry); - if (ret) { - dev_err(smsm->dev, "failed to request interrupt\n"); + if (ret) return ret; - } entry->domain = irq_domain_create_linear(of_fwnode_handle(node), 32, &smsm_irq_ops, entry); if (!entry->domain) { @@ -513,9 +503,9 @@ static int qcom_smsm_probe(struct platform_device *pdev) struct device_node *node; struct smsm_entry *entry; struct qcom_smsm *smsm; - u32 *intr_mask; + u32 __iomem *intr_mask; size_t size; - u32 *states; + u32 __iomem *states; u32 id; int ret; @@ -579,7 +569,7 @@ static int qcom_smsm_probe(struct platform_device *pdev) goto out_put; } - states = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_SHARED_STATE, NULL); + states = (u32 __iomem *)qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_SHARED_STATE, NULL); if (IS_ERR(states)) { dev_err(&pdev->dev, "Unable to acquire shared state entry\n"); ret = PTR_ERR(states); @@ -594,7 +584,7 @@ static int qcom_smsm_probe(struct platform_device *pdev) goto out_put; } - intr_mask = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, NULL); + intr_mask = (u32 __iomem *)qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, NULL); if (IS_ERR(intr_mask)) { dev_err(&pdev->dev, "unable to acquire shared memory interrupt mask\n"); ret = PTR_ERR(intr_mask);
diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 1836e22..38efc5d 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c
@@ -450,6 +450,7 @@ static const struct soc_id soc_id[] = { { qcom_board_id(IPQ8172) }, { qcom_board_id(IPQ8173) }, { qcom_board_id(IPQ8174) }, + { qcom_board_id(SM7250) }, { qcom_board_id(IPQ6018) }, { qcom_board_id(IPQ6028) }, { qcom_board_id(SDM429W) }, @@ -541,8 +542,10 @@ static const struct soc_id soc_id[] = { { qcom_board_id(QCS9075) }, { qcom_board_id(QCS615) }, { qcom_board_id(SA8797P) }, + { qcom_board_id(SM8975) }, { qcom_board_id(CQ7790M) }, { qcom_board_id(CQ7790S) }, + { qcom_board_id(SM8950) }, { qcom_board_id(CQ2390M) }, { qcom_board_id(CQ2390S) }, { qcom_board_id(IQ2390S) },
diff --git a/drivers/soc/qcom/ubwc_config.c b/drivers/soc/qcom/ubwc_config.c index 23901a4c..a4d8769 100644 --- a/drivers/soc/qcom/ubwc_config.c +++ b/drivers/soc/qcom/ubwc_config.c
@@ -105,6 +105,13 @@ static const struct qcom_ubwc_cfg_data milos_data = { .highest_bank_bit = 15, }; +static const struct qcom_ubwc_cfg_data ubwc_7_0_hbb16 = { + .ubwc_enc_version = UBWC_7_0, + .flags = UBWC_SWIZZLE_ENABLE_LVL2 | + UBWC_SWIZZLE_ENABLE_LVL3, + .highest_bank_bit = 16, +}; + static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = { { .compatible = "qcom,apq8016", .data = &no_ubwc_data }, { .compatible = "qcom,apq8026", .data = &no_ubwc_data }, @@ -112,8 +119,11 @@ static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = { { .compatible = "qcom,apq8096", .data = &ubwc_1_0_hbb15 }, { .compatible = "qcom,eliza", .data = &ubwc_5_0_hbb15 }, { .compatible = "qcom,glymur", .data = &glymur_data}, + { .compatible = "qcom,hawi", .data = &ubwc_7_0_hbb16 }, { .compatible = "qcom,kaanapali", .data = &ubwc_6_0_hbb16 }, + { .compatible = "qcom,kalambo", .data = &glymur_data }, { .compatible = "qcom,mahua", .data = &glymur_data }, + { .compatible = "qcom,maili", .data = &ubwc_7_0_hbb16, }, { .compatible = "qcom,milos", .data = &milos_data }, { .compatible = "qcom,msm8226", .data = &no_ubwc_data }, { .compatible = "qcom,msm8916", .data = &no_ubwc_data }, @@ -121,12 +131,14 @@ static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = { { .compatible = "qcom,msm8937", .data = &ubwc_1_0_hbb14 }, { .compatible = "qcom,msm8929", .data = &no_ubwc_data }, { .compatible = "qcom,msm8939", .data = &no_ubwc_data }, + { .compatible = "qcom,msm8952", .data = &no_ubwc_data }, { .compatible = "qcom,msm8953", .data = &ubwc_1_0_hbb14 }, { .compatible = "qcom,msm8956", .data = &no_ubwc_data }, { .compatible = "qcom,msm8974", .data = &no_ubwc_data }, { .compatible = "qcom,msm8976", .data = &no_ubwc_data }, { .compatible = "qcom,msm8996", .data = &ubwc_1_0_hbb15 }, { .compatible = "qcom,msm8998", .data = &ubwc_1_0_hbb15 }, + { .compatible = "qcom,nord", .data = &glymur_data }, { .compatible = "qcom,qcm2290", .data = &ubwc_0_0_hbb15, }, { .compatible = "qcom,qcm6490", .data = &ubwc_3_1_hbb14, }, { .compatible = "qcom,qcs8300", .data = &ubwc_4_0_hbb16, },
diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig index eb8ac0d..a63df28 100644 --- a/drivers/soc/renesas/Kconfig +++ b/drivers/soc/renesas/Kconfig
@@ -227,6 +227,14 @@ help This enables support for the Renesas RZ/G2M SoC. +config ARCH_R8A774A3 + bool "ARM64 Platform support for R8A774A3 (RZ/G2M v3.0)" + default y if ARCH_RENESAS + select ARCH_RCAR_GEN3 + select SYSC_R8A774A3 + help + This enables support for the Renesas RZ/G2M SoC (version 3.0). + config ARCH_R8A774B1 bool "ARM64 Platform support for R8A774B1 (RZ/G2N)" default y if ARCH_RENESAS @@ -410,6 +418,7 @@ config ARCH_R9A09G047 bool "ARM64 Platform support for R9A09G047 (RZ/G3E)" default y if ARCH_RENESAS + select RENESAS_RZV2H_ICU select SYS_R9A09G047 help This enables support for the Renesas RZ/G3E SoC variants. @@ -417,6 +426,7 @@ config ARCH_R9A09G056 bool "ARM64 Platform support for R9A09G056 (RZ/V2N)" default y if ARCH_RENESAS + select RENESAS_RZV2H_ICU select SYS_R9A09G056 help This enables support for the Renesas RZ/V2N SoC variants. @@ -468,11 +478,12 @@ config RCAR_MFIS tristate "Renesas R-Car MFIS driver" depends on ARCH_RENESAS || COMPILE_TEST - depends on MAILBOX + depends on MAILBOX && HWSPINLOCK help - Select this option to enable the Renesas R-Car MFIS core driver for - the MFIS device found on SoCs like R-Car. On families like Gen5, this - is needed to communicate with the SCP. + Select this option to enable support for the Renesas R-Car + Multifunctional Interface (MFIS) device found on SoCs like R-Car. + On families like R-Car Gen5, this is needed to communicate with the + SCP. config PWC_RZV2M bool "Renesas RZ/V2M PWC support" if COMPILE_TEST @@ -486,6 +497,7 @@ config SYSC_RZ bool "System controller for RZ SoCs" if COMPILE_TEST select MFD_SYSCON + select AUXILIARY_BUS config SYSC_R9A08G045 bool "Renesas System controller support for R9A08G045 (RZ/G3S)" if COMPILE_TEST @@ -494,6 +506,8 @@ config SYSC_R9A08G046 bool "Renesas System controller support for R9A08G046 (RZ/G3L)" if COMPILE_TEST select SYSC_RZ + select POWER_SEQUENCING + select POWER_SEQUENCING_RENESAS_PWRRDY config SYS_R9A09G047 bool "Renesas System controller support for R9A09G047 (RZ/G3E)" if COMPILE_TEST
diff --git a/drivers/soc/renesas/r9a08g046-sysc.c b/drivers/soc/renesas/r9a08g046-sysc.c index 90db9d3..cd129c7 100644 --- a/drivers/soc/renesas/r9a08g046-sysc.c +++ b/drivers/soc/renesas/r9a08g046-sysc.c
@@ -76,6 +76,7 @@ static const struct rz_sysc_soc_id_init_data rzg3l_sysc_soc_id_init_data __initc .devid_offset = 0xa04, .revision_mask = GENMASK(31, 28), .specific_id_mask = GENMASK(27, 0), + .pwrrdy_pwrseq = true, }; const struct rz_sysc_init_data rzg3l_sysc_init_data __initconst = {
diff --git a/drivers/soc/renesas/rcar-mfis.c b/drivers/soc/renesas/rcar-mfis.c index 3435c3e..d5bbc30 100644 --- a/drivers/soc/renesas/rcar-mfis.c +++ b/drivers/soc/renesas/rcar-mfis.c
@@ -8,6 +8,7 @@ */ #include <dt-bindings/soc/renesas,r8a78000-mfis.h> #include <linux/device.h> +#include <linux/hwspinlock.h> #include <linux/interrupt.h> #include <linux/io.h> #include <linux/kernel.h> @@ -19,12 +20,18 @@ #include <linux/platform_device.h> #include <linux/spinlock.h> +/* FIXME: hwspinlock core refactoring to not need internal header is on-going */ +#include "../../hwspinlock/hwspinlock_internal.h" + +#define MFISLCKR0 0xc0 +#define MFISLCKR8 0x0724 #define MFISWPCNTR 0x0900 #define MFISWACNTR 0x0904 #define MFIS_X5H_IICR(i) ((i) * 0x1000 + 0x00) #define MFIS_X5H_EICR(i) ((i) * 0x1000 + 0x04) +#define MFIS_NUM_LOCKS 64 #define MFIS_UNPROTECT_KEY 0xACCE0000 struct mfis_priv; @@ -42,6 +49,7 @@ struct mfis_info { unsigned int mb_tx_uses_eicr:1; unsigned int mb_channels_are_unidir:1; u32 (*mb_calc_reg)(u32 chan_num, bool tx_uses_eicr, bool is_only_rx); + int hwsp_base_id; }; struct mfis_chan_priv { @@ -50,7 +58,7 @@ struct mfis_chan_priv { }; struct mfis_priv { - spinlock_t unprotect_lock; /* guards access to the unprotection reg */ + raw_spinlock_t unprotect_lock; /* guards access to unprotection reg */ struct device *dev; struct mfis_reg common_reg; struct mfis_reg mbox_reg; @@ -59,6 +67,9 @@ struct mfis_priv { /* mailbox private data */ struct mbox_controller mbox; struct mfis_chan_priv *chan_privs; + + /* hwspinlock private data */ + struct hwspinlock_device bank; /* flex array inside, must be last! */ }; static u32 mfis_read(struct mfis_reg *mreg, unsigned int reg) @@ -80,13 +91,45 @@ static void mfis_write(struct mfis_reg *mreg, u32 reg, u32 val) unprotect_code = (MFIS_UNPROTECT_KEY & ~unprotect_mask) | ((mreg->start + reg) & unprotect_mask); - spin_lock_irqsave(&priv->unprotect_lock, flags); + raw_spin_lock_irqsave(&priv->unprotect_lock, flags); iowrite32(unprotect_code, priv->common_reg.base + MFISWACNTR); iowrite32(val, mreg->base + reg); - spin_unlock_irqrestore(&priv->unprotect_lock, flags); + raw_spin_unlock_irqrestore(&priv->unprotect_lock, flags); } /******************************************************** + * HW Spinlocks * + ********************************************************/ + +#define MFISLCKR8_CH_OFS (MFISLCKR8 - 8 * sizeof(u32)) + +static int rcar_mfis_hwsp_trylock(struct hwspinlock *lock) +{ + struct mfis_priv *priv = lock->priv; + int id = hwlock_to_id(lock) - lock->bank->base_id; + u32 val, reg; + + reg = id * sizeof(u32) + (id < 8 ? MFISLCKR0 : MFISLCKR8_CH_OFS); + val = mfis_read(&priv->common_reg, reg); + return !val; +} + +static void rcar_mfis_hwsp_unlock(struct hwspinlock *lock) +{ + struct mfis_priv *priv = lock->priv; + int id = hwlock_to_id(lock) - lock->bank->base_id; + u32 reg; + + reg = id * sizeof(u32) + (id < 8 ? MFISLCKR0 : MFISLCKR8_CH_OFS); + mfis_write(&priv->common_reg, reg, 0); +} + +static const struct hwspinlock_ops rcar_mfis_hwsp_ops = { + .trylock = rcar_mfis_hwsp_trylock, + .unlock = rcar_mfis_hwsp_unlock, +}; + +/******************************************************** * Mailbox * ********************************************************/ @@ -314,7 +357,7 @@ static int mfis_probe(struct platform_device *pdev) struct mfis_priv *priv; int ret; - priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + priv = devm_kzalloc(dev, struct_size(priv, bank.lock, MFIS_NUM_LOCKS), GFP_KERNEL); if (!priv) return -ENOMEM; @@ -323,7 +366,7 @@ static int mfis_probe(struct platform_device *pdev) if (!priv->info) return -ENOENT; - spin_lock_init(&priv->unprotect_lock); + raw_spin_lock_init(&priv->unprotect_lock); ret = mfis_reg_probe(pdev, priv, &priv->common_reg, "common", true); if (ret) @@ -333,6 +376,14 @@ static int mfis_probe(struct platform_device *pdev) if (ret) return ret; + for (unsigned int ch = 0; ch < MFIS_NUM_LOCKS; ch++) + priv->bank.lock[ch].priv = priv; + + ret = devm_hwspin_lock_register(dev, &priv->bank, &rcar_mfis_hwsp_ops, + priv->info->hwsp_base_id, MFIS_NUM_LOCKS); + if (ret) + return ret; + return mfis_mb_probe(priv); } @@ -357,6 +408,7 @@ static const struct mfis_info mfis_info_r8a78000_scp = { .mb_tx_uses_eicr = true, .mb_channels_are_unidir = true, .mb_calc_reg = mfis_mb_r8a78000_calc_reg, + .hwsp_base_id = MFIS_NUM_LOCKS, }; static const struct of_device_id mfis_mfd_of_match[] = {
diff --git a/drivers/soc/renesas/rcar-rst.c b/drivers/soc/renesas/rcar-rst.c index 0541990..26f9768 100644 --- a/drivers/soc/renesas/rcar-rst.c +++ b/drivers/soc/renesas/rcar-rst.c
@@ -93,6 +93,7 @@ static const struct of_device_id rcar_rst_matches[] __initconst = { { .compatible = "renesas,r8a77470-rst", .data = &rcar_rst_gen2 }, /* RZ/G2 is handled like R-Car Gen3 */ { .compatible = "renesas,r8a774a1-rst", .data = &rcar_rst_gen3 }, + { .compatible = "renesas,r8a774a3-rst", .data = &rcar_rst_gen3 }, { .compatible = "renesas,r8a774b1-rst", .data = &rcar_rst_gen3 }, { .compatible = "renesas,r8a774c0-rst", .data = &rcar_rst_gen3 }, { .compatible = "renesas,r8a774e1-rst", .data = &rcar_rst_gen3 },
diff --git a/drivers/soc/renesas/renesas-soc.c b/drivers/soc/renesas/renesas-soc.c index 18acca7..5a5d050 100644 --- a/drivers/soc/renesas/renesas-soc.c +++ b/drivers/soc/renesas/renesas-soc.c
@@ -312,6 +312,9 @@ static const struct of_device_id renesas_socs[] __initconst __maybe_unused = { #ifdef CONFIG_ARCH_R8A774A1 { .compatible = "renesas,r8a774a1", .data = &soc_rz_g2m }, #endif +#ifdef CONFIG_ARCH_R8A774A3 + { .compatible = "renesas,r8a774a3", .data = &soc_rz_g2m }, +#endif #ifdef CONFIG_ARCH_R8A774B1 { .compatible = "renesas,r8a774b1", .data = &soc_rz_g2n }, #endif
diff --git a/drivers/soc/renesas/rz-sysc.c b/drivers/soc/renesas/rz-sysc.c index 161e8c3..0e92c41 100644 --- a/drivers/soc/renesas/rz-sysc.c +++ b/drivers/soc/renesas/rz-sysc.c
@@ -5,6 +5,7 @@ * Copyright (C) 2024 Renesas Electronics Corp. */ +#include <linux/auxiliary_bus.h> #include <linux/bitfield.h> #include <linux/cleanup.h> #include <linux/io.h> @@ -149,6 +150,10 @@ static int rz_sysc_probe(struct platform_device *pdev) if (IS_ERR(regmap)) return PTR_ERR(regmap); + if (data->soc_id_init_data->pwrrdy_pwrseq && + !devm_auxiliary_device_create(dev, "pwrseq-pwrrdy", regmap)) + return -ENODEV; + return of_syscon_register_regmap(dev->of_node, regmap); }
diff --git a/drivers/soc/renesas/rz-sysc.h b/drivers/soc/renesas/rz-sysc.h index 921ee0d..e55f325 100644 --- a/drivers/soc/renesas/rz-sysc.h +++ b/drivers/soc/renesas/rz-sysc.h
@@ -20,6 +20,7 @@ * @revision_mask: SYSC SoC ID revision mask * @specific_id_mask: SYSC SoC ID specific ID mask * @print_id: print SoC-specific extended device identification + * @pwrrdy_pwrseq: has pwrrdy register controlled through power sequencer */ struct rz_sysc_soc_id_init_data { const char * const family; @@ -29,6 +30,7 @@ struct rz_sysc_soc_id_init_data { u32 specific_id_mask; void (*print_id)(struct device *dev, void __iomem *sysc_base, struct soc_device_attribute *soc_dev_attr); + bool pwrrdy_pwrseq; }; /**
diff --git a/drivers/soc/samsung/exynos-chipid.c b/drivers/soc/samsung/exynos-chipid.c index 6ef9751..506a0bc 100644 --- a/drivers/soc/samsung/exynos-chipid.c +++ b/drivers/soc/samsung/exynos-chipid.c
@@ -64,6 +64,7 @@ static const struct exynos_soc_id { { "EXYNOS8890", 0xE8890000 }, /* Compatible with: samsung,exynos850-chipid */ { "EXYNOS2200", 0xE9925000 }, + { "EXYNOS5515", 0xE5515000 }, { "EXYNOS7885", 0xE7885000 }, { "EXYNOS850", 0xE3830000 }, { "EXYNOS8895", 0xE8895000 },
diff --git a/drivers/soc/samsung/exynos-pmu.c b/drivers/soc/samsung/exynos-pmu.c index efccdd6..702f7d2 100644 --- a/drivers/soc/samsung/exynos-pmu.c +++ b/drivers/soc/samsung/exynos-pmu.c
@@ -38,6 +38,8 @@ struct exynos_pmu_context { unsigned long *in_cpuhp; bool sys_insuspend; bool sys_inreboot; + int cpuhp_prepare_state; + int cpuhp_online_state; }; void __iomem *pmu_base_addr; @@ -59,11 +61,14 @@ void exynos_sys_powerdown_conf(enum sys_powerdown mode) { unsigned int i; const struct exynos_pmu_data *pmu_data; + struct exynos_pmu_context *ctx; - if (!pmu_context || !pmu_context->pmu_data) + /* Pairs with the smp_store_release() in exynos_pmu_probe(). */ + ctx = smp_load_acquire(&pmu_context); + if (!ctx || !ctx->pmu_data) return; - pmu_data = pmu_context->pmu_data; + pmu_data = ctx->pmu_data; if (pmu_data->powerdown_conf) pmu_data->powerdown_conf(mode); @@ -458,22 +463,62 @@ static int setup_cpuhp_and_cpuidle(struct device *dev) gs101_cpuhp_pmu_online(cpu); /* register CPU hotplug callbacks */ - cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "soc/exynos-pmu:prepare", - gs101_cpuhp_pmu_online, NULL); + pmu_context->cpuhp_prepare_state = CPUHP_INVALID; + pmu_context->cpuhp_online_state = CPUHP_INVALID; - cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "soc/exynos-pmu:online", - NULL, gs101_cpuhp_pmu_offline); + ret = cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "soc/exynos-pmu:prepare", + gs101_cpuhp_pmu_online, NULL); + if (ret < 0) + return ret; + + pmu_context->cpuhp_prepare_state = ret; + + ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "soc/exynos-pmu:online", + NULL, gs101_cpuhp_pmu_offline); + if (ret < 0) + goto clean_cpuhp_state_prepare; + + pmu_context->cpuhp_online_state = ret; /* register CPU PM notifiers for cpuidle */ - cpu_pm_register_notifier(&gs101_cpu_pm_notifier); - register_reboot_notifier(&exynos_cpupm_reboot_nb); - return 0; + ret = cpu_pm_register_notifier(&gs101_cpu_pm_notifier); + if (ret) + goto clean_cpuhp_states; + + ret = register_reboot_notifier(&exynos_cpupm_reboot_nb); + if (!ret) + /* Success */ + return ret; + + cpu_pm_unregister_notifier(&gs101_cpu_pm_notifier); + +clean_cpuhp_states: + cpuhp_remove_state(pmu_context->cpuhp_online_state); + pmu_context->cpuhp_online_state = CPUHP_INVALID; + +clean_cpuhp_state_prepare: + cpuhp_remove_state(pmu_context->cpuhp_prepare_state); + pmu_context->cpuhp_prepare_state = CPUHP_INVALID; + + return ret; +} + +static void destroy_cpuhp_and_cpuidle(void) +{ + cpu_pm_unregister_notifier(&gs101_cpu_pm_notifier); + unregister_reboot_notifier(&exynos_cpupm_reboot_nb); + + if (pmu_context->cpuhp_prepare_state != CPUHP_INVALID) + cpuhp_remove_state(pmu_context->cpuhp_prepare_state); + if (pmu_context->cpuhp_online_state != CPUHP_INVALID) + cpuhp_remove_state(pmu_context->cpuhp_online_state); } static int exynos_pmu_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct regmap_config pmu_regmcfg; + struct exynos_pmu_context *ctx; struct regmap *regmap; struct resource *res; int ret; @@ -482,12 +527,19 @@ static int exynos_pmu_probe(struct platform_device *pdev) if (IS_ERR(pmu_base_addr)) return PTR_ERR(pmu_base_addr); - pmu_context = devm_kzalloc(&pdev->dev, - sizeof(struct exynos_pmu_context), - GFP_KERNEL); - if (!pmu_context) + ctx = devm_kzalloc(&pdev->dev, sizeof(struct exynos_pmu_context), + GFP_KERNEL); + if (!ctx) return -ENOMEM; + /* + * exynos_sys_powerdown_conf() gates on pmu_context and then writes + * through pmu_base_addr, which is a separate global. Publish the + * context with release semantics so that the mapping is visible to + * a CPU that passes the gate. + */ + smp_store_release(&pmu_context, ctx); + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) return -ENODEV; @@ -541,8 +593,12 @@ static int exynos_pmu_probe(struct platform_device *pdev) ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_NONE, exynos_pmu_devs, ARRAY_SIZE(exynos_pmu_devs), NULL, 0, NULL); - if (ret) + if (ret) { + if (pmu_context->pmu_data && pmu_context->pmu_data->pmu_cpuhp) + destroy_cpuhp_and_cpuidle(); + return ret; + } if (devm_of_platform_populate(dev)) dev_err(dev, "Error populating children, reboot and poweroff might not work properly\n");
diff --git a/drivers/soc/st/Kconfig b/drivers/soc/st/Kconfig new file mode 100644 index 0000000..2a9d6a7 --- /dev/null +++ b/drivers/soc/st/Kconfig
@@ -0,0 +1,12 @@ +# SPDX-License-Identifier: GPL-2.0-only +menu "ST SoC drivers" + +config SOC_STM32MP2 + tristate "STM32MP2 SoC family support" + depends on ARCH_STM32 || COMPILE_TEST + default ARCH_STM32 && ARM64 + select SOC_BUS + help + If you say yes here, you get support for the ST STM32MP2 family + +endmenu
diff --git a/drivers/soc/st/Makefile b/drivers/soc/st/Makefile new file mode 100644 index 0000000..5ca3134 --- /dev/null +++ b/drivers/soc/st/Makefile
@@ -0,0 +1 @@ +obj-$(CONFIG_SOC_STM32MP2) += stm32mp2-syscfg.o
diff --git a/drivers/soc/st/stm32mp2-syscfg.c b/drivers/soc/st/stm32mp2-syscfg.c new file mode 100644 index 0000000..770321a --- /dev/null +++ b/drivers/soc/st/stm32mp2-syscfg.c
@@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2026 Marek Vasut + */ + +#include <linux/module.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> + +static int stm32mp2_syscfg_probe(struct platform_device *pdev) +{ + return devm_of_platform_populate(&pdev->dev); +} + +static const struct of_device_id stm32mp2_syscfg_ids[] = { + { .compatible = "st,stm32mp23-syscfg" }, + { .compatible = "st,stm32mp25-syscfg" }, + { } +}; +MODULE_DEVICE_TABLE(of, stm32mp2_syscfg_ids); + +static struct platform_driver stm32mp2_syscfg_driver = { + .driver = { + .name = "stm32mp2_syscfg", + .of_match_table = stm32mp2_syscfg_ids, + }, + .probe = stm32mp2_syscfg_probe, +}; +module_platform_driver(stm32mp2_syscfg_driver); + +MODULE_AUTHOR("Marek Vasut <marex@nabladev.com>"); +MODULE_DESCRIPTION("ST STM32MP2 SYSCFG driver"); +MODULE_LICENSE("GPL");
diff --git a/drivers/soc/starfive/Kconfig b/drivers/soc/starfive/Kconfig new file mode 100644 index 0000000..04b0200 --- /dev/null +++ b/drivers/soc/starfive/Kconfig
@@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0-only +menu "StarFive SoC (System On Chip) specific Drivers" + +source "drivers/soc/starfive/socinfo/Kconfig" + +endmenu
diff --git a/drivers/soc/starfive/Makefile b/drivers/soc/starfive/Makefile new file mode 100644 index 0000000..ca1e609 --- /dev/null +++ b/drivers/soc/starfive/Makefile
@@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-y += socinfo/
diff --git a/drivers/soc/starfive/socinfo/Kconfig b/drivers/soc/starfive/socinfo/Kconfig new file mode 100644 index 0000000..64f1b1e0 --- /dev/null +++ b/drivers/soc/starfive/socinfo/Kconfig
@@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-only + +config STARFIVE_JHB100_SOCINFO + bool "StarFive JHB100 SoC Information" + depends on ARCH_STARFIVE || COMPILE_TEST + select SOC_BUS + select MFD_CORE + select MFD_SYSCON + default y + help + Include support for the SoC bus socinfo for the StarFive JHB100 SoC + platforms to provide information about the SoC family and variant + to user space.
diff --git a/drivers/soc/starfive/socinfo/Makefile b/drivers/soc/starfive/socinfo/Makefile new file mode 100644 index 0000000..26c2bdf --- /dev/null +++ b/drivers/soc/starfive/socinfo/Makefile
@@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0-only +obj-$(CONFIG_STARFIVE_JHB100_SOCINFO) += jhb100-socinfo.o
diff --git a/drivers/soc/starfive/socinfo/jhb100-socinfo.c b/drivers/soc/starfive/socinfo/jhb100-socinfo.c new file mode 100644 index 0000000..0a31cae --- /dev/null +++ b/drivers/soc/starfive/socinfo/jhb100-socinfo.c
@@ -0,0 +1,105 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (C) 2025 StarFive Technology Co., Ltd. + * + * Author: Changhuang Liang <changhuang.liang@starfivetech.com> + */ + +#include <linux/bitfield.h> +#include <linux/device.h> +#include <linux/mfd/core.h> +#include <linux/mfd/syscon.h> +#include <linux/of.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/sys_soc.h> + +#define JHB100_REV_ID 0x38 +#define JHB100_REV_ID_CHAR GENMASK(3, 2) +#define JHB100_REV_ID_NUM GENMASK(1, 0) + +/* + * The sys0 system controller region only contains the PLL controls, this + * revision ID register and a few debug registers, so instead of describing + * a child node in the devicetree the PLL device is instantiated from here. + */ +static const struct mfd_cell jhb100_sys0_syscon_cells[] = { + { .name = "jhb100-sys0-pll", }, +}; + +static void jhb100_socinfo_unregister(void *data) +{ + soc_device_unregister(data); +} + +static int jhb100_socinfo_probe(struct platform_device *pdev) +{ + struct soc_device_attribute *attrs; + struct device *dev = &pdev->dev; + struct soc_device *soc_dev; + struct regmap *regmap; + char rev_char; + u32 rev_id; + int ret; + + regmap = syscon_node_to_regmap(dev->of_node); + if (IS_ERR(regmap)) + return dev_err_probe(dev, PTR_ERR(regmap), + "failed to get syscon regmap\n"); + + ret = regmap_read(regmap, JHB100_REV_ID, &rev_id); + if (ret) + return dev_err_probe(dev, ret, "failed to read revision ID\n"); + + attrs = devm_kzalloc(dev, sizeof(*attrs), GFP_KERNEL); + if (!attrs) + return -ENOMEM; + + rev_char = FIELD_GET(JHB100_REV_ID_CHAR, rev_id) + 'A'; + + attrs->family = "JH"; + attrs->soc_id = "JHB100"; + attrs->revision = devm_kasprintf(dev, GFP_KERNEL, "%c%lu", rev_char, + FIELD_GET(JHB100_REV_ID_NUM, rev_id)); + if (!attrs->revision) + return -ENOMEM; + + soc_dev = soc_device_register(attrs); + if (IS_ERR(soc_dev)) + return dev_err_probe(dev, PTR_ERR(soc_dev), + "failed to register SoC device\n"); + + ret = devm_add_action_or_reset(dev, jhb100_socinfo_unregister, soc_dev); + if (ret) + return ret; + + ret = devm_mfd_add_devices(dev, PLATFORM_DEVID_AUTO, + jhb100_sys0_syscon_cells, + ARRAY_SIZE(jhb100_sys0_syscon_cells), + NULL, 0, NULL); + if (ret) + return dev_err_probe(dev, ret, "failed to add mfd cells\n"); + + dev_info(dev, "StarFive %s SoC rev(%s)\n", attrs->soc_id, attrs->revision); + + return 0; +} + +static const struct of_device_id jhb100_socinfo_of_match[] = { + { .compatible = "starfive,jhb100-sys0-syscon" }, + { /* sentinel */ } +}; + +static struct platform_driver jhb100_socinfo_driver = { + .probe = jhb100_socinfo_probe, + .driver = { + .name = "jhb100-socinfo", + .of_match_table = jhb100_socinfo_of_match, + }, +}; + +static int __init jhb100_socinfo_init(void) +{ + return platform_driver_register(&jhb100_socinfo_driver); +} +subsys_initcall(jhb100_socinfo_init);
diff --git a/drivers/soc/tegra/cbb/tegra194-cbb.c b/drivers/soc/tegra/cbb/tegra194-cbb.c index 69ef929..be35ec0 100644 --- a/drivers/soc/tegra/cbb/tegra194-cbb.c +++ b/drivers/soc/tegra/cbb/tegra194-cbb.c
@@ -1912,7 +1912,7 @@ static bool print_errlog0(struct seq_file *file, struct tegra194_cbb *cbb) /* * Print debug information about failed transaction using - * ErrLog registers of error loggger having ErrVld set + * ErrLog registers of error logger having ErrVld set */ static bool print_errloggerX_info(struct seq_file *file, struct tegra194_cbb *cbb, int errloggerX)
diff --git a/drivers/soc/tegra/flowctrl.c b/drivers/soc/tegra/flowctrl.c index 221202d..d5c3af5 100644 --- a/drivers/soc/tegra/flowctrl.c +++ b/drivers/soc/tegra/flowctrl.c
@@ -195,11 +195,14 @@ static int __init tegra_flowctrl_init(void) np = of_find_matching_node(NULL, tegra_flowctrl_match); if (np) { - if (of_address_to_resource(np, 0, &res) < 0) { + int err = of_address_to_resource(np, 0, &res); + + of_node_put(np); + + if (err < 0) { pr_err("failed to get flowctrl register\n"); return -ENXIO; } - of_node_put(np); } else if (IS_ENABLED(CONFIG_ARM)) { /* * Hardcoded fallback for 32-bit Tegra
diff --git a/drivers/soc/tegra/fuse/fuse-tegra.c b/drivers/soc/tegra/fuse/fuse-tegra.c index 3965496..04075e2 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra.c +++ b/drivers/soc/tegra/fuse/fuse-tegra.c
@@ -34,6 +34,7 @@ static const char *tegra_revision_name[TEGRA_REVISION_MAX] = { [TEGRA_REVISION_A03] = "A03", [TEGRA_REVISION_A03p] = "A03 prime", [TEGRA_REVISION_A04] = "A04", + [TEGRA_REVISION_B01] = "B01", }; static const char *tegra_platform_name[TEGRA_PLATFORM_MAX] = { @@ -65,6 +66,9 @@ static struct tegra_fuse *fuse = &(struct tegra_fuse) { }; static const struct of_device_id tegra_fuse_match[] = { +#ifdef CONFIG_ARCH_TEGRA_264_SOC + { .compatible = "nvidia,tegra264-efuse", .data = &tegra264_fuse_soc }, +#endif #ifdef CONFIG_ARCH_TEGRA_234_SOC { .compatible = "nvidia,tegra234-efuse", .data = &tegra234_fuse_soc }, #endif @@ -176,6 +180,11 @@ static int tegra_fuse_probe(struct platform_device *pdev) fuse->soc = &tegra241_fuse_soc; break; #endif +#if defined(CONFIG_ARCH_TEGRA_264_SOC) + case TEGRA264: + fuse->soc = &tegra264_fuse_soc; + break; +#endif default: return dev_err_probe(&pdev->dev, -EINVAL, "Unsupported SoC: %02x\n", chip); } @@ -413,7 +422,8 @@ const struct attribute_group tegra_soc_attr_group = { #if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \ IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) || \ - IS_ENABLED(CONFIG_ARCH_TEGRA_241_SOC) + IS_ENABLED(CONFIG_ARCH_TEGRA_241_SOC) || \ + IS_ENABLED(CONFIG_ARCH_TEGRA_264_SOC) static ssize_t platform_show(struct device *dev, struct device_attribute *attr, char *buf) {
diff --git a/drivers/soc/tegra/fuse/fuse-tegra30.c b/drivers/soc/tegra/fuse/fuse-tegra30.c index 2fad8b1..6238481 100644 --- a/drivers/soc/tegra/fuse/fuse-tegra30.c +++ b/drivers/soc/tegra/fuse/fuse-tegra30.c
@@ -39,7 +39,8 @@ defined(CONFIG_ARCH_TEGRA_186_SOC) || \ defined(CONFIG_ARCH_TEGRA_194_SOC) || \ defined(CONFIG_ARCH_TEGRA_234_SOC) || \ - defined(CONFIG_ARCH_TEGRA_241_SOC) + defined(CONFIG_ARCH_TEGRA_241_SOC) || \ + defined(CONFIG_ARCH_TEGRA_264_SOC) static u32 tegra30_fuse_read_early(struct tegra_fuse *fuse, unsigned int offset) { if (WARN_ON(!fuse->base)) @@ -802,3 +803,168 @@ const struct tegra_fuse_soc tegra241_fuse_soc = { .soc_attr_group = &tegra194_soc_attr_group, }; #endif + +#ifdef CONFIG_ARCH_TEGRA_264_SOC +static const struct nvmem_keepout tegra264_fuse_keepouts[] = { + { .start = 0x0019c, .end = 0x001a0 }, + { .start = 0x00308, .end = 0x00310 }, + { .start = 0x0032c, .end = 0x00334 }, + { .start = 0x00350, .end = 0x00354 }, + { .start = 0x00494, .end = 0x0049c }, + { .start = 0x0078c, .end = 0x00790 }, + { .start = 0x007a0, .end = 0x007a8 }, + { .start = 0x007dc, .end = 0x007e4 }, + { .start = 0x008d8, .end = 0x008dc }, + { .start = 0x0096c, .end = 0x00970 }, + { .start = 0x00974, .end = 0x0097c }, + { .start = 0x009f4, .end = 0x009f8 }, + { .start = 0x00a14, .end = 0x00a20 }, + { .start = 0x00a44, .end = 0x00a4c }, + { .start = 0x00a50, .end = 0x00a58 }, + { .start = 0x00a5c, .end = 0x00a64 }, + { .start = 0x00a68, .end = 0x00a70 }, + { .start = 0x00acc, .end = 0x00ad0 }, + { .start = 0x00b0c, .end = 0x00b18 }, + { .start = 0x00c80, .end = 0x00c8c }, + { .start = 0x00dac, .end = 0x00db4 }, + { .start = 0x00db8, .end = 0x00dbc }, + { .start = 0x00e0c, .end = 0x00e10 }, + { .start = 0x00fd0, .end = 0x01f00 }, + { .start = 0x01f1c, .end = 0x10064 }, + { .start = 0x10084, .end = 0x100a0 }, + { .start = 0x100a4, .end = 0x1019c }, + { .start = 0x101a0, .end = 0x101cc }, + { .start = 0x101d0, .end = 0x10308 }, + { .start = 0x10310, .end = 0x1055c }, + { .start = 0x1057c, .end = 0x106b0 }, + { .start = 0x106b4, .end = 0x11008 }, + { .start = 0x1100c, .end = 0x11018 }, + { .start = 0x11020, .end = 0x110b8 }, + { .start = 0x110c4, .end = 0x110c8 }, + { .start = 0x110e8, .end = 0x110ec }, + { .start = 0x110f0, .end = 0x11124 }, + { .start = 0x11128, .end = 0x11168 }, + { .start = 0x1116c, .end = 0x111b8 }, + { .start = 0x111bc, .end = 0x111e4 }, + { .start = 0x111e8, .end = 0x111ec }, + { .start = 0x111f0, .end = 0x1121c }, + { .start = 0x11250, .end = 0x1133c }, + { .start = 0x11340, .end = 0x113c8 }, + { .start = 0x113d0, .end = 0x11420 }, + { .start = 0x11430, .end = 0x11440 }, + { .start = 0x11444, .end = 0x11468 }, + { .start = 0x1146c, .end = 0x114a8 }, + { .start = 0x114ac, .end = 0x115cc }, + { .start = 0x115d0, .end = 0x115dc }, + { .start = 0x115e0, .end = 0x116b4 }, + { .start = 0x116bc, .end = 0x11740 }, + { .start = 0x11744, .end = 0x117b8 }, + { .start = 0x117bc, .end = 0x11810 }, + { .start = 0x11814, .end = 0x11850 }, + { .start = 0x11858, .end = 0x118a0 }, + { .start = 0x118ac, .end = 0x11b48 }, + { .start = 0x11b50, .end = 0x11b5c }, + { .start = 0x11b60, .end = 0x11bf8 }, + { .start = 0x11bfc, .end = 0x11c18 }, + { .start = 0x11c40, .end = 0x12000 }, + { .start = 0x12004, .end = 0x12010 }, + { .start = 0x12014, .end = 0x120fc }, + { .start = 0x1211c, .end = 0x12120 }, + { .start = 0x12124, .end = 0x12144 }, + { .start = 0x1214c, .end = 0x12300 }, + { .start = 0x12308, .end = 0x1236c }, + { .start = 0x12370, .end = 0x126ac }, + { .start = 0x126b0, .end = 0x12c60 }, + { .start = 0x12c64, .end = 0x12d94 }, + { .start = 0x12da4, .end = 0x13004 }, + { .start = 0x13008, .end = 0x1300c }, + { .start = 0x13010, .end = 0x13014 }, + { .start = 0x13018, .end = 0x13020 }, + { .start = 0x13064, .end = 0x13084 }, + { .start = 0x130a0, .end = 0x130a4 }, + { .start = 0x130b8, .end = 0x130c4 }, + { .start = 0x130c8, .end = 0x130e8 }, + { .start = 0x130ec, .end = 0x130f0 }, + { .start = 0x130fc, .end = 0x1311c }, + { .start = 0x13120, .end = 0x13128 }, + { .start = 0x13144, .end = 0x1314c }, + { .start = 0x13168, .end = 0x1316c }, + { .start = 0x1319c, .end = 0x131a0 }, + { .start = 0x131ac, .end = 0x131c0 }, + { .start = 0x131cc, .end = 0x131d0 }, + { .start = 0x131e4, .end = 0x131e8 }, + { .start = 0x131ec, .end = 0x131f0 }, + { .start = 0x1321c, .end = 0x13250 }, + { .start = 0x132f0, .end = 0x13310 }, + { .start = 0x1332c, .end = 0x13334 }, + { .start = 0x1333c, .end = 0x13344 }, + { .start = 0x13350, .end = 0x13354 }, + { .start = 0x1336c, .end = 0x13370 }, + { .start = 0x133ac, .end = 0x133b0 }, + { .start = 0x133c8, .end = 0x133d0 }, + { .start = 0x13420, .end = 0x13430 }, + { .start = 0x13440, .end = 0x13444 }, + { .start = 0x13468, .end = 0x13470 }, + { .start = 0x13494, .end = 0x1349c }, + { .start = 0x134a8, .end = 0x134ac }, + { .start = 0x13544, .end = 0x1354c }, + { .start = 0x1355c, .end = 0x1357c }, + { .start = 0x135cc, .end = 0x135e0 }, + { .start = 0x135e4, .end = 0x13608 }, + { .start = 0x1360c, .end = 0x13620 }, + { .start = 0x136ac, .end = 0x136bc }, + { .start = 0x136c0, .end = 0x136c8 }, + { .start = 0x13714, .end = 0x13718 }, + { .start = 0x13724, .end = 0x13728 }, + { .start = 0x1372c, .end = 0x13730 }, + { .start = 0x13734, .end = 0x1373c }, + { .start = 0x13740, .end = 0x13744 }, + { .start = 0x13754, .end = 0x13758 }, + { .start = 0x13760, .end = 0x13784 }, + { .start = 0x1378c, .end = 0x13790 }, + { .start = 0x137a0, .end = 0x137a8 }, + { .start = 0x137b8, .end = 0x137bc }, + { .start = 0x137dc, .end = 0x137e4 }, + { .start = 0x137ec, .end = 0x137f0 }, + { .start = 0x13800, .end = 0x13818 }, + { .start = 0x13820, .end = 0x13828 }, + { .start = 0x13830, .end = 0x13858 }, + { .start = 0x138a0, .end = 0x138b0 }, + { .start = 0x138d0, .end = 0x138dc }, + { .start = 0x1396c, .end = 0x13970 }, + { .start = 0x13974, .end = 0x1397c }, + { .start = 0x139f4, .end = 0x139f8 }, + { .start = 0x13a14, .end = 0x13a20 }, + { .start = 0x13a44, .end = 0x13a4c }, + { .start = 0x13a50, .end = 0x13a58 }, + { .start = 0x13a5c, .end = 0x13a64 }, + { .start = 0x13a68, .end = 0x13a70 }, + { .start = 0x13acc, .end = 0x13ad8 }, + { .start = 0x13b0c, .end = 0x13b18 }, + { .start = 0x13b48, .end = 0x13b50 }, + { .start = 0x13b5c, .end = 0x13b60 }, + { .start = 0x13bf8, .end = 0x13bfc }, + { .start = 0x13c18, .end = 0x13c40 }, + { .start = 0x13c60, .end = 0x13c64 }, + { .start = 0x13c74, .end = 0x13c8c }, + { .start = 0x13d94, .end = 0x13da4 }, + { .start = 0x13dac, .end = 0x13db4 }, + { .start = 0x13db8, .end = 0x13dbc }, + { .start = 0x13df4, .end = 0x13e04 }, + { .start = 0x13e0c, .end = 0x13e10 }, +}; + +static const struct tegra_fuse_info tegra264_fuse_info = { + .read = tegra30_fuse_read, + .size = 0x13eb8, +}; + +const struct tegra_fuse_soc tegra264_fuse_soc = { + .init = tegra30_fuse_init, + .info = &tegra264_fuse_info, + .keepouts = tegra264_fuse_keepouts, + .num_keepouts = ARRAY_SIZE(tegra264_fuse_keepouts), + .soc_attr_group = &tegra194_soc_attr_group, + .clk_suspend_on = false, +}; +#endif
diff --git a/drivers/soc/tegra/fuse/fuse.h b/drivers/soc/tegra/fuse/fuse.h index 9fee6ad..0fb9750 100644 --- a/drivers/soc/tegra/fuse/fuse.h +++ b/drivers/soc/tegra/fuse/fuse.h
@@ -125,7 +125,8 @@ extern const struct tegra_fuse_soc tegra186_fuse_soc; #if IS_ENABLED(CONFIG_ARCH_TEGRA_194_SOC) || \ IS_ENABLED(CONFIG_ARCH_TEGRA_234_SOC) || \ - IS_ENABLED(CONFIG_ARCH_TEGRA_241_SOC) + IS_ENABLED(CONFIG_ARCH_TEGRA_241_SOC) || \ + IS_ENABLED(CONFIG_ARCH_TEGRA_264_SOC) extern const struct attribute_group tegra194_soc_attr_group; #endif @@ -141,4 +142,8 @@ extern const struct tegra_fuse_soc tegra234_fuse_soc; extern const struct tegra_fuse_soc tegra241_fuse_soc; #endif +#ifdef CONFIG_ARCH_TEGRA_264_SOC +extern const struct tegra_fuse_soc tegra264_fuse_soc; +#endif + #endif
diff --git a/drivers/soc/tegra/fuse/speedo-tegra210.c b/drivers/soc/tegra/fuse/speedo-tegra210.c index 06c2bcb..699751f 100644 --- a/drivers/soc/tegra/fuse/speedo-tegra210.c +++ b/drivers/soc/tegra/fuse/speedo-tegra210.c
@@ -65,7 +65,25 @@ static void __init rev_sku_to_speedo_ids(struct tegra_sku_info *sku_info, sku_info->gpu_speedo_id = 0; *threshold = THRESHOLD_INDEX_0; - if (sku_info->revision >= TEGRA_REVISION_A02) { + if (sku_info->revision >= TEGRA_REVISION_B01) { + sku_info->gpu_speedo_id = 1; + + switch (sku) { + case 0x00: /* Engineering SKU */ + case 0x01: /* Engineering SKU */ + case 0x83: + break; + + case 0x87: + sku_info->cpu_speedo_id = 3; + break; + + default: + pr_err("Tegra210B01: unknown SKU %#04x\n", sku); + /* Using the default for the error case */ + break; + } + } else if (sku_info->revision >= TEGRA_REVISION_A02) { switch (sku) { case 0x00: /* Engineering SKU */ case 0x01: /* Engineering SKU */ @@ -154,7 +172,7 @@ void __init tegra210_init_speedo_data(struct tegra_sku_info *sku_info) speedo_revision = get_speedo_revision(); pr_info("Speedo Revision %u\n", speedo_revision); - if (speedo_revision >= 3) { + if (sku_info->revision == TEGRA_REVISION_B01 || speedo_revision >= 3) { sku_info->cpu_speedo_value = cpu_speedo[0]; sku_info->gpu_speedo_value = cpu_speedo[2]; sku_info->soc_speedo_value = soc_speedo[0];
diff --git a/drivers/soc/tegra/fuse/tegra-apbmisc.c b/drivers/soc/tegra/fuse/tegra-apbmisc.c index f86c88f..3ad4629 100644 --- a/drivers/soc/tegra/fuse/tegra-apbmisc.c +++ b/drivers/soc/tegra/fuse/tegra-apbmisc.c
@@ -167,30 +167,41 @@ static const struct of_device_id apbmisc_match[] __initconst = { void __init tegra_init_revision(void) { - u8 chip_id, minor_rev; + u8 chip_id, major_rev, minor_rev; chip_id = tegra_get_chip_id(); + major_rev = tegra_get_major_rev(); minor_rev = tegra_get_minor_rev(); - switch (minor_rev) { - case 1: - tegra_sku_info.revision = TEGRA_REVISION_A01; - break; - case 2: - tegra_sku_info.revision = TEGRA_REVISION_A02; - break; - case 3: - if (chip_id == TEGRA20 && (tegra_fuse_read_spare(18) || - tegra_fuse_read_spare(19))) - tegra_sku_info.revision = TEGRA_REVISION_A03p; - else - tegra_sku_info.revision = TEGRA_REVISION_A03; - break; - case 4: - tegra_sku_info.revision = TEGRA_REVISION_A04; - break; - default: - tegra_sku_info.revision = TEGRA_REVISION_UNKNOWN; + if (major_rev > 1) { + switch (minor_rev) { + case 1: + tegra_sku_info.revision = TEGRA_REVISION_B01; + break; + default: + tegra_sku_info.revision = TEGRA_REVISION_UNKNOWN; + } + } else { + switch (minor_rev) { + case 1: + tegra_sku_info.revision = TEGRA_REVISION_A01; + break; + case 2: + tegra_sku_info.revision = TEGRA_REVISION_A02; + break; + case 3: + if (chip_id == TEGRA20 && (tegra_fuse_read_spare(18) || + tegra_fuse_read_spare(19))) + tegra_sku_info.revision = TEGRA_REVISION_A03p; + else + tegra_sku_info.revision = TEGRA_REVISION_A03; + break; + case 4: + tegra_sku_info.revision = TEGRA_REVISION_A04; + break; + default: + tegra_sku_info.revision = TEGRA_REVISION_UNKNOWN; + } } tegra_sku_info.sku_id = tegra_fuse_read_early(FUSE_SKU_INFO);
diff --git a/drivers/soc/tegra/pmc.c b/drivers/soc/tegra/pmc.c index ea4dfe1..2c70eed 100644 --- a/drivers/soc/tegra/pmc.c +++ b/drivers/soc/tegra/pmc.c
@@ -11,6 +11,7 @@ #define pr_fmt(fmt) "tegra-pmc: " fmt +#include <linux/acpi.h> #include <linux/arm-smccc.h> #include <linux/clk.h> #include <linux/clk-provider.h> @@ -2694,7 +2695,7 @@ tegra_pmc_clk_out_register(struct tegra_pmc *pmc, const struct pmc_clk_init_data *data, unsigned long offset) { - struct clk_init_data init; + struct clk_init_data init = {}; struct pmc_clk *pmc_clk; pmc_clk = devm_kzalloc(pmc->dev, sizeof(*pmc_clk), GFP_KERNEL); @@ -2752,7 +2753,7 @@ tegra_pmc_clk_gate_register(struct tegra_pmc *pmc, const char *name, const char *parent_name, unsigned long offset, u32 shift) { - struct clk_init_data init; + struct clk_init_data init = {}; struct pmc_clk_gate *gate; gate = devm_kzalloc(pmc->dev, sizeof(*gate), GFP_KERNEL); @@ -2980,6 +2981,18 @@ static void tegra_pmc_reset_suspend_mode(void *data) pmc->suspend_mode = TEGRA_SUSPEND_NOT_READY; } +static int tegra_pmc_acpi_probe(struct platform_device *pdev, struct tegra_pmc *pmc) +{ + pmc->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(pmc->base)) + return PTR_ERR(pmc->base); + + tegra_pmc_reset_sysfs_init(pmc); + platform_set_drvdata(pdev, pmc); + + return 0; +} + static int tegra_pmc_probe(struct platform_device *pdev) { struct tegra_pmc *pmc; @@ -3004,6 +3017,9 @@ static int tegra_pmc_probe(struct platform_device *pdev) mutex_init(&pmc->powergates_lock); pmc->dev = &pdev->dev; + if (is_acpi_node(dev_fwnode(&pdev->dev))) + return tegra_pmc_acpi_probe(pdev, pmc); + err = tegra_pmc_parse_dt(pmc, pdev->dev.of_node); if (err < 0) return dev_err_probe(&pdev->dev, err, "failed to parse DT\n"); @@ -3901,6 +3917,67 @@ static const struct tegra_pmc_soc tegra210_pmc_soc = { .has_single_mmio_aperture = true, }; +static const char * const tegra210b01_powergates[] = { + [TEGRA_POWERGATE_CPU] = "crail", + [TEGRA_POWERGATE_3D] = "3d", + [TEGRA_POWERGATE_VENC] = "venc", + [TEGRA_POWERGATE_PCIE] = "pcie", + [TEGRA_POWERGATE_MPE] = "mpe", + [TEGRA_POWERGATE_CPU1] = "cpu1", + [TEGRA_POWERGATE_CPU2] = "cpu2", + [TEGRA_POWERGATE_CPU3] = "cpu3", + [TEGRA_POWERGATE_CPU0] = "cpu0", + [TEGRA_POWERGATE_C0NC] = "c0nc", + [TEGRA_POWERGATE_SOR] = "sor", + [TEGRA_POWERGATE_DIS] = "dis", + [TEGRA_POWERGATE_DISB] = "disb", + [TEGRA_POWERGATE_XUSBA] = "xusba", + [TEGRA_POWERGATE_XUSBB] = "xusbb", + [TEGRA_POWERGATE_XUSBC] = "xusbc", + [TEGRA_POWERGATE_VIC] = "vic", + [TEGRA_POWERGATE_IRAM] = "iram", + [TEGRA_POWERGATE_NVDEC] = "nvdec", + [TEGRA_POWERGATE_NVJPG] = "nvjpg", + [TEGRA_POWERGATE_AUD] = "aud", + [TEGRA_POWERGATE_DFD] = "dfd", +}; + +static const struct tegra_pmc_soc tegra210b01_pmc_soc = { + .supports_core_domain = false, + .num_powergates = ARRAY_SIZE(tegra210b01_powergates), + .powergates = tegra210b01_powergates, + .num_cpu_powergates = ARRAY_SIZE(tegra210_cpu_powergates), + .cpu_powergates = tegra210_cpu_powergates, + .has_tsense_reset = true, + .has_gpu_clamps = true, + .needs_mbist_war = false, + .has_io_pad_wren = true, + .maybe_tz_only = true, + .num_io_pads = ARRAY_SIZE(tegra210_io_pads), + .io_pads = tegra210_io_pads, + .num_io_pad_vctrls = ARRAY_SIZE(tegra210_io_pad_vctrls), + .io_pad_vctrls = tegra210_io_pad_vctrls, + .num_pin_descs = ARRAY_SIZE(tegra210_pin_descs), + .pin_descs = tegra210_pin_descs, + .regs = &tegra20_pmc_regs, + .init = tegra20_pmc_init, + .setup_irq_polarity = tegra20_pmc_setup_irq_polarity, + .powergate_set = tegra114_powergate_set, + .irq_set_wake = tegra210_pmc_irq_set_wake, + .irq_set_type = tegra210_pmc_irq_set_type, + .reset_sources = tegra210_reset_sources, + .num_reset_sources = ARRAY_SIZE(tegra210_reset_sources), + .reset_levels = NULL, + .num_reset_levels = 0, + .num_wake_events = ARRAY_SIZE(tegra210_wake_events), + .wake_events = tegra210_wake_events, + .pmc_clks_data = tegra_pmc_clks_data, + .num_pmc_clks = ARRAY_SIZE(tegra_pmc_clks_data), + .has_blink_output = true, + .has_usb_sleepwalk = true, + .has_single_mmio_aperture = true, +}; + static const struct tegra_io_pad_soc tegra186_io_pads[] = { TEGRA_IO_PAD(TEGRA_IO_PAD_CSIA, 0, 0x74, 0x78, "csia"), TEGRA_IO_PAD(TEGRA_IO_PAD_CSIB, 1, 0x74, 0x78, "csib"), @@ -4422,6 +4499,7 @@ static const char * const tegra234_reset_sources[] = { }; static const struct tegra_wake_event tegra234_wake_events[] = { + TEGRA_WAKE_GPIO("pcie-wake", 1, 0, TEGRA234_MAIN_GPIO(L, 2)), TEGRA_WAKE_GPIO("sd-wake", 8, 0, TEGRA234_MAIN_GPIO(G, 7)), TEGRA_WAKE_GPIO("eqos", 20, 0, TEGRA234_MAIN_GPIO(G, 4)), TEGRA_WAKE_IRQ("pmu", 24, 209), @@ -4821,6 +4899,81 @@ static const struct tegra_pmc_soc tegra264_pmc_soc = { .max_wake_vectors = 4, }; +static const char * const tegra410_reset_sources[] = { + "SYS_RESET_N", /* 0x0 */ + "CSDC_RTC_XTAL", + "VREFRO_POWER_BAD", + "FMON_32K", + "FMON_OSC", + "POD_RTC", + "POD_IO", + "POD_PLUS_IO_SPLL", + "POD_PLUS_IO_VMON", /* 0x8 */ + "POD_PLUS_SOC", + "VMON_PLUS_UV", + "VMON_PLUS_OV", + "FUSECRC_FAULT", + "OSC_FAULT", + "BPMP_BOOT_FAULT", + "SCPM_BPMP_CORE_CLK", + "SCPM_PSC_SE_CLK", /* 0x10 */ + "VMON_SOC_MIN", + "VMON_SOC_MAX", + "NVJTAG_SEL_MONITOR", + "L0_RST_REQ_N", + "NV_THERM_FAULT", + "PSC_SW", + "POD_C2C_LPI_0", + "POD_C2C_LPI_1", /* 0x18 */ + "BPMP_FMON", + "FMON_SPLL_OUT", + "L1_RST_REQ_N", + "OCP_RECOVERY", + "AO_WDT_POR", + "BPMP_WDT_POR", + "RAS_WDT_POR", + "TOP_0_WDT_POR", /* 0x20 */ + "TOP_1_WDT_POR", + "TOP_2_WDT_POR", + "PSC_WDT_POR", + "OOBHUB_WDT_POR", + "MSS_SEQ_WDT_POR", + "SW_MAIN", + "L0L1_RST_OUT_N", + "HSM", /* 0x28 */ + "CSITE_SW", + "AO_WDT_DBG", + "BPMP_WDT_DBG", + "RAS_WDT_DBG", + "TOP_0_WDT_DBG", + "TOP_1_WDT_DBG", + "TOP_2_WDT_DBG", + "PSC_WDT_DBG", /* 0x30 */ + "TSC_0_WDT_DBG", + "TSC_1_WDT_DBG", + "OOBHUB_WDT_DBG", + "MSS_SEQ_WDT_DBG", + "L2_RST_REQ_N", + "L2_RST_OUT_N", + "SC7" +}; + +static const struct tegra_pmc_regs tegra410_pmc_regs = { + .rst_status = 0x8, + .rst_source_shift = 0x2, + .rst_source_mask = 0xfc, + .rst_level_shift = 0x0, + .rst_level_mask = 0x3, +}; + +static const struct tegra_pmc_soc tegra410_pmc_soc = { + .regs = &tegra410_pmc_regs, + .reset_sources = tegra410_reset_sources, + .num_reset_sources = ARRAY_SIZE(tegra410_reset_sources), + .reset_levels = tegra186_reset_levels, + .num_reset_levels = ARRAY_SIZE(tegra186_reset_levels), +}; + static const struct of_device_id tegra_pmc_match[] = { { .compatible = "nvidia,tegra264-pmc", .data = &tegra264_pmc_soc }, { .compatible = "nvidia,tegra238-pmc", .data = &tegra238_pmc_soc }, @@ -4828,6 +4981,7 @@ static const struct of_device_id tegra_pmc_match[] = { { .compatible = "nvidia,tegra194-pmc", .data = &tegra194_pmc_soc }, { .compatible = "nvidia,tegra186-pmc", .data = &tegra186_pmc_soc }, { .compatible = "nvidia,tegra210-pmc", .data = &tegra210_pmc_soc }, + { .compatible = "nvidia,tegra210b01-pmc", .data = &tegra210b01_pmc_soc }, { .compatible = "nvidia,tegra132-pmc", .data = &tegra124_pmc_soc }, { .compatible = "nvidia,tegra124-pmc", .data = &tegra124_pmc_soc }, { .compatible = "nvidia,tegra114-pmc", .data = &tegra114_pmc_soc }, @@ -4836,6 +4990,12 @@ static const struct of_device_id tegra_pmc_match[] = { { } }; +static const struct acpi_device_id tegra_pmc_acpi_match[] = { + { .id = "NVDA2016", .driver_data = (kernel_ulong_t)&tegra410_pmc_soc }, + { } +}; +MODULE_DEVICE_TABLE(acpi, tegra_pmc_acpi_match); + static void tegra_pmc_sync_state(struct device *dev) { struct tegra_pmc *pmc = dev_get_drvdata(dev); @@ -4887,6 +5047,7 @@ static struct platform_driver tegra_pmc_driver = { .name = "tegra-pmc", .suppress_bind_attrs = true, .of_match_table = tegra_pmc_match, + .acpi_match_table = tegra_pmc_acpi_match, #if defined(CONFIG_PM_SLEEP) && defined(CONFIG_ARM) .pm = &tegra_pmc_pm_ops, #endif
diff --git a/drivers/soc/ti/knav_qmss_queue.c b/drivers/soc/ti/knav_qmss_queue.c index 3e40414..6186454 100644 --- a/drivers/soc/ti/knav_qmss_queue.c +++ b/drivers/soc/ti/knav_qmss_queue.c
@@ -509,7 +509,7 @@ static int knav_queue_flush(struct knav_queue *qh) /** * knav_queue_open() - open a hardware queue * @name: - name to give the queue handle - * @id: - desired queue number if any or specifes the type + * @id: - desired queue number if any or specifies the type * of queue * @flags: - the following flags are applicable to queues: * KNAV_QUEUE_SHARED - allow the queue to be shared. Queues are @@ -805,7 +805,7 @@ void *knav_pool_create(const char *name, } /* Region maintains a sorted (by region offset) list of pools - * use the first free slot which is large enough to accomodate + * use the first free slot which is large enough to accommodate * the request */ last_offset = 0;
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index a0f37e2..49088e5 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig
@@ -63,7 +63,6 @@ config SPI_AIROHA_SNFI tristate "Airoha SPI NAND Flash Interface" depends on ARCH_AIROHA || COMPILE_TEST - depends on SPI_MASTER select REGMAP_MMIO help This enables support for SPI-NAND mode on the Airoha NAND @@ -92,6 +91,14 @@ Altera SPI master controller. The SPI master is connected to a SPI slave to Avalon bridge in a Intel MAX BMC. +config SPI_AMD + tristate "AMD SPI controller" + depends on PCI + depends on X86 || COMPILE_TEST + depends on SPI_MEM + help + Enables SPI controller driver for AMD SoC. + config SPI_AMLOGIC_SPIFC_A1 tristate "Amlogic A1 SPIFC controller" depends on ARCH_MESON || COMPILE_TEST @@ -136,6 +143,13 @@ This enables support for the SPI controller present on the Qualcomm Atheros AR934X/QCA95XX SoCs. +config SPI_ARMADA_3700 + tristate "Marvell Armada 3700 SPI Controller" + depends on (ARCH_MVEBU && OF) || COMPILE_TEST + help + This enables support for the SPI controller present on the + Marvell Armada 3700 SoCs. + config SPI_ATCSPI200 tristate "Andes ATCSPI200 SPI controller" depends on ARCH_ANDES || COMPILE_TEST @@ -153,13 +167,6 @@ This enables support for the SPI controller present on the Atheros AR71XX/AR724X/AR913X SoCs. -config SPI_ARMADA_3700 - tristate "Marvell Armada 3700 SPI Controller" - depends on (ARCH_MVEBU && OF) || COMPILE_TEST - help - This enables support for the SPI controller present on the - Marvell Armada 3700 SoCs. - config SPI_ASPEED_SMC tristate "Aspeed flash controllers in SPI mode" depends on ARCH_ASPEED || COMPILE_TEST @@ -333,7 +340,7 @@ config SPI_CH341 tristate "CH341 USB2SPI adapter" - depends on SPI_MASTER && USB + depends on USB help Enables the SPI controller on the CH341a USB to serial chip @@ -388,14 +395,14 @@ endif config SPI_DLN2 - tristate "Diolan DLN-2 USB SPI adapter" - depends on MFD_DLN2 - help - If you say yes to this option, support will be included for Diolan - DLN2, a USB to SPI interface. + tristate "Diolan DLN-2 USB SPI adapter" + depends on MFD_DLN2 + help + If you say yes to this option, support will be included for Diolan + DLN2, a USB to SPI interface. - This driver can also be built as a module. If so, the module - will be called spi-dln2. + This driver can also be built as a module. If so, the module + will be called spi-dln2. config SPI_EP93XX tristate "Cirrus Logic EP93xx SPI controller" @@ -420,6 +427,22 @@ This enables support for the driver for FSI bus attached SPI controllers. +config SPI_FSL_DSPI + tristate "Freescale DSPI controller" + select REGMAP_MMIO + depends on ARCH_MXC || ARCH_NXP || M5441x || COMPILE_TEST + help + This enables support for the Freescale DSPI controller in master + mode. S32, VF610, LS1021A and ColdFire platforms uses the controller. + +config SPI_FSL_ESPI + tristate "Freescale eSPI controller" + depends on FSL_SOC + help + This enables using the Freescale eSPI controllers in master mode. + From MPC8536, 85xx platform uses the controller, and all P10xx, + P20xx, P30xx,P40xx, P50xx uses this controller. + config SPI_FSL_LPSPI tristate "Freescale i.MX LPSPI controller" depends on ARCH_MXC || COMPILE_TEST @@ -438,6 +461,26 @@ This controller does not support generic SPI messages. It only supports the high-level SPI memory interface. +config SPI_FSL_LIB + tristate + depends on OF + +config SPI_FSL_CPM + tristate + depends on FSL_SOC + +config SPI_FSL_SPI + tristate "Freescale SPI controller and Aeroflex Gaisler GRLIB SPI controller" + depends on OF + select SPI_FSL_LIB + select SPI_FSL_CPM if FSL_SOC + help + This enables using the Freescale SPI controllers in master mode. + MPC83xx platform uses the controller in cpu mode or CPM/QE mode. + MPC8569 uses the controller in QE mode, MPC8610 in cpu mode. + This also enables using the Aeroflex Gaisler GRLIB SPI controller in + master mode. + config SPI_GXP tristate "GXP SPI driver" depends on ARCH_HPE || COMPILE_TEST @@ -463,27 +506,6 @@ This enables support for HiSilicon v3xx SPI NOR flash controller found in hi16xx chipsets. -config SPI_NXP_FLEXSPI - tristate "NXP Flex SPI controller" - depends on ARCH_LAYERSCAPE || ARCH_MXC || COMPILE_TEST - depends on HAS_IOMEM - help - This enables support for the Flex SPI controller in master mode. - Up to four slave devices can be connected on two buses with two - chipselects each. - This controller does not support generic SPI messages and only - supports the high-level SPI memory interface. - -config SPI_NXP_XSPI - tristate "NXP xSPI controller" - depends on ARCH_MXC || COMPILE_TEST - depends on HAS_IOMEM - help - This enables support for the xSPI controller. Up to two devices - can be connected to one host. - This controller does not support generic SPI messages and only - supports the high-level SPI memory interface. - config SPI_GPIO tristate "GPIO-based bitbanging SPI Master" depends on GPIOLIB || COMPILE_TEST @@ -581,6 +603,25 @@ This driver can also be built as a module. If so, the module will be called spi-kspi2. +config SPI_LANTIQ_SSC + tristate "Lantiq SSC SPI controller" + depends on LANTIQ || X86 || COMPILE_TEST + help + This driver supports the Lantiq SSC SPI controller in master + mode. This controller is found on Intel (former Lantiq) SoCs like + the Danube, Falcon, xRX200, xRX300, Lightning Mountain. + +config SPI_LJCA + tristate "Intel La Jolla Cove Adapter SPI support" + depends on USB_LJCA + default USB_LJCA + help + Select this option to enable SPI driver for the Intel + La Jolla Cove Adapter (LJCA) board. + + This driver can also be built as a module. If so, the module + will be called spi-ljca. + config SPI_LM70_LLP tristate "Parallel port adapter for LM70 eval board (DEVELOPMENT)" depends on PARPORT @@ -626,73 +667,16 @@ Say N here unless you plan to run the kernel on an ICP DAS LP-8x4x industrial computer. -config SPI_MPC52xx - tristate "Freescale MPC52xx SPI (non-PSC) controller support" - depends on PPC_MPC52xx +config SPI_MA35D1 + tristate "Nuvoton MA35D1 SPI controller" + depends on ARCH_MA35 || COMPILE_TEST help - This drivers supports the MPC52xx SPI controller in master SPI - mode. + This enables support for the SPI controller found in + Nuvoton MA35D1 SoCs. -config SPI_MPC52xx_PSC - tristate "Freescale MPC52xx PSC SPI controller" - depends on PPC_MPC52xx - help - This enables using the Freescale MPC52xx Programmable Serial - Controller in master SPI mode. - -config SPI_MPC512x_PSC - tristate "Freescale MPC512x PSC SPI controller" - depends on PPC_MPC512x - help - This enables using the Freescale MPC5121 Programmable Serial - Controller in SPI master mode. - -config SPI_FSL_LIB - tristate - depends on OF - -config SPI_FSL_CPM - tristate - depends on FSL_SOC - -config SPI_FSL_SPI - tristate "Freescale SPI controller and Aeroflex Gaisler GRLIB SPI controller" - depends on OF - select SPI_FSL_LIB - select SPI_FSL_CPM if FSL_SOC - help - This enables using the Freescale SPI controllers in master mode. - MPC83xx platform uses the controller in cpu mode or CPM/QE mode. - MPC8569 uses the controller in QE mode, MPC8610 in cpu mode. - This also enables using the Aeroflex Gaisler GRLIB SPI controller in - master mode. - -config SPI_FSL_DSPI - tristate "Freescale DSPI controller" - select REGMAP_MMIO - depends on ARCH_MXC || ARCH_NXP || M5441x || COMPILE_TEST - help - This enables support for the Freescale DSPI controller in master - mode. S32, VF610, LS1021A and ColdFire platforms uses the controller. - -config SPI_FSL_ESPI - tristate "Freescale eSPI controller" - depends on FSL_SOC - help - This enables using the Freescale eSPI controllers in master mode. - From MPC8536, 85xx platform uses the controller, and all P10xx, - P20xx, P30xx,P40xx, P50xx uses this controller. - -config SPI_LJCA - tristate "Intel La Jolla Cove Adapter SPI support" - depends on USB_LJCA - default USB_LJCA - help - Select this option to enable SPI driver for the Intel - La Jolla Cove Adapter (LJCA) board. - - This driver can also be built as a module. If so, the module - will be called spi-ljca. + The controller supports standard SPI peripheral devices with + configurable clock polarity and phase, chip select, and data + word sizes from 8 to 32 bits. config SPI_MA35D1_QSPI tristate "Nuvoton MA35D1 QSPI controller" @@ -722,7 +706,6 @@ config SPI_MICROCHIP_CORE_QSPI tristate "Microchip FPGA QSPI controllers" - depends on SPI_MASTER help This enables the QSPI driver for Microchip FPGA QSPI controllers. Say Y or M here if you want to use the QSPI controllers on @@ -731,13 +714,33 @@ config SPI_MICROCHIP_CORE_SPI tristate "Microchip FPGA CoreSPI controller" - depends on SPI_MASTER help This enables the SPI driver for Microchip FPGA CoreSPI controller. Say Y or M here if you want to use the "soft" controllers on PolarFire SoC. If built as a module, it will be called spi-microchip-core-spi. +config SPI_MPC52xx + tristate "Freescale MPC52xx SPI (non-PSC) controller support" + depends on PPC_MPC52xx + help + This drivers supports the MPC52xx SPI controller in master SPI + mode. + +config SPI_MPC52xx_PSC + tristate "Freescale MPC52xx PSC SPI controller" + depends on PPC_MPC52xx + help + This enables using the Freescale MPC52xx Programmable Serial + Controller in master SPI mode. + +config SPI_MPC512x_PSC + tristate "Freescale MPC512x PSC SPI controller" + depends on PPC_MPC512x + help + This enables using the Freescale MPC5121 Programmable Serial + Controller in SPI master mode. + config SPI_MT65XX tristate "MediaTek SPI controller" depends on ARCH_MEDIATEK || COMPILE_TEST @@ -773,6 +776,19 @@ is implemented as a SPI-MEM controller with pipelined ECC capability. +config SPI_MXIC + tristate "Macronix MX25F0A SPI controller" + imply MTD_NAND_ECC_MXIC + help + This selects the Macronix MX25F0A SPI controller driver. + +config SPI_MXS + tristate "Freescale MXS SPI controller" + depends on ARCH_MXS + select STMP_DEVICE + help + SPI driver for Freescale MXS devices. + config SPI_WPCM_FIU tristate "Nuvoton WPCM450 Flash Interface Unit" depends on ARCH_NPCM || COMPILE_TEST @@ -801,13 +817,26 @@ This driver provides support for Nuvoton NPCM BMC Peripheral SPI controller in master mode. -config SPI_LANTIQ_SSC - tristate "Lantiq SSC SPI controller" - depends on LANTIQ || X86 || COMPILE_TEST +config SPI_NXP_FLEXSPI + tristate "NXP Flex SPI controller" + depends on ARCH_LAYERSCAPE || ARCH_MXC || COMPILE_TEST + depends on HAS_IOMEM help - This driver supports the Lantiq SSC SPI controller in master - mode. This controller is found on Intel (former Lantiq) SoCs like - the Danube, Falcon, xRX200, xRX300, Lightning Mountain. + This enables support for the Flex SPI controller in master mode. + Up to four slave devices can be connected on two buses with two + chipselects each. + This controller does not support generic SPI messages and only + supports the high-level SPI memory interface. + +config SPI_NXP_XSPI + tristate "NXP xSPI controller" + depends on ARCH_MXC || COMPILE_TEST + depends on HAS_IOMEM + help + This enables support for the xSPI controller. Up to two devices + can be connected to one host. + This controller does not support generic SPI messages and only + supports the high-level SPI memory interface. config SPI_OC_TINY tristate "OpenCores tiny SPI" @@ -838,14 +867,6 @@ SPI master controller for OMAP24XX and later Multichannel SPI (McSPI) modules. -config SPI_TI_QSPI - tristate "DRA7xxx QSPI controller support" - depends on ARCH_OMAP2PLUS || COMPILE_TEST - help - QSPI master controller for DRA7xxx used for flash devices. - This device supports single, dual and quad read support, while - it only supports single write mode. - config SPI_ORION tristate "Orion SPI master" depends on PLAT_ORION || ARCH_MVEBU || COMPILE_TEST @@ -887,7 +908,6 @@ config SPI_POLARFIRE_SOC tristate "Microchip FPGA SPI controllers" - depends on SPI_MASTER depends on ARCH_MICROCHIP || COMPILE_TEST help This enables the SPI driver for Microchip FPGA SPI controllers. @@ -950,7 +970,7 @@ config SPI_RB4XX tristate "Mikrotik RB4XX SPI master" - depends on SPI_MASTER && (ATH79 || COMPILE_TEST) + depends on ATH79 || COMPILE_TEST depends on OF help SPI controller driver for the Mikrotik RB4xx series boards. @@ -967,6 +987,16 @@ help SPI driver for Renesas RSPI and QSPI blocks. +config SPI_RTK_NOR + tristate "Realtek SPI-NOR flash controller" + depends on ARCH_REALTEK || COMPILE_TEST + depends on SPI_MEM + help + This enables support for the SPI NOR Flash Controller found on + Realtek DHC SoCs. The controller supports single and dual I/O + transfers and offloads the payload to an integrated DMA engine. + Say Y or M here if you are building a kernel for a Realtek DHC SoC + config SPI_RZV2H_RSPI tristate "Renesas RZ/V2H RSPI controller" depends on ARCH_RENESAS || COMPILE_TEST @@ -1035,12 +1065,14 @@ help SPI driver for NXP SC18IS602/602B/603 I2C to SPI bridge. -config SPI_SH_MSIOF - tristate "SuperH MSIOF SPI controller" - depends on HAVE_CLK - depends on ARCH_SHMOBILE || ARCH_RENESAS || COMPILE_TEST +config SPI_SG2044_NOR + tristate "SG2044 SPI NOR Controller" + depends on ARCH_SOPHGO || COMPILE_TEST help - SPI driver for SuperH and SH Mobile MSIOF blocks. + This enables support for the SG2044 SPI NOR controller, + which supports Dual/Quad read and write operations while + also supporting 3Byte address devices and 4Byte address + devices. config SPI_SH tristate "SuperH SPI controller" @@ -1048,6 +1080,19 @@ help SPI driver for SuperH SPI blocks. +config SPI_SH_HSPI + tristate "SuperH HSPI controller" + depends on ARCH_RENESAS || COMPILE_TEST + help + SPI driver for SuperH HSPI blocks. + +config SPI_SH_MSIOF + tristate "SuperH MSIOF SPI controller" + depends on HAVE_CLK + depends on ARCH_SHMOBILE || ARCH_RENESAS || COMPILE_TEST + help + SPI driver for SuperH and SH Mobile MSIOF blocks. + config SPI_SH_SCI tristate "SuperH SCI SPI controller" depends on SUPERH @@ -1055,28 +1100,12 @@ help SPI driver for SuperH SCI blocks. -config SPI_SH_HSPI - tristate "SuperH HSPI controller" - depends on ARCH_RENESAS || COMPILE_TEST - help - SPI driver for SuperH HSPI blocks. - config SPI_SIFIVE tristate "SiFive SPI controller" depends on HAS_IOMEM help This exposes the SPI controller IP from SiFive. -config SPI_SLAVE_MT27XX - tristate "MediaTek SPI slave device" - depends on ARCH_MEDIATEK || COMPILE_TEST - depends on SPI_SLAVE - help - This selects the MediaTek(R) SPI slave device driver. - If you want to use MediaTek(R) SPI slave interface, - say Y or M here.If you are not sure, say N. - SPI slave drivers for Mediatek MT27XX series ARM SoCs. - config SPI_SN_F_OSPI tristate "Socionext F_OSPI SPI flash controller" depends on OF && HAS_IOMEM @@ -1086,15 +1115,6 @@ for connecting an SPI Flash memory over up to 8-bit wide bus. It supports indirect access mode only. -config SPI_SG2044_NOR - tristate "SG2044 SPI NOR Controller" - depends on ARCH_SOPHGO || COMPILE_TEST - help - This enables support for the SG2044 SPI NOR controller, - which supports Dual/Quad read and write operations while - also supporting 3Byte address devices and 4Byte address - devices. - config SPI_SPACEMIT_K1 tristate "K1 SPI Controller" depends on ARCH_SPACEMIT || COMPILE_TEST @@ -1189,20 +1209,6 @@ It also supports the new dual-bit and quad-bit SPI protocol. -config SPI_MXIC - tristate "Macronix MX25F0A SPI controller" - depends on SPI_MASTER - imply MTD_NAND_ECC_MXIC - help - This selects the Macronix MX25F0A SPI controller driver. - -config SPI_MXS - tristate "Freescale MXS SPI controller" - depends on ARCH_MXS - select STMP_DEVICE - help - SPI driver for Freescale MXS devices. - config SPI_TEGRA210_QUAD tristate "NVIDIA Tegra QSPI Controller" depends on ARCH_TEGRA || COMPILE_TEST @@ -1244,6 +1250,23 @@ SPI host driver for the hardware found on Cavium ThunderX SOCs. +config SPI_TI_QSPI + tristate "DRA7xxx QSPI controller support" + depends on ARCH_OMAP2PLUS || COMPILE_TEST + help + QSPI master controller for DRA7xxx used for flash devices. + This device supports single, dual and quad read support, while + it only supports single write mode. + +config SPI_TLE62X0 + tristate "Infineon TLE62X0 (for power switching)" + depends on SYSFS + help + SPI driver for Infineon TLE62X0 series line driver chips, + such as the TLE6220, TLE6230 and TLE6240. This provides a + sysfs interface, with each line presented as a kind of GPIO + exposing both switch control and diagnostic feedback. + config SPI_TOPCLIFF_PCH tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) SPI" depends on PCI && (X86_32 || MIPS || COMPILE_TEST) @@ -1270,7 +1293,7 @@ config SPI_VIRTIO tristate "Virtio SPI Controller" - depends on SPI_MASTER && VIRTIO + depends on VIRTIO help If you say yes to this option, support will be included for the virtio SPI controller driver. The hardware can be emulated by any device model @@ -1336,14 +1359,6 @@ Enables Xilinx GQSPI controller driver for Zynq UltraScale+ MPSoC. This controller only supports SPI memory interface. -config SPI_AMD - tristate "AMD SPI controller" - depends on PCI - depends on SPI_MASTER || X86 || COMPILE_TEST - depends on SPI_MEM - help - Enables SPI controller driver for AMD SoC. - # # Add new SPI master controllers in alphabetical order above this line # @@ -1392,15 +1407,6 @@ primarily used for development of spi_master drivers and to detect regressions -config SPI_TLE62X0 - tristate "Infineon TLE62X0 (for power switching)" - depends on SYSFS - help - SPI driver for Infineon TLE62X0 series line driver chips, - such as the TLE6220, TLE6230 and TLE6240. This provides a - sysfs interface, with each line presented as a kind of GPIO - exposing both switch control and diagnostic feedback. - # # Add new SPI protocol masters in alphabetical order above this line # @@ -1431,6 +1437,15 @@ SPI slave handler to allow remote control of system reboot, power off, halt, and suspend. +config SPI_SLAVE_MT27XX + tristate "MediaTek SPI slave device" + depends on ARCH_MEDIATEK || COMPILE_TEST + help + This selects the MediaTek(R) SPI slave device driver. + If you want to use MediaTek(R) SPI slave interface, + say Y or M here.If you are not sure, say N. + SPI slave drivers for Mediatek MT27XX series ARM SoCs. + endif # SPI_SLAVE config SPI_DYNAMIC
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index a18814f..b493f50 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile
@@ -86,6 +86,7 @@ obj-$(CONFIG_SPI_LOONGSON_PCI) += spi-loongson-pci.o obj-$(CONFIG_SPI_LOONGSON_PLATFORM) += spi-loongson-plat.o obj-$(CONFIG_SPI_LP8841_RTC) += spi-lp8841-rtc.o +obj-$(CONFIG_SPI_MA35D1) += spi-ma35d1.o obj-$(CONFIG_SPI_MA35D1_QSPI) += spi-ma35d1-qspi.o obj-$(CONFIG_SPI_MESON_SPICC) += spi-meson-spicc.o obj-$(CONFIG_SPI_MESON_SPIFC) += spi-meson-spifc.o @@ -133,6 +134,7 @@ obj-$(CONFIG_SPI_REALTEK_SNAND) += spi-realtek-rtl-snand.o obj-$(CONFIG_SPI_RPCIF) += spi-rpc-if.o obj-$(CONFIG_SPI_RSPI) += spi-rspi.o +obj-$(CONFIG_SPI_RTK_NOR) += spi-rtk-nor.o obj-$(CONFIG_SPI_RZV2H_RSPI) += spi-rzv2h-rspi.o obj-$(CONFIG_SPI_RZV2M_CSI) += spi-rzv2m-csi.o obj-$(CONFIG_SPI_S3C64XX) += spi-s3c64xx.o
diff --git a/drivers/spi/atmel-quadspi.c b/drivers/spi/atmel-quadspi.c index ec19fa0..762a3fb 100644 --- a/drivers/spi/atmel-quadspi.c +++ b/drivers/spi/atmel-quadspi.c
@@ -792,7 +792,7 @@ static int atmel_qspi_dma_xfer(struct atmel_qspi *aq, struct dma_chan *chan, reinit_completion(&aq->dma_completion); tx->callback = atmel_qspi_dma_callback; tx->callback_param = aq; - cookie = tx->tx_submit(tx); + cookie = dmaengine_submit(tx); ret = dma_submit_error(cookie); if (ret) { dev_err(&aq->pdev->dev, "dma_submit_error %d\n", cookie); @@ -1590,12 +1590,14 @@ static int atmel_qspi_suspend(struct device *dev) if (aq->caps->has_gclk) { ret = atmel_qspi_sama7g5_suspend(aq); - clk_disable_unprepare(aq->pclk); - return ret; + if (ret) { + pm_runtime_put_autosuspend(dev); + return ret; + } + } else { + atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR); } - atmel_qspi_write(QSPI_CR_QSPIDIS, aq, QSPI_CR); - pm_runtime_mark_last_busy(dev); pm_runtime_force_suspend(dev); @@ -1621,20 +1623,20 @@ static int atmel_qspi_resume(struct device *dev) return ret; } - if (aq->caps->has_gclk) - return aq->caps->init(aq); - ret = pm_runtime_force_resume(dev); if (ret < 0) return ret; - atmel_qspi_init(aq); - - atmel_qspi_write(aq->scr, aq, QSPI_SCR); + if (aq->caps->has_gclk) { + ret = aq->caps->init(aq); + } else { + atmel_qspi_init(aq); + atmel_qspi_write(aq->scr, aq, QSPI_SCR); + } pm_runtime_put_autosuspend(dev); - return 0; + return ret; } static int atmel_qspi_runtime_suspend(struct device *dev)
diff --git a/drivers/spi/spi-amd.c b/drivers/spi/spi-amd.c index 71a6e5c..ddf89e5 100644 --- a/drivers/spi/spi-amd.c +++ b/drivers/spi/spi-amd.c
@@ -322,11 +322,22 @@ static inline int amd_spi_fifo_xfer(struct amd_spi *amd_spi, list_for_each_entry(xfer, &message->transfers, transfer_list) { + /* Skip zero-length transfers to avoid len underflow below */ + if (!xfer->len) + continue; + if (xfer->speed_hz) amd_set_spi_freq(amd_spi, xfer->speed_hz); else amd_set_spi_freq(amd_spi, spi->max_speed_hz); + /* Reject transfers that would overflow the FIFO window */ + if (fifo_pos + xfer->len > + AMD_SPI_FIFO_BASE + AMD_SPI_FIFO_SIZE) { + message->status = -EMSGSIZE; + goto fin_msg; + } + if (xfer->tx_buf) { buf = (u8 *)xfer->tx_buf; if (!tx_len) { @@ -369,6 +380,12 @@ static inline int amd_spi_fifo_xfer(struct amd_spi *amd_spi, list_for_each_entry(xfer, &message->transfers, transfer_list) if (xfer->rx_buf) { + /* Reject transfers that would overflow the FIFO window */ + if (fifo_pos + xfer->len > + AMD_SPI_FIFO_BASE + AMD_SPI_FIFO_SIZE) { + message->status = -EMSGSIZE; + goto fin_msg; + } buf = (u8 *)xfer->rx_buf; /* Read data from FIFO to receive buffer */ for (i = 0; i < xfer->len; i++)
diff --git a/drivers/spi/spi-amlogic-spisg.c b/drivers/spi/spi-amlogic-spisg.c index 9049a87..1b00f34 100644 --- a/drivers/spi/spi-amlogic-spisg.c +++ b/drivers/spi/spi-amlogic-spisg.c
@@ -37,6 +37,12 @@ #define CFG_HW_POS BIT(6) /* start on vsync falling */ #define CFG_HW_NEG BIT(7) +#define CFG_WORD_GAP GENMASK(9, 8) +#define CFG_MO_IDLE_OUTPUT GENMASK(11, 10) +/* cs hold time in pclk */ +#define CFG_CS_HOLD GENMASK(26, 12) +/* high 4 bits of cs setup time in sclk */ +#define CFG_CS_SETUP_EXTEND GENMASK(30, 27) #define SPISG_REG_CFG_START 0x08 #define CFG_BLOCK_NUM GENMASK(19, 0) @@ -95,7 +101,7 @@ #define SPISG_MAX_REG 0x40 -#define SPISG_BLOCK_MAX 0x100000 +#define SPISG_BLOCK_MAX 0xFFFFF #define SPISG_OP_MODE_WRITE_CMD 0 #define SPISG_OP_MODE_READ_STS 1 @@ -143,6 +149,13 @@ struct spisg_descriptor_extra { int rx_ccsg_len; }; +struct aml_spisg_data { + bool mo_idle_output_ctrl; + bool word_gap_ctrl; + bool cs_hold_ctrl; + bool cs_setup_extend_ctrl; +}; + struct spisg_device { struct spi_controller *controller; struct platform_device *pdev; @@ -152,6 +165,7 @@ struct spisg_device { struct clk *sclk; struct clk_div_table *tbl; struct completion completion; + const struct aml_spisg_data *data; u32 status; u32 speed_hz; u32 effective_speed_hz; @@ -175,7 +189,7 @@ static int spi_delay_to_sclk(u32 slck_speed_hz, struct spi_delay *delay) if (ns < 0) return 0; - return DIV_ROUND_UP_ULL(slck_speed_hz * ns, NSEC_PER_SEC); + return DIV_ROUND_UP_ULL((u64)slck_speed_hz * ns, NSEC_PER_SEC); } static inline u32 aml_spisg_sem_down_read(struct spisg_device *spisg) @@ -424,7 +438,8 @@ static void aml_spisg_setup_null_desc(struct spisg_device *spisg, static void aml_spisg_pending(struct spisg_device *spisg, dma_addr_t desc_paddr, bool trig, - bool irq_en) + bool irq_en, + u32 delay) { u32 desc_l, desc_h, cfg_spi, irq_enable; @@ -437,6 +452,13 @@ static void aml_spisg_pending(struct spisg_device *spisg, #endif cfg_spi = spisg->cfg_spi; + + if (spisg->data && spisg->data->word_gap_ctrl) { + if (delay > 3) + delay = 3; + cfg_spi |= FIELD_PREP(CFG_WORD_GAP, delay); + } + if (trig) cfg_spi |= CFG_HW_POS; else @@ -483,13 +505,16 @@ static int aml_spisg_transfer_one_message(struct spi_controller *ctlr, { struct spisg_device *spisg = spi_controller_get_devdata(ctlr); struct device *dev = &spisg->pdev->dev; + const struct aml_spisg_data *data = spisg->data; unsigned long long ms = 0; struct spi_transfer *xfer; struct spisg_descriptor *descs, *desc; struct spisg_descriptor_extra *exdescs, *exdesc; dma_addr_t descs_paddr; int desc_num = 1, descs_len; + bool last_xfer_keep_ss = false; u32 cs_hold_in_sclk = 0; + u32 val, delay = 0; int ret = -EIO; if (!aml_spisg_sem_down_read(spisg)) { @@ -523,15 +548,27 @@ static int aml_spisg_transfer_one_message(struct spi_controller *ctlr, goto end; } - /* calculate cs-setup delay with the first xfer speed */ - if (list_is_first(&xfer->transfer_list, &msg->transfers)) - desc->cfg_bus |= FIELD_PREP(CFG_CS_SETUP, - spi_delay_to_sclk(xfer->effective_speed_hz, &msg->spi->cs_setup)); + /* calculate cs-setup delay with the first xfer speed and word dealy*/ + if (list_is_first(&xfer->transfer_list, &msg->transfers)) { + val = spi_delay_to_sclk(xfer->effective_speed_hz, &msg->spi->cs_setup); + if (data && data->cs_setup_extend_ctrl) { + val = min_t(u32, 0xFF, val); + desc->cfg_bus |= FIELD_PREP(CFG_CS_SETUP, val & 0xF); + FIELD_MODIFY(CFG_CS_SETUP_EXTEND, &spisg->cfg_spi, val >> 4); + } else { + val = min_t(u32, 0xF, val); + desc->cfg_bus |= FIELD_PREP(CFG_CS_SETUP, val); + } + + delay = spi_delay_to_sclk(xfer->effective_speed_hz, &msg->spi->word_delay); + } /* calculate cs-hold delay with the last xfer speed */ - if (list_is_last(&xfer->transfer_list, &msg->transfers)) + if (list_is_last(&xfer->transfer_list, &msg->transfers)) { cs_hold_in_sclk = spi_delay_to_sclk(xfer->effective_speed_hz, &msg->spi->cs_hold); + last_xfer_keep_ss = xfer->cs_change; + } desc++; exdesc++; @@ -539,13 +576,23 @@ static int aml_spisg_transfer_one_message(struct spi_controller *ctlr, xfer->effective_speed_hz); } - if (cs_hold_in_sclk) + if (data && data->cs_hold_ctrl) { + cs_hold_in_sclk = cs_hold_in_sclk ? : 1; + val = cs_hold_in_sclk * (FIELD_GET(CFG_CLK_DIV, spisg->cfg_bus) + 1); + val = min_t(u32, 0x7FFF, val); + FIELD_MODIFY(CFG_CS_HOLD, &spisg->cfg_spi, val); + desc--; + } else if (cs_hold_in_sclk) { /* additional null-descriptor to achieve the cs-hold delay */ aml_spisg_setup_null_desc(spisg, desc, cs_hold_in_sclk); - else desc--; + desc->cfg_bus |= FIELD_PREP(CFG_KEEP_SS, 1); + desc++; + } else { + desc--; + } - desc->cfg_bus |= FIELD_PREP(CFG_KEEP_SS, 0); + FIELD_MODIFY(CFG_KEEP_SS, &desc->cfg_bus, last_xfer_keep_ss); desc->cfg_start |= FIELD_PREP(CFG_EOC, 1); /* some tolerances */ @@ -562,13 +609,16 @@ static int aml_spisg_transfer_one_message(struct spi_controller *ctlr, } reinit_completion(&spisg->completion); - aml_spisg_pending(spisg, descs_paddr, false, true); + aml_spisg_pending(spisg, descs_paddr, false, true, delay); if (wait_for_completion_timeout(&spisg->completion, spi_controller_is_target(spisg->controller) ? - MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(ms))) + MAX_SCHEDULE_TIMEOUT : msecs_to_jiffies(ms))) { ret = spisg->status ? -EIO : 0; - else + } else { + /* stop transfer */ + regmap_write(spisg->map, SPISG_REG_DESC_LIST_H, 0); ret = -ETIMEDOUT; + } dma_unmap_single(dev, descs_paddr, descs_len, DMA_TO_DEVICE); end: @@ -704,7 +754,9 @@ static int aml_spisg_clk_init(struct spisg_device *spisg, void __iomem *base) return PTR_ERR(spisg->sclk); } - clk_prepare_enable(spisg->sclk); + ret = clk_prepare_enable(spisg->sclk); + if (ret) + return ret; return 0; } @@ -715,6 +767,7 @@ static int aml_spisg_probe(struct platform_device *pdev) struct spisg_device *spisg; struct device *dev = &pdev->dev; void __iomem *base; + u32 val = 0; int ret, irq; const struct regmap_config aml_regmap_config = { @@ -733,6 +786,7 @@ static int aml_spisg_probe(struct platform_device *pdev) spisg = spi_controller_get_devdata(ctlr); spisg->controller = ctlr; + spisg->data = (struct aml_spisg_data *)of_device_get_match_data(dev); spisg->pdev = pdev; platform_set_drvdata(pdev, spisg); @@ -763,6 +817,14 @@ static int aml_spisg_probe(struct platform_device *pdev) spisg->cfg_spi = FIELD_PREP(CFG_SFLASH_WP, 1) | FIELD_PREP(CFG_SFLASH_HD, 1); + + if (spisg->data && spisg->data->mo_idle_output_ctrl) { + if (!of_property_read_u32(dev->of_node, "amlogic,mo-idle-output", &val)) + spisg->cfg_spi |= FIELD_PREP(CFG_MO_IDLE_OUTPUT, val); + else + spisg->cfg_spi |= FIELD_PREP(CFG_MO_IDLE_OUTPUT, 0); + } + if (spi_controller_is_target(ctlr)) { spisg->cfg_spi |= FIELD_PREP(CFG_SLAVE_EN, 1); spisg->cfg_bus = FIELD_PREP(CFG_TX_TUNING, 0xf); @@ -841,14 +903,30 @@ static int spisg_suspend_runtime(struct device *dev) static int spisg_resume_runtime(struct device *dev) { struct spisg_device *spisg = dev_get_drvdata(dev); + int ret; - clk_prepare_enable(spisg->core); - clk_prepare_enable(spisg->sclk); + ret = clk_prepare_enable(spisg->core); + if (ret) + return ret; + + ret = clk_prepare_enable(spisg->sclk); + if (ret) { + clk_disable_unprepare(spisg->core); + return ret; + } + pinctrl_pm_select_default_state(&spisg->pdev->dev); return 0; } +static const struct aml_spisg_data a9_spisg_data = { + .mo_idle_output_ctrl = true, + .word_gap_ctrl = true, + .cs_hold_ctrl = true, + .cs_setup_extend_ctrl = true, +}; + static const struct dev_pm_ops amlogic_spisg_pm_ops = { .runtime_suspend = spisg_suspend_runtime, .runtime_resume = spisg_resume_runtime, @@ -858,6 +936,10 @@ static const struct of_device_id amlogic_spisg_of_match[] = { { .compatible = "amlogic,a4-spisg", }, + { + .compatible = "amlogic,a9-spisg", + .data = &a9_spisg_data, + }, { /* sentinel */ } };
diff --git a/drivers/spi/spi-ar934x.c b/drivers/spi/spi-ar934x.c index 2210186..01e51a3 100644 --- a/drivers/spi/spi-ar934x.c +++ b/drivers/spi/spi-ar934x.c
@@ -197,23 +197,13 @@ static int ar934x_spi_probe(struct platform_device *pdev) SPI_BPW_MASK(16) | SPI_BPW_MASK(8); ctlr->num_chipselect = 3; - dev_set_drvdata(&pdev->dev, ctlr); - sp = spi_controller_get_devdata(ctlr); sp->base = base; sp->clk = clk; sp->clk_freq = clk_get_rate(clk); sp->ctlr = ctlr; - return spi_register_controller(ctlr); -} - -static void ar934x_spi_remove(struct platform_device *pdev) -{ - struct spi_controller *ctlr; - - ctlr = dev_get_drvdata(&pdev->dev); - spi_unregister_controller(ctlr); + return devm_spi_register_controller(&pdev->dev, ctlr); } static struct platform_driver ar934x_spi_driver = { @@ -222,7 +212,6 @@ static struct platform_driver ar934x_spi_driver = { .of_match_table = ar934x_spi_match, }, .probe = ar934x_spi_probe, - .remove = ar934x_spi_remove, }; module_platform_driver(ar934x_spi_driver);
diff --git a/drivers/spi/spi-at91-usart.c b/drivers/spi/spi-at91-usart.c index 804f619..aadcdf7 100644 --- a/drivers/spi/spi-at91-usart.c +++ b/drivers/spi/spi-at91-usart.c
@@ -231,16 +231,16 @@ static int at91_usart_spi_dma_transfer(struct spi_controller *ctlr, rxdesc->callback = dma_callback; rxdesc->callback_param = ctlr; - cookie = rxdesc->tx_submit(rxdesc); + cookie = dmaengine_submit(rxdesc); if (dma_submit_error(cookie)) goto at91_usart_spi_err_dma; - cookie = txdesc->tx_submit(txdesc); + cookie = dmaengine_submit(txdesc); if (dma_submit_error(cookie)) goto at91_usart_spi_err_dma; - rxchan->device->device_issue_pending(rxchan); - txchan->device->device_issue_pending(txchan); + dma_async_issue_pending(rxchan); + dma_async_issue_pending(txchan); return 0;
diff --git a/drivers/spi/spi-atmel.c b/drivers/spi/spi-atmel.c index c8012c8..c107c61 100644 --- a/drivers/spi/spi-atmel.c +++ b/drivers/spi/spi-atmel.c
@@ -871,14 +871,14 @@ static int atmel_spi_next_xfer_dma_submit(struct spi_controller *host, rxdesc->callback_param = host; /* Submit and fire RX and TX with TX last so we're ready to read! */ - cookie = rxdesc->tx_submit(rxdesc); + cookie = dmaengine_submit(rxdesc); if (dma_submit_error(cookie)) goto err_dma; - cookie = txdesc->tx_submit(txdesc); + cookie = dmaengine_submit(txdesc); if (dma_submit_error(cookie)) goto err_dma; - rxchan->device->device_issue_pending(rxchan); - txchan->device->device_issue_pending(txchan); + dma_async_issue_pending(rxchan); + dma_async_issue_pending(txchan); return 0;
diff --git a/drivers/spi/spi-axi-spi-engine.c b/drivers/spi/spi-axi-spi-engine.c index 02bbc5d..ead5b29 100644 --- a/drivers/spi/spi-axi-spi-engine.c +++ b/drivers/spi/spi-axi-spi-engine.c
@@ -887,6 +887,7 @@ static int spi_engine_setup(struct spi_device *device) struct spi_controller *host = device->controller; struct spi_engine *spi_engine = spi_controller_get_devdata(host); unsigned int reg; + int ret; if (device->mode & SPI_CS_HIGH) spi_engine->cs_inv |= BIT(spi_get_chipselect(device, 0)); @@ -922,8 +923,15 @@ static int spi_engine_setup(struct spi_device *device) writel_relaxed(SPI_ENGINE_CMD_SYNC(1), spi_engine->base + SPI_ENGINE_REG_CMD_FIFO); - return readl_relaxed_poll_timeout(spi_engine->base + SPI_ENGINE_REG_SYNC_ID, - reg, reg == 1, 1, 1000); + ret = readl_relaxed_poll_timeout(spi_engine->base + SPI_ENGINE_REG_SYNC_ID, + reg, reg == 1, 1, 1 * USEC_PER_MSEC); + + /* Clear the stale SYNC pending bit so it doesn't fire when the IRQ is later enabled. */ + writel_relaxed(SPI_ENGINE_INT_SYNC, spi_engine->base + SPI_ENGINE_REG_INT_PENDING); + /* Read back to flush posted write. */ + readl_relaxed(spi_engine->base + SPI_ENGINE_REG_INT_PENDING); + + return ret; } static int spi_engine_transfer_one_message(struct spi_controller *host, @@ -1028,7 +1036,13 @@ static int spi_engine_trigger_enable(struct spi_offload *offload) spi_engine->base + SPI_ENGINE_REG_CMD_FIFO); ret = readl_relaxed_poll_timeout(spi_engine->base + SPI_ENGINE_REG_SYNC_ID, - reg, reg == 1, 1, 1000); + reg, reg == 1, 1, 1 * USEC_PER_MSEC); + + /* Clear the stale SYNC pending bit so it doesn't fire when the IRQ is later enabled */ + writel_relaxed(SPI_ENGINE_INT_SYNC, spi_engine->base + SPI_ENGINE_REG_INT_PENDING); + /* Read back to flush posted write. */ + readl_relaxed(spi_engine->base + SPI_ENGINE_REG_INT_PENDING); + if (ret) return ret;
diff --git a/drivers/spi/spi-bcm-qspi.c b/drivers/spi/spi-bcm-qspi.c index 0f96ac5..5031b21 100644 --- a/drivers/spi/spi-bcm-qspi.c +++ b/drivers/spi/spi-bcm-qspi.c
@@ -1197,8 +1197,9 @@ static int bcm_qspi_exec_mem_op(struct spi_mem *mem, u32 addr = 0, len; u_char *buf; + /* cmd[] holds 1 opcode + 4 address + 1 dummy byte at most */ if (!op->data.nbytes || !op->addr.nbytes || op->addr.nbytes > 4 || - op->data.dir != SPI_MEM_DATA_IN) + op->dummy.nbytes > 1 || op->data.dir != SPI_MEM_DATA_IN) return -EOPNOTSUPP; buf = op->data.buf.in;
diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 8f87158..cc57489 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c
@@ -527,7 +527,7 @@ static void bcm2835_spi_transfer_prologue(struct spi_controller *ctlr, | BCM2835_SPI_CS_CLEAR_TX | BCM2835_SPI_CS_DONE); - dma_sync_single_for_device(ctlr->dma_rx->device->dev, + dma_sync_single_for_device(dmaengine_get_dma_device(ctlr->dma_rx), sg_dma_address(&tfr->rx_sg.sgl[0]), bs->rx_prologue, DMA_FROM_DEVICE); @@ -871,7 +871,7 @@ static void bcm2835_dma_release(struct spi_controller *ctlr, dmaengine_desc_free(bs->fill_tx_desc); if (bs->fill_tx_addr) - dma_unmap_page_attrs(ctlr->dma_tx->device->dev, + dma_unmap_page_attrs(dmaengine_get_dma_device(ctlr->dma_tx), bs->fill_tx_addr, sizeof(u32), DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC); @@ -891,6 +891,7 @@ static int bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev, struct bcm2835_spi *bs) { struct dma_slave_config slave_config; + struct device *tx_dma_dev; const __be32 *addr; dma_addr_t dma_reg_base; int ret; @@ -932,11 +933,13 @@ static int bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev, if (ret) goto err_config; - bs->fill_tx_addr = dma_map_page_attrs(ctlr->dma_tx->device->dev, + tx_dma_dev = dmaengine_get_dma_device(ctlr->dma_tx); + + bs->fill_tx_addr = dma_map_page_attrs(tx_dma_dev, ZERO_PAGE(0), 0, sizeof(u32), DMA_TO_DEVICE, DMA_ATTR_SKIP_CPU_SYNC); - if (dma_mapping_error(ctlr->dma_tx->device->dev, bs->fill_tx_addr)) { + if (dma_mapping_error(tx_dma_dev, bs->fill_tx_addr)) { dev_err(dev, "cannot map zero page - not using DMA mode\n"); bs->fill_tx_addr = 0; ret = -ENOMEM; @@ -1157,7 +1160,7 @@ static void bcm2835_spi_cleanup(struct spi_device *spi) dmaengine_desc_free(target->clear_rx_desc); if (target->clear_rx_addr) - dma_unmap_single(ctlr->dma_rx->device->dev, + dma_unmap_single(dmaengine_get_dma_device(ctlr->dma_rx), target->clear_rx_addr, sizeof(u32), DMA_TO_DEVICE); @@ -1174,16 +1177,16 @@ static int bcm2835_spi_setup_dma(struct spi_controller *ctlr, struct bcm2835_spi *bs, struct bcm2835_spidev *target) { + struct device *rx_dev; int ret; if (!ctlr->dma_rx) return 0; - target->clear_rx_addr = dma_map_single(ctlr->dma_rx->device->dev, - &target->clear_rx_cs, - sizeof(u32), - DMA_TO_DEVICE); - if (dma_mapping_error(ctlr->dma_rx->device->dev, target->clear_rx_addr)) { + rx_dev = dmaengine_get_dma_device(ctlr->dma_rx); + target->clear_rx_addr = dma_map_single(rx_dev, &target->clear_rx_cs, + sizeof(u32), DMA_TO_DEVICE); + if (dma_mapping_error(rx_dev, target->clear_rx_addr)) { dev_err(&spi->dev, "cannot map clear_rx_cs\n"); target->clear_rx_addr = 0; return -ENOMEM; @@ -1268,7 +1271,7 @@ static int bcm2835_spi_setup(struct spi_device *spi) target->clear_rx_cs = cs | BCM2835_SPI_CS_TA | BCM2835_SPI_CS_DMAEN | BCM2835_SPI_CS_CLEAR_RX; - dma_sync_single_for_device(ctlr->dma_rx->device->dev, + dma_sync_single_for_device(dmaengine_get_dma_device(ctlr->dma_rx), target->clear_rx_addr, sizeof(u32), DMA_TO_DEVICE); @@ -1297,7 +1300,9 @@ static int bcm2835_spi_setup(struct spi_device *spi) } for (i = 0; i < ARRAY_SIZE(pinctrl_compats); i++) { - if (of_find_compatible_node(NULL, NULL, pinctrl_compats[i])) + struct device_node *np __free(device_node) = + of_find_compatible_node(NULL, NULL, pinctrl_compats[i]); + if (np) break; }
diff --git a/drivers/spi/spi-bcm63xx-hsspi.c b/drivers/spi/spi-bcm63xx-hsspi.c index 25f169a..abfbf97 100644 --- a/drivers/spi/spi-bcm63xx-hsspi.c +++ b/drivers/spi/spi-bcm63xx-hsspi.c
@@ -152,7 +152,7 @@ static ssize_t wait_mode_show(struct device *dev, struct device_attribute *attr, struct spi_controller *ctrl = dev_get_drvdata(dev); struct bcm63xx_hsspi *bs = spi_controller_get_devdata(ctrl); - return sprintf(buf, "%d\n", bs->wait_mode); + return sysfs_emit(buf, "%d\n", bs->wait_mode); } static ssize_t wait_mode_store(struct device *dev, struct device_attribute *attr, @@ -188,7 +188,7 @@ static ssize_t xfer_mode_show(struct device *dev, struct device_attribute *attr, struct spi_controller *ctrl = dev_get_drvdata(dev); struct bcm63xx_hsspi *bs = spi_controller_get_devdata(ctrl); - return sprintf(buf, "%d\n", bs->xfer_mode); + return sysfs_emit(buf, "%d\n", bs->xfer_mode); } static ssize_t xfer_mode_store(struct device *dev, struct device_attribute *attr, @@ -882,6 +882,7 @@ static void bcm63xx_hsspi_remove(struct platform_device *pdev) /* reset the hardware and block queue progress */ __raw_writel(0, bs->regs + HSSPI_INT_MASK_REG); sysfs_remove_group(&pdev->dev.kobj, &bcm63xx_hsspi_group); + pm_runtime_disable(&pdev->dev); } static int bcm63xx_hsspi_suspend(struct device *dev)
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 1d8e257..3f349c1 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c
@@ -413,7 +413,7 @@ static irqreturn_t bcm63xx_spi_interrupt(int irq, void *dev_id) struct bcm63xx_spi *bs = spi_controller_get_devdata(host); u8 intr; - /* Read interupts and clear them immediately */ + /* Read interrupts and clear them immediately */ intr = bcm_spi_readb(bs, SPI_INT_STATUS); bcm_spi_writeb(bs, SPI_INTR_CLEAR_ALL, SPI_INT_STATUS); bcm_spi_writeb(bs, 0, SPI_INT_MASK);
diff --git a/drivers/spi/spi-bcmbca-hsspi.c b/drivers/spi/spi-bcmbca-hsspi.c index 5dc9e0f..8c01475 100644 --- a/drivers/spi/spi-bcmbca-hsspi.c +++ b/drivers/spi/spi-bcmbca-hsspi.c
@@ -129,7 +129,7 @@ static ssize_t wait_mode_show(struct device *dev, struct device_attribute *attr, struct spi_controller *ctrl = dev_get_drvdata(dev); struct bcmbca_hsspi *bs = spi_controller_get_devdata(ctrl); - return sprintf(buf, "%d\n", bs->wait_mode); + return sysfs_emit(buf, "%d\n", bs->wait_mode); } static ssize_t wait_mode_store(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/spi/spi-bitbang.c b/drivers/spi/spi-bitbang.c index fb288ed..347265e 100644 --- a/drivers/spi/spi-bitbang.c +++ b/drivers/spi/spi-bitbang.c
@@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later /* - * Polling/bitbanging SPI host controller controller driver utilities + * Polling/bitbanging SPI host controller driver utilities */ #include <linux/spinlock.h>
diff --git a/drivers/spi/spi-butterfly.c b/drivers/spi/spi-butterfly.c index 84eb454..5e1e205 100644 --- a/drivers/spi/spi-butterfly.c +++ b/drivers/spi/spi-butterfly.c
@@ -259,7 +259,8 @@ static void butterfly_attach(struct parport *p) */ pp->info[0].max_speed_hz = 15 * 1000 * 1000; - strcpy(pp->info[0].modalias, "mtd_dataflash"); + strscpy(pp->info[0].modalias, "mtd_dataflash", + sizeof(pp->info[0].modalias)); pp->info[0].platform_data = &flash; pp->info[0].chip_select = 1; pp->info[0].controller_data = pp;
diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c index 5a5f1a8..73ea51c 100644 --- a/drivers/spi/spi-cadence-quadspi.c +++ b/drivers/spi/spi-cadence-quadspi.c
@@ -1381,7 +1381,7 @@ static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata, return 0; } - ddev = cqspi->rx_chan->device->dev; + ddev = dmaengine_get_dma_device(cqspi->rx_chan); dma_dst = dma_map_single(ddev, buf, len, DMA_FROM_DEVICE); if (dma_mapping_error(ddev, dma_dst)) { dev_err(dev, "dma mapping failed\n"); @@ -1397,7 +1397,7 @@ static int cqspi_direct_read_execute(struct cqspi_flash_pdata *f_pdata, tx->callback = cqspi_rx_dma_callback; tx->callback_param = cqspi; - cookie = tx->tx_submit(tx); + cookie = dmaengine_submit(tx); reinit_completion(&cqspi->rx_dma_complete); ret = dma_submit_error(cookie); @@ -1741,6 +1741,12 @@ static const struct spi_controller_mem_caps cqspi_mem_caps = { .per_op_freq = true, }; +static const struct spi_controller_mem_caps cqspi_am654_mem_caps = { + .dtr = true, + .per_op_freq = true, + .no_cs_assertion = true, +}; + static int cqspi_setup_flash(struct cqspi_st *cqspi) { struct platform_device *pdev = cqspi->pdev; @@ -1798,6 +1804,8 @@ static int cqspi_probe(struct platform_device *pdev) host->mode_bits = SPI_RX_QUAD | SPI_RX_DUAL; host->mem_ops = &cqspi_mem_ops; host->mem_caps = &cqspi_mem_caps; + if (of_device_is_compatible(pdev->dev.of_node, "ti,am654-ospi")) + host->mem_caps = &cqspi_am654_mem_caps; cqspi = spi_controller_get_devdata(host); if (of_device_is_compatible(pdev->dev.of_node, "starfive,jh7110-qspi"))
diff --git a/drivers/spi/spi-cadence-xspi.c b/drivers/spi/spi-cadence-xspi.c index 39c868a..3687853 100644 --- a/drivers/spi/spi-cadence-xspi.c +++ b/drivers/spi/spi-cadence-xspi.c
@@ -268,6 +268,7 @@ #define MRVL_XFER_FUNC_START BIT(0) #define MRVL_XFER_QWORD_COUNT 32 #define MRVL_XFER_QWORD_BYTECOUNT 8 +#define MRVL_XFER_MAX_LEN (MRVL_XFER_QWORD_COUNT * MRVL_XFER_QWORD_BYTECOUNT) #define MRVL_XSPI_POLL_TIMEOUT_US 1000 #define MRVL_XSPI_POLL_DELAY_US 10 @@ -332,6 +333,7 @@ struct cdns_xspi_dev { int irq; int cur_cs; unsigned int sdmasize; + unsigned int sdma_xfer_len; struct completion cmd_complete; struct completion auto_cmd_complete; @@ -346,7 +348,7 @@ struct cdns_xspi_dev { u8 hw_num_banks; const struct cdns_xspi_driver_data *driver_data; - void (*sdma_handler)(struct cdns_xspi_dev *cdns_xspi); + int (*sdma_handler)(struct cdns_xspi_dev *cdns_xspi); void (*set_interrupts_handler)(struct cdns_xspi_dev *cdns_xspi, bool enabled); bool xfer_in_progress; @@ -496,7 +498,7 @@ static inline void cdns_xspi_sdma_write(struct cdns_xspi_dev *cdns_xspi, size_t iowrite8_rep(dst, (const u8 *)buf + offset, len); } -static void cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi) +static int cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi) { u32 sdma_size, sdma_trd_info; u8 sdma_dir; @@ -505,6 +507,13 @@ static void cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi) sdma_trd_info = readl(cdns_xspi->iobase + CDNS_XSPI_SDMA_TRD_INFO_REG); sdma_dir = FIELD_GET(CDNS_XSPI_SDMA_DIR, sdma_trd_info); + if (sdma_size > cdns_xspi->sdma_xfer_len) { + dev_err(cdns_xspi->dev, + "SDMA size %u exceeds the requested length %u\n", + sdma_size, cdns_xspi->sdma_xfer_len); + return -EINVAL; + } + switch (sdma_dir) { case CDNS_XSPI_SDMA_DIR_READ: cdns_xspi_sdma_read(cdns_xspi, sdma_size); @@ -514,6 +523,8 @@ static void cdns_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi) cdns_xspi_sdma_write(cdns_xspi, sdma_size); break; } + + return 0; } static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi, @@ -559,6 +570,7 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi, cdns_xspi->in_buffer = op->data.buf.in; cdns_xspi->out_buffer = op->data.buf.out; + cdns_xspi->sdma_xfer_len = op->data.nbytes; cdns_xspi_trigger_command(cdns_xspi, cmd_regs); @@ -567,7 +579,11 @@ static int cdns_xspi_send_stig_command(struct cdns_xspi_dev *cdns_xspi, cdns_xspi->set_interrupts_handler(cdns_xspi, false); return -EIO; } - cdns_xspi->sdma_handler(cdns_xspi); + ret = cdns_xspi->sdma_handler(cdns_xspi); + if (ret) { + cdns_xspi->set_interrupts_handler(cdns_xspi, false); + return ret; + } } wait_for_completion(&cdns_xspi->cmd_complete); @@ -950,7 +966,7 @@ static void m_iowriteq(void __iomem *addr, const void *buf, int len) } } -static void marvell_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi) +static int marvell_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi) { u32 sdma_size, sdma_trd_info; u8 sdma_dir; @@ -959,6 +975,13 @@ static void marvell_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi) sdma_trd_info = readl(cdns_xspi->iobase + CDNS_XSPI_SDMA_TRD_INFO_REG); sdma_dir = FIELD_GET(CDNS_XSPI_SDMA_DIR, sdma_trd_info); + if (sdma_size > cdns_xspi->sdma_xfer_len) { + dev_err(cdns_xspi->dev, + "SDMA size %u exceeds the requested length %u\n", + sdma_size, cdns_xspi->sdma_xfer_len); + return -EINVAL; + } + switch (sdma_dir) { case CDNS_XSPI_SDMA_DIR_READ: m_ioreadq(cdns_xspi->sdmabase, @@ -970,6 +993,8 @@ static void marvell_xspi_sdma_handle(struct cdns_xspi_dev *cdns_xspi) cdns_xspi->out_buffer, sdma_size); break; } + + return 0; } static const struct spi_controller_mem_ops marvell_xspi_mem_ops = { @@ -1083,7 +1108,7 @@ static int cdns_xspi_transfer_one_message_b0(struct spi_controller *controller, struct spi_device *spi = m->spi; struct spi_transfer *t = NULL; - const unsigned int max_len = MRVL_XFER_QWORD_BYTECOUNT * MRVL_XFER_QWORD_COUNT; + const unsigned int max_len = MRVL_XFER_MAX_LEN; int current_transfer_len; int cs = spi_get_chipselect(spi, 0); int cs_change = 0; @@ -1106,13 +1131,16 @@ static int cdns_xspi_transfer_one_message_b0(struct spi_controller *controller, list_for_each_entry(t, &m->transfers, transfer_list) { u8 *txd = (u8 *) t->tx_buf; u8 *rxd = (u8 *) t->rx_buf; - u8 data[10]; + u8 data[MRVL_XFER_MAX_LEN] = {0}; u32 cmd_regs[6]; if (!txd) txd = data; - cdns_xspi->in_buffer = txd + 1; + if (rxd) + cdns_xspi->in_buffer = rxd; + else + cdns_xspi->in_buffer = data; cdns_xspi->out_buffer = txd + 1; while (t->len) { @@ -1131,14 +1159,18 @@ static int cdns_xspi_transfer_one_message_b0(struct spi_controller *controller, cdns_xspi_prepare_transfer(cs, 1, current_transfer_len - 1, cmd_regs); cdns_xspi_trigger_command(cdns_xspi, cmd_regs); + cdns_xspi->sdma_xfer_len = current_transfer_len - 1; if (!cdns_xspi_is_sdma_ready(cdns_xspi, true)) return -EIO; - cdns_xspi->sdma_handler(cdns_xspi); + if (cdns_xspi->sdma_handler(cdns_xspi)) + return -EIO; if (!cdns_xspi_is_stig_ready(cdns_xspi, true)) return -EIO; - cdns_xspi->in_buffer += current_transfer_len; - cdns_xspi->out_buffer += current_transfer_len; + if (rxd) + cdns_xspi->in_buffer += current_transfer_len; + if (t->tx_buf) + cdns_xspi->out_buffer += current_transfer_len; } if (rxd) {
diff --git a/drivers/spi/spi-ch341.c b/drivers/spi/spi-ch341.c index 6448a44..56a5caa 100644 --- a/drivers/spi/spi-ch341.c +++ b/drivers/spi/spi-ch341.c
@@ -189,6 +189,12 @@ static int ch341_probe(struct usb_interface *intf, ctrl->transfer_one = ch341_transfer_one; ctrl->set_cs = ch341_set_cs; ctrl->auto_runtime_pm = false; + /* + * The CH341A SPI_STREAM command clocks data in both directions on + * every transfer, so the driver always needs a TX and an RX buffer; + * let the SPI core supply dummy buffers for half-duplex transfers. + */ + ctrl->flags = SPI_CONTROLLER_MUST_TX | SPI_CONTROLLER_MUST_RX; usb_set_intfdata(intf, ch341);
diff --git a/drivers/spi/spi-dw-core.c b/drivers/spi/spi-dw-core.c index 206d3f9..47434fa 100644 --- a/drivers/spi/spi-dw-core.c +++ b/drivers/spi/spi-dw-core.c
@@ -32,6 +32,22 @@ struct dw_spi_chip_data { u32 rx_sample_dly; /* RX sample delay */ }; +/* Slave spi_transfer/spi_mem_op related */ +struct dw_spi_cfg { + u8 tmode; + u8 dfs; + u32 ndf; + u32 freq; + u8 spi_frf; +}; + +struct dw_spi_enh_cfg { + u8 wait_c; + u8 inst_l; + u8 addr_l; + u8 trans_t; +}; + #ifdef CONFIG_DEBUG_FS #define DW_SPI_DBGFS_REG(_name, _off) \ @@ -132,10 +148,11 @@ static inline u32 dw_spi_rx_max(struct dw_spi *dws) return min_t(u32, dws->rx_len, dw_readl(dws, DW_SPI_RXFLR)); } -static void dw_writer(struct dw_spi *dws) +static u32 dw_writer(struct dw_spi *dws) { u32 max = dw_spi_tx_max(dws); u32 txw = 0; + u32 tx = 0; while (max--) { if (dws->tx) { @@ -150,13 +167,16 @@ static void dw_writer(struct dw_spi *dws) } dw_write_io_reg(dws, DW_SPI_DR, txw); --dws->tx_len; + ++tx; } + return tx; } -static void dw_reader(struct dw_spi *dws) +static u32 dw_reader(struct dw_spi *dws) { u32 max = dw_spi_rx_max(dws); u32 rxw; + u32 rx = 0; while (max--) { rxw = dw_read_io_reg(dws, DW_SPI_DR); @@ -171,7 +191,9 @@ static void dw_reader(struct dw_spi *dws) dws->rx += dws->n_bytes; } --dws->rx_len; + ++rx; } + return rx; } int dw_spi_check_status(struct dw_spi *dws, bool raw) @@ -210,9 +232,55 @@ int dw_spi_check_status(struct dw_spi *dws, bool raw) } EXPORT_SYMBOL_NS_GPL(dw_spi_check_status, "SPI_DW_CORE"); +static irqreturn_t dw_spi_irq_thread_fn(int irq, void *dev_id) +{ + struct spi_controller *ctlr = dev_id; + struct dw_spi *dws = spi_controller_get_devdata(ctlr); + u32 rx, tx, imask, mask = 0; + bool finalize = false; + + do { + /* + * Read data from the Rx FIFO every time we've got a chance executing + * this method. If there is nothing left to receive, terminate the + * procedure. Otherwise adjust the Rx FIFO Threshold level if it's a + * final stage of the transfer. By doing so we'll get the next IRQ + * right when the leftover incoming data is received. + */ + rx = dw_reader(dws); + if (!dws->rx_len) { + mask |= 0xff; + finalize = true; + } else if (dws->rx_len <= dw_readl(dws, DW_SPI_RXFTLR)) { + dw_writel(dws, DW_SPI_RXFTLR, dws->rx_len - 1); + } + + /* + * Send data out as much as possible. The Tx FIFO Empty IRQ will be + * disabled after the data transmission is finished so not to + * have the TXE IRQ flood at the final stage of the transfer. + */ + tx = dw_writer(dws); + if (!dws->tx_len) + mask |= DW_SPI_INT_TXEI; + cond_resched(); + } while (rx != 0 || tx != 0); + + imask = DW_SPI_INT_TXEI | DW_SPI_INT_TXOI | + DW_SPI_INT_RXUI | DW_SPI_INT_RXOI | DW_SPI_INT_RXFI; + imask &= ~mask; + dw_spi_umask_intr(dws, imask); + + if (finalize) + spi_finalize_current_transfer(dws->ctlr); + + return IRQ_HANDLED; +} + static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws) { u16 irq_status = dw_readl(dws, DW_SPI_ISR); + bool finalize = false; if (dw_spi_check_status(dws, false)) { spi_finalize_current_transfer(dws->ctlr); @@ -229,6 +297,7 @@ static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws) dw_reader(dws); if (!dws->rx_len) { dw_spi_mask_intr(dws, 0xff); + finalize = true; spi_finalize_current_transfer(dws->ctlr); } else if (dws->rx_len <= dw_readl(dws, DW_SPI_RXFTLR)) { dw_writel(dws, DW_SPI_RXFTLR, dws->rx_len - 1); @@ -245,7 +314,14 @@ static irqreturn_t dw_spi_transfer_handler(struct dw_spi *dws) dw_spi_mask_intr(dws, DW_SPI_INT_TXEI); } - return IRQ_HANDLED; + if (spi_controller_is_target(dws->ctlr) || finalize || + !dws->rx_len || !dws->tx_len || + !spi_get_csgpiod(dws->ctlr->cur_msg->spi, 0)) { + return IRQ_HANDLED; + } + + dw_spi_mask_intr(dws, 0xff); + return IRQ_WAKE_THREAD; } static irqreturn_t dw_spi_enh_handler(struct dw_spi *dws) @@ -275,22 +351,15 @@ static irqreturn_t dw_spi_irq(int irq, void *dev_id) { struct spi_controller *ctlr = dev_id; struct dw_spi *dws = spi_controller_get_devdata(ctlr); - u16 irq_status = dw_readl(dws, DW_SPI_ISR) & DW_SPI_INT_MASK; + u16 irq_status = dw_readl(dws, DW_SPI_ISR); if (!irq_status) return IRQ_NONE; - if (!dws->transfer_handler || - (!ctlr->cur_msg && dws->transfer_handler == dw_spi_transfer_handler)) { + if (!ctlr->cur_msg && dws->transfer_handler != dw_spi_enh_handler) { dw_spi_mask_intr(dws, 0xff); return IRQ_HANDLED; } - if (dws->transfer_handler == dw_spi_enh_handler && - !dws->rx_len && !dws->tx_len) { - dw_spi_mask_intr(dws, 0xff); - spi_finalize_current_transfer(ctlr); - return IRQ_HANDLED; - } return dws->transfer_handler(dws); } @@ -342,8 +411,8 @@ static u32 dw_spi_prepare_cr0(struct dw_spi *dws, struct spi_device *spi) return cr0; } -void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, - struct dw_spi_cfg *cfg, struct dw_spi_enh_cfg *enh_cfg) +static void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, + struct dw_spi_cfg *cfg, struct dw_spi_enh_cfg *enh_cfg) { struct dw_spi_chip_data *chip = spi_get_ctldata(spi); u32 cr0 = chip->cr0; @@ -406,7 +475,6 @@ void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, dw_writel(dws, DW_SPI_SPI_CTRLR0, cr0); } } -EXPORT_SYMBOL_NS_GPL(dw_spi_update_config, "SPI_DW_CORE"); static void dw_spi_irq_setup(struct dw_spi *dws) { @@ -937,6 +1005,15 @@ static void dw_spi_enh_write_cmd_addr(struct dw_spi *dws, const struct spi_mem_o dw_spi_set_cs(mem->spi, false); } + + /* + * FIXME: The exact reason for this delay is not fully understood, + * but empirical testing shows it significantly improves the stability + * of read/write operations. Without this delay, occasional transfer + * errors or timeouts may occur under certain conditions. + * Keeping it as a safeguard based on practical validation. + */ + udelay(5); } static int dw_spi_exec_enh_mem_op(struct spi_mem *mem, const struct spi_mem_op *op) @@ -948,6 +1025,8 @@ static int dw_spi_exec_enh_mem_op(struct spi_mem *mem, const struct spi_mem_op * unsigned long long ms; int ret; + dws->dma_mapped = false; + switch (op->data.buswidth) { case 0: case 1: @@ -971,10 +1050,13 @@ static int dw_spi_exec_enh_mem_op(struct spi_mem *mem, const struct spi_mem_op * cfg.dfs = 8; cfg.freq = clamp(op->max_freq, 0U, dws->max_mem_freq); cfg.ndf = op->data.nbytes; - if (op->data.dir == SPI_MEM_DATA_IN) + if (op->data.dir == SPI_MEM_DATA_IN) { cfg.tmode = DW_SPI_CTRLR0_TMOD_RO; - else + dws->tx_dir = false; + } else { cfg.tmode = DW_SPI_CTRLR0_TMOD_TO; + dws->tx_dir = true; + } if (op->data.buswidth == op->addr.buswidth && op->data.buswidth == op->cmd.buswidth) @@ -1010,47 +1092,61 @@ static int dw_spi_exec_enh_mem_op(struct spi_mem *mem, const struct spi_mem_op * } } - dw_spi_enh_write_cmd_addr(dws, op, mem); - - /* - * FIXME: The exact reason for this delay is not fully understood, - * but empirical testing shows it significantly improves the stability - * of read/write operations. Without this delay, occasional transfer - * errors or timeouts may occur under certain conditions. - * Keeping it as a safeguard based on practical validation. - */ - udelay(5); - - dw_spi_enh_irq_setup(dws); - - /* Use timeout calculation from spi_transfer_wait() */ - ms = 8LL * MSEC_PER_SEC * (dws->rx_len ? dws->rx_len : dws->tx_len); - do_div(ms, dws->current_freq); - - /* - * Increase it twice and add 200 ms tolerance, use - * predefined maximum in case of overflow. - */ - ms += ms + 200; - if (ms > UINT_MAX) - ms = UINT_MAX; - - ms = wait_for_completion_timeout(&ctlr->xfer_completion, - msecs_to_jiffies(ms)); - if (ms == 0) { - dw_spi_mask_intr(dws, 0xff); - synchronize_irq(dws->irq); - dws->rx = NULL; - dws->tx = NULL; - dws->rx_len = 0; - dws->tx_len = 0; - dw_spi_stop_mem_op(dws, mem->spi); - return -EIO; + if (dws->dma_nr_chans && dws->dma_ops->dma_enh_mem_get_chan && + op->data.nbytes > dws->fifo_len) { + ret = dws->dma_ops->dma_enh_mem_get_chan(ctlr->dev.parent, dws); + if (ret) { + /* fall back to the PIO/IRQ path */ + dev_dbg(&ctlr->dev, "DMA enh mem channel unavailable (%d)\n", ret); + } else if (dws->dma_ops->can_dma_enh_mem(ctlr)) { + ret = dws->dma_ops->dma_enh_mem_setup(dws); + if (ret) + dev_err(&ctlr->dev, "DMA enh mem setup failed (%d)\n", ret); + else + dws->dma_mapped = true; + } } - ret = dw_spi_wait_mem_op_done(dws); + if (dws->dma_mapped) { + dw_spi_enh_write_cmd_addr(dws, op, mem); - dw_spi_stop_mem_op(dws, mem->spi); + ret = dws->dma_ops->dma_enh_mem_transfer(mem, op); + + dw_spi_stop_mem_op(dws, mem->spi); + } else { + dw_spi_enh_write_cmd_addr(dws, op, mem); + + dw_spi_enh_irq_setup(dws); + + /* Use timeout calculation from spi_transfer_wait() */ + ms = 8LL * MSEC_PER_SEC * (dws->rx_len ? dws->rx_len : dws->tx_len); + do_div(ms, dws->current_freq); + + /* + * Increase it twice and add 200 ms tolerance, use + * predefined maximum in case of overflow. + */ + ms += ms + 200; + if (ms > UINT_MAX) + ms = UINT_MAX; + + ms = wait_for_completion_timeout(&ctlr->xfer_completion, + msecs_to_jiffies(ms)); + if (ms == 0) { + dw_spi_mask_intr(dws, 0xff); + synchronize_irq(dws->irq); + dws->rx = NULL; + dws->tx = NULL; + dws->rx_len = 0; + dws->tx_len = 0; + dw_spi_stop_mem_op(dws, mem->spi); + return -EIO; + } + + ret = dw_spi_wait_mem_op_done(dws); + + dw_spi_stop_mem_op(dws, mem->spi); + } return ret; } @@ -1104,12 +1200,13 @@ static int dw_spi_setup(struct spi_device *spi) if (!chip) return -ENOMEM; spi_set_ctldata(spi, chip); - /* Get specific / default rx-sample-delay */ - if (device_property_read_u32(&spi->dev, - "rx-sample-delay-ns", - &rx_sample_dly_ns) != 0) - /* Use default controller value */ - rx_sample_dly_ns = dws->def_rx_sample_dly_ns; + /* + * Use the per-device value the core parsed from the peripheral + * node, and fall back to the controller-wide default when the + * device does not ask for a delay of its own. + */ + rx_sample_dly_ns = spi->rx_sample_delay_ns ?: + dws->def_rx_sample_dly_ns; chip->rx_sample_dly = DIV_ROUND_CLOSEST(rx_sample_dly_ns, NSEC_PER_SEC / dws->max_freq); @@ -1312,8 +1409,8 @@ int dw_spi_add_controller(struct device *dev, struct dw_spi *dws) /* Basic HW init */ dw_spi_hw_init(dev, dws); - ret = request_irq(dws->irq, dw_spi_irq, IRQF_SHARED, dev_name(dev), - ctlr); + ret = request_threaded_irq(dws->irq, dw_spi_irq, dw_spi_irq_thread_fn, + IRQF_SHARED, dev_name(dev), ctlr); if (ret < 0 && ret != -ENOTCONN) { dev_err(dev, "can not request IRQ\n"); goto err_free_ctlr; @@ -1360,6 +1457,9 @@ int dw_spi_add_controller(struct device *dev, struct dw_spi *dws) goto err_free_irq; } else if (ret) { dev_warn(dev, "DMA init failed\n"); + } else if (dws->dma_nr_chans == 1) { + /* Full-duplex DMA transfers need both channels */ + dev_info(dev, "Single DMA channel, full-duplex DMA disabled\n"); } else { ctlr->can_dma = dws->dma_ops->can_dma; ctlr->flags |= SPI_CONTROLLER_MUST_TX;
diff --git a/drivers/spi/spi-dw-dma.c b/drivers/spi/spi-dw-dma.c index f7d848f..b706770 100644 --- a/drivers/spi/spi-dw-dma.c +++ b/drivers/spi/spi-dw-dma.c
@@ -42,14 +42,19 @@ static void dw_spi_dma_maxburst_init(struct dw_spi *dws) def_burst = dws->fifo_len / 2; - ret = dma_get_slave_caps(dws->rxchan, &caps); - if (!ret && caps.max_burst) - max_burst = caps.max_burst; - else - max_burst = DW_SPI_RX_BURST_LEVEL; + if (dws->rxchan) { + ret = dma_get_slave_caps(dws->rxchan, &caps); + if (!ret && caps.max_burst) + max_burst = caps.max_burst; + else + max_burst = DW_SPI_RX_BURST_LEVEL; - dws->rxburst = min(max_burst, def_burst); - dw_writel(dws, DW_SPI_DMARDLR, dws->rxburst - 1); + dws->rxburst = min(max_burst, def_burst); + dw_writel(dws, DW_SPI_DMARDLR, dws->rxburst - 1); + } + + if (!dws->txchan) + return; ret = dma_get_slave_caps(dws->txchan, &caps); if (!ret && caps.max_burst) @@ -74,20 +79,39 @@ static void dw_spi_dma_maxburst_init(struct dw_spi *dws) static int dw_spi_dma_caps_init(struct dw_spi *dws) { - struct dma_slave_caps tx, rx; + struct dma_slave_caps tx = {}, rx = {}; int ret; - ret = dma_get_slave_caps(dws->txchan, &tx); - if (ret) - return ret; + if (dws->txchan) { + ret = dma_get_slave_caps(dws->txchan, &tx); + if (ret) + return ret; - ret = dma_get_slave_caps(dws->rxchan, &rx); - if (ret) - return ret; + if (!(tx.directions & BIT(DMA_MEM_TO_DEV))) + return -ENXIO; + } - if (!(tx.directions & BIT(DMA_MEM_TO_DEV) && - rx.directions & BIT(DMA_DEV_TO_MEM))) - return -ENXIO; + if (dws->rxchan) { + ret = dma_get_slave_caps(dws->rxchan, &rx); + if (ret) + return ret; + + if (!(rx.directions & BIT(DMA_DEV_TO_MEM))) + return -ENXIO; + } + + /* With a single channel only one direction is available at a time */ + if (!dws->rxchan) { + dws->dma_sg_burst = tx.max_sg_burst; + dws->dma_addr_widths = tx.dst_addr_widths; + return 0; + } + + if (!dws->txchan) { + dws->dma_sg_burst = rx.max_sg_burst; + dws->dma_addr_widths = rx.src_addr_widths; + return 0; + } if (tx.max_sg_burst > 0 && rx.max_sg_burst > 0) dws->dma_sg_burst = min(tx.max_sg_burst, rx.max_sg_burst); @@ -169,40 +193,54 @@ static int dw_spi_dma_init_generic(struct device *dev, struct dw_spi *dws) { int ret; + dws->dma_nr_chans = 0; + dws->rxchan = dma_request_chan(dev, "rx"); if (IS_ERR(dws->rxchan)) { ret = PTR_ERR(dws->rxchan); dws->rxchan = NULL; goto err_exit; } + dws->dma_nr_chans++; + /* + * Some platforms have only one DMA channel for the controller. Keep + * the Rx channel in that case, it can still serve half-duplex + * transfers. + */ dws->txchan = dma_request_chan(dev, "tx"); if (IS_ERR(dws->txchan)) { ret = PTR_ERR(dws->txchan); dws->txchan = NULL; - goto free_rxchan; + if (ret == -EPROBE_DEFER) + goto free_rxchan; + } else { + dws->dma_nr_chans++; } - dws->ctlr->dma_rx = dws->rxchan; - dws->ctlr->dma_tx = dws->txchan; - - init_completion(&dws->dma_completion); - ret = dw_spi_dma_caps_init(dws); if (ret) goto free_txchan; dw_spi_dma_maxburst_init(dws); + init_completion(&dws->dma_completion); + + dws->ctlr->dma_rx = dws->rxchan; + dws->ctlr->dma_tx = dws->txchan; + return 0; free_txchan: - dma_release_channel(dws->txchan); - dws->txchan = NULL; + if (dws->txchan) { + dma_release_channel(dws->txchan); + dws->txchan = NULL; + } free_rxchan: dma_release_channel(dws->rxchan); dws->rxchan = NULL; err_exit: + dws->dma_nr_chans = 0; return ret; } @@ -286,19 +324,27 @@ static inline bool dw_spi_dma_tx_busy(struct dw_spi *dws) (DW_SPI_SR_BUSY | DW_SPI_SR_TF_EMPT)) != DW_SPI_SR_TF_EMPT; } -static int dw_spi_dma_wait_tx_done(struct dw_spi *dws, - struct spi_transfer *xfer) +static int dw_spi_dma_wait_tx_done(struct dw_spi *dws, u32 speed_hz) { int retry = DW_SPI_WAIT_RETRIES; struct spi_delay delay; + unsigned long ns, us; u32 nents; nents = dw_readl(dws, DW_SPI_TXFLR); - delay.unit = SPI_DELAY_UNIT_SCK; - delay.value = nents * dws->n_bytes * BITS_PER_BYTE; + ns = DIV_ROUND_UP(NSEC_PER_SEC, speed_hz) * nents * + dws->n_bytes * BITS_PER_BYTE; + if (ns <= NSEC_PER_USEC) { + delay.unit = SPI_DELAY_UNIT_NSECS; + delay.value = ns; + } else { + us = DIV_ROUND_UP(ns, NSEC_PER_USEC); + delay.unit = SPI_DELAY_UNIT_USECS; + delay.value = clamp_val(us, 0, USHRT_MAX); + } while (dw_spi_dma_tx_busy(dws) && retry--) - spi_delay_exec(&delay, xfer); + spi_delay_exec(&delay, NULL); if (retry < 0) { dev_err(&dws->ctlr->dev, "Tx hanged up\n"); @@ -659,7 +705,7 @@ static int dw_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer) return ret; if (dws->ctlr->cur_msg->status == -EINPROGRESS) { - ret = dw_spi_dma_wait_tx_done(dws, xfer); + ret = dw_spi_dma_wait_tx_done(dws, xfer->effective_speed_hz); if (ret) return ret; } @@ -672,14 +718,180 @@ static int dw_spi_dma_transfer(struct dw_spi *dws, struct spi_transfer *xfer) static void dw_spi_dma_stop(struct dw_spi *dws) { - if (test_bit(DW_SPI_TX_BUSY, &dws->dma_chan_busy)) { + /* + * This is only called on errors, so don't rely on the busy flags + * being in sync with the DMA engine state. A channel may be missing + * when only one DMA channel is available. + */ + if (dws->txchan) dmaengine_terminate_sync(dws->txchan); - clear_bit(DW_SPI_TX_BUSY, &dws->dma_chan_busy); - } - if (test_bit(DW_SPI_RX_BUSY, &dws->dma_chan_busy)) { + if (dws->rxchan) dmaengine_terminate_sync(dws->rxchan); - clear_bit(DW_SPI_RX_BUSY, &dws->dma_chan_busy); + + clear_bit(DW_SPI_TX_BUSY, &dws->dma_chan_busy); + clear_bit(DW_SPI_RX_BUSY, &dws->dma_chan_busy); +} + +/* + * The enhanced SPI memory operations are half-duplex, so a single DMA channel + * is enough for them. On a platform with only one channel, the channel is + * bound to a direction by its "tx"/"rx" DMA specifier, and whichever channel + * is currently held tells which direction it serves. Keep it across + * operations and swap it only when the transfer direction changes. + */ +static int dw_spi_enh_mem_dma_get_chan(struct device *dev, struct dw_spi *dws) +{ + struct dma_chan **chan, **other; + const char *name; + int ret; + + if (dws->dma_nr_chans == 2) + return 0; + + if (dws->tx_dir) { + chan = &dws->txchan; + other = &dws->rxchan; + name = "tx"; + } else { + chan = &dws->rxchan; + other = &dws->txchan; + name = "rx"; } + + if (*chan) + return 0; + + dws->ctlr->dma_tx = NULL; + dws->ctlr->dma_rx = NULL; + + /* + * With a single physical channel, the held channel must be released + * before it can be requested again with the handshake of the other + * direction. On failure both stay NULL, and the next operation + * retries the request and falls back to PIO meanwhile. + */ + + if (*other) { + dma_release_channel(*other); + *other = NULL; + } + + *chan = dma_request_chan(dev, name); + if (IS_ERR(*chan)) { + ret = PTR_ERR(*chan); + *chan = NULL; + return ret; + } + + ret = dw_spi_dma_caps_init(dws); + if (ret) { + dma_release_channel(*chan); + *chan = NULL; + return ret; + } + + dw_spi_dma_maxburst_init(dws); + + dws->ctlr->dma_tx = dws->txchan; + dws->ctlr->dma_rx = dws->rxchan; + + return 0; +} + +static int dw_spi_enh_mem_dma_setup(struct dw_spi *dws) +{ + u16 dma_ctrl, level; + int ret; + + /* Setup DMA channels */ + if (dws->tx_dir) { + ret = dw_spi_dma_config_tx(dws); + if (ret) + return ret; + + dma_ctrl = DW_SPI_DMACR_TDMAE; + } else { + ret = dw_spi_dma_config_rx(dws); + if (ret) + return ret; + + dma_ctrl = DW_SPI_DMACR_RDMAE; + } + + dw_writel(dws, DW_SPI_DMACR, dma_ctrl); + + /* Clear stale error status, it is checked after the transfer */ + dw_readl(dws, DW_SPI_ICR); + + reinit_completion(&dws->dma_completion); + + level = min_t(unsigned int, dws->fifo_len / 2, dws->tx_len); + dw_writel(dws, DW_SPI_TXFTLR, level); + + level = min_t(unsigned int, dws->fifo_len / 2, dws->rx_len); + dw_writel(dws, DW_SPI_RXFTLR, level ? level - 1 : 0); + + return 0; +} + +static bool dw_spi_enh_mem_can_dma(struct spi_controller *ctlr) +{ + struct dw_spi *dws = spi_controller_get_devdata(ctlr); + unsigned int len = dws->tx_dir ? dws->tx_len : dws->rx_len; + enum dma_slave_buswidth dma_bus_width; + + if (len <= dws->fifo_len) + return false; + + dma_bus_width = dw_spi_dma_convert_width(dws->n_bytes); + + return dws->dma_addr_widths & BIT(dma_bus_width); +} + +static int dw_spi_enh_mem_dma_transfer(struct spi_mem *mem, const struct spi_mem_op *op) +{ + struct spi_controller *ctlr = mem->spi->controller; + struct dw_spi *dws = spi_controller_get_devdata(ctlr); + struct sg_table sgt; + int ret; + + ret = spi_controller_dma_map_mem_op_data(ctlr, op, &sgt); + if (ret) + goto out_clear_dmac; + + if (dws->tx_dir) { + ret = dw_spi_dma_submit_tx(dws, sgt.sgl, sgt.nents); + if (ret) + goto out_unmap; + + dma_async_issue_pending(dws->txchan); + + ret = dw_spi_dma_wait(dws, dws->tx_len, dws->current_freq); + if (!ret) + ret = dw_spi_dma_wait_tx_done(dws, dws->current_freq); + } else { + ret = dw_spi_dma_submit_rx(dws, sgt.sgl, sgt.nents); + if (ret) + goto out_unmap; + + dma_async_issue_pending(dws->rxchan); + + ret = dw_spi_dma_wait(dws, dws->rx_len, dws->current_freq); + if (!ret) + ret = dw_spi_dma_wait_rx_done(dws); + } + + if (ret) + dw_spi_dma_stop(dws); + else + ret = dw_spi_check_status(dws, true); + +out_unmap: + spi_controller_dma_unmap_mem_op_data(ctlr, op, &sgt); +out_clear_dmac: + dw_writel(dws, DW_SPI_DMACR, 0); + + return ret; } static const struct dw_spi_dma_ops dw_spi_dma_mfld_ops = { @@ -704,6 +916,11 @@ static const struct dw_spi_dma_ops dw_spi_dma_generic_ops = { .can_dma = dw_spi_can_dma, .dma_transfer = dw_spi_dma_transfer, .dma_stop = dw_spi_dma_stop, + + .dma_enh_mem_get_chan = dw_spi_enh_mem_dma_get_chan, + .dma_enh_mem_setup = dw_spi_enh_mem_dma_setup, + .can_dma_enh_mem = dw_spi_enh_mem_can_dma, + .dma_enh_mem_transfer = dw_spi_enh_mem_dma_transfer, }; void dw_spi_dma_setup_generic(struct dw_spi *dws)
diff --git a/drivers/spi/spi-dw-mmio.c b/drivers/spi/spi-dw-mmio.c index 8cdb035..9c70947 100644 --- a/drivers/spi/spi-dw-mmio.c +++ b/drivers/spi/spi-dw-mmio.c
@@ -363,6 +363,8 @@ static int dw_spi_jhb100_init(struct platform_device *pdev, dw_spi_jhb100_mask_intr(&dwsmmio->dws, 0xff); + dw_spi_dma_setup_generic(&dwsmmio->dws); + return 0; }
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h index e62f919..c16225c 100644 --- a/drivers/spi/spi-dw.h +++ b/drivers/spi/spi-dw.h
@@ -158,22 +158,6 @@ #define DW_SPI_GET_BYTE(_val, _idx) \ ((_val) >> (BITS_PER_BYTE * (_idx)) & 0xff) -/* Slave spi_transfer/spi_mem_op related */ -struct dw_spi_cfg { - u8 tmode; - u8 dfs; - u32 ndf; - u32 freq; - u8 spi_frf; -}; - -struct dw_spi_enh_cfg { - u8 wait_c; - u8 inst_l; - u8 addr_l; - u8 trans_t; -}; - struct dw_spi; struct dw_spi_dma_ops { int (*dma_init)(struct device *dev, struct dw_spi *dws); @@ -183,6 +167,12 @@ struct dw_spi_dma_ops { struct spi_transfer *xfer); int (*dma_transfer)(struct dw_spi *dws, struct spi_transfer *xfer); void (*dma_stop)(struct dw_spi *dws); + + /* enh mem dma ops */ + int (*dma_enh_mem_get_chan)(struct device *dev, struct dw_spi *dws); + int (*dma_enh_mem_setup)(struct dw_spi *dws); + bool (*can_dma_enh_mem)(struct spi_controller *ctlr); + int (*dma_enh_mem_transfer)(struct spi_mem *mem, const struct spi_mem_op *op); }; struct dw_spi { @@ -227,6 +217,8 @@ struct dw_spi { u32 txburst; struct dma_chan *rxchan; u32 rxburst; + unsigned int dma_nr_chans; + bool tx_dir; u32 dma_sg_burst; u32 dma_addr_widths; unsigned long dma_chan_busy; @@ -337,8 +329,6 @@ static inline void dw_spi_shutdown_chip(struct dw_spi *dws) } extern void dw_spi_set_cs(struct spi_device *spi, bool enable); -extern void dw_spi_update_config(struct dw_spi *dws, struct spi_device *spi, - struct dw_spi_cfg *cfg, struct dw_spi_enh_cfg *enh_cfg); extern int dw_spi_check_status(struct dw_spi *dws, bool raw); extern int dw_spi_add_controller(struct device *dev, struct dw_spi *dws); extern void dw_spi_remove_controller(struct dw_spi *dws);
diff --git a/drivers/spi/spi-ep93xx.c b/drivers/spi/spi-ep93xx.c index bf389d7..d8f4aa3 100644 --- a/drivers/spi/spi-ep93xx.c +++ b/drivers/spi/spi-ep93xx.c
@@ -273,6 +273,7 @@ ep93xx_spi_dma_prepare(struct spi_controller *host, struct dma_async_tx_descriptor *txd; enum dma_slave_buswidth buswidth; struct dma_slave_config conf; + struct device *dma_dev; struct scatterlist *sg; struct sg_table *sgt; struct dma_chan *chan; @@ -348,14 +349,15 @@ ep93xx_spi_dma_prepare(struct spi_controller *host, return ERR_PTR(-EINVAL); } - nents = dma_map_sg(chan->device->dev, sgt->sgl, sgt->nents, dir); + dma_dev = dmaengine_get_dma_device(chan); + nents = dma_map_sg(dma_dev, sgt->sgl, sgt->nents, dir); if (!nents) return ERR_PTR(-ENOMEM); txd = dmaengine_prep_slave_sg(chan, sgt->sgl, nents, conf.direction, DMA_CTRL_ACK); if (!txd) { - dma_unmap_sg(chan->device->dev, sgt->sgl, sgt->nents, dir); + dma_unmap_sg(dma_dev, sgt->sgl, sgt->nents, dir); return ERR_PTR(-ENOMEM); } return txd; @@ -384,7 +386,7 @@ static void ep93xx_spi_dma_finish(struct spi_controller *host, sgt = &espi->tx_sgt; } - dma_unmap_sg(chan->device->dev, sgt->sgl, sgt->nents, dir); + dma_unmap_sg(dmaengine_get_dma_device(chan), sgt->sgl, sgt->nents, dir); } static void ep93xx_spi_dma_callback(void *callback_param)
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c index 23e6bc5..f034888 100644 --- a/drivers/spi/spi-fsl-dspi.c +++ b/drivers/spi/spi-fsl-dspi.c
@@ -670,6 +670,7 @@ static void dspi_dma_xfer(struct fsl_dspi *dspi) static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr) { struct device *dev = &dspi->pdev->dev; + struct device *tx_dev, *rx_dev; struct dma_slave_config cfg; struct fsl_dspi_dma *dma; int ret; @@ -688,20 +689,23 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr) goto err_tx_channel; } + tx_dev = dmaengine_get_dma_device(dma->chan_tx); + rx_dev = dmaengine_get_dma_device(dma->chan_rx); + if (spi_controller_is_target(dspi->ctlr)) { /* * In target mode we have to be ready to receive the maximum * that can possibly be transferred at once by EDMA without any * FIFO underflows. */ - dma->bufsize = min(dma_get_max_seg_size(dma->chan_rx->device->dev), - dma_get_max_seg_size(dma->chan_tx->device->dev)) * + dma->bufsize = min(dma_get_max_seg_size(rx_dev), + dma_get_max_seg_size(tx_dev)) * DMA_SLAVE_BUSWIDTH_4_BYTES; } else { dma->bufsize = PAGE_SIZE; } - dma->tx_dma_buf = dma_alloc_noncoherent(dma->chan_tx->device->dev, + dma->tx_dma_buf = dma_alloc_noncoherent(tx_dev, dma->bufsize, &dma->tx_dma_phys, DMA_TO_DEVICE, GFP_KERNEL); if (!dma->tx_dma_buf) { @@ -709,7 +713,7 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr) goto err_tx_dma_buf; } - dma->rx_dma_buf = dma_alloc_noncoherent(dma->chan_rx->device->dev, + dma->rx_dma_buf = dma_alloc_noncoherent(rx_dev, dma->bufsize, &dma->rx_dma_phys, DMA_FROM_DEVICE, GFP_KERNEL); if (!dma->rx_dma_buf) { @@ -746,12 +750,11 @@ static int dspi_request_dma(struct fsl_dspi *dspi, phys_addr_t phy_addr) return 0; err_slave_config: - dma_free_noncoherent(dma->chan_rx->device->dev, dma->bufsize, - dma->rx_dma_buf, dma->rx_dma_phys, - DMA_FROM_DEVICE); + dma_free_noncoherent(rx_dev, dma->bufsize, dma->rx_dma_buf, + dma->rx_dma_phys, DMA_FROM_DEVICE); err_rx_dma_buf: - dma_free_noncoherent(dma->chan_tx->device->dev, dma->bufsize, - dma->tx_dma_buf, dma->tx_dma_phys, DMA_TO_DEVICE); + dma_free_noncoherent(tx_dev, dma->bufsize, dma->tx_dma_buf, + dma->tx_dma_phys, DMA_TO_DEVICE); err_tx_dma_buf: dma_release_channel(dma->chan_tx); err_tx_channel: @@ -771,16 +774,18 @@ static void dspi_release_dma(struct fsl_dspi *dspi) return; if (dma->chan_tx) { - dma_free_noncoherent(dma->chan_tx->device->dev, dma->bufsize, - dma->tx_dma_buf, dma->tx_dma_phys, - DMA_TO_DEVICE); + struct device *tx_dev = dmaengine_get_dma_device(dma->chan_tx); + + dma_free_noncoherent(tx_dev, dma->bufsize, dma->tx_dma_buf, + dma->tx_dma_phys, DMA_TO_DEVICE); dma_release_channel(dma->chan_tx); } if (dma->chan_rx) { - dma_free_noncoherent(dma->chan_rx->device->dev, dma->bufsize, - dma->rx_dma_buf, dma->rx_dma_phys, - DMA_FROM_DEVICE); + struct device *rx_dev = dmaengine_get_dma_device(dma->chan_rx); + + dma_free_noncoherent(rx_dev, dma->bufsize, dma->rx_dma_buf, + dma->rx_dma_phys, DMA_FROM_DEVICE); dma_release_channel(dma->chan_rx); } }
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c index e45816e..6659027 100644 --- a/drivers/spi/spi-fsl-spi.c +++ b/drivers/spi/spi-fsl-spi.c
@@ -702,10 +702,18 @@ static void of_fsl_spi_remove(struct platform_device *ofdev) { struct spi_controller *host = platform_get_drvdata(ofdev); struct mpc8xxx_spi *mpc8xxx_spi = spi_controller_get_devdata(host); +#if IS_ENABLED(CONFIG_FSL_SOC) + struct fsl_spi_platform_data *pdata = dev_get_platdata(&ofdev->dev); + struct mpc8xxx_spi_probe_info *pinfo = to_of_pinfo(pdata); +#endif spi_unregister_controller(host); fsl_spi_cpm_free(mpc8xxx_spi); +#if IS_ENABLED(CONFIG_FSL_SOC) + if (pinfo->immr_spi_cs) + iounmap(pinfo->immr_spi_cs); +#endif } static struct platform_driver of_fsl_spi_driver = {
diff --git a/drivers/spi/spi-geni-qcom.c b/drivers/spi/spi-geni-qcom.c index 6c57f83..91e75e2 100644 --- a/drivers/spi/spi-geni-qcom.c +++ b/drivers/spi/spi-geni-qcom.c
@@ -10,10 +10,13 @@ #include <linux/dmaengine.h> #include <linux/dma-mapping.h> #include <linux/dma/qcom-gpi-dma.h> +#include <linux/gpio/consumer.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <linux/iopoll.h> #include <linux/log2.h> #include <linux/module.h> +#include <linux/panic_notifier.h> #include <linux/platform_device.h> #include <linux/pm_opp.h> #include <linux/pm_runtime.h> @@ -115,6 +118,8 @@ struct spi_geni_master { struct dma_chan *rx; int cur_xfer_mode; const struct geni_spi_desc *dev_data; + struct notifier_block panic_nb; + struct gpio_desc *ready_gpio; }; static void spi_slv_setup(struct spi_geni_master *mas) @@ -173,6 +178,9 @@ static void handle_se_timeout(struct spi_controller *spi) xfer = mas->cur_xfer; mas->cur_xfer = NULL; + if (spi->target) + gpiod_set_value(mas->ready_gpio, 0); + /* The controller doesn't support the Cancel commnand in target mode */ if (!spi->target) { reinit_completion(&mas->cancel_done); @@ -363,8 +371,8 @@ static int geni_spi_set_clock_and_bw(struct geni_se *se, return 0; } -static int setup_fifo_params(struct spi_device *spi_slv, - struct spi_controller *spi) +static void setup_spi_params(struct spi_device *spi_slv, + struct spi_controller *spi) { struct spi_geni_master *mas = spi_controller_get_devdata(spi); struct geni_se *se = &mas->se; @@ -390,8 +398,6 @@ static int setup_fifo_params(struct spi_device *spi_slv, trace_geni_spi_setup_params(mas->dev, chipselect, spi_slv->mode, mode_changed, cs_changed); - - return 0; } static void @@ -554,17 +560,14 @@ static int spi_geni_prepare_message(struct spi_controller *spi, struct spi_message *spi_msg) { struct spi_geni_master *mas = spi_controller_get_devdata(spi); - int ret; switch (mas->cur_xfer_mode) { case GENI_SE_FIFO: case GENI_SE_DMA: if (spi_geni_is_abort_still_pending(mas)) return -EBUSY; - ret = setup_fifo_params(spi_msg->spi, spi); - if (ret) - dev_err(mas->dev, "Couldn't select mode %d\n", ret); - return ret; + setup_spi_params(spi_msg->spi, spi); + return 0; case GENI_GPI_DMA: /* nothing to do for GPI DMA */ @@ -700,7 +703,7 @@ static int spi_geni_init(struct spi_geni_master *mas) case 0: mas->cur_xfer_mode = GENI_SE_FIFO; geni_se_select_mode(se, GENI_SE_FIFO); - /* setup_fifo_params assumes that these registers start with a zero value */ + /* setup_spi_params assumes that these registers start with a zero value */ writel(0, se->base + SE_SPI_LOOPBACK); writel(0, se->base + SE_SPI_DEMUX_SEL); writel(0, se->base + SE_SPI_CPHA); @@ -938,8 +941,12 @@ static int spi_geni_transfer_one(struct spi_controller *spi, if (mas->cur_xfer_mode == GENI_SE_FIFO || mas->cur_xfer_mode == GENI_SE_DMA) { ret = setup_se_xfer(xfer, mas, slv->mode, spi); /* SPI framework expects +ve ret code to wait for transfer complete */ - if (!ret) + if (!ret) { + if (spi->target) + gpiod_set_value(mas->ready_gpio, 1); ret = 1; + } + return ret; } return setup_gsi_xfer(xfer, mas, slv, spi); @@ -1025,6 +1032,8 @@ static irqreturn_t geni_spi_isr(int irq, void *data) if (dma_rx_status & RX_RESET_DONE) complete(&mas->rx_reset_done); if (!mas->tx_rem_bytes && !mas->rx_rem_bytes && xfer) { + if (spi->target) + gpiod_set_value(mas->ready_gpio, 0); spi_finalize_current_transfer(spi); mas->cur_xfer = NULL; } @@ -1066,6 +1075,69 @@ static int spi_geni_target_abort(struct spi_controller *spi) return 0; } +static void spi_geni_shutdown(struct platform_device *pdev) +{ + struct spi_controller *spi = platform_get_drvdata(pdev); + + spi_controller_suspend(spi); +} + +static int spi_geni_panic_notifier(struct notifier_block *nb, + unsigned long action, void *data) +{ + struct spi_geni_master *mas = container_of(nb, struct spi_geni_master, panic_nb); + struct spi_controller *spi = dev_get_drvdata(mas->dev); + struct geni_se *se = &mas->se; + u32 val; + + if (!pm_runtime_active(mas->dev)) + return NOTIFY_OK; + + if (mas->cur_xfer_mode == GENI_GPI_DMA) { + dmaengine_terminate_async(mas->tx); + dmaengine_terminate_async(mas->rx); + return NOTIFY_OK; + } + + if (!(readl_relaxed(se->base + SE_GENI_STATUS) & M_GENI_CMD_ACTIVE)) + return NOTIFY_OK; + + if (!spi->target) { + geni_se_cancel_m_cmd(se); + if (!readl_poll_timeout_atomic(se->base + SE_GENI_M_IRQ_STATUS, val, + val & M_CMD_CANCEL_EN, 10, 50000)) { + writel_relaxed(M_CMD_CANCEL_EN, se->base + SE_GENI_M_IRQ_CLEAR); + return NOTIFY_OK; + } + } + + geni_se_abort_m_cmd(se); + if (!readl_poll_timeout_atomic(se->base + SE_GENI_M_IRQ_STATUS, val, + val & M_CMD_ABORT_EN, 10, 50000)) + writel_relaxed(M_CMD_ABORT_EN, se->base + SE_GENI_M_IRQ_CLEAR); + + if (mas->cur_xfer_mode == GENI_SE_DMA) { + writel_relaxed(1, se->base + SE_DMA_TX_FSM_RST); + readl_poll_timeout_atomic(se->base + SE_DMA_TX_IRQ_STAT, val, + val & TX_RESET_DONE, 10, 50000); + writel_relaxed(val, se->base + SE_DMA_TX_IRQ_CLR); + + writel_relaxed(1, se->base + SE_DMA_RX_FSM_RST); + readl_poll_timeout_atomic(se->base + SE_DMA_RX_IRQ_STAT, val, + val & RX_RESET_DONE, 10, 50000); + writel_relaxed(val, se->base + SE_DMA_RX_IRQ_CLR); + } + + return NOTIFY_OK; +} + +static void spi_geni_unregister_notifiers(void *data) +{ + struct spi_geni_master *mas = data; + + atomic_notifier_chain_unregister(&panic_notifier_list, &mas->panic_nb); +} + static int spi_geni_probe(struct platform_device *pdev) { int ret, irq; @@ -1131,8 +1203,14 @@ static int spi_geni_probe(struct platform_device *pdev) init_completion(&mas->rx_reset_done); spin_lock_init(&mas->lock); - if (spi->target) + if (spi->target) { spi->target_abort = spi_geni_target_abort; + mas->ready_gpio = devm_gpiod_get_optional(dev, "ready", + GPIOD_OUT_LOW); + if (IS_ERR(mas->ready_gpio)) + return dev_err_probe(dev, PTR_ERR(mas->ready_gpio), + "Failed to request GPIO\n"); + } pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_set_autosuspend_delay(&pdev->dev, 250); @@ -1154,6 +1232,15 @@ static int spi_geni_probe(struct platform_device *pdev) if (ret) return ret; + mas->panic_nb.notifier_call = spi_geni_panic_notifier; + ret = atomic_notifier_chain_register(&panic_notifier_list, &mas->panic_nb); + if (ret) + return ret; + + ret = devm_add_action_or_reset(dev, spi_geni_unregister_notifiers, mas); + if (ret) + return ret; + return devm_spi_register_controller(dev, spi); } @@ -1241,7 +1328,8 @@ static const struct of_device_id spi_geni_dt_match[] = { MODULE_DEVICE_TABLE(of, spi_geni_dt_match); static struct platform_driver spi_geni_driver = { - .probe = spi_geni_probe, + .probe = spi_geni_probe, + .shutdown = spi_geni_shutdown, .driver = { .name = "geni_spi", .pm = pm_ptr(&spi_geni_pm_ops),
diff --git a/drivers/spi/spi-imx.c b/drivers/spi/spi-imx.c index 3851c50..cadf0b9 100644 --- a/drivers/spi/spi-imx.c +++ b/drivers/spi/spi-imx.c
@@ -673,7 +673,7 @@ static int mx51_ecspi_prepare_message(struct spi_imx_data *spi_imx, * propagate into the hardware. It takes exactly one tick of the * SCLK clock, but we will wait two SCLK clock just to be sure. The * effect of the delay it takes for the hardware to apply changes - * is noticable if the SCLK clock run very slow. In such a case, if + * is noticeable if the SCLK clock run very slow. In such a case, if * the polarity of SCLK should be inverted, the GPIO ChipSelect might * be asserted before the SCLK polarity changes, which would disrupt * the SPI communication as the device on the other end would consider @@ -1467,8 +1467,8 @@ static int spi_imx_calculate_timeout(struct spi_imx_data *spi_imx, int size) static void spi_imx_dma_unmap(struct spi_imx_data *spi_imx, struct dma_data_package *dma_data) { - struct device *tx_dev = spi_imx->controller->dma_tx->device->dev; - struct device *rx_dev = spi_imx->controller->dma_rx->device->dev; + struct device *tx_dev = dmaengine_get_dma_device(spi_imx->controller->dma_tx); + struct device *rx_dev = dmaengine_get_dma_device(spi_imx->controller->dma_rx); dma_unmap_single(tx_dev, dma_data->dma_tx_addr, DMA_CACHE_ALIGNED_LEN(dma_data->dma_len), @@ -1526,8 +1526,8 @@ static int spi_imx_dma_map(struct spi_imx_data *spi_imx, struct dma_data_package *dma_data) { struct spi_controller *controller = spi_imx->controller; - struct device *tx_dev = controller->dma_tx->device->dev; - struct device *rx_dev = controller->dma_rx->device->dev; + struct device *tx_dev = dmaengine_get_dma_device(controller->dma_tx); + struct device *rx_dev = dmaengine_get_dma_device(controller->dma_rx); int ret; dma_data->dma_tx_addr = dma_map_single(tx_dev, dma_data->dma_tx_buf, @@ -1921,7 +1921,7 @@ static int spi_imx_dma_package_transfer(struct spi_imx_data *spi_imx, return ret; /* Trim the DMA RX buffer and copy the actual data to rx_buf */ - dma_sync_single_for_cpu(controller->dma_rx->device->dev, dma_data->dma_rx_addr, + dma_sync_single_for_cpu(dmaengine_get_dma_device(controller->dma_rx), dma_data->dma_rx_addr, DMA_CACHE_ALIGNED_LEN(dma_data->dma_len), DMA_FROM_DEVICE); spi_imx_dma_rx_data_handle(spi_imx, dma_data, transfer->rx_buf + spi_imx->rx_offset,
diff --git a/drivers/spi/spi-ingenic.c b/drivers/spi/spi-ingenic.c index adcf85b..a0a0475 100644 --- a/drivers/spi/spi-ingenic.c +++ b/drivers/spi/spi-ingenic.c
@@ -164,10 +164,8 @@ spi_ingenic_prepare_dma(struct spi_controller *ctlr, struct dma_chan *chan, cookie = dmaengine_submit(desc); ret = dma_submit_error(cookie); - if (ret) { - dmaengine_desc_free(desc); + if (ret) return ERR_PTR(ret); - } return desc; } @@ -186,7 +184,6 @@ static int spi_ingenic_dma_tx(struct spi_controller *ctlr, &xfer->tx_sg, DMA_MEM_TO_DEV, bits); if (IS_ERR(tx_desc)) { dmaengine_terminate_async(ctlr->dma_rx); - dmaengine_desc_free(rx_desc); return PTR_ERR(tx_desc); } @@ -354,8 +351,11 @@ static int spi_ingenic_request_dma(struct spi_controller *ctlr, ctlr->dma_tx = chan; chan = dma_request_chan(dev, "rx"); - if (IS_ERR(chan)) + if (IS_ERR(chan)) { + dma_release_channel(ctlr->dma_tx); + ctlr->dma_tx = NULL; return PTR_ERR(chan); + } ctlr->dma_rx = chan; ctlr->can_dma = spi_ingenic_can_dma;
diff --git a/drivers/spi/spi-jcore.c b/drivers/spi/spi-jcore.c index a75cd61..347f14f 100644 --- a/drivers/spi/spi-jcore.c +++ b/drivers/spi/spi-jcore.c
@@ -84,6 +84,8 @@ static void jcore_spi_baudrate(struct jcore_spi *hw, int speed) { if (speed == hw->speed_hz) return; + if (speed <= 0) + speed = 1; hw->speed_hz = speed; if (speed >= hw->clock_freq / 2) hw->speed_reg = 0; @@ -143,7 +145,6 @@ static int jcore_spi_probe(struct platform_device *pdev) struct device_node *node = pdev->dev.of_node; struct jcore_spi *hw; struct spi_controller *host; - struct resource *res; u32 clock_freq; struct clk *clk; @@ -164,16 +165,9 @@ static int jcore_spi_probe(struct platform_device *pdev) platform_set_drvdata(pdev, hw); /* Find and map our resources */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -EBUSY; - if (!devm_request_mem_region(&pdev->dev, res->start, - resource_size(res), pdev->name)) - return -EBUSY; - hw->base = devm_ioremap(&pdev->dev, res->start, - resource_size(res)); - if (!hw->base) - return -EBUSY; + hw->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(hw->base)) + return PTR_ERR(hw->base); /* * The SPI clock rate controlled via a configurable clock divider
diff --git a/drivers/spi/spi-ljca.c b/drivers/spi/spi-ljca.c index 0c6e624..8fd0016 100644 --- a/drivers/spi/spi-ljca.c +++ b/drivers/spi/spi-ljca.c
@@ -105,7 +105,12 @@ static int ljca_spi_read_write(struct ljca_spi_dev *ljca_spi, const u8 *w_data, (u8 *)r_packet, LJCA_SPI_BUF_SIZE); if (ret < 0) return ret; - else if (ret < sizeof(*r_packet) || r_packet->len <= 0) + + if (ret < sizeof(*r_packet)) + return -EIO; + + if (!r_packet->len || ret < sizeof(*r_packet) + r_packet->len || + r_packet->len > len) return -EIO; if (r_data)
diff --git a/drivers/spi/spi-lm70llp.c b/drivers/spi/spi-lm70llp.c index e61e89b..bd80288 100644 --- a/drivers/spi/spi-lm70llp.c +++ b/drivers/spi/spi-lm70llp.c
@@ -252,7 +252,7 @@ static void spi_lm70llp_attach(struct parport *p) * We are binding to the generic drivers/hwmon/lm70.c device * driver. */ - strcpy(pp->info.modalias, "lm70"); + strscpy(pp->info.modalias, "lm70", sizeof(pp->info.modalias)); pp->info.max_speed_hz = 6 * 1000 * 1000; pp->info.chip_select = 0; pp->info.mode = SPI_3WIRE | SPI_MODE_0;
diff --git a/drivers/spi/spi-ma35d1-qspi.c b/drivers/spi/spi-ma35d1-qspi.c index 7f938d0..0644bb2 100644 --- a/drivers/spi/spi-ma35d1-qspi.c +++ b/drivers/spi/spi-ma35d1-qspi.c
@@ -62,7 +62,7 @@ #define NUVOTON_QSPI_STATUS_RXEMPTY_MASK BIT(8) /* Receive FIFO Empty */ #define NUVOTON_QSPI_STATUS_BUSY_MASK BIT(0) /* Busy Status */ -#define NUVOTON_QSPI_MAX_NUM_CS 2 +#define NUVOTON_QSPI_MAX_NATIVE_CS 2 #define NUVOTON_QSPI_DEFAULT_NUM_CS 2 #define NUVOTON_QSPI_DEFAULT_BPW 8 /* Bound PIO operations to avoid long atomic polling loops. */ @@ -442,13 +442,35 @@ static void nuvoton_qspi_set_cs_level(struct nuvoton_qspi *qspi, spin_unlock_irqrestore(&qspi->ssctl_lock, flags); } +static int nuvoton_qspi_setup(struct spi_device *spi) +{ + unsigned int cs = spi_get_chipselect(spi, 0); + + if (spi_get_csgpiod(spi, 0)) + return 0; + + if (cs >= NUVOTON_QSPI_MAX_NATIVE_CS) { + dev_err(&spi->dev, "invalid native chip select %u\n", cs); + return -EINVAL; + } + + if (spi->mode & SPI_CS_HIGH) { + dev_err(&spi->dev, + "active-high native chip select is not supported\n"); + return -EINVAL; + } + + return 0; +} + static void nuvoton_qspi_set_cs(struct spi_device *spi, bool level) { struct nuvoton_qspi *qspi = spi_controller_get_devdata(spi->controller); /* - * The SPI core passes the physical CS level to ->set_cs(). This - * initial driver only supports active-low native chip selects. + * GPIO chip selects are handled by the SPI core. For native chip + * selects, the core passes the physical CS level to ->set_cs(). + * Native chip selects are active low. */ nuvoton_qspi_set_cs_level(qspi, spi_get_chipselect(spi, 0), !level); } @@ -457,7 +479,11 @@ static void nuvoton_qspi_mem_set_cs(struct spi_device *spi, bool assert) { struct nuvoton_qspi *qspi = spi_controller_get_devdata(spi->controller); - /* The direct spi-mem path passes a logical assertion state. */ + /* + * Direct spi-mem operations are only executed for native chip + * selects. GPIO chip selects use the regular SPI fallback path. + * This helper takes a logical assertion state. + */ nuvoton_qspi_set_cs_level(qspi, spi_get_chipselect(spi, 0), assert); } @@ -633,18 +659,26 @@ static int nuvoton_qspi_probe(struct platform_device *pdev) return dev_err_probe(dev, ret, "failed to deassert reset\n"); ret = device_property_read_u32(dev, "num-cs", &num_cs); - if (ret && ret != -EINVAL) - return dev_err_probe(dev, ret, "failed to read num-cs\n"); + if (ret && ret != -EINVAL) { + ret = dev_err_probe(dev, ret, "failed to read num-cs\n"); + goto err_assert; + } - if (!num_cs || num_cs > NUVOTON_QSPI_MAX_NUM_CS) - return dev_err_probe(dev, -EINVAL, "invalid num-cs %u\n", + if (!num_cs || num_cs > NUVOTON_QSPI_MAX_NATIVE_CS) { + ret = dev_err_probe(dev, -EINVAL, "invalid num-cs %u\n", num_cs); + goto err_assert; + } ctlr->num_chipselect = num_cs; + ctlr->max_native_cs = NUVOTON_QSPI_MAX_NATIVE_CS; + ctlr->use_gpio_descriptors = true; ctlr->max_transfer_size = nuvoton_qspi_max_transfer_size; ctlr->max_message_size = nuvoton_qspi_max_message_size; ctlr->mem_ops = &nuvoton_qspi_mem_ops; ctlr->mem_caps = &nuvoton_qspi_mem_caps; + ctlr->dtr_caps = true; + ctlr->setup = nuvoton_qspi_setup; ctlr->set_cs = nuvoton_qspi_set_cs; ctlr->transfer_one = nuvoton_qspi_transfer_one; ctlr->bits_per_word_mask = SPI_BPW_MASK(8); @@ -655,14 +689,20 @@ static int nuvoton_qspi_probe(struct platform_device *pdev) ret = nuvoton_qspi_hw_init(qspi); if (ret) - return ret; + goto err_assert; ret = devm_spi_register_controller(dev, ctlr); - if (ret) - return dev_err_probe(dev, ret, - "failed to register spi controller\n"); + if (ret) { + ret = dev_err_probe(dev, ret, + "failed to register spi controller\n"); + goto err_assert; + } return 0; + +err_assert: + reset_control_assert(rst); + return ret; } static const struct of_device_id nuvoton_qspi_of_match[] = {
diff --git a/drivers/spi/spi-ma35d1.c b/drivers/spi/spi-ma35d1.c new file mode 100644 index 0000000..7560cb7 --- /dev/null +++ b/drivers/spi/spi-ma35d1.c
@@ -0,0 +1,716 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// +// Nuvoton MA35D1 SPI controller driver +// +// Copyright (c) 2026 Nuvoton Technology Corp. +// Author: Chi-Wen Weng <cwweng@nuvoton.com> + +#include <linux/bitfield.h> +#include <linux/bits.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/device.h> +#include <linux/io.h> +#include <linux/iopoll.h> +#include <linux/math.h> +#include <linux/module.h> +#include <linux/pm.h> +#include <linux/platform_device.h> +#include <linux/property.h> +#include <linux/reset.h> +#include <linux/sizes.h> +#include <linux/spi/spi.h> +#include <linux/time.h> +#include <linux/unaligned.h> + +/* Register offset definitions */ +#define NUVOTON_SPI_CTL_OFFSET 0x00 +#define NUVOTON_SPI_CLKDIV_OFFSET 0x04 +#define NUVOTON_SPI_SSCTL_OFFSET 0x08 +#define NUVOTON_SPI_PDMACTL_OFFSET 0x0c +#define NUVOTON_SPI_FIFOCTL_OFFSET 0x10 +#define NUVOTON_SPI_STATUS_OFFSET 0x14 +#define NUVOTON_SPI_TX_OFFSET 0x20 +#define NUVOTON_SPI_RX_OFFSET 0x30 + +/* SPI Control Register bit masks */ +#define NUVOTON_SPI_CTL_DATDIR_MASK BIT(20) +#define NUVOTON_SPI_CTL_REORDER_MASK BIT(19) +#define NUVOTON_SPI_CTL_SLAVE_MASK BIT(18) +#define NUVOTON_SPI_CTL_UNITIEN_MASK BIT(17) +#define NUVOTON_SPI_CTL_RXONLY_MASK BIT(15) +#define NUVOTON_SPI_CTL_HALFDPX_MASK BIT(14) +#define NUVOTON_SPI_CTL_LSB_MASK BIT(13) +#define NUVOTON_SPI_CTL_DWIDTH_MASK GENMASK(12, 8) +#define NUVOTON_SPI_CTL_SUSPITV_MASK GENMASK(7, 4) +#define NUVOTON_SPI_CTL_CLKPOL_MASK BIT(3) +#define NUVOTON_SPI_CTL_TXNEG_MASK BIT(2) +#define NUVOTON_SPI_CTL_RXNEG_MASK BIT(1) +#define NUVOTON_SPI_CTL_SPIEN_MASK BIT(0) + +/* SPI Clock Divider Register bit masks */ +#define NUVOTON_SPI_CLKDIV_MASK GENMASK(8, 0) + +/* SPI Slave Select Control Register bit masks */ +#define NUVOTON_SPI_SSCTL_SS1_MASK BIT(1) +#define NUVOTON_SPI_SSCTL_SS0_MASK BIT(0) +#define NUVOTON_SPI_SSCTL_SSACTPOL_MASK BIT(2) +#define NUVOTON_SPI_SSCTL_AUTOSS_MASK BIT(3) +#define NUVOTON_SPI_SSCTL_SLV3WIRE_MASK BIT(4) +#define NUVOTON_SPI_SSCTL_SLVBEIEN_MASK BIT(8) +#define NUVOTON_SPI_SSCTL_SLVURIEN_MASK BIT(9) +#define NUVOTON_SPI_SSCTL_SSACTIEN_MASK BIT(12) +#define NUVOTON_SPI_SSCTL_SSINAIEN_MASK BIT(13) + +/* SPI PDMA Control Register bit masks */ +#define NUVOTON_SPI_PDMACTL_TXPDMAEN_MASK BIT(0) +#define NUVOTON_SPI_PDMACTL_RXPDMAEN_MASK BIT(1) + +/* SPI FIFO Control Register bit masks */ +#define NUVOTON_SPI_FIFOCTL_SLVBERX_MASK BIT(10) +#define NUVOTON_SPI_FIFOCTL_TXUFIEN_MASK BIT(7) +#define NUVOTON_SPI_FIFOCTL_TXUFPOL_MASK BIT(6) +#define NUVOTON_SPI_FIFOCTL_RXOVIEN_MASK BIT(5) +#define NUVOTON_SPI_FIFOCTL_RXTOIEN_MASK BIT(4) +#define NUVOTON_SPI_FIFOCTL_TXTHIEN_MASK BIT(3) +#define NUVOTON_SPI_FIFOCTL_RXTHIEN_MASK BIT(2) +#define NUVOTON_SPI_FIFOCTL_TXRST_MASK BIT(1) +#define NUVOTON_SPI_FIFOCTL_RXRST_MASK BIT(0) + +/* SPI Status Register bit masks */ +#define NUVOTON_SPI_STATUS_TXRXRST_MASK BIT(23) +#define NUVOTON_SPI_STATUS_TXFULL_MASK BIT(17) +#define NUVOTON_SPI_STATUS_SPIENSTS_MASK BIT(15) +#define NUVOTON_SPI_STATUS_RXEMPTY_MASK BIT(8) +#define NUVOTON_SPI_STATUS_BUSY_MASK BIT(0) + +#define NUVOTON_SPI_MAX_NATIVE_CS 2 +#define NUVOTON_SPI_DEFAULT_NUM_CS 2 +#define NUVOTON_SPI_DEFAULT_BPW 8 +#define NUVOTON_SPI_MAX_SPEED_HZ 100000000U +#define NUVOTON_SPI_MIN_DIVISOR 2U +#define NUVOTON_SPI_MAX_DIVISOR 512U +#define NUVOTON_SPI_RESET_CYCLES 5U + +/* Bound PIO operations to avoid long polling loops. */ +#define NUVOTON_SPI_MAX_TRANSFER_SIZE SZ_4K +#define NUVOTON_SPI_TIMEOUT_US 10000 + +struct nuvoton_spi { + void __iomem *regs; + struct device *dev; + unsigned long clk_rate; +}; + +static u32 nuvoton_spi_read(struct nuvoton_spi *nspi, u32 reg) +{ + return readl(nspi->regs + reg); +} + +static void nuvoton_spi_write(struct nuvoton_spi *nspi, u32 val, u32 reg) +{ + writel(val, nspi->regs + reg); +} + +static void nuvoton_spi_update_bits(struct nuvoton_spi *nspi, u32 reg, + u32 mask, u32 val) +{ + u32 tmp; + + tmp = nuvoton_spi_read(nspi, reg); + tmp &= ~mask; + tmp |= val & mask; + nuvoton_spi_write(nspi, tmp, reg); +} + +static int nuvoton_spi_disable(struct nuvoton_spi *nspi) +{ + u32 ctl; + u32 val; + + ctl = nuvoton_spi_read(nspi, NUVOTON_SPI_CTL_OFFSET); + if (!(ctl & NUVOTON_SPI_CTL_SPIEN_MASK)) + return 0; + + nuvoton_spi_write(nspi, ctl & ~NUVOTON_SPI_CTL_SPIEN_MASK, + NUVOTON_SPI_CTL_OFFSET); + + return readl_poll_timeout_atomic(nspi->regs + NUVOTON_SPI_STATUS_OFFSET, + val, + !(val & NUVOTON_SPI_STATUS_SPIENSTS_MASK), + 1, NUVOTON_SPI_TIMEOUT_US); +} + +static int nuvoton_spi_enable(struct nuvoton_spi *nspi) +{ + u32 ctl; + u32 val; + + ctl = nuvoton_spi_read(nspi, NUVOTON_SPI_CTL_OFFSET); + if (ctl & NUVOTON_SPI_CTL_SPIEN_MASK) + return 0; + + nuvoton_spi_write(nspi, ctl | NUVOTON_SPI_CTL_SPIEN_MASK, + NUVOTON_SPI_CTL_OFFSET); + + return readl_poll_timeout_atomic(nspi->regs + NUVOTON_SPI_STATUS_OFFSET, + val, + val & NUVOTON_SPI_STATUS_SPIENSTS_MASK, + 1, NUVOTON_SPI_TIMEOUT_US); +} + +static int nuvoton_spi_wait_ready(struct nuvoton_spi *nspi) +{ + u32 val; + + return readl_poll_timeout(nspi->regs + NUVOTON_SPI_STATUS_OFFSET, val, + !(val & NUVOTON_SPI_STATUS_BUSY_MASK), + 0, NUVOTON_SPI_TIMEOUT_US); +} + +static int nuvoton_spi_reset_fifo(struct nuvoton_spi *nspi) +{ + u32 val; + + nuvoton_spi_update_bits(nspi, NUVOTON_SPI_FIFOCTL_OFFSET, + NUVOTON_SPI_FIFOCTL_TXRST_MASK | + NUVOTON_SPI_FIFOCTL_RXRST_MASK, + NUVOTON_SPI_FIFOCTL_TXRST_MASK | + NUVOTON_SPI_FIFOCTL_RXRST_MASK); + + /* + * Give the controller a short time to latch the FIFO reset request + * before polling the reset status bit. + */ + udelay(1); + + return readl_poll_timeout(nspi->regs + NUVOTON_SPI_STATUS_OFFSET, val, + !(val & NUVOTON_SPI_STATUS_TXRXRST_MASK), + 1, NUVOTON_SPI_TIMEOUT_US); +} + +static int nuvoton_spi_wait_tx_not_full(struct nuvoton_spi *nspi) +{ + u32 val; + + return readl_poll_timeout(nspi->regs + NUVOTON_SPI_STATUS_OFFSET, val, + !(val & NUVOTON_SPI_STATUS_TXFULL_MASK), + 0, NUVOTON_SPI_TIMEOUT_US); +} + +static int nuvoton_spi_wait_rx_not_empty(struct nuvoton_spi *nspi) +{ + u32 val; + + return readl_poll_timeout(nspi->regs + NUVOTON_SPI_STATUS_OFFSET, val, + !(val & NUVOTON_SPI_STATUS_RXEMPTY_MASK), + 0, NUVOTON_SPI_TIMEOUT_US); +} + +static int nuvoton_spi_calc_divisor(unsigned long clk_rate, u32 speed_hz, + unsigned int *divisor) +{ + unsigned int div; + + div = DIV_ROUND_UP(clk_rate, speed_hz); + if (div < NUVOTON_SPI_MIN_DIVISOR) + div = NUVOTON_SPI_MIN_DIVISOR; + + /* + * CLKDIV only accepts odd register values, corresponding to even + * clock divisors. Round up so the generated clock never exceeds + * the requested frequency. + */ + if (div & 1) + div++; + + if (div > NUVOTON_SPI_MAX_DIVISOR) + return -EINVAL; + + *divisor = div; + + return 0; +} + +static int nuvoton_spi_configure_mode(struct nuvoton_spi *nspi, + struct spi_device *spi) +{ + u32 mask = NUVOTON_SPI_CTL_TXNEG_MASK | + NUVOTON_SPI_CTL_RXNEG_MASK | + NUVOTON_SPI_CTL_CLKPOL_MASK | + NUVOTON_SPI_CTL_LSB_MASK; + u32 ctl = 0; + u32 cur_ctl; + u32 mode; + int ret; + + mode = spi->mode & SPI_MODE_X_MASK; + if (mode == SPI_MODE_0 || mode == SPI_MODE_3) + ctl |= NUVOTON_SPI_CTL_TXNEG_MASK; + else + ctl |= NUVOTON_SPI_CTL_RXNEG_MASK; + + if (spi->mode & SPI_CPOL) + ctl |= NUVOTON_SPI_CTL_CLKPOL_MASK; + + if (spi->mode & SPI_LSB_FIRST) + ctl |= NUVOTON_SPI_CTL_LSB_MASK; + + cur_ctl = nuvoton_spi_read(nspi, NUVOTON_SPI_CTL_OFFSET); + if ((cur_ctl & mask) == ctl) + return 0; + + ret = nuvoton_spi_disable(nspi); + if (ret) + return ret; + + nuvoton_spi_update_bits(nspi, NUVOTON_SPI_CTL_OFFSET, mask, ctl); + + return 0; +} + +static int nuvoton_spi_configure_transfer(struct nuvoton_spi *nspi, + struct spi_transfer *xfer) +{ + u32 ctl_mask = NUVOTON_SPI_CTL_DWIDTH_MASK; + u32 cur_clkdiv; + u32 cur_ctl; + u32 clkdiv; + u32 dwidth; + unsigned int divisor; + int ret; + + ret = nuvoton_spi_calc_divisor(nspi->clk_rate, xfer->speed_hz, + &divisor); + if (ret) { + dev_err(nspi->dev, "unsupported SPI clock %u Hz\n", + xfer->speed_hz); + return ret; + } + + clkdiv = FIELD_PREP(NUVOTON_SPI_CLKDIV_MASK, divisor - 1); + dwidth = xfer->bits_per_word == 32 ? 0 : xfer->bits_per_word; + dwidth = FIELD_PREP(NUVOTON_SPI_CTL_DWIDTH_MASK, dwidth); + + xfer->effective_speed_hz = nspi->clk_rate / divisor; + + cur_ctl = nuvoton_spi_read(nspi, NUVOTON_SPI_CTL_OFFSET); + cur_clkdiv = nuvoton_spi_read(nspi, NUVOTON_SPI_CLKDIV_OFFSET); + + if ((cur_ctl & ctl_mask) == dwidth && + (cur_clkdiv & NUVOTON_SPI_CLKDIV_MASK) == clkdiv) + return 0; + + ret = nuvoton_spi_disable(nspi); + if (ret) + return ret; + + if ((cur_ctl & ctl_mask) != dwidth) + nuvoton_spi_update_bits(nspi, NUVOTON_SPI_CTL_OFFSET, + ctl_mask, dwidth); + + if ((cur_clkdiv & NUVOTON_SPI_CLKDIV_MASK) != clkdiv) + nuvoton_spi_write(nspi, clkdiv, NUVOTON_SPI_CLKDIV_OFFSET); + + return 0; +} + +static u32 nuvoton_spi_get_tx_word(const void *txbuf, unsigned int offset, + unsigned int bytes_per_word) +{ + if (!txbuf) + return 0; + + switch (bytes_per_word) { + case 1: + return ((const u8 *)txbuf)[offset]; + case 2: + return get_unaligned((const u16 *)((const u8 *)txbuf + offset)); + case 4: + return get_unaligned((const u32 *)((const u8 *)txbuf + offset)); + default: + return 0; + } +} + +static void nuvoton_spi_put_rx_word(void *rxbuf, unsigned int offset, + unsigned int bytes_per_word, u32 val) +{ + if (!rxbuf) + return; + + switch (bytes_per_word) { + case 1: + ((u8 *)rxbuf)[offset] = val; + break; + case 2: + put_unaligned((u16)val, (u16 *)((u8 *)rxbuf + offset)); + break; + case 4: + put_unaligned(val, (u32 *)((u8 *)rxbuf + offset)); + break; + } +} + +static int nuvoton_spi_txrx(struct nuvoton_spi *nspi, + struct spi_transfer *xfer) +{ + unsigned int bytes_per_word; + unsigned int offset; + u32 val; + int ret; + + bytes_per_word = spi_bpw_to_bytes(xfer->bits_per_word); + + /* + * Use conservative word-by-word PIO. Each transmitted word produces + * one receive FIFO entry, so always drain RX, including TX-only + * transfers. RX-only transfers send zero-filled dummy words. + */ + for (offset = 0; offset < xfer->len; offset += bytes_per_word) { + ret = nuvoton_spi_wait_tx_not_full(nspi); + if (ret) { + dev_err(nspi->dev, "TX FIFO full timeout\n"); + return ret; + } + + val = nuvoton_spi_get_tx_word(xfer->tx_buf, offset, + bytes_per_word); + nuvoton_spi_write(nspi, val, NUVOTON_SPI_TX_OFFSET); + + ret = nuvoton_spi_wait_rx_not_empty(nspi); + if (ret) { + dev_err(nspi->dev, "RX FIFO empty timeout\n"); + return ret; + } + + val = nuvoton_spi_read(nspi, NUVOTON_SPI_RX_OFFSET); + nuvoton_spi_put_rx_word(xfer->rx_buf, offset, bytes_per_word, + val); + + spi_delay_exec(&xfer->word_delay, xfer); + } + + ret = nuvoton_spi_wait_ready(nspi); + if (ret) + dev_err(nspi->dev, "controller busy timeout\n"); + + return ret; +} + +static void nuvoton_spi_set_cs_level(struct nuvoton_spi *nspi, + unsigned int cs, bool assert) +{ + u32 mask; + + switch (cs) { + case 0: + mask = NUVOTON_SPI_SSCTL_SS0_MASK; + break; + case 1: + mask = NUVOTON_SPI_SSCTL_SS1_MASK; + break; + default: + dev_warn(nspi->dev, "invalid chip select %u\n", cs); + return; + } + + nuvoton_spi_update_bits(nspi, NUVOTON_SPI_SSCTL_OFFSET, + mask, assert ? mask : 0); +} + +static int nuvoton_spi_setup(struct spi_device *spi) +{ + unsigned int cs = spi_get_chipselect(spi, 0); + + if (spi_get_csgpiod(spi, 0)) + return 0; + + if (cs >= NUVOTON_SPI_MAX_NATIVE_CS) { + dev_err(&spi->dev, "invalid native chip select %u\n", cs); + return -EINVAL; + } + + if (spi->mode & SPI_CS_HIGH) { + dev_err(&spi->dev, + "active-high native chip select is not supported\n"); + return -EINVAL; + } + + return 0; +} + +static void nuvoton_spi_set_cs(struct spi_device *spi, bool level) +{ + struct nuvoton_spi *nspi = spi_controller_get_devdata(spi->controller); + int ret; + + /* + * SSCTL may only be changed while SPIEN is clear. Clearing SPIEN + * retains the CLK and MOSI output levels. + */ + ret = nuvoton_spi_disable(nspi); + if (ret) { + dev_err(nspi->dev, "failed to disable controller for chip select\n"); + return; + } + + /* + * The SPI core passes the physical CS level to ->set_cs(). This + * initial driver only supports active-low native chip selects. + */ + nuvoton_spi_set_cs_level(nspi, spi_get_chipselect(spi, 0), !level); +} + +static int nuvoton_spi_prepare_message(struct spi_controller *ctlr, + struct spi_message *message) +{ + struct nuvoton_spi *nspi = spi_controller_get_devdata(ctlr); + int ret; + + ret = nuvoton_spi_configure_mode(nspi, message->spi); + if (ret) + dev_err(nspi->dev, "failed to configure SPI mode\n"); + + return ret; +} + +static int nuvoton_spi_transfer_one(struct spi_controller *ctlr, + struct spi_device *spi, + struct spi_transfer *xfer) +{ + struct nuvoton_spi *nspi = spi_controller_get_devdata(ctlr); + int ret; + + ret = nuvoton_spi_configure_transfer(nspi, xfer); + if (ret) + return ret; + + ret = nuvoton_spi_enable(nspi); + if (ret) { + dev_err(nspi->dev, "failed to enable controller\n"); + return ret; + } + + return nuvoton_spi_txrx(nspi, xfer); +} + +static void nuvoton_spi_handle_err(struct spi_controller *ctlr, + struct spi_message *message) +{ + struct nuvoton_spi *nspi = spi_controller_get_devdata(ctlr); + int ret; + + ret = nuvoton_spi_disable(nspi); + if (ret) { + dev_err(nspi->dev, + "failed to disable controller during recovery\n"); + return; + } + + ret = nuvoton_spi_reset_fifo(nspi); + if (ret) + dev_err(nspi->dev, "failed to reset FIFO during recovery\n"); +} + +static size_t nuvoton_spi_max_transfer_size(struct spi_device *spi) +{ + return NUVOTON_SPI_MAX_TRANSFER_SIZE; +} + +static int nuvoton_spi_hw_init(struct nuvoton_spi *nspi) +{ + u32 ctl_mask; + u32 fifo_mask; + u32 ssctl_mask; + int ret; + + ret = nuvoton_spi_disable(nspi); + if (ret) { + dev_err(nspi->dev, "failed to disable controller\n"); + return ret; + } + + ctl_mask = NUVOTON_SPI_CTL_DATDIR_MASK | + NUVOTON_SPI_CTL_REORDER_MASK | + NUVOTON_SPI_CTL_SLAVE_MASK | + NUVOTON_SPI_CTL_UNITIEN_MASK | + NUVOTON_SPI_CTL_RXONLY_MASK | + NUVOTON_SPI_CTL_HALFDPX_MASK | + NUVOTON_SPI_CTL_LSB_MASK | + NUVOTON_SPI_CTL_DWIDTH_MASK | + NUVOTON_SPI_CTL_SUSPITV_MASK | + NUVOTON_SPI_CTL_CLKPOL_MASK | + NUVOTON_SPI_CTL_TXNEG_MASK | + NUVOTON_SPI_CTL_RXNEG_MASK; + + nuvoton_spi_update_bits(nspi, NUVOTON_SPI_CTL_OFFSET, ctl_mask, + NUVOTON_SPI_CTL_TXNEG_MASK | + FIELD_PREP(NUVOTON_SPI_CTL_DWIDTH_MASK, + NUVOTON_SPI_DEFAULT_BPW)); + + ssctl_mask = NUVOTON_SPI_SSCTL_SS0_MASK | + NUVOTON_SPI_SSCTL_SS1_MASK | + NUVOTON_SPI_SSCTL_SSACTPOL_MASK | + NUVOTON_SPI_SSCTL_AUTOSS_MASK | + NUVOTON_SPI_SSCTL_SLV3WIRE_MASK | + NUVOTON_SPI_SSCTL_SLVBEIEN_MASK | + NUVOTON_SPI_SSCTL_SLVURIEN_MASK | + NUVOTON_SPI_SSCTL_SSACTIEN_MASK | + NUVOTON_SPI_SSCTL_SSINAIEN_MASK; + + nuvoton_spi_update_bits(nspi, NUVOTON_SPI_SSCTL_OFFSET, + ssctl_mask, 0); + + nuvoton_spi_update_bits(nspi, NUVOTON_SPI_PDMACTL_OFFSET, + NUVOTON_SPI_PDMACTL_TXPDMAEN_MASK | + NUVOTON_SPI_PDMACTL_RXPDMAEN_MASK, 0); + + fifo_mask = NUVOTON_SPI_FIFOCTL_SLVBERX_MASK | + NUVOTON_SPI_FIFOCTL_TXUFIEN_MASK | + NUVOTON_SPI_FIFOCTL_TXUFPOL_MASK | + NUVOTON_SPI_FIFOCTL_RXOVIEN_MASK | + NUVOTON_SPI_FIFOCTL_RXTOIEN_MASK | + NUVOTON_SPI_FIFOCTL_TXTHIEN_MASK | + NUVOTON_SPI_FIFOCTL_RXTHIEN_MASK; + + nuvoton_spi_update_bits(nspi, NUVOTON_SPI_FIFOCTL_OFFSET, fifo_mask, 0); + + ret = nuvoton_spi_reset_fifo(nspi); + if (ret) + dev_err(nspi->dev, "FIFO reset timed out\n"); + + return ret; +} + +static int nuvoton_spi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct spi_controller *ctlr; + struct nuvoton_spi *nspi; + struct reset_control *rst; + struct clk *clk; + unsigned int max_divisor; + u32 num_cs = NUVOTON_SPI_DEFAULT_NUM_CS; + int ret; + + if (device_property_read_bool(dev, "spi-slave")) + return dev_err_probe(dev, -EOPNOTSUPP, + "target mode is not supported\n"); + + ctlr = devm_spi_alloc_host(dev, sizeof(*nspi)); + if (!ctlr) + return -ENOMEM; + + platform_set_drvdata(pdev, ctlr); + + nspi = spi_controller_get_devdata(ctlr); + nspi->dev = dev; + + nspi->regs = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(nspi->regs)) + return PTR_ERR(nspi->regs); + + clk = devm_clk_get_enabled(dev, NULL); + if (IS_ERR(clk)) + return dev_err_probe(dev, PTR_ERR(clk), + "failed to get and enable clock\n"); + + nspi->clk_rate = clk_get_rate(clk); + if (!nspi->clk_rate) + return dev_err_probe(dev, -EINVAL, "invalid clock rate\n"); + + rst = devm_reset_control_get_exclusive_deasserted(dev, NULL); + if (IS_ERR(rst)) + return dev_err_probe(dev, PTR_ERR(rst), + "failed to get and deassert reset\n"); + + /* + * The hardware requires at least five peripheral clock cycles after + * reset deassertion before programming controller registers. + */ + udelay(DIV_ROUND_UP_ULL((u64)NUVOTON_SPI_RESET_CYCLES * + USEC_PER_SEC, nspi->clk_rate)); + + ret = device_property_read_u32(dev, "num-cs", &num_cs); + if (ret && ret != -EINVAL) + return dev_err_probe(dev, ret, "failed to read num-cs\n"); + + if (!num_cs || num_cs > NUVOTON_SPI_MAX_NATIVE_CS) + return dev_err_probe(dev, -EINVAL, "invalid num-cs %u\n", + num_cs); + + ctlr->num_chipselect = num_cs; + ctlr->max_native_cs = NUVOTON_SPI_MAX_NATIVE_CS; + ctlr->use_gpio_descriptors = true; + ctlr->max_transfer_size = nuvoton_spi_max_transfer_size; + ctlr->setup = nuvoton_spi_setup; + ctlr->set_cs = nuvoton_spi_set_cs; + ctlr->prepare_message = nuvoton_spi_prepare_message; + ctlr->transfer_one = nuvoton_spi_transfer_one; + ctlr->handle_err = nuvoton_spi_handle_err; + ctlr->bits_per_word_mask = SPI_BPW_RANGE_MASK(8, 32); + ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST; + ctlr->min_speed_hz = DIV_ROUND_UP(nspi->clk_rate, + NUVOTON_SPI_MAX_DIVISOR); + + ret = nuvoton_spi_calc_divisor(nspi->clk_rate, + NUVOTON_SPI_MAX_SPEED_HZ, &max_divisor); + if (ret) + return dev_err_probe(dev, ret, + "clock rate does not support SPI transfers\n"); + + ctlr->max_speed_hz = nspi->clk_rate / max_divisor; + + ret = nuvoton_spi_hw_init(nspi); + if (ret) + return ret; + + ret = devm_spi_register_controller(dev, ctlr); + if (ret) + return dev_err_probe(dev, ret, + "failed to register SPI controller\n"); + + return 0; +} + +static int nuvoton_spi_suspend(struct device *dev) +{ + struct spi_controller *ctlr = dev_get_drvdata(dev); + + return spi_controller_suspend(ctlr); +} + +static int nuvoton_spi_resume(struct device *dev) +{ + struct spi_controller *ctlr = dev_get_drvdata(dev); + + /* + * The MA35D1 SPI registers are retained across power-down and deep + * sleep, so the controller state does not need to be restored here. + */ + return spi_controller_resume(ctlr); +} + +static DEFINE_SIMPLE_DEV_PM_OPS(nuvoton_spi_pm_ops, nuvoton_spi_suspend, + nuvoton_spi_resume); + +static const struct of_device_id nuvoton_spi_of_match[] = { + { .compatible = "nuvoton,ma35d1-spi" }, + { } +}; +MODULE_DEVICE_TABLE(of, nuvoton_spi_of_match); + +static struct platform_driver nuvoton_spi_driver = { + .driver = { + .name = "ma35d1-spi", + .of_match_table = nuvoton_spi_of_match, + .pm = pm_sleep_ptr(&nuvoton_spi_pm_ops), + }, + .probe = nuvoton_spi_probe, +}; +module_platform_driver(nuvoton_spi_driver); + +MODULE_DESCRIPTION("Nuvoton MA35D1 SPI controller driver"); +MODULE_AUTHOR("Chi-Wen Weng <cwweng@nuvoton.com>"); +MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi-mem.c b/drivers/spi/spi-mem.c index 5f973eb..b94680b 100644 --- a/drivers/spi/spi-mem.c +++ b/drivers/spi/spi-mem.c
@@ -46,9 +46,9 @@ int spi_controller_dma_map_mem_op_data(struct spi_controller *ctlr, return -EINVAL; if (op->data.dir == SPI_MEM_DATA_OUT && ctlr->dma_tx) - dmadev = ctlr->dma_tx->device->dev; + dmadev = dmaengine_get_dma_device(ctlr->dma_tx); else if (op->data.dir == SPI_MEM_DATA_IN && ctlr->dma_rx) - dmadev = ctlr->dma_rx->device->dev; + dmadev = dmaengine_get_dma_device(ctlr->dma_rx); else dmadev = ctlr->dev.parent; @@ -92,9 +92,9 @@ void spi_controller_dma_unmap_mem_op_data(struct spi_controller *ctlr, return; if (op->data.dir == SPI_MEM_DATA_OUT && ctlr->dma_tx) - dmadev = ctlr->dma_tx->device->dev; + dmadev = dmaengine_get_dma_device(ctlr->dma_tx); else if (op->data.dir == SPI_MEM_DATA_IN && ctlr->dma_rx) - dmadev = ctlr->dma_rx->device->dev; + dmadev = dmaengine_get_dma_device(ctlr->dma_rx); else dmadev = ctlr->dev.parent; @@ -172,7 +172,7 @@ bool spi_mem_default_supports_op(struct spi_mem *mem, op->cmd.dtr || op->addr.dtr || op->dummy.dtr || op->data.dtr; if (op_is_dtr) { - if (!spi_mem_controller_is_capable(ctlr, dtr)) + if (!spi_mem_controller_is_capable(ctlr, dtr) && !ctlr->dtr_caps) return false; if (op->data.swap16 && !spi_mem_controller_is_capable(ctlr, swap16)) @@ -461,6 +461,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) xfers[xferpos].len = op->cmd.nbytes; xfers[xferpos].tx_nbits = op->cmd.buswidth; xfers[xferpos].speed_hz = op->max_freq; + xfers[xferpos].dtr_mode = op->cmd.dtr; spi_message_add_tail(&xfers[xferpos], &msg); xferpos++; totalxferlen++; @@ -476,6 +477,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) xfers[xferpos].len = op->addr.nbytes; xfers[xferpos].tx_nbits = op->addr.buswidth; xfers[xferpos].speed_hz = op->max_freq; + xfers[xferpos].dtr_mode = op->addr.dtr; spi_message_add_tail(&xfers[xferpos], &msg); xferpos++; totalxferlen += op->addr.nbytes; @@ -488,6 +490,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) xfers[xferpos].tx_nbits = op->dummy.buswidth; xfers[xferpos].dummy_data = 1; xfers[xferpos].speed_hz = op->max_freq; + xfers[xferpos].dtr_mode = op->dummy.dtr; spi_message_add_tail(&xfers[xferpos], &msg); xferpos++; totalxferlen += op->dummy.nbytes; @@ -504,6 +507,7 @@ int spi_mem_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) xfers[xferpos].len = op->data.nbytes; xfers[xferpos].speed_hz = op->max_freq; + xfers[xferpos].dtr_mode = op->data.dtr; spi_message_add_tail(&xfers[xferpos], &msg); xferpos++; totalxferlen += op->data.nbytes;
diff --git a/drivers/spi/spi-meson-spicc.c b/drivers/spi/spi-meson-spicc.c index fa2d2db..b1f8c82 100644 --- a/drivers/spi/spi-meson-spicc.c +++ b/drivers/spi/spi-meson-spicc.c
@@ -235,6 +235,13 @@ static int meson_spicc_dma_map(struct meson_spicc_device *spicc, { struct device *dev = spicc->host->dev.parent; + /* + * Mark the DMA addresses as invalid so that meson_spicc_dma_unmap() + * will not try to unmap a buffer which was not (successfully) mapped. + */ + t->tx_dma = DMA_MAPPING_ERROR; + t->rx_dma = DMA_MAPPING_ERROR; + if (!(t->tx_buf && t->rx_buf)) return -EINVAL; @@ -257,9 +264,9 @@ static void meson_spicc_dma_unmap(struct meson_spicc_device *spicc, { struct device *dev = spicc->host->dev.parent; - if (t->tx_dma) + if (!dma_mapping_error(dev, t->tx_dma)) dma_unmap_single(dev, t->tx_dma, t->len, DMA_TO_DEVICE); - if (t->rx_dma) + if (!dma_mapping_error(dev, t->rx_dma)) dma_unmap_single(dev, t->rx_dma, t->len, DMA_FROM_DEVICE); }
diff --git a/drivers/spi/spi-mtk-nor.c b/drivers/spi/spi-mtk-nor.c index 63f5139..6b6e55d 100644 --- a/drivers/spi/spi-mtk-nor.c +++ b/drivers/spi/spi-mtk-nor.c
@@ -929,6 +929,7 @@ static int mtk_nor_probe(struct platform_device *pdev) return 0; err_probe: + pm_runtime_put_noidle(&pdev->dev); pm_runtime_disable(&pdev->dev); pm_runtime_set_suspended(&pdev->dev); pm_runtime_dont_use_autosuspend(&pdev->dev);
diff --git a/drivers/spi/spi-mxic.c b/drivers/spi/spi-mxic.c index e3c85e5..481edd4 100644 --- a/drivers/spi/spi-mxic.c +++ b/drivers/spi/spi-mxic.c
@@ -744,7 +744,13 @@ static int mxic_spi_runtime_resume(struct device *dev) return ret; } - return mxic_spi_clk_enable(mxic); + ret = mxic_spi_clk_enable(mxic); + if (ret) { + clk_disable_unprepare(mxic->ps_clk); + return ret; + } + + return 0; } static const struct dev_pm_ops mxic_spi_dev_pm_ops = {
diff --git a/drivers/spi/spi-npcm-fiu.c b/drivers/spi/spi-npcm-fiu.c index 96dfef4..9c0a655 100644 --- a/drivers/spi/spi-npcm-fiu.c +++ b/drivers/spi/spi-npcm-fiu.c
@@ -343,6 +343,10 @@ static int npcm_fiu_uma_read(struct spi_mem *mem, u32 val; u32 i; + /* data_reg holds at most 16 bytes */ + if (data_size > sizeof(data_reg)) + return -EOPNOTSUPP; + regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS, NPCM_FIU_UMA_CTS_DEV_NUM, (spi_get_chipselect(mem->spi, 0) << @@ -398,6 +402,10 @@ static int npcm_fiu_uma_write(struct spi_mem *mem, u32 val; u32 i; + /* data_reg holds at most 16 bytes */ + if (data_size > sizeof(data_reg)) + return -EOPNOTSUPP; + regmap_update_bits(fiu->regmap, NPCM_FIU_UMA_CTS, NPCM_FIU_UMA_CTS_DEV_NUM, (spi_get_chipselect(mem->spi, 0) <<
diff --git a/drivers/spi/spi-nxp-xspi.c b/drivers/spi/spi-nxp-xspi.c index 70cbc3e..38c8d62 100644 --- a/drivers/spi/spi-nxp-xspi.c +++ b/drivers/spi/spi-nxp-xspi.c
@@ -841,23 +841,23 @@ static int nxp_xspi_ahb_dma_read(struct nxp_xspi *xspi, { struct dma_async_tx_descriptor *desc; struct dma_chan *chan = xspi->dma_rx; + struct device *dma_dev = dmaengine_get_dma_device(chan); unsigned long timeout; dma_addr_t src_addr, dst_addr; int ret = 0; - dst_addr = dma_map_single(chan->device->dev, - op->data.buf.in, op->data.nbytes, + dst_addr = dma_map_single(dma_dev, op->data.buf.in, op->data.nbytes, DMA_FROM_DEVICE); - if (dma_mapping_error(chan->device->dev, dst_addr)) { + if (dma_mapping_error(dma_dev, dst_addr)) { dev_err(xspi->dev, "failed to map DMA dst buffer\n"); return -ENOMEM; } - src_addr = dma_map_resource(chan->device->dev, + src_addr = dma_map_resource(dma_dev, (phys_addr_t)xspi->memmap_phy + op->addr.val, op->data.nbytes, DMA_TO_DEVICE, 0); - if (dma_mapping_error(chan->device->dev, src_addr)) { + if (dma_mapping_error(dma_dev, src_addr)) { dev_err(xspi->dev, "failed to map DMA src resource\n"); ret = -ENOMEM; goto err_unmap_dst; @@ -886,12 +886,10 @@ static int nxp_xspi_ahb_dma_read(struct nxp_xspi *xspi, } err_unmap_src: - dma_unmap_resource(chan->device->dev, src_addr, - op->data.nbytes, DMA_TO_DEVICE, 0); + dma_unmap_resource(dma_dev, src_addr, op->data.nbytes, DMA_TO_DEVICE, 0); err_unmap_dst: - dma_unmap_single(chan->device->dev, dst_addr, - op->data.nbytes, DMA_FROM_DEVICE); + dma_unmap_single(dma_dev, dst_addr, op->data.nbytes, DMA_FROM_DEVICE); return ret; }
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index a335514..e46b1d9 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c
@@ -413,10 +413,11 @@ static void omap2_mcspi_tx_callback(void *data) complete(&mcspi_dma->dma_tx_completion); } -static void omap2_mcspi_tx_dma(struct spi_device *spi, - struct spi_transfer *xfer, - struct dma_slave_config cfg) +static int omap2_mcspi_tx_dma(struct spi_device *spi, + struct spi_transfer *xfer, + struct dma_slave_config cfg) { + int ret; struct omap2_mcspi *mcspi; struct omap2_mcspi_dma *mcspi_dma; struct dma_async_tx_descriptor *tx; @@ -424,31 +425,31 @@ static void omap2_mcspi_tx_dma(struct spi_device *spi, mcspi = spi_controller_get_devdata(spi->controller); mcspi_dma = &mcspi->dma_channels[spi_get_chipselect(spi, 0)]; - dmaengine_slave_config(mcspi_dma->dma_tx, &cfg); + ret = dmaengine_slave_config(mcspi_dma->dma_tx, &cfg); + if (ret) + return ret; tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, xfer->tx_sg.sgl, xfer->tx_sg.nents, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (tx) { - tx->callback = omap2_mcspi_tx_callback; - tx->callback_param = spi; - dmaengine_submit(tx); - } else { - /* FIXME: fall back to PIO? */ - } - dma_async_issue_pending(mcspi_dma->dma_tx); - omap2_mcspi_set_dma_req(spi, 0, 1); + if (!tx) + return -EIO; + + tx->callback = omap2_mcspi_tx_callback; + tx->callback_param = spi; + + return dma_submit_error(dmaengine_submit(tx)); } -static unsigned +static int omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, - struct dma_slave_config cfg, - unsigned es) + struct dma_slave_config cfg, unsigned int es, + unsigned int *count, bool *rx_submitted, bool *dma_started) { struct omap2_mcspi *mcspi; struct omap2_mcspi_dma *mcspi_dma; - unsigned int count, transfer_reduction = 0; + unsigned int transfer_reduction = 0; struct scatterlist *sg_out[2]; int nb_sizes = 0, out_mapped_nents[2], ret, x; size_t sizes[2]; @@ -461,7 +462,8 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, mcspi = spi_controller_get_devdata(spi->controller); mcspi_dma = &mcspi->dma_channels[spi_get_chipselect(spi, 0)]; - count = xfer->len; + *count = xfer->len; + *rx_submitted = false; /* * In the "End-of-Transfer Procedure" section for DMA RX in OMAP35x TRM @@ -475,14 +477,16 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, l = mcspi_cached_chconf0(spi); if (word_len <= 8) - element_count = count; + element_count = *count; else if (word_len <= 16) - element_count = count >> 1; + element_count = *count >> 1; else /* word_len <= 32 */ - element_count = count >> 2; + element_count = *count >> 2; - dmaengine_slave_config(mcspi_dma->dma_rx, &cfg); + ret = dmaengine_slave_config(mcspi_dma->dma_rx, &cfg); + if (ret) + return ret; /* * Reduce DMA transfer length by one more if McSPI is @@ -493,7 +497,7 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, if (transfer_reduction) { /* Split sgl into two. The second sgl won't be used. */ - sizes[0] = count - transfer_reduction; + sizes[0] = *count - transfer_reduction; sizes[1] = transfer_reduction; nb_sizes = 2; } else { @@ -501,44 +505,56 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, * Don't bother splitting the sgl. This essentially * clones the original sgl. */ - sizes[0] = count; + sizes[0] = *count; nb_sizes = 1; } ret = sg_split(xfer->rx_sg.sgl, xfer->rx_sg.nents, 0, nb_sizes, sizes, sg_out, out_mapped_nents, GFP_KERNEL); - if (ret < 0) { + if (ret) { dev_err(&spi->dev, "sg_split failed\n"); - return 0; + return ret; } tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, sg_out[0], out_mapped_nents[0], DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (tx) { - tx->callback = omap2_mcspi_rx_callback; - tx->callback_param = spi; - dmaengine_submit(tx); - } else { - /* FIXME: fall back to PIO? */ + if (!tx) { + ret = -EIO; + goto out_free_sg; } + tx->callback = omap2_mcspi_rx_callback; + tx->callback_param = spi; + ret = dma_submit_error(dmaengine_submit(tx)); + if (ret) + goto out_free_sg; + + *rx_submitted = true; + if (mcspi->target_aborted) { + ret = -EINTR; + goto out_free_sg; + } + *dma_started = true; + if (xfer->tx_buf) { + if (spi_controller_is_target(mcspi->ctlr)) + mcspi_write_reg(mcspi->ctlr, OMAP2_MCSPI_IRQENABLE, + OMAP2_MCSPI_IRQSTATUS_EOW); + dma_async_issue_pending(mcspi_dma->dma_tx); + omap2_mcspi_set_dma_req(spi, 0, 1); + } dma_async_issue_pending(mcspi_dma->dma_rx); omap2_mcspi_set_dma_req(spi, 1, 1); - ret = mcspi_wait_for_completion(mcspi, &mcspi_dma->dma_rx_completion); - if (ret || mcspi->target_aborted) { - dmaengine_terminate_sync(mcspi_dma->dma_rx); - omap2_mcspi_set_dma_req(spi, 1, 0); - return 0; - } + if (ret || mcspi->target_aborted) + goto out_free_sg; for (x = 0; x < nb_sizes; x++) kfree(sg_out[x]); if (mcspi->fifo_depth > 0) - return count; + return 0; /* * Due to the DMA transfer length reduction the missing bytes must @@ -565,9 +581,9 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, } else { int bytes_per_word = mcspi_bytes_per_word(word_len); dev_err(&spi->dev, "DMA RX penultimate word empty\n"); - count -= (bytes_per_word << 1); + *count -= (bytes_per_word << 1); omap2_mcspi_set_enable(spi, 1); - return count; + return 0; } } if (!mcspi_wait_for_reg_bit(chstat_reg, OMAP2_MCSPI_CHSTAT_RXS)) { @@ -582,19 +598,27 @@ omap2_mcspi_rx_dma(struct spi_device *spi, struct spi_transfer *xfer, ((u32 *)xfer->rx_buf)[elements] = w; } else { dev_err(&spi->dev, "DMA RX last word empty\n"); - count -= mcspi_bytes_per_word(word_len); + *count -= mcspi_bytes_per_word(word_len); } omap2_mcspi_set_enable(spi, 1); - return count; + return 0; + +out_free_sg: + if (!ret) + ret = -EINTR; + for (x = 0; x < nb_sizes; x++) + kfree(sg_out[x]); + return ret; } -static unsigned -omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) +static int omap2_mcspi_txrx_dma(struct spi_device *spi, + struct spi_transfer *xfer, + unsigned int *count, + bool *pio_fallback) { struct omap2_mcspi *mcspi; struct omap2_mcspi_cs *cs = spi->controller_state; struct omap2_mcspi_dma *mcspi_dma; - unsigned int count; u8 *rx; const u8 *tx; struct dma_slave_config cfg; @@ -602,10 +626,13 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) unsigned es; void __iomem *chstat_reg; void __iomem *irqstat_reg; - int wait_res; + bool tx_submitted = false, rx_submitted = false; + bool dma_started = false, terminate_failed = false; + int ret, wait_res; mcspi = spi_controller_get_devdata(spi->controller); mcspi_dma = &mcspi->dma_channels[spi_get_chipselect(spi, 0)]; + *pio_fallback = false; if (cs->word_len <= 8) { width = DMA_SLAVE_BUSWIDTH_1_BYTE; @@ -618,7 +645,7 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) es = 4; } - count = xfer->len; + *count = xfer->len; memset(&cfg, 0, sizeof(cfg)); cfg.src_addr = cs->phys + OMAP2_MCSPI_RX0; @@ -636,31 +663,39 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) reinit_completion(&mcspi_dma->dma_rx_completion); reinit_completion(&mcspi->txdone); if (tx) { - /* Enable EOW IRQ to know end of tx in target mode */ - if (spi_controller_is_target(spi->controller)) - mcspi_write_reg(spi->controller, - OMAP2_MCSPI_IRQENABLE, - OMAP2_MCSPI_IRQSTATUS_EOW); - omap2_mcspi_tx_dma(spi, xfer, cfg); + ret = omap2_mcspi_tx_dma(spi, xfer, cfg); + if (ret) + goto out; + tx_submitted = true; } - if (rx != NULL) - count = omap2_mcspi_rx_dma(spi, xfer, cfg, es); - - if (tx != NULL) { - int ret; - - ret = mcspi_wait_for_completion(mcspi, &mcspi_dma->dma_tx_completion); - if (ret || mcspi->target_aborted) { - dmaengine_terminate_sync(mcspi_dma->dma_tx); - omap2_mcspi_set_dma_req(spi, 0, 0); - return 0; + if (rx) { + ret = omap2_mcspi_rx_dma(spi, xfer, cfg, es, count, + &rx_submitted, &dma_started); + if (ret) + goto out; + } else if (tx) { + if (mcspi->target_aborted) { + ret = -EINTR; + goto out; } + if (spi_controller_is_target(spi->controller)) + mcspi_write_reg(spi->controller, OMAP2_MCSPI_IRQENABLE, + OMAP2_MCSPI_IRQSTATUS_EOW); + dma_started = true; + dma_async_issue_pending(mcspi_dma->dma_tx); + omap2_mcspi_set_dma_req(spi, 0, 1); + } + + if (tx) { + ret = mcspi_wait_for_completion(mcspi, &mcspi_dma->dma_tx_completion); + if (ret || mcspi->target_aborted) + goto out; if (spi_controller_is_target(mcspi->ctlr)) { ret = mcspi_wait_for_completion(mcspi, &mcspi->txdone); if (ret || mcspi->target_aborted) - return 0; + goto out; } if (mcspi->fifo_depth > 0) { @@ -694,7 +729,43 @@ omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer) dev_err(&spi->dev, "EOT timed out\n"); } } - return count; + return 0; + +out: + if (!ret) + ret = -EINTR; + if (rx_submitted) { + wait_res = dmaengine_terminate_sync(mcspi_dma->dma_rx); + if (wait_res) { + dev_err(&spi->dev, "failed to terminate RX DMA: %d\n", + wait_res); + terminate_failed = true; + ret = wait_res; + } + omap2_mcspi_set_dma_req(spi, 1, 0); + } + if (tx_submitted) { + wait_res = dmaengine_terminate_sync(mcspi_dma->dma_tx); + if (wait_res) { + dev_err(&spi->dev, "failed to terminate TX DMA: %d\n", + wait_res); + terminate_failed = true; + ret = wait_res; + } + omap2_mcspi_set_dma_req(spi, 0, 0); + } + if (spi_controller_is_target(mcspi->ctlr)) + mcspi_write_reg(mcspi->ctlr, OMAP2_MCSPI_IRQENABLE, 0); + + *pio_fallback = !dma_started && !terminate_failed; + return ret; +} + +static bool omap2_mcspi_can_pio_fallback(bool cleanup_ok, + const struct spi_transfer *xfer, + bool is_target) +{ + return cleanup_ok && xfer->tx_buf && !is_target; } static unsigned @@ -1214,6 +1285,8 @@ static int omap2_mcspi_transfer_one(struct spi_controller *ctlr, if (t->len) { unsigned count; + bool pio_fallback; + int ret; if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) && spi_xfer_is_dma_mapped(ctlr, spi, t)) @@ -1227,10 +1300,31 @@ static int omap2_mcspi_transfer_one(struct spi_controller *ctlr, + OMAP2_MCSPI_TX0); if ((mcspi_dma->dma_rx && mcspi_dma->dma_tx) && - spi_xfer_is_dma_mapped(ctlr, spi, t)) - count = omap2_mcspi_txrx_dma(spi, t); - else + spi_xfer_is_dma_mapped(ctlr, spi, t)) { + ret = omap2_mcspi_txrx_dma(spi, t, &count, + &pio_fallback); + if (ret) { + bool is_target = spi_controller_is_target(ctlr); + bool fallback; + + fallback = omap2_mcspi_can_pio_fallback(pio_fallback, t, + is_target); + if (!fallback) { + status = ret; + goto out; + } + + dev_warn(&spi->dev, + "DMA setup failed, falling back to PIO\n"); + /* PIO does not use the FIFO enabled for DMA */ + omap2_mcspi_set_enable(spi, 0); + omap2_mcspi_set_fifo(spi, t, 0); + omap2_mcspi_set_enable(spi, 1); + count = omap2_mcspi_txrx_pio(spi, t); + } + } else { count = omap2_mcspi_txrx_pio(spi, t); + } if (count != t->len) { status = -EIO; @@ -1244,10 +1338,14 @@ static int omap2_mcspi_transfer_one(struct spi_controller *ctlr, omap2_mcspi_set_fifo(spi, t, 0); out: - /* Restore defaults if they were overriden */ + /* Restore defaults if they were overridden */ if (par_override) { + int restore_status; + par_override = 0; - status = omap2_mcspi_setup_transfer(spi, NULL); + restore_status = omap2_mcspi_setup_transfer(spi, NULL); + if (!status) + status = restore_status; } omap2_mcspi_set_enable(spi, 0); @@ -1544,8 +1642,10 @@ static int omap2_mcspi_probe(struct platform_device *pdev) return -ENOMEM; for (i = 0; i < ctlr->num_chipselect; i++) { - sprintf(mcspi->dma_channels[i].dma_rx_ch_name, "rx%d", i); - sprintf(mcspi->dma_channels[i].dma_tx_ch_name, "tx%d", i); + snprintf(mcspi->dma_channels[i].dma_rx_ch_name, + sizeof(mcspi->dma_channels[i].dma_rx_ch_name), "rx%d", i); + snprintf(mcspi->dma_channels[i].dma_tx_ch_name, + sizeof(mcspi->dma_channels[i].dma_tx_ch_name), "tx%d", i); status = omap2_mcspi_request_dma(mcspi, &mcspi->dma_channels[i]); @@ -1595,7 +1695,6 @@ static int omap2_mcspi_probe(struct platform_device *pdev) err_disable_rpm: pm_runtime_dont_use_autosuspend(&pdev->dev); - pm_runtime_put_sync(&pdev->dev); pm_runtime_disable(&pdev->dev); err_release_dma: omap2_mcspi_release_dma(ctlr); @@ -1613,7 +1712,6 @@ static void omap2_mcspi_remove(struct platform_device *pdev) omap2_mcspi_release_dma(ctlr); pm_runtime_dont_use_autosuspend(mcspi->dev); - pm_runtime_put_sync(mcspi->dev); pm_runtime_disable(&pdev->dev); }
diff --git a/drivers/spi/spi-orion.c b/drivers/spi/spi-orion.c index 26a9f26..b888222 100644 --- a/drivers/spi/spi-orion.c +++ b/drivers/spi/spi-orion.c
@@ -370,7 +370,16 @@ static inline int orion_spi_wait_till_ready(struct orion_spi *orion_spi) if (readl(spi_reg(orion_spi, ORION_SPI_INT_CAUSE_REG))) return 1; + /* + * This is a polled, byte-at-a-time transfer loop. Each + * iteration busy-waits in a tight udelay() loop, which can + * starve other time-sensitive peripherals (e.g. SATA) of CPU + * time and interfere with them if they run on this SoC. + * Yield to the scheduler between polls so pending IRQs can + * be serviced. + */ udelay(1); + cond_resched(); } return -1;
diff --git a/drivers/spi/spi-pci1xxxx.c b/drivers/spi/spi-pci1xxxx.c index af6ed78..c50e684 100644 --- a/drivers/spi/spi-pci1xxxx.c +++ b/drivers/spi/spi-pci1xxxx.c
@@ -542,6 +542,8 @@ static int pci1xxxx_spi_transfer_with_dma(struct spi_controller *spi_ctlr, struct pci1xxxx_spi_internal *p = spi_controller_get_devdata(spi_ctlr); struct pci1xxxx_spi *par = p->parent; dma_addr_t tx_dma_addr = 0; + unsigned long flags; + bool engines_stopped; int ret = 0; u32 regval; @@ -618,12 +620,72 @@ static int pci1xxxx_spi_transfer_with_dma(struct spi_controller *spi_ctlr, p->dma_aborted_wr = false; ret = -ECANCELED; } + + /* + * A timed out transfer leaves the DMA engines running and + * the done/abort interrupt status armed with p->xfer, + * p->tx_sgl and p->rx_sgl still registered. Stop the + * engines, drain the pending status and synchronize the + * IRQs before dropping the transfer state, otherwise a + * late interrupt makes the ISRs reprogram the engines + * from or signal completion through memory which the SPI + * core is about to unmap or free. + */ + writel(SPI_DMA_ENGINE_DIS, + par->dma_offset_bar + SPI_DMA_GLOBAL_WR_ENGINE_EN); + writel(SPI_DMA_ENGINE_DIS, + par->dma_offset_bar + SPI_DMA_GLOBAL_RD_ENGINE_EN); + engines_stopped = + !(readl_poll_timeout(par->dma_offset_bar + + SPI_DMA_GLOBAL_WR_ENGINE_EN, + regval, regval == 0x0, 0, + USEC_PER_MSEC) || + readl_poll_timeout(par->dma_offset_bar + + SPI_DMA_GLOBAL_RD_ENGINE_EN, + regval, regval == 0x0, 0, + USEC_PER_MSEC)); + if (!engines_stopped) + dev_warn(&par->dev->dev, + "SPI DMA engines failed to stop\n"); + + spin_lock_irqsave(&par->dma_wr_reg_lock, flags); + writel((SPI_DMA_DONE_INT_MASK(p->hw_inst) | + SPI_DMA_ABORT_INT_MASK(p->hw_inst)), + par->dma_offset_bar + SPI_DMA_INTR_WR_CLR); + spin_unlock_irqrestore(&par->dma_wr_reg_lock, flags); + spin_lock_irqsave(&par->dma_rd_reg_lock, flags); + writel((SPI_DMA_DONE_INT_MASK(p->hw_inst) | + SPI_DMA_ABORT_INT_MASK(p->hw_inst)), + par->dma_offset_bar + SPI_DMA_INTR_RD_CLR); + spin_unlock_irqrestore(&par->dma_rd_reg_lock, flags); + + p->spi_xfer_in_progress = false; + synchronize_irq(p->irq[1]); + synchronize_irq(p->irq[2]); + + /* + * Turn the engines back on only once both are confirmed + * to have stopped: re-enabling an engine that failed to + * stop would cancel the pending stop request and let it + * run into buffers the SPI core is about to unmap or + * free. An engine that failed to stop is left disabled, + * as the abort paths already do. + */ + if (engines_stopped) { + writel(SPI_DMA_ENGINE_EN, + par->dma_offset_bar + SPI_DMA_GLOBAL_WR_ENGINE_EN); + writel(SPI_DMA_ENGINE_EN, + par->dma_offset_bar + SPI_DMA_GLOBAL_RD_ENGINE_EN); + } goto error; } ret = 0; error: p->spi_xfer_in_progress = false; + p->xfer = NULL; + p->tx_sgl = NULL; + p->rx_sgl = NULL; return ret; } @@ -695,6 +757,9 @@ static irqreturn_t pci1xxxx_spi_isr_dma_rd(int irq, void *dev) unsigned long flags; u32 regval; + if (!p->spi_xfer_in_progress) + return IRQ_NONE; + /* Clear the DMA RD INT and start spi xfer*/ regval = readl(p->parent->dma_offset_bar + SPI_DMA_INTR_RD_STS); if (regval) { @@ -723,6 +788,9 @@ static irqreturn_t pci1xxxx_spi_isr_dma_wr(int irq, void *dev) unsigned long flags; u32 regval; + if (!p->spi_xfer_in_progress) + return IRQ_NONE; + /* Clear the DMA WR INT */ regval = readl(p->parent->dma_offset_bar + SPI_DMA_INTR_WR_STS); if (regval) { @@ -755,6 +823,9 @@ static irqreturn_t pci1xxxx_spi_isr_dma(int irq, void *dev) irqreturn_t spi_int_fired = IRQ_NONE; u32 regval; + if (!p->spi_xfer_in_progress) + return IRQ_NONE; + /* Clear the SPI GO_BIT Interrupt */ regval = readl(p->parent->reg_base + SPI_MST_EVENT_REG_OFFSET(p->hw_inst)); if (regval & SPI_INTR) {
diff --git a/drivers/spi/spi-pic32.c b/drivers/spi/spi-pic32.c index 9721282..8363bc8 100644 --- a/drivers/spi/spi-pic32.c +++ b/drivers/spi/spi-pic32.c
@@ -53,7 +53,7 @@ struct pic32_spi_regs { #define TX_FIFO_ALL_EMPTY 0 /* completely empty */ #define TX_FIFO_EMPTY 1 /* empty */ #define TX_FIFO_HALF_EMPTY 2 /* empty by half or more */ -#define TX_FIFO_NOT_FULL 3 /* atleast one empty */ +#define TX_FIFO_NOT_FULL 3 /* at least one empty */ #define CTRL_MSTEN BIT(5) /* enable master mode */ #define CTRL_CKP BIT(6) /* active low */
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 4877ab9..3ff3048 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c
@@ -684,9 +684,9 @@ static void readwriter(struct pl022 *pl022) static void unmap_free_dma_scatter(struct pl022 *pl022) { /* Unmap and free the SG tables */ - dma_unmap_sg(pl022->dma_tx_channel->device->dev, pl022->sgt_tx.sgl, + dma_unmap_sg(dmaengine_get_dma_device(pl022->dma_tx_channel), pl022->sgt_tx.sgl, pl022->sgt_tx.nents, DMA_TO_DEVICE); - dma_unmap_sg(pl022->dma_rx_channel->device->dev, pl022->sgt_rx.sgl, + dma_unmap_sg(dmaengine_get_dma_device(pl022->dma_rx_channel), pl022->sgt_rx.sgl, pl022->sgt_rx.nents, DMA_FROM_DEVICE); sg_free_table(&pl022->sgt_rx); sg_free_table(&pl022->sgt_tx); @@ -811,6 +811,7 @@ static int configure_dma(struct pl022 *pl022) struct dma_chan *txchan = pl022->dma_tx_channel; struct dma_async_tx_descriptor *rxdesc; struct dma_async_tx_descriptor *txdesc; + struct device *rx_dev, *tx_dev; /* Check that the channels are available */ if (!rxchan || !txchan) @@ -924,14 +925,16 @@ static int configure_dma(struct pl022 *pl022) setup_dma_scatter(pl022, pl022->tx, pl022->cur_transfer->len, &pl022->sgt_tx); + rx_dev = dmaengine_get_dma_device(rxchan); /* Map DMA buffers */ - rx_sglen = dma_map_sg(rxchan->device->dev, pl022->sgt_rx.sgl, - pl022->sgt_rx.nents, DMA_FROM_DEVICE); + rx_sglen = dma_map_sg(rx_dev, pl022->sgt_rx.sgl, + pl022->sgt_rx.nents, DMA_FROM_DEVICE); if (!rx_sglen) goto err_rx_sgmap; - tx_sglen = dma_map_sg(txchan->device->dev, pl022->sgt_tx.sgl, - pl022->sgt_tx.nents, DMA_TO_DEVICE); + tx_dev = dmaengine_get_dma_device(txchan); + tx_sglen = dma_map_sg(tx_dev, pl022->sgt_tx.sgl, + pl022->sgt_tx.nents, DMA_TO_DEVICE); if (!tx_sglen) goto err_tx_sgmap; @@ -969,10 +972,10 @@ static int configure_dma(struct pl022 *pl022) dmaengine_terminate_all(txchan); err_rxdesc: dmaengine_terminate_all(rxchan); - dma_unmap_sg(txchan->device->dev, pl022->sgt_tx.sgl, + dma_unmap_sg(tx_dev, pl022->sgt_tx.sgl, pl022->sgt_tx.nents, DMA_TO_DEVICE); err_tx_sgmap: - dma_unmap_sg(rxchan->device->dev, pl022->sgt_rx.sgl, + dma_unmap_sg(rx_dev, pl022->sgt_rx.sgl, pl022->sgt_rx.nents, DMA_FROM_DEVICE); err_rx_sgmap: sg_free_table(&pl022->sgt_tx);
diff --git a/drivers/spi/spi-qpic-snand.c b/drivers/spi/spi-qpic-snand.c index 05efe63..c90c200 100644 --- a/drivers/spi/spi-qpic-snand.c +++ b/drivers/spi/spi-qpic-snand.c
@@ -63,7 +63,6 @@ #define ACC_FEATURE 0xe #define BAD_BLOCK_MARKER_SIZE 0x2 #define OOB_BUF_SIZE 128 -#define ecceng_to_qspi(eng) container_of(eng, struct qpic_spi_nand, ecc_eng) struct snandc_read_status { __le32 snandc_flash; @@ -98,7 +97,6 @@ struct qpic_ecc { u32 cfg1; u32 cfg0_raw; u32 cfg1_raw; - u32 ecc_buf_cfg; u32 ecc_bch_cfg; bool bch_enabled; }; @@ -117,6 +115,7 @@ struct qpic_spi_nand { __le32 addr2; __le32 cmd; u32 num_cw; + bool bbm_read; bool oob_rw; bool page_rw; bool raw_rw; @@ -168,8 +167,9 @@ static void qcom_spi_set_read_loc_last(struct qcom_nand_controller *snandc, static struct qcom_nand_controller *nand_to_qcom_snand(struct nand_device *nand) { struct nand_ecc_engine *eng = nand->ecc.engine; - struct qpic_spi_nand *qspi = ecceng_to_qspi(eng); + struct qpic_spi_nand *qspi; + qspi = container_of(eng, struct qpic_spi_nand, ecc_eng); return qspi->snandc; } @@ -343,6 +343,15 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand) ecc_cfg->cw_size = ecc_cfg->cw_data + ecc_cfg->bytes; bad_block_byte = mtd->writesize - ecc_cfg->cw_size * (cwperpage - 1) + 1; + if ((ecc_cfg->cw_size * cwperpage) > (mtd->writesize + mtd->oobsize)) { + dev_err(snandc->dev, + "Current ECC settings require %d bytes, but the flash only has %d+%d bytes.\n", + (ecc_cfg->cw_size * cwperpage), mtd->writesize, + mtd->oobsize); + ret = -EINVAL; + goto err_free_ecc_cfg; + } + mtd_set_ooblayout(mtd, &qcom_spi_ooblayout); /* @@ -398,8 +407,6 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand) FIELD_PREP(ECC_MODE_MASK, ecc_cfg->ecc_mode) | FIELD_PREP(ECC_PARITY_SIZE_BYTES_BCH_MASK, ecc_cfg->ecc_bytes_hw); - ecc_cfg->ecc_buf_cfg = FIELD_PREP(NUM_STEPS_MASK, 0x203); - conf->step_size = ecc_cfg->step_size; conf->strength = ecc_cfg->strength; @@ -411,6 +418,8 @@ static int qcom_spi_ecc_init_ctx_pipelined(struct nand_device *nand) dev_dbg(snandc->dev, "ECC strength: %u bits per %u bytes\n", ecc_cfg->strength, ecc_cfg->step_size); + snandc->qspi->ecc = ecc_cfg; + return 0; err_free_ecc_cfg: @@ -427,6 +436,7 @@ static void qcom_spi_ecc_cleanup_ctx_pipelined(struct nand_device *nand) kfree(snandc->qspi->oob_buf); snandc->qspi->oob_buf = NULL; + snandc->qspi->ecc = NULL; kfree(ecc_cfg); } @@ -434,9 +444,7 @@ static int qcom_spi_ecc_prepare_io_req_pipelined(struct nand_device *nand, struct nand_page_io_req *req) { struct qcom_nand_controller *snandc = nand_to_qcom_snand(nand); - struct qpic_ecc *ecc_cfg = nand_to_ecc_ctx(nand); - snandc->qspi->ecc = ecc_cfg; snandc->qspi->raw_rw = false; snandc->qspi->oob_rw = false; snandc->qspi->page_rw = false; @@ -450,6 +458,16 @@ static int qcom_spi_ecc_prepare_io_req_pipelined(struct nand_device *nand, if (req->mode == MTD_OPS_RAW) snandc->qspi->raw_rw = true; + /* + * Try to detect when the SPI NAND framework reads the first + * two bytes of the OOB area searching for bad block marker + * bytes. + */ + snandc->qspi->bbm_read = req->mode == MTD_OPS_RAW && + req->type == NAND_PAGE_READ && + req->dataoffs == 0 && req->datalen == 0 && + req->ooboffs == 0 && req->ooblen == 2; + return 0; } @@ -500,18 +518,28 @@ static void qcom_spi_set_read_loc(struct qcom_nand_controller *snandc, int cw, i read_size, is_last_read_loc); } +static void qcom_spi_config_page_read(struct qcom_nand_controller *snandc) +{ + qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0); + qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0); + qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_clr, + NAND_ERASED_CW_DETECT_CFG, 1, 0); + qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_set, + NAND_ERASED_CW_DETECT_CFG, 1, + NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL); +} + static void qcom_spi_config_cw_read(struct qcom_nand_controller *snandc, bool use_ecc, int cw) { - __le32 *reg = &snandc->regs->read_location0; - int num_cw = snandc->qspi->num_cw; - - qcom_write_reg_dma(snandc, reg, NAND_READ_LOCATION_0, 4, NAND_BAM_NEXT_SGL); - if (cw == (num_cw - 1)) { - reg = &snandc->regs->read_location_last0; - qcom_write_reg_dma(snandc, reg, NAND_READ_LOCATION_LAST_CW_0, 4, + if (cw == (snandc->qspi->num_cw - 1)) + qcom_write_reg_dma(snandc, &snandc->regs->read_location_last0, + NAND_READ_LOCATION_LAST_CW_0, 4, NAND_BAM_NEXT_SGL); - } + else + qcom_write_reg_dma(snandc, &snandc->regs->read_location0, + NAND_READ_LOCATION_0, 4, + NAND_BAM_NEXT_SGL); qcom_write_reg_dma(snandc, &snandc->regs->cmd, NAND_FLASH_CMD, 1, NAND_BAM_NEXT_SGL); qcom_write_reg_dma(snandc, &snandc->regs->exec, NAND_EXEC_CMD, 1, NAND_BAM_NEXT_SGL); @@ -563,13 +591,7 @@ static void qcom_spi_config_single_cw_page_read(struct qcom_nand_controller *sna __le32 *reg = &snandc->regs->read_location0; int num_cw = snandc->qspi->num_cw; - qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0); - qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0); - qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_clr, - NAND_ERASED_CW_DETECT_CFG, 1, 0); - qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_set, - NAND_ERASED_CW_DETECT_CFG, 1, - NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL); + qcom_spi_config_page_read(snandc); if (cw == (num_cw - 1)) { reg = &snandc->regs->read_location_last0; @@ -655,7 +677,8 @@ static int qcom_spi_read_last_cw(struct qcom_nand_controller *snandc, * This can be removed once single-byte bad block marker support * gets implemented in the SPINAND code. */ - snandc->data_buffer[bbpos + 1] = snandc->data_buffer[bbpos]; + if (snandc->qspi->bbm_read) + snandc->data_buffer[bbpos + 1] = snandc->data_buffer[bbpos]; memcpy(op->data.buf.in, snandc->data_buffer + bbpos, op->data.nbytes); @@ -762,14 +785,7 @@ static int qcom_spi_read_cw_raw(struct qcom_nand_controller *snandc, u8 *data_bu snandc->regs->exec = cpu_to_le32(1); qcom_spi_set_read_loc(snandc, raw_cw, 0, 0, ecc_cfg->cw_size, 1); - - qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0); - qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0); - qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_clr, - NAND_ERASED_CW_DETECT_CFG, 1, 0); - qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_set, - NAND_ERASED_CW_DETECT_CFG, 1, - NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL); + qcom_spi_config_page_read(snandc); data_size1 = mtd->writesize - ecc_cfg->cw_size * (num_cw - 1); oob_size1 = ecc_cfg->bbm_size; @@ -874,14 +890,7 @@ static int qcom_spi_read_page_ecc(struct qcom_nand_controller *snandc, snandc->regs->exec = cpu_to_le32(1); qcom_clear_bam_transaction(snandc); - - qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0); - qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0); - qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_clr, - NAND_ERASED_CW_DETECT_CFG, 1, 0); - qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_set, - NAND_ERASED_CW_DETECT_CFG, 1, - NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL); + qcom_spi_config_page_read(snandc); for (i = 0; i < num_cw; i++) { int data_size, oob_size; @@ -962,13 +971,7 @@ static int qcom_spi_read_page_oob(struct qcom_nand_controller *snandc, snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg); snandc->regs->exec = cpu_to_le32(1); - qcom_write_reg_dma(snandc, &snandc->regs->addr0, NAND_ADDR0, 2, 0); - qcom_write_reg_dma(snandc, &snandc->regs->cfg0, NAND_DEV0_CFG0, 3, 0); - qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_clr, - NAND_ERASED_CW_DETECT_CFG, 1, 0); - qcom_write_reg_dma(snandc, &snandc->regs->erased_cw_detect_cfg_set, - NAND_ERASED_CW_DETECT_CFG, 1, - NAND_ERASED_CW_SET | NAND_BAM_NEXT_SGL); + qcom_spi_config_page_read(snandc); for (i = 0; i < num_cw; i++) { int data_size, oob_size; @@ -1204,13 +1207,12 @@ static int qcom_spi_program_ecc(struct qcom_nand_controller *snandc, u8 *data_buf = NULL, *oob_buf = NULL; int i, ret; int num_cw = snandc->qspi->num_cw; - u32 cfg0, cfg1, ecc_bch_cfg, ecc_buf_cfg; + u32 cfg0, cfg1, ecc_bch_cfg; cfg0 = (ecc_cfg->cfg0 & ~CW_PER_PAGE_MASK) | FIELD_PREP(CW_PER_PAGE_MASK, num_cw - 1); cfg1 = ecc_cfg->cfg1; ecc_bch_cfg = ecc_cfg->ecc_bch_cfg; - ecc_buf_cfg = ecc_cfg->ecc_buf_cfg; if (snandc->qspi->data_buf) data_buf = snandc->qspi->data_buf; @@ -1228,7 +1230,6 @@ static int qcom_spi_program_ecc(struct qcom_nand_controller *snandc, snandc->regs->cfg0 = cpu_to_le32(cfg0); snandc->regs->cfg1 = cpu_to_le32(cfg1); snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg); - snandc->regs->ecc_buf_cfg = cpu_to_le32(ecc_buf_cfg); snandc->regs->exec = cpu_to_le32(1); qcom_spi_config_page_write(snandc); @@ -1281,13 +1282,12 @@ static int qcom_spi_program_oob(struct qcom_nand_controller *snandc, u8 *oob_buf = NULL; int ret, col, data_size, oob_size; int num_cw = snandc->qspi->num_cw; - u32 cfg0, cfg1, ecc_bch_cfg, ecc_buf_cfg; + u32 cfg0, cfg1, ecc_bch_cfg; cfg0 = (ecc_cfg->cfg0 & ~CW_PER_PAGE_MASK) | FIELD_PREP(CW_PER_PAGE_MASK, 0); cfg1 = ecc_cfg->cfg1; ecc_bch_cfg = ecc_cfg->ecc_bch_cfg; - ecc_buf_cfg = ecc_cfg->ecc_buf_cfg; col = ecc_cfg->cw_size * (num_cw - 1); @@ -1303,7 +1303,6 @@ static int qcom_spi_program_oob(struct qcom_nand_controller *snandc, snandc->regs->cfg0 = cpu_to_le32(cfg0); snandc->regs->cfg1 = cpu_to_le32(cfg1); snandc->regs->ecc_bch_cfg = cpu_to_le32(ecc_bch_cfg); - snandc->regs->ecc_buf_cfg = cpu_to_le32(ecc_buf_cfg); snandc->regs->exec = cpu_to_le32(1); /* calculate the data and oob size for the last codeword/step */ @@ -1481,7 +1480,7 @@ static int qcom_spi_io_op(struct qcom_nand_controller *snandc, const struct spi_ if (copy_ftr) { qcom_nandc_dev_to_mem(snandc, true); - val = le32_to_cpu(*(__le32 *)snandc->reg_read_buf); + val = le32_to_cpu(*snandc->reg_read_buf); val >>= 8; memcpy(op->data.buf.in, &val, snandc->buf_count); @@ -1579,15 +1578,9 @@ static int qcom_spi_probe(struct platform_device *pdev) struct spi_controller *ctlr; struct qcom_nand_controller *snandc; struct qpic_spi_nand *qspi; - struct qpic_ecc *ecc; struct resource *res; - const void *dev_data; int ret; - ecc = devm_kzalloc(dev, sizeof(*ecc), GFP_KERNEL); - if (!ecc) - return -ENOMEM; - qspi = devm_kzalloc(dev, sizeof(*qspi), GFP_KERNEL); if (!qspi) return -ENOMEM; @@ -1607,16 +1600,13 @@ static int qcom_spi_probe(struct platform_device *pdev) snandc->dev = dev; snandc->qspi = qspi; snandc->qspi->ctlr = ctlr; - snandc->qspi->ecc = ecc; - dev_data = of_device_get_match_data(dev); - if (!dev_data) { + snandc->props = of_device_get_match_data(dev); + if (!snandc->props) { dev_err(&pdev->dev, "failed to get device data\n"); return -ENODEV; } - snandc->props = dev_data; - snandc->core_clk = devm_clk_get_enabled(dev, "core"); if (IS_ERR(snandc->core_clk)) return PTR_ERR(snandc->core_clk); @@ -1699,6 +1689,7 @@ static void qcom_spi_remove(struct platform_device *pdev) static const struct qcom_nandc_props ipq9574_snandc_props = { .dev_cmd_reg_start = 0x7000, .bam_offset = 0x30000, + .qpic_version2 = true, .supports_bam = true, };
diff --git a/drivers/spi/spi-realtek-rtl.c b/drivers/spi/spi-realtek-rtl.c index e1c40ff..7b250b4 100644 --- a/drivers/spi/spi-realtek-rtl.c +++ b/drivers/spi/spi-realtek-rtl.c
@@ -18,7 +18,6 @@ struct rtspi { #define RTL_SPI_SFCSR_CSB0 BIT(31) #define RTL_SPI_SFCSR_CSB1 BIT(30) #define RTL_SPI_SFCSR_RDY BIT(27) -#define RTL_SPI_SFCSR_CS BIT(24) #define RTL_SPI_SFCSR_LEN_MASK ~(0x03 << 28) #define RTL_SPI_SFCSR_LEN1 (0x00 << 28) #define RTL_SPI_SFCSR_LEN4 (0x03 << 28) @@ -29,17 +28,31 @@ struct rtspi { #define REG(x) (rtspi->base + x) -static void rt_set_cs(struct spi_device *spi, bool active) +static void rt_set_cs(struct spi_device *spi, bool level) { struct rtspi *rtspi = spi_controller_get_devdata(spi->controller); - u32 value; + unsigned int cs = spi_get_chipselect(spi, 0); + u32 cs_mask, value; - /* CS0 bit is active low */ + switch (cs) { + case 0: + cs_mask = RTL_SPI_SFCSR_CSB0; + break; + case 1: + cs_mask = RTL_SPI_SFCSR_CSB1; + break; + default: + return; + } + value = __raw_readl(REG(RTL_SPI_SFCSR)); - if (active) - value |= RTL_SPI_SFCSR_CSB0; + + /* CSBx is active low */ + if (level) + value |= cs_mask; else - value &= ~RTL_SPI_SFCSR_CSB0; + value &= ~cs_mask; + __raw_writel(value, REG(RTL_SPI_SFCSR)); } @@ -138,11 +151,9 @@ static void init_hw(struct rtspi *rtspi) value |= RTL_SPI_SFCR_RBO | RTL_SPI_SFCR_WBO; __raw_writel(value, REG(RTL_SPI_SFCR)); - value = __raw_readl(REG(RTL_SPI_SFCSR)); - /* Permanently disable CS1, since it's never used */ - value |= RTL_SPI_SFCSR_CSB1; - /* Select CS0 for use */ - value &= RTL_SPI_SFCSR_CS; + /* CHIP_SEL is only used in MMIO mode; CSB0/CSB1 are active low. */ + value = 0; + value |= RTL_SPI_SFCSR_CSB0 | RTL_SPI_SFCSR_CSB1; __raw_writel(value, REG(RTL_SPI_SFCSR)); } @@ -171,6 +182,7 @@ static int realtek_rtl_spi_probe(struct platform_device *pdev) ctrl->flags = SPI_CONTROLLER_HALF_DUPLEX; ctrl->set_cs = rt_set_cs; ctrl->transfer_one = transfer_one; + ctrl->num_chipselect = 2; err = devm_spi_register_controller(&pdev->dev, ctrl); if (err) {
diff --git a/drivers/spi/spi-rockchip-sfc.c b/drivers/spi/spi-rockchip-sfc.c index 662a994..a85a260 100644 --- a/drivers/spi/spi-rockchip-sfc.c +++ b/drivers/spi/spi-rockchip-sfc.c
@@ -719,10 +719,12 @@ static int rockchip_sfc_probe(struct platform_device *pdev) return 0; err_register: - dma_unmap_single(dev, sfc->dma_buffer, sfc->max_iosize, - DMA_BIDIRECTIONAL); + if (sfc->use_dma) + dma_unmap_single(dev, sfc->dma_buffer, sfc->max_iosize, + DMA_BIDIRECTIONAL); err_dma_map: - free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize)); + if (sfc->use_dma) + free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize)); err_dma: pm_runtime_get_sync(dev); pm_runtime_put_noidle(dev); @@ -743,9 +745,16 @@ static void rockchip_sfc_remove(struct platform_device *pdev) struct spi_controller *host = sfc->host; spi_unregister_controller(host); - dma_unmap_single(&pdev->dev, sfc->dma_buffer, sfc->max_iosize, - DMA_BIDIRECTIONAL); - free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize)); + pm_runtime_get_sync(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); + pm_runtime_disable(&pdev->dev); + pm_runtime_set_suspended(&pdev->dev); + pm_runtime_dont_use_autosuspend(&pdev->dev); + if (sfc->use_dma) { + dma_unmap_single(&pdev->dev, sfc->dma_buffer, sfc->max_iosize, + DMA_BIDIRECTIONAL); + free_pages((unsigned long)sfc->buffer, get_order(sfc->max_iosize)); + } clk_disable_unprepare(sfc->clk); clk_disable_unprepare(sfc->hclk);
diff --git a/drivers/spi/spi-rspi.c b/drivers/spi/spi-rspi.c index 38df676..c61edd1 100644 --- a/drivers/spi/spi-rspi.c +++ b/drivers/spi/spi-rspi.c
@@ -22,7 +22,6 @@ #include <linux/of.h> #include <linux/pm_runtime.h> #include <linux/reset.h> -#include <linux/sh_dma.h> #include <linux/spi/spi.h> #include <linux/spinlock.h> @@ -1091,24 +1090,15 @@ static irqreturn_t rspi_irq_tx(int irq, void *_sr) static struct dma_chan *rspi_request_dma_chan(struct device *dev, enum dma_transfer_direction dir, - unsigned int id, dma_addr_t port_addr) { - dma_cap_mask_t mask; struct dma_chan *chan; struct dma_slave_config cfg; int ret; - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - chan = dma_request_slave_channel_compat(mask, shdma_chan_filter, - (void *)(unsigned long)id, dev, - dir == DMA_MEM_TO_DEV ? "tx" : "rx"); - if (!chan) { - dev_warn(dev, "dma_request_slave_channel_compat failed\n"); - return NULL; - } + chan = dma_request_chan(dev, dir == DMA_MEM_TO_DEV ? "tx" : "rx"); + if (IS_ERR(chan)) + return chan; memset(&cfg, 0, sizeof(cfg)); cfg.dst_addr = port_addr + RSPI_SPDR; @@ -1121,7 +1111,7 @@ static struct dma_chan *rspi_request_dma_chan(struct device *dev, if (ret) { dev_warn(dev, "dmaengine_slave_config failed %d\n", ret); dma_release_channel(chan); - return NULL; + return ERR_PTR(ret); } return chan; @@ -1130,29 +1120,23 @@ static struct dma_chan *rspi_request_dma_chan(struct device *dev, static int rspi_request_dma(struct device *dev, struct spi_controller *ctlr, const struct resource *res) { - unsigned int dma_tx_id, dma_rx_id; + struct dma_chan *chan; - if (dev->of_node) { - /* In the OF case we will get the slave IDs from the DT */ - dma_tx_id = 0; - dma_rx_id = 0; - } else { - /* The driver assumes no error. */ + if (!dev->of_node) return 0; - } - ctlr->dma_tx = rspi_request_dma_chan(dev, DMA_MEM_TO_DEV, dma_tx_id, - res->start); - if (!ctlr->dma_tx) - return -ENODEV; + chan = rspi_request_dma_chan(dev, DMA_MEM_TO_DEV, res->start); + if (IS_ERR(chan)) + return PTR_ERR(chan); + ctlr->dma_tx = chan; - ctlr->dma_rx = rspi_request_dma_chan(dev, DMA_DEV_TO_MEM, dma_rx_id, - res->start); - if (!ctlr->dma_rx) { + chan = rspi_request_dma_chan(dev, DMA_DEV_TO_MEM, res->start); + if (IS_ERR(chan)) { dma_release_channel(ctlr->dma_tx); ctlr->dma_tx = NULL; - return -ENODEV; + return PTR_ERR(chan); } + ctlr->dma_rx = chan; ctlr->can_dma = rspi_can_dma; dev_info(dev, "DMA available"); @@ -1355,6 +1339,11 @@ static int rspi_probe(struct platform_device *pdev) } ret = rspi_request_dma(&pdev->dev, ctlr, res); + if (ret == -EPROBE_DEFER) { + dev_err_probe(&pdev->dev, ret, + "failed to request DMA channels\n"); + goto error2; + } if (ret < 0) dev_warn(&pdev->dev, "DMA not available, using PIO\n");
diff --git a/drivers/spi/spi-rtk-nor.c b/drivers/spi/spi-rtk-nor.c new file mode 100644 index 0000000..75856c3 --- /dev/null +++ b/drivers/spi/spi-rtk-nor.c
@@ -0,0 +1,624 @@ +// SPDX-License-Identifier: GPL-2.0 +// +// Realtek SPI Nor Flash Controller Driver (SFC) +// +// Copyright (c) 2024-2026 Realtek Semiconductor Corp. + +#include <linux/bits.h> +#include <linux/clk.h> +#include <linux/delay.h> +#include <linux/dma-mapping.h> +#include <linux/errno.h> +#include <linux/iopoll.h> +#include <linux/minmax.h> +#include <linux/module.h> +#include <linux/platform_device.h> +#include <linux/pm_runtime.h> +#include <linux/reset.h> +#include <linux/spi/spi.h> +#include <linux/spi/spi-mem.h> +#include <linux/types.h> + +#define SFC_OPCODE 0x00 +#define DUAL_MODE_EN BIT(9) + +#define SFC_CTL 0x04 +#define RW_DATAEN BIT(4) +#define ADDR_EN BIT(3) + +#define SFC_SCK 0x08 +#define FDIV_MASK GENMASK(7, 0) + +#define SFC_CE 0x0c +#define DESLT_TIME 0x1a +#define DESLT_TIME_SHIFT 16 +#define PH_CNT 0x13 +#define PH_CNT_SHIFT 8 +#define PL_CNT 0x7 + +#define WT_PROM_DONE BIT(8) + +#define SFC_POS_LATCH 0x14 +#define FALLING_EDGE_EN 0x0 + +#define SFC_WAIT_WR 0x18 +#define SFC_EN_WR 0x1c +#define WT_PROM_EN BIT(8) + +#define SFC_ADR_FOUR_BYTE_EN 0x28 + +#define MD_FDMA_DDR_SADDR 0x0c +#define MD_FDMA_FL_SADDR 0x10 + +#define MD_FDMA_CTRL2 0x14 +#define MAX_XFER_DMA_LEN (BIT(26) | BIT(27)) +#define MAX_XFER_256 BIT(26) +#define DMA_TO_FLASH BIT(25) + +#define MD_FDMA_CTRL1 0x18 +#define DMA_W_EN_START BIT(3) +#define DMA_END BIT(2) +#define DMA_W_EN BIT(1) +#define DMA_START BIT(0) + +#define MD_FDMA_DDR_SADDR1 0x20 + +#define SFC_DMA_TIMEOUT 20000 +#define SFC_DMA_MAX_LEN 0x100 + +#define SFC_CTL_DMYCNT_MASK GENMASK(31, 24) +#define SFC_CTL_DMYCNT_SHIFT 24 + +#define DMA_HIGH_BITS_MASK 0x7 + +#define RTK_SPI_OP_RDSR 0x05 +#define RTK_SPI_OP_WREN 0x06 +#define RTK_SPI_OP_EN4B 0xb7 +#define RTK_SPI_OP_EX4B 0xe9 + +#define SFC_AUTOSUSPEND_TIMEOUT 2000 + +struct rtk_spi_host { + struct device *dev; + struct clk *clk; + struct reset_control *rstc; + void __iomem *regbase; + void __iomem *iobase; + void __iomem *mdbase; + void *buffer; + bool is_4byte; + dma_addr_t dma_buffer; + resource_size_t flash_phys_base; + size_t dirmap_size; +}; + +static u32 rtk_spi_calc_dummy_cycles(const struct spi_mem_op *op) +{ + if (!op->dummy.nbytes) + return 0; + + return (op->dummy.nbytes * 8) / op->dummy.buswidth; +} + +static void rtk_spi_read_mode(struct rtk_spi_host *host, const struct spi_mem_op *op) +{ + u32 opcode = op->cmd.opcode; + u32 dummy_cycles, val; + + if (op->data.buswidth == 2) + opcode |= DUAL_MODE_EN; + + writel(opcode, host->regbase + SFC_OPCODE); + + val = readl(host->regbase + SFC_CTL); + val |= RW_DATAEN | ADDR_EN; + + dummy_cycles = rtk_spi_calc_dummy_cycles(op); + + val &= ~SFC_CTL_DMYCNT_MASK; + val |= (dummy_cycles << SFC_CTL_DMYCNT_SHIFT) & SFC_CTL_DMYCNT_MASK; + writel(val, host->regbase + SFC_CTL); + + readl(host->iobase); +} + +static void rtk_spi_write_mode(struct rtk_spi_host *host, + const struct spi_mem_op *op) +{ + u32 opcode = op->cmd.opcode; + u32 val; + + writel(opcode, host->regbase + SFC_OPCODE); + + val = readl(host->regbase + SFC_CTL); + val |= RW_DATAEN | ADDR_EN; + writel(val, host->regbase + SFC_CTL); +} + +static void rtk_spi_enable_auto_write(struct rtk_spi_host *host) +{ + u32 val; + + val = WT_PROM_DONE | RTK_SPI_OP_RDSR; + writel(val, host->regbase + SFC_WAIT_WR); + + val = WT_PROM_EN | RTK_SPI_OP_WREN; + writel(val, host->regbase + SFC_EN_WR); +} + +static void rtk_spi_disable_auto_write(struct rtk_spi_host *host) +{ + writel(RTK_SPI_OP_RDSR, host->regbase + SFC_WAIT_WR); + writel(RTK_SPI_OP_WREN, host->regbase + SFC_EN_WR); +} + +static int rtk_spi_byte_transfer(struct rtk_spi_host *host, loff_t offset, + size_t len, unsigned char *buf, bool is_read) +{ + if (offset + len > host->dirmap_size) { + dev_err(host->dev, "PIO transfer out of bounds\n"); + return -EINVAL; + } + + if (is_read) + memcpy_fromio(buf, host->iobase + offset, len); + else + memcpy_toio(host->iobase + offset, buf, len); + + return 0; +} + +static void rtk_spi_init(struct rtk_spi_host *host) +{ + u32 val; + + val = readl(host->regbase + SFC_SCK); + val &= ~FDIV_MASK; + val |= (3 << 0) & FDIV_MASK; + writel(val, host->regbase + SFC_SCK); + + val = (DESLT_TIME << DESLT_TIME_SHIFT) | (PH_CNT << PH_CNT_SHIFT) | PL_CNT; + writel(val, host->regbase + SFC_CE); + + writel(FALLING_EDGE_EN, host->regbase + SFC_POS_LATCH); + writel(RTK_SPI_OP_RDSR, host->regbase + SFC_WAIT_WR); + writel(RTK_SPI_OP_WREN, host->regbase + SFC_EN_WR); + + writel(host->is_4byte ? 0x1 : 0x0, host->regbase + SFC_ADR_FOUR_BYTE_EN); +} + +static int rtk_spi_command_read(struct rtk_spi_host *host, const struct spi_mem_op *op) +{ + size_t len = op->data.nbytes; + loff_t offset = op->addr.val; + u8 opcode = op->cmd.opcode; + u32 dummy_cycles, val; + + writel(opcode, host->regbase + SFC_OPCODE); + + val = readl(host->regbase + SFC_CTL); + val &= ~(SFC_CTL_DMYCNT_MASK | ADDR_EN); + val |= RW_DATAEN; + + if (op->addr.nbytes > 0) + val |= ADDR_EN; + + dummy_cycles = rtk_spi_calc_dummy_cycles(op); + val |= (dummy_cycles << SFC_CTL_DMYCNT_SHIFT) & SFC_CTL_DMYCNT_MASK; + writel(val, host->regbase + SFC_CTL); + + return rtk_spi_byte_transfer(host, offset, len, op->data.buf.in, true); +} + +static int rtk_spi_do_write_and_cmds(struct rtk_spi_host *host, const struct spi_mem_op *op) +{ + u8 opcode = op->cmd.opcode; + u32 ctl_val = 0; + + writel(opcode, host->regbase + SFC_OPCODE); + + if (op->data.nbytes > 0) + ctl_val |= RW_DATAEN; + + if (op->addr.nbytes > 0) + ctl_val |= ADDR_EN; + + writel(ctl_val, host->regbase + SFC_CTL); + + if (op->data.nbytes > 0) { + const u8 *buf = op->data.buf.out; + + if (op->addr.val + op->data.nbytes > host->dirmap_size) + return -EINVAL; + + writeb(*buf, host->iobase + op->addr.val); + } else { + if (op->addr.val >= host->dirmap_size) + return -EINVAL; + + readb(host->iobase + op->addr.val); + } + + return 0; +} + +static int rtk_spi_dma_transfer(struct rtk_spi_host *host, loff_t offset, + size_t len, bool is_read) +{ + u64 dma_buffer, timeout_us = SFC_DMA_TIMEOUT * 100; + u32 flash_phys_addr, val; + int ret; + + if (offset + len > host->dirmap_size) { + dev_err(host->dev, "DMA transfer out of bounds\n"); + return -EINVAL; + } + + writel(DMA_W_EN_START | DMA_W_EN, host->mdbase + MD_FDMA_CTRL1); + + dma_buffer = host->dma_buffer; + + /* Setup MD DDR address and flash address */ + writel(lower_32_bits(dma_buffer), host->mdbase + MD_FDMA_DDR_SADDR); + writel(upper_32_bits(dma_buffer) & DMA_HIGH_BITS_MASK, + host->mdbase + MD_FDMA_DDR_SADDR1); + + /* MD_FDMA_FL_SADDR is a 32-bit hardware register */ + flash_phys_addr = lower_32_bits(host->flash_phys_base + offset); + writel(flash_phys_addr, host->mdbase + MD_FDMA_FL_SADDR); + + if (is_read) + val = MAX_XFER_DMA_LEN | len; + else + val = DMA_TO_FLASH | MAX_XFER_256 | len; + + writel(val, host->mdbase + MD_FDMA_CTRL2); + + writel(DMA_W_EN | DMA_START, host->mdbase + MD_FDMA_CTRL1); + udelay(1); + + ret = readl_poll_timeout(host->mdbase + MD_FDMA_CTRL1, val, + !(val & DMA_START), 100, timeout_us); + if (ret) { + dev_err(host->dev, "DMA transfer timed out\n"); + val = readl(host->mdbase + MD_FDMA_CTRL1); + val |= DMA_END | DMA_W_EN_START; + writel(val, host->mdbase + MD_FDMA_CTRL1); + + if (readl_poll_timeout(host->mdbase + MD_FDMA_CTRL1, val, + !(val & DMA_END), 10, 1000)) { + dev_err(host->dev, "Failed to stop DMA gracefully\n"); + } + + return ret; + } + + return 0; +} + +static int rtk_spi_exec_op(struct spi_mem *mem, const struct spi_mem_op *op) +{ + struct rtk_spi_host *host = spi_controller_get_devdata(mem->spi->controller); + u32 opcode = op->cmd.opcode; + + /* + * Hardware Workaround: + * The controller's auto-mode engine requires SFC_ADR_FOUR_BYTE_EN to be + * explicitly updated when the flash enters or exits 4-byte mode via control + * commands. + */ + if ((op->addr.nbytes == 4 || opcode == RTK_SPI_OP_EN4B) && !host->is_4byte) { + host->is_4byte = true; + writel(0x1, host->regbase + SFC_ADR_FOUR_BYTE_EN); + } else if ((op->addr.nbytes == 3 || opcode == RTK_SPI_OP_EX4B) && host->is_4byte) { + host->is_4byte = false; + writel(0x0, host->regbase + SFC_ADR_FOUR_BYTE_EN); + } + + if (op->data.dir == SPI_MEM_DATA_IN) + return rtk_spi_command_read(host, op); + + return rtk_spi_do_write_and_cmds(host, op); +} + +static bool rtk_spi_supports_op(struct spi_mem *mem, + const struct spi_mem_op *op) +{ + if (op->cmd.buswidth != 1) + return false; + + if (op->cmd.dtr || op->addr.dtr || op->data.dtr) + return false; + + if (op->addr.nbytes != 0) { + if (op->addr.buswidth > 1) + return false; + if (op->addr.nbytes < 3 || op->addr.nbytes > 4) + return false; + } + + /* + * The data window is access-triggered: each CPU access to host->iobase + * generates one complete SPI transaction. Consecutive byte accesses + * therefore cannot be merged into a single transaction, so + * multi-byte stateless commands are not supported by this controller. + */ + if (!op->addr.nbytes && op->data.nbytes > 1) + return false; + + if (op->dummy.nbytes != 0) { + if (op->dummy.buswidth > 1 || op->dummy.nbytes > 7) + return false; + } + + if (op->data.nbytes != 0 && op->data.buswidth > 2) + return false; + + return spi_mem_default_supports_op(mem, op); +} + +static int rtk_spi_dirmap_create(struct spi_mem_dirmap_desc *desc) +{ + const struct spi_mem_op *op = desc->info.op_tmpl; + + if (op->data.dir == SPI_MEM_DATA_IN && op->addr.nbytes != 3 && op->addr.nbytes != 4) + return -EOPNOTSUPP; + + if (op->data.dir != SPI_MEM_DATA_IN && op->data.dir != SPI_MEM_DATA_OUT) + return -EOPNOTSUPP; + + return 0; +} + +static ssize_t rtk_spi_dirmap_read(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, void *buf) +{ + struct rtk_spi_host *host = spi_controller_get_devdata(desc->mem->spi->controller); + const struct spi_mem_op *op = desc->info.op_tmpl; + loff_t addr = desc->info.offset + offs; + size_t chunk_len; + int ret; + + /* + * Handle unaligned address bytes at the beginning of the read operation. + * The hardware requires 4-byte alignment for DMA transfers. + */ + if (addr & 0x3) { + rtk_spi_read_mode(host, op); + chunk_len = min_t(size_t, 4 - (addr & 0x3), len); + ret = rtk_spi_byte_transfer(host, addr, chunk_len, buf, true); + if (ret) + return ret; + + return chunk_len; + } + + rtk_spi_read_mode(host, op); + chunk_len = min_t(size_t, len, SFC_DMA_MAX_LEN); + ret = rtk_spi_dma_transfer(host, addr, chunk_len, true); + if (ret) { + dev_err(host->dev, "DMA read transfer failed: %d\n", ret); + return ret; + } + + memcpy(buf, host->buffer, chunk_len); + + return chunk_len; +} + +static ssize_t rtk_spi_dirmap_write(struct spi_mem_dirmap_desc *desc, + u64 offs, size_t len, const void *buf) +{ + struct rtk_spi_host *host = spi_controller_get_devdata(desc->mem->spi->controller); + const struct spi_mem_op *op = desc->info.op_tmpl; + loff_t addr = desc->info.offset + offs; + size_t chunk_len; + int ret = 0; + + rtk_spi_enable_auto_write(host); + rtk_spi_write_mode(host, op); + + /* + * Handle unaligned address bytes at the beginning of the write operation. + * The hardware requires 4-byte alignment for DMA transfers. + */ + if (addr & 0x3) { + chunk_len = min_t(size_t, 4 - (addr & 0x3), len); + ret = rtk_spi_byte_transfer(host, addr, chunk_len, (u8 *)buf, false); + + goto out; + } + + chunk_len = min_t(size_t, len, SFC_DMA_MAX_LEN); + + memcpy(host->buffer, buf, chunk_len); + + ret = rtk_spi_dma_transfer(host, addr, chunk_len, false); + if (ret) + dev_err(host->dev, "DMA write transfer failed: %d\n", ret); + +out: + rtk_spi_disable_auto_write(host); + + return ret < 0 ? ret : chunk_len; +} + +static const struct spi_controller_mem_ops rtk_spi_mem_ops = { + .supports_op = rtk_spi_supports_op, + .exec_op = rtk_spi_exec_op, + .dirmap_create = rtk_spi_dirmap_create, + .dirmap_read = rtk_spi_dirmap_read, + .dirmap_write = rtk_spi_dirmap_write, +}; + +static int rtk_spi_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct spi_controller *ctrl; + struct rtk_spi_host *host; + struct resource *res; + int ret; + + ctrl = devm_spi_alloc_host(dev, sizeof(*host)); + if (!ctrl) + return -ENOMEM; + + platform_set_drvdata(pdev, ctrl); + host = spi_controller_get_devdata(ctrl); + host->dev = dev; + + host->clk = devm_clk_get(dev, NULL); + if (IS_ERR(host->clk)) + return PTR_ERR(host->clk); + + host->rstc = devm_reset_control_get_optional_exclusive(dev, NULL); + if (IS_ERR(host->rstc)) + return PTR_ERR(host->rstc); + + ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(35)); + if (ret) { + dev_err(dev, "Failed to set dma mask\n"); + return ret; + } + + host->buffer = dmam_alloc_coherent(dev, SFC_DMA_MAX_LEN, + &host->dma_buffer, GFP_KERNEL); + if (!host->buffer) + return -ENOMEM; + + host->regbase = devm_platform_ioremap_resource_byname(pdev, "ctrl"); + if (IS_ERR(host->regbase)) + return PTR_ERR(host->regbase); + + host->mdbase = devm_platform_ioremap_resource_byname(pdev, "dma"); + if (IS_ERR(host->mdbase)) + return PTR_ERR(host->mdbase); + + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirmap"); + host->iobase = devm_ioremap_resource(dev, res); + if (IS_ERR(host->iobase)) + return PTR_ERR(host->iobase); + + host->dirmap_size = resource_size(res); + host->flash_phys_base = res->start; + host->is_4byte = false; + + ret = clk_prepare_enable(host->clk); + if (ret) + return ret; + + ret = reset_control_assert(host->rstc); + usleep_range(10, 20); + ret = reset_control_deassert(host->rstc); + + rtk_spi_init(host); + + pm_runtime_set_autosuspend_delay(dev, SFC_AUTOSUSPEND_TIMEOUT); + pm_runtime_use_autosuspend(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + pm_runtime_get_noresume(dev); + + ctrl->mode_bits = SPI_RX_DUAL | SPI_TX_DUAL; + ctrl->bus_num = -1; + ctrl->mem_ops = &rtk_spi_mem_ops; + ctrl->num_chipselect = 1; + ctrl->auto_runtime_pm = true; + + ret = spi_register_controller(ctrl); + if (ret < 0) { + dev_err(dev, "failed to register controller\n"); + goto err_pm_disable; + } + + pm_runtime_put_autosuspend(dev); + + return 0; + +err_pm_disable: + pm_runtime_put_noidle(dev); + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + pm_runtime_dont_use_autosuspend(dev); + reset_control_assert(host->rstc); + clk_disable_unprepare(host->clk); + + return ret; +} + +static void rtk_spi_remove(struct platform_device *pdev) +{ + struct spi_controller *ctrl = platform_get_drvdata(pdev); + struct rtk_spi_host *host = spi_controller_get_devdata(ctrl); + struct device *dev = &pdev->dev; + + spi_unregister_controller(ctrl); + + if (pm_runtime_resume_and_get(dev) < 0) + dev_warn(dev, "Failed to resume device during remove\n"); + + pm_runtime_put_noidle(dev); + pm_runtime_disable(dev); + pm_runtime_set_suspended(dev); + pm_runtime_dont_use_autosuspend(dev); + reset_control_assert(host->rstc); + clk_disable_unprepare(host->clk); +} + +static const struct of_device_id rtk_spi_dt_ids[] = { + { .compatible = "realtek,rtd1625-nor" }, + { /* sentinel */ } +}; + +MODULE_DEVICE_TABLE(of, rtk_spi_dt_ids); + +static int rtk_spi_runtime_suspend(struct device *dev) +{ + struct spi_controller *ctlr = dev_get_drvdata(dev); + struct rtk_spi_host *host = spi_controller_get_devdata(ctlr); + + reset_control_assert(host->rstc); + + clk_disable_unprepare(host->clk); + + return 0; +} + +static int rtk_spi_runtime_resume(struct device *dev) +{ + struct spi_controller *ctlr = dev_get_drvdata(dev); + struct rtk_spi_host *host = spi_controller_get_devdata(ctlr); + int ret; + + ret = clk_prepare_enable(host->clk); + if (ret < 0) { + dev_err(dev, "clk_prepare_enable failed: %d\n", ret); + return ret; + } + + reset_control_assert(host->rstc); + usleep_range(10, 20); + reset_control_deassert(host->rstc); + + rtk_spi_init(host); + + return 0; +} + +static DEFINE_RUNTIME_DEV_PM_OPS(rtk_spi_pm_ops, rtk_spi_runtime_suspend, + rtk_spi_runtime_resume, NULL); + +static struct platform_driver rtk_spi_driver = { + .driver = { + .name = "rtk-spi-nor", + .of_match_table = rtk_spi_dt_ids, + .pm = pm_ptr(&rtk_spi_pm_ops), + }, + .probe = rtk_spi_probe, + .remove = rtk_spi_remove, +}; +module_platform_driver(rtk_spi_driver); + +MODULE_DESCRIPTION("Realtek SPI Nor Controller Driver"); +MODULE_AUTHOR("Jyan Chou <jyanchou@realtek.com>"); +MODULE_LICENSE("GPL");
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 8d4120c..58e306c 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c
@@ -661,7 +661,7 @@ static int s3c64xx_wait_for_pio(struct s3c64xx_spi_driver_data *sdd, * loops = length / max fifo size (calculated by using the * fifo mask). * For any size less than the fifo size the below code is - * executed atleast once. + * executed at least once. */ loops = xfer->len / sdd->fifo_depth; buf = xfer->rx_buf; @@ -1331,7 +1331,8 @@ static int s3c64xx_spi_probe(struct platform_device *pdev) return dev_err_probe(&pdev->dev, PTR_ERR(sdd->clk), "Unable to acquire clock 'spi'\n"); - sprintf(clk_name, "spi_busclk%d", sci->src_clk_nr); + snprintf(clk_name, sizeof(clk_name), "spi_busclk%d", + sci->src_clk_nr); sdd->src_clk = devm_clk_get_enabled(&pdev->dev, clk_name); if (IS_ERR(sdd->src_clk)) return dev_err_probe(&pdev->dev, PTR_ERR(sdd->src_clk),
diff --git a/drivers/spi/spi-sh-hspi.c b/drivers/spi/spi-sh-hspi.c index f840467..56df076 100644 --- a/drivers/spi/spi-sh-hspi.c +++ b/drivers/spi/spi-sh-hspi.c
@@ -211,19 +211,11 @@ static int hspi_transfer_one_message(struct spi_controller *ctlr, static int hspi_probe(struct platform_device *pdev) { - struct resource *res; struct spi_controller *ctlr; struct hspi_priv *hspi; struct clk *clk; int ret; - /* get base addr */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "invalid resource\n"); - return -EINVAL; - } - ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*hspi)); if (!ctlr) return -ENOMEM; @@ -241,10 +233,9 @@ static int hspi_probe(struct platform_device *pdev) hspi->ctlr = ctlr; hspi->dev = &pdev->dev; hspi->clk = clk; - hspi->addr = devm_ioremap(hspi->dev, - res->start, resource_size(res)); - if (!hspi->addr) { - ret = -ENOMEM; + hspi->addr = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(hspi->addr)) { + ret = PTR_ERR(hspi->addr); goto error1; }
diff --git a/drivers/spi/spi-sh-msiof.c b/drivers/spi/spi-sh-msiof.c index 1aeab7e..89fbdde 100644 --- a/drivers/spi/spi-sh-msiof.c +++ b/drivers/spi/spi-sh-msiof.c
@@ -453,6 +453,7 @@ static int sh_msiof_spi_setup(struct spi_device *spi) struct sh_msiof_spi_priv *p = spi_controller_get_devdata(spi->controller); u32 clr, set, tmp; + int ret; if (spi_get_csgpiod(spi, 0) || spi_controller_is_target(p->ctlr)) return 0; @@ -468,7 +469,9 @@ static int sh_msiof_spi_setup(struct spi_device *spi) clr |= SIMDR1_SYNCAC; else set |= SIMDR1_SYNCAC; - pm_runtime_get_sync(&p->pdev->dev); + ret = pm_runtime_resume_and_get(&p->pdev->dev); + if (ret < 0) + return ret; tmp = sh_msiof_read(p, SITMDR1) & ~clr; sh_msiof_write(p, SITMDR1, tmp | set | SIMDR1_TRMD | SITMDR1_PCON); tmp = sh_msiof_read(p, SIRMDR1) & ~clr; @@ -671,7 +674,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, if (tx) { ier_bits |= SIIER_TDREQE | SIIER_TDMAE; - dma_sync_single_for_device(p->ctlr->dma_tx->device->dev, + dma_sync_single_for_device(dmaengine_get_dma_device(p->ctlr->dma_tx), p->tx_dma_addr, len, DMA_TO_DEVICE); desc_tx = dmaengine_prep_slave_single(p->ctlr->dma_tx, p->tx_dma_addr, len, DMA_MEM_TO_DEV, @@ -751,7 +754,7 @@ static int sh_msiof_dma_once(struct sh_msiof_spi_priv *p, const void *tx, } if (rx) - dma_sync_single_for_cpu(p->ctlr->dma_rx->device->dev, + dma_sync_single_for_cpu(dmaengine_get_dma_device(p->ctlr->dma_rx), p->rx_dma_addr, len, DMA_FROM_DEVICE); return 0; @@ -1013,6 +1016,7 @@ static const struct of_device_id sh_msiof_match[] __maybe_unused = { { .compatible = "renesas,msiof-r8a779a0", .data = &rcar_gen3_data }, { .compatible = "renesas,msiof-r8a779f0", .data = &rcar_gen3_data }, { .compatible = "renesas,rcar-gen4-msiof", .data = &rcar_gen4_data }, + { .compatible = "renesas,rcar-gen5-msiof", .data = &rcar_gen4_data }, { .compatible = "renesas,sh-msiof", .data = &sh_data }, /* Deprecated */ { /* sentinel */ } }; @@ -1138,13 +1142,13 @@ static int sh_msiof_request_dma(struct sh_msiof_spi_priv *p) if (!p->rx_dma_page) goto free_tx_page; - tx_dev = ctlr->dma_tx->device->dev; + tx_dev = dmaengine_get_dma_device(ctlr->dma_tx); p->tx_dma_addr = dma_map_single(tx_dev, p->tx_dma_page, PAGE_SIZE, DMA_TO_DEVICE); if (dma_mapping_error(tx_dev, p->tx_dma_addr)) goto free_rx_page; - rx_dev = ctlr->dma_rx->device->dev; + rx_dev = dmaengine_get_dma_device(ctlr->dma_rx); p->rx_dma_addr = dma_map_single(rx_dev, p->rx_dma_page, PAGE_SIZE, DMA_FROM_DEVICE); if (dma_mapping_error(rx_dev, p->rx_dma_addr)) @@ -1174,9 +1178,9 @@ static void sh_msiof_release_dma(struct sh_msiof_spi_priv *p) if (!ctlr->dma_tx) return; - dma_unmap_single(ctlr->dma_rx->device->dev, p->rx_dma_addr, PAGE_SIZE, + dma_unmap_single(dmaengine_get_dma_device(ctlr->dma_rx), p->rx_dma_addr, PAGE_SIZE, DMA_FROM_DEVICE); - dma_unmap_single(ctlr->dma_tx->device->dev, p->tx_dma_addr, PAGE_SIZE, + dma_unmap_single(dmaengine_get_dma_device(ctlr->dma_tx), p->tx_dma_addr, PAGE_SIZE, DMA_TO_DEVICE); free_page((unsigned long)p->rx_dma_page); free_page((unsigned long)p->tx_dma_page);
diff --git a/drivers/spi/spi-stm32.c b/drivers/spi/spi-stm32.c index be88e62..4c3ae54 100644 --- a/drivers/spi/spi-stm32.c +++ b/drivers/spi/spi-stm32.c
@@ -515,7 +515,7 @@ static int stm32h7_spi_get_bpw_mask(struct stm32_spi *spi) /* * The most significant bit at DSIZE bit field is reserved when the - * maximum data size of periperal instances is limited to 16-bit + * maximum data size of peripheral instances is limited to 16-bit */ stm32_spi_set_bits(spi, STM32H7_SPI_CFG1, STM32H7_SPI_CFG1_DSIZE); @@ -2511,6 +2511,7 @@ static int stm32_spi_probe(struct platform_device *pdev) gen_pool_free(spi->sram_pool, (unsigned long)spi->sram_rx_buf, spi->sram_rx_buf_size); + spi->sram_rx_buf = NULL; dev_warn(&pdev->dev, "failed to request rx mdma channel, DMA only\n"); } @@ -2548,7 +2549,7 @@ static int stm32_spi_probe(struct platform_device *pdev) if (spi->mdma_rx) dma_release_channel(spi->mdma_rx); err_pool_free: - if (spi->sram_pool) + if (spi->sram_rx_buf) gen_pool_free(spi->sram_pool, (unsigned long)spi->sram_rx_buf, spi->sram_rx_buf_size); if (spi->dma_rx)
diff --git a/drivers/spi/spi-sun4i.c b/drivers/spi/spi-sun4i.c index d5c1639..59941b3 100644 --- a/drivers/spi/spi-sun4i.c +++ b/drivers/spi/spi-sun4i.c
@@ -82,6 +82,8 @@ struct sun4i_spi { struct completion done; + int irq; + const u8 *tx_buf; u8 *rx_buf; int len; @@ -142,15 +144,21 @@ static inline void sun4i_spi_drain_fifo(struct sun4i_spi *sspi, int len) } } -static inline void sun4i_spi_fill_fifo(struct sun4i_spi *sspi, int len) +static inline void sun4i_spi_fill_fifo(struct sun4i_spi *sspi) { u32 cnt; + int len; u8 byte; - /* See how much data we can fit */ - cnt = SUN4I_FIFO_DEPTH - sun4i_spi_get_tx_fifo_count(sspi); + /* + * See how much data we can fit + * + * Filling the FIFO fully causes timeout for some reason + * at least on spi2 on A10s + */ + cnt = SUN4I_FIFO_DEPTH - 1 - sun4i_spi_get_tx_fifo_count(sspi); - len = min3(len, (int)cnt, sspi->len); + len = min_t(int, cnt, sspi->len); while (len--) { byte = sspi->tx_buf ? *sspi->tx_buf++ : 0; @@ -206,7 +214,7 @@ static int sun4i_spi_transfer_one(struct spi_controller *host, struct spi_transfer *tfr) { struct sun4i_spi *sspi = spi_controller_get_devdata(host); - unsigned int mclk_rate, div; + unsigned int mclk_rate, div, div_cdr1, div_cdr2; unsigned long time_left; unsigned int start, end, tx_time; unsigned int tx_len = 0; @@ -271,9 +279,17 @@ static int sun4i_spi_transfer_one(struct spi_controller *host, /* Ensure that we have a parent clock fast enough */ mclk_rate = clk_get_rate(sspi->mclk); + if (!mclk_rate) + return -EINVAL; + if (mclk_rate < (2 * tfr->speed_hz)) { - clk_set_rate(sspi->mclk, 2 * tfr->speed_hz); + ret = clk_set_rate(sspi->mclk, 2 * tfr->speed_hz); + if (ret) + return ret; + mclk_rate = clk_get_rate(sspi->mclk); + if (!mclk_rate) + return -EINVAL; } /* @@ -290,15 +306,15 @@ static int sun4i_spi_transfer_one(struct spi_controller *host, * First try CDR2, and if we can't reach the expected * frequency, fall back to CDR1. */ - div = mclk_rate / (2 * tfr->speed_hz); - if (div <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) { - if (div > 0) - div--; - - reg = SUN4I_CLK_CTL_CDR2(div) | SUN4I_CLK_CTL_DRS; + div_cdr1 = DIV_ROUND_UP(mclk_rate, tfr->speed_hz); + div_cdr2 = DIV_ROUND_UP(div_cdr1, 2); + if (div_cdr2 <= (SUN4I_CLK_CTL_CDR2_MASK + 1)) { + reg = SUN4I_CLK_CTL_CDR2(div_cdr2 - 1) | SUN4I_CLK_CTL_DRS; + tfr->effective_speed_hz = mclk_rate / (2 * div_cdr2); } else { - div = ilog2(mclk_rate) - ilog2(tfr->speed_hz); - reg = SUN4I_CLK_CTL_CDR1(div); + div = min(SUN4I_CLK_CTL_CDR1_MASK + 1, order_base_2(div_cdr1)); + reg = SUN4I_CLK_CTL_CDR1(div - 1); + tfr->effective_speed_hz = mclk_rate / (1 << div); } sun4i_spi_write(sspi, SUN4I_CLK_CTL_REG, reg); @@ -311,18 +327,14 @@ static int sun4i_spi_transfer_one(struct spi_controller *host, sun4i_spi_write(sspi, SUN4I_BURST_CNT_REG, SUN4I_BURST_CNT(tfr->len)); sun4i_spi_write(sspi, SUN4I_XMIT_CNT_REG, SUN4I_XMIT_CNT(tx_len)); - /* - * Fill the TX FIFO - * Filling the FIFO fully causes timeout for some reason - * at least on spi2 on A10s - */ - sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH - 1); + /* Fill the TX FIFO */ + sun4i_spi_fill_fifo(sspi); /* Enable the interrupts */ sun4i_spi_enable_interrupt(sspi, SUN4I_INT_CTL_TC | SUN4I_INT_CTL_RF_F34); /* Only enable Tx FIFO interrupt if we really need it */ - if (tx_len > SUN4I_FIFO_DEPTH) + if (tx_len > SUN4I_FIFO_DEPTH - 1) sun4i_spi_enable_interrupt(sspi, SUN4I_INT_CTL_TF_E34); /* Start the transfer */ @@ -333,6 +345,7 @@ static int sun4i_spi_transfer_one(struct spi_controller *host, start = jiffies; time_left = wait_for_completion_timeout(&sspi->done, msecs_to_jiffies(tx_time)); + end = jiffies; if (!time_left) { dev_warn(&host->dev, @@ -340,12 +353,11 @@ static int sun4i_spi_transfer_one(struct spi_controller *host, dev_name(&spi->dev), tfr->len, tfr->speed_hz, jiffies_to_msecs(end - start), tx_time); ret = -ETIMEDOUT; - goto out; + sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0); + synchronize_irq(sspi->irq); } - -out: - sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0); + sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH); return ret; } @@ -357,8 +369,7 @@ static irqreturn_t sun4i_spi_handler(int irq, void *dev_id) /* Transfer complete */ if (status & SUN4I_INT_CTL_TC) { - sun4i_spi_write(sspi, SUN4I_INT_STA_REG, SUN4I_INT_CTL_TC); - sun4i_spi_drain_fifo(sspi, SUN4I_FIFO_DEPTH); + sun4i_spi_write(sspi, SUN4I_INT_CTL_REG, 0); complete(&sspi->done); return IRQ_HANDLED; } @@ -373,7 +384,7 @@ static irqreturn_t sun4i_spi_handler(int irq, void *dev_id) /* Transmit FIFO 3/4 empty */ if (status & SUN4I_INT_CTL_TF_E34) { - sun4i_spi_fill_fifo(sspi, SUN4I_FIFO_DEPTH); + sun4i_spi_fill_fifo(sspi); if (!sspi->len) /* nothing left to transmit */ @@ -456,6 +467,7 @@ static int sun4i_spi_probe(struct platform_device *pdev) return ret; } + sspi->irq = irq; sspi->host = host; host->max_speed_hz = 100 * 1000 * 1000; host->min_speed_hz = 3 * 1000;
diff --git a/drivers/spi/spi-sun6i.c b/drivers/spi/spi-sun6i.c index 4631e9c..6b7a05d 100644 --- a/drivers/spi/spi-sun6i.c +++ b/drivers/spi/spi-sun6i.c
@@ -386,7 +386,7 @@ static int sun6i_spi_transfer_one(struct spi_controller *host, * SPI_CLK = MOD_CLK / (2 ^ cdr) * Or we can use CDR2, which is calculated with the formula: * SPI_CLK = MOD_CLK / (2 * (cdr + 1)) - * Wether we use the former or the latter is set through the + * Whether we use the former or the latter is set through the * DRS bit. * * First try CDR2, and if we can't reach the expected
diff --git a/drivers/spi/spi-sunplus-sp7021.c b/drivers/spi/spi-sunplus-sp7021.c index f16fcda..54431c3 100644 --- a/drivers/spi/spi-sunplus-sp7021.c +++ b/drivers/spi/spi-sunplus-sp7021.c
@@ -337,10 +337,15 @@ static int sp7021_spi_host_transfer_one(struct spi_controller *ctlr, struct spi_ SP7021_SPI_START_FD; writel(reg_temp, pspim->m_base + SP7021_SPI_STATUS_REG); - if (!wait_for_completion_interruptible_timeout(&pspim->isr_done, timeout)) { - dev_err(&spi->dev, "wait_for_completion err\n"); - mutex_unlock(&pspim->buf_lock); - return -ETIMEDOUT; + { + long ret = wait_for_completion_interruptible_timeout( + &pspim->isr_done, timeout); + if (ret <= 0) { + dev_err(&spi->dev, ret == 0 ? "SPI transfer timeout\n" + : "SPI transfer interrupted\n"); + mutex_unlock(&pspim->buf_lock); + return ret == 0 ? -ETIMEDOUT : -EINTR; + } } reg_temp = readl(pspim->m_base + SP7021_SPI_STATUS_REG);
diff --git a/drivers/spi/spi-tegra114.c b/drivers/spi/spi-tegra114.c index 5f8d8da..f43f2df 100644 --- a/drivers/spi/spi-tegra114.c +++ b/drivers/spi/spi-tegra114.c
@@ -1308,6 +1308,9 @@ static int tegra_spi_probe(struct platform_device *pdev) struct resource *r; int ret, spi_irq; int bus_num; + u32 conflicting_cs; + u32 enabled_child_cs_polarity = 0, disabled_child_cs_low = 0, disabled_child_cs_high = 0; + u32 enabled_cs_mask = 0; host = devm_spi_alloc_host(&pdev->dev, sizeof(*tspi)); if (!host) { @@ -1402,6 +1405,52 @@ static int tegra_spi_probe(struct platform_device *pdev) udelay(2); reset_control_deassert(tspi->rst); tspi->def_command1_reg = SPI_M_S; + + /* + * SPI_COMMAND1 is written before any child is registered, so a chip + * select with CS_POL_INACTIVE clear stays asserted until + * tegra_spi_setup() runs for that device. Program the level the + * device tree asks for up front instead. + * + * Disabled children are included deliberately. The core never + * registers them, so this is the only chance to park their chip + * select at the level their hardware needs. An enabled child on the + * same CS takes priority. + */ + for_each_child_of_node_scoped(pdev->dev.of_node, np) { + u32 cs; + u32 polarity_bitmask; + u32 cs_polarity = 0; + + if (of_property_read_u32(np, "reg", &cs)) + continue; + + if (cs >= MAX_CHIP_SELECT) + continue; + + polarity_bitmask = SPI_CS_POL_INACTIVE(cs); + if (!of_property_read_bool(np, "spi-cs-high")) + cs_polarity = polarity_bitmask; + + if (of_device_is_available(np)) { + enabled_cs_mask |= polarity_bitmask; + enabled_child_cs_polarity |= cs_polarity; + } else { + if (cs_polarity) + disabled_child_cs_low |= polarity_bitmask; + else + disabled_child_cs_high |= polarity_bitmask; + } + } + conflicting_cs = disabled_child_cs_low & disabled_child_cs_high & ~enabled_cs_mask; + for (u32 cs = 0; cs < MAX_CHIP_SELECT; cs++) { + if (SPI_CS_POL_INACTIVE(cs) & conflicting_cs) + dev_warn(&pdev->dev, + "Conflicting CS polarity on disabled nodes at cs %u\n", cs); + } + + tspi->def_command1_reg |= enabled_child_cs_polarity | + (disabled_child_cs_low & ~enabled_cs_mask); tegra_spi_writel(tspi, tspi->def_command1_reg, SPI_COMMAND1); tspi->spi_cs_timing1 = tegra_spi_readl(tspi, SPI_CS_TIMING1); tspi->spi_cs_timing2 = tegra_spi_readl(tspi, SPI_CS_TIMING2);
diff --git a/drivers/spi/spi-tegra210-quad.c b/drivers/spi/spi-tegra210-quad.c index 8ede864..d8cca3a 100644 --- a/drivers/spi/spi-tegra210-quad.c +++ b/drivers/spi/spi-tegra210-quad.c
@@ -191,6 +191,15 @@ struct tegra_qspi { void __iomem *base; phys_addr_t phys; unsigned int irq; + struct work_struct irq_work; + struct workqueue_struct *wq; + /* + * Set by tegra_qspi_handle_timeout() while it drains the bottom + * half so tegra_qspi_isr() suppresses new queue_work() calls + * that would otherwise race the recovery path or the caller's + * cleanup of curr_xfer. + */ + bool recovery_in_progress; u32 cur_speed; unsigned int cur_pos; @@ -205,6 +214,18 @@ struct tegra_qspi { unsigned int dma_buf_size; unsigned int max_buf_size; bool is_curr_dma_xfer; + /* + * Cached "this PIO chunk completes the whole transfer" decision, + * computed by tegra_qspi_start_cpu_based_transfer() before it + * unmasks the IRQ. Used by the hard IRQ small-PIO fastpath in + * place of dereferencing curr_xfer->len, so the ISR cannot touch + * the spi_transfer object even on a late IRQ that races with the + * synchronous teardown path. Multi-chunk PIO transfers always go + * through the workqueue (this flag is only set on the final + * chunk), so the fastpath cannot recurse into + * tegra_qspi_start_cpu_based_transfer() from hard IRQ context. + */ + bool is_last_pio_chunk; struct completion rx_dma_complete; struct completion tx_dma_complete; @@ -212,6 +233,7 @@ struct tegra_qspi { u32 tx_status; u32 rx_status; u32 status_reg; + u32 trans_status; bool is_packed; bool use_dma; @@ -622,6 +644,17 @@ static int tegra_qspi_start_dma_based_transfer(struct tegra_qspi *tqspi, struct val = QSPI_DMA_BLK_SET(tqspi->curr_dma_words - 1); tegra_qspi_writel(tqspi, val, QSPI_DMA_BLK); + /* + * Reset the cached transfer status before unmasking the IRQ for + * this chunk. The cache must represent only the IRQ for THIS + * chunk; a stale RDY from the previous chunk of a multi-chunk + * transfer would otherwise mislead tegra_qspi_handle_timeout() + * into a false-positive recovery while the new chunk is still in + * flight. Pairs with smp_load_acquire() in + * tegra_qspi_handle_timeout(). The new chunk's IRQ cannot fire + * until QSPI_DMA_CTL is written below. + */ + smp_store_release(&tqspi->trans_status, 0); tegra_qspi_unmask_irq(tqspi); if (tqspi->is_packed) @@ -713,7 +746,13 @@ static int tegra_qspi_start_dma_based_transfer(struct tegra_qspi *tqspi, struct tegra_qspi_writel(tqspi, tqspi->command1_reg, QSPI_COMMAND1); - tqspi->is_curr_dma_xfer = true; + /* + * WRITE_ONCE() pairs with READ_ONCE() in tegra_qspi_isr() and + * tegra_qspi_work_handler(); the flag is read lock-free across + * the hard-IRQ / process-context boundary so the annotation + * prevents compiler tearing and silences KCSAN. + */ + WRITE_ONCE(tqspi->is_curr_dma_xfer, true); tqspi->dma_control_reg = val; val |= QSPI_DMA_EN; tegra_qspi_writel(tqspi, val, QSPI_DMA_CTL); @@ -734,9 +773,33 @@ static int tegra_qspi_start_cpu_based_transfer(struct tegra_qspi *qspi, struct s val = QSPI_DMA_BLK_SET(cur_words - 1); tegra_qspi_writel(qspi, val, QSPI_DMA_BLK); + /* + * Snapshot whether this PIO chunk completes the whole transfer + * before unmasking the IRQ, so the hard IRQ small-PIO fastpath + * can decide whether to drain inline without dereferencing the + * spi_transfer object. cur_pos / curr_dma_words / bytes_per_word + * are stable here: they are written by + * tegra_qspi_calculate_curr_xfer_param() earlier in this code + * path. The IRQ cannot fire until the QSPI_COMMAND1 write below + * kicks the transfer off, so this store happens-before any ISR + * that observes the unmask. + */ + WRITE_ONCE(qspi->is_last_pio_chunk, + qspi->cur_pos + qspi->curr_dma_words * qspi->bytes_per_word >= t->len); + + /* + * Reset the cached transfer status before unmasking the IRQ for + * this chunk so the cache represents only the IRQ for THIS chunk; + * a stale RDY from the previous chunk would otherwise mislead + * tegra_qspi_handle_timeout() into a false-positive recovery + * while the new chunk is still in flight. Pairs with + * smp_load_acquire() in tegra_qspi_handle_timeout(). The new + * chunk's IRQ cannot fire until QSPI_COMMAND1 is written below. + */ + smp_store_release(&qspi->trans_status, 0); tegra_qspi_unmask_irq(qspi); - qspi->is_curr_dma_xfer = false; + WRITE_ONCE(qspi->is_curr_dma_xfer, false); val = qspi->command1_reg; val |= QSPI_PIO; tegra_qspi_writel(qspi, val, QSPI_COMMAND1); @@ -859,6 +922,13 @@ static u32 tegra_qspi_setup_transfer_one(struct spi_device *spi, struct spi_tran tqspi->cur_rx_pos = 0; tqspi->cur_tx_pos = 0; tqspi->curr_xfer = t; + /* + * Pairs with smp_load_acquire() in tegra_qspi_handle_timeout(). + * Clearing the cached trans_status before unmasking the IRQ for + * the new transfer prevents a stale RDY bit from the previous + * transfer fooling the timeout handler into a false recovery. + */ + smp_store_release(&tqspi->trans_status, 0); spin_unlock_irqrestore(&tqspi->lock, flags); if (is_first_of_msg) { @@ -1065,40 +1135,206 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_qspi *tqspi); * tegra_qspi_handle_timeout - Handle transfer timeout with hardware check * @tqspi: QSPI controller instance * - * When a timeout occurs but hardware has completed the transfer (interrupt - * was lost or delayed), manually trigger transfer completion processing. - * This avoids failing transfers that actually succeeded. + * When wait_for_completion_timeout() expires the hardware may still have + * finished the current chunk. Drain the pending bottom half and, if the + * whole transfer really did complete during the drain, consume the + * completion and report success. * - * Returns: 0 if transfer was completed, -ETIMEDOUT if real timeout + * When the bottom half advanced the transfer by only one chunk of a + * multi-chunk DMA/PIO transfer without signalling xfer_completion, a + * fallback that ran handle_{cpu,dma}_based_xfer() here would race with + * the DMA engine already moving the next chunk into the client buffer + * (spi_finalize_current_message() would then release the buffer while + * the controller is still writing memory). Fake completion is therefore + * only attempted when the current chunk is the last chunk of the + * transfer; multi-chunk continuation timeouts return -ETIMEDOUT and + * let the caller reset the controller. + * + * Returns: 0 if the transfer completed, -ETIMEDOUT otherwise. */ static int tegra_qspi_handle_timeout(struct tegra_qspi *tqspi) { + struct spi_transfer *t; + unsigned long flags; + bool is_last_chunk; + bool lost_irq_snapshot = false; irqreturn_t ret; - u32 status; - - /* Check if hardware actually completed the transfer */ - status = tegra_qspi_readl(tqspi, QSPI_TRANS_STATUS); - if (!(status & QSPI_RDY)) - return -ETIMEDOUT; + int retval; + u32 status, refreshed; + u32 lost_fifo_status = 0; + u32 lost_tx_status = 0; + u32 lost_rx_status = 0; /* - * Hardware completed but interrupt was lost/delayed. Manually - * process the completion by calling the appropriate handler. + * Snapshot both the ISR cache and (if the cache is empty) the + * live status registers BEFORE entering recovery. The recovery + * path calls tegra_qspi_mask_clear_irq() below, which performs + * W1Cs on QSPI_TRANS_STATUS and on the QSPI_FIFO_STATUS error + * bits: a lost-IRQ recovery must capture the current FIFO error + * state before the mask erases it. + * + * Cache-live-cache retry: if the initial cache load returns zero + * we fall back to a live QSPI_TRANS_STATUS read, and if that also + * returns zero we retry the cache once more. That closes the + * interleaving where an ISR on another CPU publishes trans_status + * with release semantics and then W1Cs the hardware between our + * cache load and our live load: the second cache load observes + * the now-visible release and we correctly classify the transfer + * as complete rather than reporting a false timeout. + * + * The trans_status cache is reset to zero in + * tegra_qspi_start_{cpu,dma}_based_transfer() before unmasking + * the IRQ for every chunk, so a stale RDY from the previous + * chunk of a multi-chunk transfer cannot survive into this + * check. */ + status = smp_load_acquire(&tqspi->trans_status); + if (!status) { + status = tegra_qspi_readl(tqspi, QSPI_TRANS_STATUS); + if (!status) { + /* Retry cache; pairs with release in ISR post-store. */ + status = smp_load_acquire(&tqspi->trans_status); + } else { + /* + * Live register shows RDY but the ISR cache is + * empty: either the ISR ran and cleared HW between + * our two loads (the cache retry above would have + * observed it, so we would not be here), or the IRQ + * was genuinely lost. Snapshot the live FIFO error + * status now so tegra_qspi_mask_clear_irq() below + * does not W1C it away before the manual handler + * downstream can see it. + */ + lost_fifo_status = tegra_qspi_readl(tqspi, + QSPI_FIFO_STATUS); + lost_tx_status = lost_fifo_status & + (QSPI_TX_FIFO_UNF | QSPI_TX_FIFO_OVF); + lost_rx_status = lost_fifo_status & + (QSPI_RX_FIFO_OVF | QSPI_RX_FIFO_UNF); + lost_irq_snapshot = true; + } + } + + /* + * Enter recovery unconditionally. Every expired + * wait_for_completion_timeout() must serialise against a delayed + * ISR or worker before the caller runs dma_stop() + + * device_reset() + curr_xfer clear: publishing + * recovery_in_progress under tqspi->lock, masking the controller + * IRQ, calling synchronize_irq() to drain any in-flight ISR + * (including the small-PIO hard-IRQ fastpath), and finally + * cancel_work_sync() to drain the workqueue gives us that + * serialisation regardless of whether the hardware finished. A + * genuine hardware timeout still ends up as -ETIMEDOUT further + * down, but only after ISR and workqueue activity are quiesced. + * + * cancel_work_sync() cancels a pending worker without executing + * it and waits for a currently running one to finish; the + * recovery_in_progress guard checked inside tegra_qspi_isr() + * under tqspi->lock is atomic with its queue_work() and small-PIO + * fastpath dispatch decisions, so no new bottom-half work is + * enqueued once we publish the flag. + * + * tegra_qspi_mask_clear_irq() is idempotent: its read-modify-write + * of QSPI_INTR_MASK and W1C of QSPI_TRANS_STATUS / FIFO error + * status all tolerate a double-write, so it is safe whether or + * not the ISR has already run for this transfer. + */ + spin_lock_irqsave(&tqspi->lock, flags); + WRITE_ONCE(tqspi->recovery_in_progress, true); + spin_unlock_irqrestore(&tqspi->lock, flags); + + tegra_qspi_mask_clear_irq(tqspi); + synchronize_irq(tqspi->irq); + cancel_work_sync(&tqspi->irq_work); + + if (try_wait_for_completion(&tqspi->xfer_completion)) { + retval = 0; + goto out; + } + + /* + * Re-check the cache after the drain: the worker we just drained + * may have published a completion status the entry snapshot did + * not observe (for example the ISR fired on another CPU after we + * loaded the cache but before we masked). + */ + refreshed = smp_load_acquire(&tqspi->trans_status); + if (refreshed) + status = refreshed; + + if (!(status & QSPI_RDY)) { + retval = -ETIMEDOUT; + goto out; + } + + /* + * If the ISR never ran (lost IRQ path) publish the FIFO error + * snapshot we captured before mask_clear_irq() so the manual + * handler downstream has fresh error state rather than stale + * fields from a previous chunk's ISR. + */ + if (lost_irq_snapshot) { + WRITE_ONCE(tqspi->status_reg, lost_fifo_status); + WRITE_ONCE(tqspi->tx_status, lost_tx_status); + WRITE_ONCE(tqspi->rx_status, lost_rx_status); + } + + /* + * The bottom half did not signal full completion. Either the work + * ran and advanced the transfer by one chunk (possibly arming the + * next chunk of a multi-chunk transfer), or it was cancelled + * before it could run, or the current chunk really did not + * complete. Only fake completion when the current chunk is the + * last chunk of the transfer; otherwise the DMA engine may still + * be moving the next chunk into memory, and returning 0 here would + * let seq_xfer clear curr_xfer and finalise the message while the + * hardware is still writing. + * + * The last-chunk arithmetic mirrors tegra_qspi_start_cpu_based_ + * transfer(), which uses cur_pos + curr_dma_words * bytes_per_word + * >= t->len to set is_last_pio_chunk before arming the IRQ. + */ + spin_lock_irqsave(&tqspi->lock, flags); + t = tqspi->curr_xfer; + if (!t) { + /* CPU-path handler already cleared curr_xfer */ + spin_unlock_irqrestore(&tqspi->lock, flags); + retval = 0; + goto out; + } + is_last_chunk = (tqspi->cur_pos + + tqspi->curr_dma_words * tqspi->bytes_per_word) >= t->len; + spin_unlock_irqrestore(&tqspi->lock, flags); + + if (!is_last_chunk) { + retval = -ETIMEDOUT; + goto out; + } + dev_warn_ratelimited(tqspi->dev, "QSPI interrupt timeout, but transfer complete\n"); - /* Clear the transfer status */ - status = tegra_qspi_readl(tqspi, QSPI_TRANS_STATUS); - tegra_qspi_writel(tqspi, status, QSPI_TRANS_STATUS); - - /* Manually trigger completion handler */ - if (!tqspi->is_curr_dma_xfer) + if (!READ_ONCE(tqspi->is_curr_dma_xfer)) ret = handle_cpu_based_xfer(tqspi); else ret = handle_dma_based_xfer(tqspi); - return (ret == IRQ_HANDLED) ? 0 : -EIO; + retval = (ret == IRQ_HANDLED) ? 0 : -EIO; + +out: + /* + * The drained bottom half may have unmasked the controller IRQ + * to arm the next chunk of a multi-chunk transfer. Re-mask and + * synchronize before clearing recovery_in_progress so that no + * lingering ISR can queue fresh work behind the caller's back + * (the caller's dma_stop() + device_reset() + curr_xfer clear + * runs immediately after we return on the error path). + */ + tegra_qspi_mask_clear_irq(tqspi); + synchronize_irq(tqspi->irq); + WRITE_ONCE(tqspi->recovery_in_progress, false); + return retval; } static u32 tegra_qspi_cmd_config(bool is_ddr, u8 bus_width, u8 len) @@ -1232,9 +1468,9 @@ static int tegra_qspi_combined_seq_xfer(struct tegra_qspi *tqspi, if (ret == 0) { /* - * Check if hardware completed the transfer - * even though interrupt was lost or delayed. - * If so, process the completion and continue. + * Check if hardware completed the transfer even though + * workqueue was delayed. If so, process completion and + * continue. */ ret = tegra_qspi_handle_timeout(tqspi); if (ret < 0) { @@ -1351,8 +1587,8 @@ static int tegra_qspi_non_combined_seq_xfer(struct tegra_qspi *tqspi, if (ret == 0) { /* * Check if hardware completed the transfer even though - * interrupt was lost or delayed. If so, process the - * completion and continue. + * workqueue was delayed. If so, process completion and + * continue. */ ret = tegra_qspi_handle_timeout(tqspi); if (ret < 0) { @@ -1506,6 +1742,19 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_qspi *tqspi) long wait_status; int num_errors = 0; + /* + * Snapshot curr_xfer under the lock before the (potentially long) + * DMA waits below. The timeout path can clear tqspi->curr_xfer + * concurrently; using the local copy keeps the subsequent dma_unmap + * and FIFO-drain steps consistent with the transfer that actually + * started, and lets us bail safely if cleanup already happened. + */ + spin_lock_irqsave(&tqspi->lock, flags); + t = tqspi->curr_xfer; + spin_unlock_irqrestore(&tqspi->lock, flags); + if (!t) + return IRQ_HANDLED; + if (tqspi->cur_direction & DATA_DIR_TX) { if (tqspi->tx_status) { if (tqspi->tx_dma_chan) @@ -1539,12 +1788,6 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_qspi *tqspi) } spin_lock_irqsave(&tqspi->lock, flags); - t = tqspi->curr_xfer; - - if (!t) { - spin_unlock_irqrestore(&tqspi->lock, flags); - return IRQ_HANDLED; - } if (num_errors) { tegra_qspi_dma_unmap_xfer(tqspi, t); @@ -1581,46 +1824,41 @@ static irqreturn_t handle_dma_based_xfer(struct tegra_qspi *tqspi) return IRQ_HANDLED; } -static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data) +/** + * tegra_qspi_work_handler - Workqueue handler for interrupt bottom-half + * @work: work_struct embedded in tegra_qspi + * + * Runs in process context and can sleep (needed for DMA completion waits). + * Runs on any CPU in the WQ_UNBOUND pool, so the bottom half can migrate off + * the interrupt-taking CPU that the previous threaded IRQ pinned to + * (irq_thread() calls set_cpus_allowed_ptr() with the IRQ affinity mask). + * + * The hard IRQ handler has already: + * - Verified this is our interrupt (QSPI_RDY was set) + * - Cached FIFO status in tqspi->status_reg + * - Parsed tx_status / rx_status from FIFO status + * - Masked further interrupts + */ +static void tegra_qspi_work_handler(struct work_struct *work) { - struct tegra_qspi *tqspi = context_data; + struct tegra_qspi *tqspi = container_of(work, struct tegra_qspi, irq_work); unsigned long flags; - u32 status; - /* - * Read transfer status to check if interrupt was triggered by transfer - * completion - */ - status = tegra_qspi_readl(tqspi, QSPI_TRANS_STATUS); - - /* - * Occasionally the IRQ thread takes a long time to wake up (usually - * when the CPU that it's running on is excessively busy) and we have - * already reached the timeout before and cleaned up the timed out - * transfer. Avoid any processing in that case and bail out early. - * - * If no transfer is in progress, check if this was a real interrupt - * that the timeout handler already processed, or a spurious one. - */ spin_lock_irqsave(&tqspi->lock, flags); + + /* + * tegra_qspi_handle_timeout() sets recovery_in_progress under + * tqspi->lock and then calls cancel_work_sync(), so any running + * worker is drained and tegra_qspi_isr() cannot enqueue a new + * one while recovery runs. The curr_xfer NULL check catches the + * case where the timeout path already tore the transfer down + * before this work got a chance to run. + */ if (!tqspi->curr_xfer) { spin_unlock_irqrestore(&tqspi->lock, flags); - /* Spurious interrupt - transfer not ready */ - if (!(status & QSPI_RDY)) - return IRQ_NONE; - /* Real interrupt, already handled by timeout path */ - return IRQ_HANDLED; + return; } - tqspi->status_reg = tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS); - - if (tqspi->cur_direction & DATA_DIR_TX) - tqspi->tx_status = tqspi->status_reg & (QSPI_TX_FIFO_UNF | QSPI_TX_FIFO_OVF); - - if (tqspi->cur_direction & DATA_DIR_RX) - tqspi->rx_status = tqspi->status_reg & (QSPI_RX_FIFO_OVF | QSPI_RX_FIFO_UNF); - - tegra_qspi_mask_clear_irq(tqspi); spin_unlock_irqrestore(&tqspi->lock, flags); /* @@ -1629,10 +1867,127 @@ static irqreturn_t tegra_qspi_isr_thread(int irq, void *context_data) * DMA handler also needs to sleep in wait_for_completion_*(), which * cannot be done while holding spinlock. */ - if (!tqspi->is_curr_dma_xfer) - return handle_cpu_based_xfer(tqspi); + if (!READ_ONCE(tqspi->is_curr_dma_xfer)) + handle_cpu_based_xfer(tqspi); + else + handle_dma_based_xfer(tqspi); +} - return handle_dma_based_xfer(tqspi); +/** + * tegra_qspi_isr - Hard IRQ handler + * @irq: IRQ number + * @context_data: QSPI controller instance + * + * Runs in hard IRQ context with minimal latency. Cannot sleep. + * + * Tegra QSPI uses a dedicated, non-shared GIC SPI line on every SoC that + * uses this driver. The handler always returns IRQ_HANDLED and always + * acknowledges/re-masks the controller IRQ, so the level-triggered line + * cannot stay asserted and trip the kernel spurious-IRQ detector into + * disabling the line. On a stray IRQ where curr_xfer is NULL (e.g. the + * timeout path has already torn the transfer down) the FIFO/status + * processing and bottom-half scheduling are skipped because there is no + * transfer to drive forward. + * + * Return: IRQ_HANDLED. + */ +static irqreturn_t tegra_qspi_isr(int irq, void *context_data) +{ + struct tegra_qspi *tqspi = context_data; + u32 status_reg, trans_status; + u32 tx_status = 0, rx_status = 0; + + if (!READ_ONCE(tqspi->curr_xfer)) { + tegra_qspi_mask_clear_irq(tqspi); + return IRQ_HANDLED; + } + + spin_lock(&tqspi->lock); + status_reg = tegra_qspi_readl(tqspi, QSPI_FIFO_STATUS); + trans_status = tegra_qspi_readl(tqspi, QSPI_TRANS_STATUS); + + if (tqspi->cur_direction & DATA_DIR_TX) { + tx_status = status_reg & (QSPI_TX_FIFO_UNF | QSPI_TX_FIFO_OVF); + WRITE_ONCE(tqspi->tx_status, tx_status); + } + + if (tqspi->cur_direction & DATA_DIR_RX) { + rx_status = status_reg & (QSPI_RX_FIFO_OVF | QSPI_RX_FIFO_UNF); + WRITE_ONCE(tqspi->rx_status, rx_status); + } + + WRITE_ONCE(tqspi->status_reg, status_reg); + /* + * Publish trans_status with release semantics before we clear + * the hardware status in tegra_qspi_mask_clear_irq() below. That + * ordering matters for the lock-free cache read in + * tegra_qspi_handle_timeout(): if the timeout path sees the + * released trans_status it also observes the matching status_reg + * / tx_status / rx_status; if it does not yet see the released + * value it falls back to a live QSPI_TRANS_STATUS read, and that + * live read still returns QSPI_RDY because we have not cleared + * the register yet. Reversing this order would open a window + * where the cache is still zero but the hardware bit has already + * been cleared, making the fallback report a false timeout. + */ + smp_store_release(&tqspi->trans_status, trans_status); + + tegra_qspi_mask_clear_irq(tqspi); + + /* + * If tegra_qspi_handle_timeout() is draining the bottom half, + * skip queueing new work. The flag is set under tqspi->lock and + * queue_work() below happens while we still hold the lock, so + * the guard is atomic with the queue decision. Any ISR that had + * already passed this check is drained by the synchronize_irq() + * call that tegra_qspi_handle_timeout() issues after publishing + * the flag. + */ + if (READ_ONCE(tqspi->recovery_in_progress)) { + spin_unlock(&tqspi->lock); + return IRQ_HANDLED; + } + + /* + * Small-PIO fastpath: drain the FIFO inline only when this chunk + * completes the entire outstanding transfer and no error bit was + * latched, to avoid workqueue scheduling latency for TPM-style + * short reads. + * + * The "last chunk" decision is computed and cached as a scalar by + * tegra_qspi_start_cpu_based_transfer() before it unmasks the IRQ, + * so the hard-IRQ fastpath never dereferences the spi_transfer + * pointer here. That keeps the ISR safe against any teardown race + * where the synchronous path could clear curr_xfer concurrently. + * + * The fastpath dispatch decision is made while still holding + * tqspi->lock, so the recovery_in_progress guard above covers it + * atomically with queue_work() below: an ISR that reaches the + * fastpath cannot race a tegra_qspi_handle_timeout() that + * subsequently observes recovery_in_progress == true, because + * that path calls synchronize_irq() before proceeding. We drop + * the lock before calling handle_cpu_based_xfer() so it can take + * tqspi->lock internally without deadlocking. + * + * Multi-chunk PIO continuation stays on the workqueue so that + * tegra_qspi_start_cpu_based_transfer() can re-arm the IRQ from + * process context. DMA transfers also stay on the workqueue + * because their completion path sleeps on the DMA engine. + * tegra_qspi_handle_error() -> device_reset() can sleep, so the + * fastpath only runs when both status words are clean. + */ + if (!READ_ONCE(tqspi->is_curr_dma_xfer) && + READ_ONCE(tqspi->is_last_pio_chunk) && + !tx_status && !rx_status) { + spin_unlock(&tqspi->lock); + return handle_cpu_based_xfer(tqspi); + } + + queue_work(tqspi->wq, &tqspi->irq_work); + + spin_unlock(&tqspi->lock); + + return IRQ_HANDLED; } static struct tegra_qspi_soc_data tegra210_qspi_soc_data = { @@ -1800,12 +2155,21 @@ static int tegra_qspi_probe(struct platform_device *pdev) pm_runtime_put_autosuspend(&pdev->dev); - ret = request_threaded_irq(tqspi->irq, NULL, - tegra_qspi_isr_thread, IRQF_ONESHOT, - dev_name(&pdev->dev), tqspi); + tqspi->wq = alloc_workqueue("%s", WQ_HIGHPRI | WQ_UNBOUND, 0, + dev_name(&pdev->dev)); + if (!tqspi->wq) { + dev_err(&pdev->dev, "failed to allocate workqueue\n"); + ret = -ENOMEM; + goto exit_pm_disable; + } + + INIT_WORK(&tqspi->irq_work, tegra_qspi_work_handler); + + ret = request_irq(tqspi->irq, tegra_qspi_isr, 0, + dev_name(&pdev->dev), tqspi); if (ret < 0) { dev_err(&pdev->dev, "failed to request IRQ#%u: %d\n", tqspi->irq, ret); - goto exit_pm_disable; + goto exit_destroy_wq; } ret = spi_register_controller(host); @@ -1817,7 +2181,9 @@ static int tegra_qspi_probe(struct platform_device *pdev) return 0; exit_free_irq: - free_irq(qspi_irq, tqspi); + free_irq(tqspi->irq, tqspi); +exit_destroy_wq: + destroy_workqueue(tqspi->wq); exit_pm_disable: pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_force_suspend(&pdev->dev); @@ -1830,8 +2196,15 @@ static void tegra_qspi_remove(struct platform_device *pdev) struct spi_controller *host = platform_get_drvdata(pdev); struct tegra_qspi *tqspi = spi_controller_get_devdata(host); + /* + * Tear down in reverse order of probe() so that the controller stops + * accepting transfers before the IRQ is released, no new work can be + * queued after the IRQ is freed, and any work already queued is + * drained while the clocks are still running. + */ spi_unregister_controller(host); free_irq(tqspi->irq, tqspi); + destroy_workqueue(tqspi->wq); pm_runtime_dont_use_autosuspend(&pdev->dev); pm_runtime_force_suspend(&pdev->dev); tegra_qspi_deinit_dma(tqspi);
diff --git a/drivers/spi/spi-ti-qspi.c b/drivers/spi/spi-ti-qspi.c index 34b1549..24612e9 100644 --- a/drivers/spi/spi-ti-qspi.c +++ b/drivers/spi/spi-ti-qspi.c
@@ -454,7 +454,7 @@ static int ti_qspi_dma_xfer(struct ti_qspi *qspi, dma_addr_t dma_dst, tx->callback = ti_qspi_dma_callback; tx->callback_param = qspi; - cookie = tx->tx_submit(tx); + cookie = dmaengine_submit(tx); reinit_completion(&qspi->transfer_complete); ret = dma_submit_error(cookie);
diff --git a/drivers/spi/spi-tle62x0.c b/drivers/spi/spi-tle62x0.c index dd8bfb3..986d78a 100644 --- a/drivers/spi/spi-tle62x0.c +++ b/drivers/spi/spi-tle62x0.c
@@ -151,10 +151,10 @@ static ssize_t tle62x0_gpio_store(struct device *dev, struct tle62x0_state *st = dev_get_drvdata(dev); int gpio_num = to_gpio_num(attr); unsigned long val; - char *endp; + int ret; - val = simple_strtoul(buf, &endp, 0); - if (buf == endp) + ret = kstrtoul(buf, 0, &val); + if (ret) return -EINVAL; dev_dbg(dev, "setting gpio %d to %ld\n", gpio_num, val);
diff --git a/drivers/spi/spi-topcliff-pch.c b/drivers/spi/spi-topcliff-pch.c index 9872304..eb34851 100644 --- a/drivers/spi/spi-topcliff-pch.c +++ b/drivers/spi/spi-topcliff-pch.c
@@ -1092,8 +1092,8 @@ static void pch_spi_handle_dma(struct pch_spi_data *data, int *bpw) spin_lock_irqsave(&data->lock, flags); pch_spi_writereg(data->host, PCH_SSNXCR, SSN_LOW); - desc_rx->tx_submit(desc_rx); - desc_tx->tx_submit(desc_tx); + dmaengine_submit(desc_rx); + dmaengine_submit(desc_tx); spin_unlock_irqrestore(&data->lock, flags); /* reset transfer complete flag */
diff --git a/drivers/spi/spi-virtio.c b/drivers/spi/spi-virtio.c index 3e181bd..26f9711 100644 --- a/drivers/spi/spi-virtio.c +++ b/drivers/spi/spi-virtio.c
@@ -31,10 +31,6 @@ struct virtio_spi_priv { struct virtio_device *vdev; /* Pointer to the virtqueue */ struct virtqueue *vq; - /* Copy of config space mode_func_supported */ - u32 mode_func_supported; - /* Copy of config space max_freq_hz */ - u32 max_freq_hz; }; static void virtio_spi_msg_done(struct virtqueue *vq) @@ -162,8 +158,6 @@ static int virtio_spi_transfer_one(struct spi_controller *ctrl, if (!spi_req) return -ENOMEM; - init_completion(&spi_req->completion); - th = &spi_req->transfer_head; /* Fill struct spi_transfer_head */ @@ -258,7 +252,7 @@ static int virtio_spi_transfer_one(struct spi_controller *ctrl, static void virtio_spi_read_config(struct virtio_device *vdev) { struct spi_controller *ctrl = dev_get_drvdata(&vdev->dev); - struct virtio_spi_priv *priv = vdev->priv; + u32 mode_func_supported; u8 cs_max_number; u8 tx_nbits_supported; u8 rx_nbits_supported; @@ -268,18 +262,18 @@ static void virtio_spi_read_config(struct virtio_device *vdev) ctrl->num_chipselect = cs_max_number; /* Set the mode bits which are understood by this driver */ - priv->mode_func_supported = + mode_func_supported = virtio_cread32(vdev, offsetof(struct virtio_spi_config, mode_func_supported)); - ctrl->mode_bits = priv->mode_func_supported & + ctrl->mode_bits = mode_func_supported & (VIRTIO_SPI_CS_HIGH | VIRTIO_SPI_MODE_LSB_FIRST); - if (priv->mode_func_supported & VIRTIO_SPI_MF_SUPPORT_CPHA_1) + if (mode_func_supported & VIRTIO_SPI_MF_SUPPORT_CPHA_1) ctrl->mode_bits |= VIRTIO_SPI_CPHA; - if (priv->mode_func_supported & VIRTIO_SPI_MF_SUPPORT_CPOL_1) + if (mode_func_supported & VIRTIO_SPI_MF_SUPPORT_CPOL_1) ctrl->mode_bits |= VIRTIO_SPI_CPOL; - if (priv->mode_func_supported & VIRTIO_SPI_MF_SUPPORT_LSB_FIRST) + if (mode_func_supported & VIRTIO_SPI_MF_SUPPORT_LSB_FIRST) ctrl->mode_bits |= SPI_LSB_FIRST; - if (priv->mode_func_supported & VIRTIO_SPI_MF_SUPPORT_LOOPBACK) + if (mode_func_supported & VIRTIO_SPI_MF_SUPPORT_LOOPBACK) ctrl->mode_bits |= SPI_LOOP; tx_nbits_supported = virtio_cread8(vdev, offsetof(struct virtio_spi_config, @@ -304,7 +298,7 @@ static void virtio_spi_read_config(struct virtio_device *vdev) virtio_cread32(vdev, offsetof(struct virtio_spi_config, bits_per_word_mask)); - priv->max_freq_hz = + ctrl->max_speed_hz = virtio_cread32(vdev, offsetof(struct virtio_spi_config, max_freq_hz)); }
diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index dc1e968..df4ea99 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c
@@ -460,7 +460,7 @@ static int xilinx_spi_probe(struct platform_device *pdev) host->num_chipselect = num_cs; /* - * Detect endianess on the IP via loop bit in CR. Detection + * Detect endianness on the IP via loop bit in CR. Detection * must be done before reset is sent because incorrect reset * value generates error interrupt. * Setup little endian helper functions first and try to use them
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c index 5b5b3bc..40cda00 100644 --- a/drivers/spi/spi.c +++ b/drivers/spi/spi.c
@@ -930,6 +930,15 @@ static int __spi_add_device(struct spi_device *spi, struct spi_device *parent) } /* + * Peripheral properties the core handles on behalf of controller + * drivers are parsed here, rather than in the firmware specific + * instantiation paths, so that device tree, ACPI and software nodes + * are covered alike, and early enough for ->setup() to act on them. + */ + device_property_read_u32(&spi->dev, "rx-sample-delay-ns", + &spi->rx_sample_delay_ns); + + /* * Drivers may modify this initial i/o setup, but will * normally rely on the device being setup. Devices * using SPI_CS_HIGH can't coexist well otherwise... @@ -1456,14 +1465,14 @@ int __spi_map_msg(struct spi_controller *ctlr, struct spi_message *msg) return 0; if (ctlr->dma_tx) - tx_dev = ctlr->dma_tx->device->dev; + tx_dev = dmaengine_get_dma_device(ctlr->dma_tx); else if (ctlr->dma_map_dev) tx_dev = ctlr->dma_map_dev; else tx_dev = ctlr->dev.parent; if (ctlr->dma_rx) - rx_dev = ctlr->dma_rx->device->dev; + rx_dev = dmaengine_get_dma_device(ctlr->dma_rx); else if (ctlr->dma_map_dev) rx_dev = ctlr->dma_map_dev; else @@ -2893,7 +2902,7 @@ static void of_register_spi_devices(struct spi_controller *ctlr) { } * * This may only be called from main SPI device's probe routine. * - * Return: 0 on success; negative errno on failure + * Return: the new device on success; an ERR_PTR() on failure */ struct spi_device *spi_new_ancillary_device(struct spi_device *spi, u8 chip_select) @@ -2983,6 +2992,7 @@ EXPORT_SYMBOL_GPL(devm_spi_new_ancillary_device); #ifdef CONFIG_ACPI struct acpi_spi_lookup { struct spi_controller *ctlr; + acpi_handle device_handle; u32 max_speed_hz; u32 mode; int irq; @@ -3077,7 +3087,7 @@ static int acpi_spi_add_resource(struct acpi_resource *ares, void *data) if (lookup->index != -1 && lookup->n++ != lookup->index) return 1; - status = acpi_get_handle(NULL, + status = acpi_get_handle(lookup->device_handle, sb->resource_source.string_ptr, &parent_handle); @@ -3169,6 +3179,7 @@ struct spi_device *acpi_spi_device_alloc(struct spi_controller *ctlr, return ERR_PTR(-EINVAL); lookup.ctlr = ctlr; + lookup.device_handle = acpi_device_handle(adev); lookup.irq = -1; lookup.index = index; lookup.n = 0;
diff --git a/drivers/staging/greybus/sdio.c b/drivers/staging/greybus/sdio.c index 3952f3d..642d785 100644 --- a/drivers/staging/greybus/sdio.c +++ b/drivers/staging/greybus/sdio.c
@@ -767,17 +767,15 @@ static int gb_sdio_probe(struct gbphy_device *gbphy_dev, struct gb_sdio_host *host; int ret = 0; - mmc = mmc_alloc_host(sizeof(*host), &gbphy_dev->dev); + mmc = devm_mmc_alloc_host(&gbphy_dev->dev, sizeof(*host)); if (!mmc) return -ENOMEM; connection = gb_connection_create(gbphy_dev->bundle, le16_to_cpu(gbphy_dev->cport_desc->id), gb_sdio_request_handler); - if (IS_ERR(connection)) { - ret = PTR_ERR(connection); - goto exit_mmc_free; - } + if (IS_ERR(connection)) + return PTR_ERR(connection); host = mmc_priv(mmc); host->mmc = mmc; @@ -835,8 +833,6 @@ static int gb_sdio_probe(struct gbphy_device *gbphy_dev, gb_connection_disable(connection); exit_connection_destroy: gb_connection_destroy(connection); -exit_mmc_free: - mmc_free_host(mmc); return ret; } @@ -863,7 +859,6 @@ static void gb_sdio_remove(struct gbphy_device *gbphy_dev) mmc_remove_host(mmc); gb_connection_disable(connection); gb_connection_destroy(connection); - mmc_free_host(mmc); } static const struct gbphy_device_id gb_sdio_id_table[] = {
diff --git a/drivers/ufs/host/ufs-amd-versal2.c b/drivers/ufs/host/ufs-amd-versal2.c index 2154d62..dff0c2c 100644 --- a/drivers/ufs/host/ufs-amd-versal2.c +++ b/drivers/ufs/host/ufs-amd-versal2.c
@@ -225,8 +225,6 @@ static int ufs_versal2_setup_phy(struct ufs_hba *hba) static int ufs_versal2_phy_init(struct ufs_hba *hba) { struct ufs_versal2_host *host = ufshcd_get_variant(hba); - u32 time_left; - bool is_ready; int ret; static const struct ufshcd_dme_attr_val rmmi_attrs[] = { { UIC_ARG_MIB(CBREFCLKCTRL2), CBREFREFCLK_GATE_OVR_EN, DME_LOCAL }, @@ -235,23 +233,15 @@ static int ufs_versal2_phy_init(struct ufs_hba *hba) { UIC_ARG_MIB(VS_MPHYCFGUPDT), 1, DME_LOCAL } }; - /* Wait for Tx/Rx config_rdy */ - time_left = TIMEOUT_MICROSEC; - do { - time_left--; - ret = zynqmp_pm_is_mphy_tx_rx_config_ready(&is_ready); - if (ret) - return ret; - - if (!is_ready) - break; - - usleep_range(1, 5); - } while (time_left); - - if (!time_left) { + /* + * Wait for Tx/Rx config_rdy. The poll loop lives in the firmware + * backend (EEMI today, SCMI in future) so this driver stays + * backend-agnostic; the timeout budget stays here with the consumer. + */ + ret = zynqmp_pm_wait_mphy_tx_rx_config_ready(TIMEOUT_MICROSEC); + if (ret) { dev_err(hba->dev, "Tx/Rx configuration signal busy.\n"); - return -ETIMEDOUT; + return ret; } ret = ufshcd_dwc_dme_set_attrs(hba, rmmi_attrs, ARRAY_SIZE(rmmi_attrs)); @@ -264,23 +254,11 @@ static int ufs_versal2_phy_init(struct ufs_hba *hba) return ret; } - /* Wait for SRAM init done */ - time_left = TIMEOUT_MICROSEC; - do { - time_left--; - ret = zynqmp_pm_is_sram_init_done(&is_ready); - if (ret) - return ret; - - if (is_ready) - break; - - usleep_range(1, 5); - } while (time_left); - - if (!time_left) { + /* Wait for SRAM init done (poll handled by the firmware backend). */ + ret = zynqmp_pm_wait_sram_init_done(TIMEOUT_MICROSEC); + if (ret) { dev_err(hba->dev, "SRAM initialization failed.\n"); - return -ETIMEDOUT; + return ret; } ret = ufs_versal2_setup_phy(hba);
diff --git a/drivers/usb/host/fhci-hcd.c b/drivers/usb/host/fhci-hcd.c index 71e785f..d572f0c 100644 --- a/drivers/usb/host/fhci-hcd.c +++ b/drivers/usb/host/fhci-hcd.c
@@ -643,7 +643,7 @@ static int of_fhci_probe(struct platform_device *ofdev) } for (j = 0; j < NUM_PINS; j++) { - fhci->pins[j] = qe_pin_request(dev, j); + fhci->pins[j] = qe_pin_request(dev, fhci->gpiods[j]); if (IS_ERR(fhci->pins[j])) { ret = PTR_ERR(fhci->pins[j]); dev_err(dev, "can't get pin %d: %d\n", j, ret);
diff --git a/drivers/watchdog/acquirewdt.c b/drivers/watchdog/acquirewdt.c index 052f65c..cb62800 100644 --- a/drivers/watchdog/acquirewdt.c +++ b/drivers/watchdog/acquirewdt.c
@@ -64,6 +64,7 @@ #include <linux/init.h> /* For __init/__exit/... */ #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ #include <linux/io.h> /* For inb/outb/... */ +#include <linux/stringify.h> /* For __stringify */ /* Module information */ #define DRV_NAME "acquirewdt" @@ -92,7 +93,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* * Watchdog Operations
diff --git a/drivers/watchdog/advantech_ec_wdt.c b/drivers/watchdog/advantech_ec_wdt.c index 7c380f9..2470c43 100644 --- a/drivers/watchdog/advantech_ec_wdt.c +++ b/drivers/watchdog/advantech_ec_wdt.c
@@ -14,6 +14,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/moduleparam.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define DRIVER_NAME "advantech_ec_wdt" @@ -49,7 +50,7 @@ static ktime_t ec_timestamp; module_param(timeout, uint, 0); MODULE_PARM_DESC(timeout, - "Default Watchdog timer setting (" __MODULE_STRING(DEFAULT_TIME) "s). The range is from " __MODULE_STRING(MIN_TIME) " to " __MODULE_STRING(MAX_TIME) "."); + "Default Watchdog timer setting (" __stringify(DEFAULT_TIME) "s). The range is from " __stringify(MIN_TIME) " to " __stringify(MAX_TIME) "."); static void adv_ec_wdt_timing_gate(void) {
diff --git a/drivers/watchdog/advantechwdt.c b/drivers/watchdog/advantechwdt.c index 42d3f37..6d24a6b 100644 --- a/drivers/watchdog/advantechwdt.c +++ b/drivers/watchdog/advantechwdt.c
@@ -37,6 +37,7 @@ #include <linux/init.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> #define DRV_NAME "advantechwdt" @@ -71,13 +72,13 @@ static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=63, default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) "."); + __stringify(WATCHDOG_TIMEOUT) "."); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* * Watchdog Operations
diff --git a/drivers/watchdog/airoha_wdt.c b/drivers/watchdog/airoha_wdt.c index 4bd3331..c535c48 100644 --- a/drivers/watchdog/airoha_wdt.c +++ b/drivers/watchdog/airoha_wdt.c
@@ -20,6 +20,7 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/watchdog.h> +#include <linux/stringify.h> /* Base address of timer and watchdog registers */ #define TIMER_CTRL 0x0 @@ -44,12 +45,12 @@ struct airoha_wdt_desc { static int heartbeat = WDT_HEARTBEAT; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds. (default=" - __MODULE_STRING(WDT_HEARTBEAT) ")"); + __stringify(WDT_HEARTBEAT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static int airoha_wdt_start(struct watchdog_device *wdog_dev) {
diff --git a/drivers/watchdog/alim1535_wdt.c b/drivers/watchdog/alim1535_wdt.c index 1ecbd1a..d2f8d33 100644 --- a/drivers/watchdog/alim1535_wdt.c +++ b/drivers/watchdog/alim1535_wdt.c
@@ -18,6 +18,7 @@ #include <linux/pci.h> #include <linux/uaccess.h> #include <linux/io.h> +#include <linux/stringify.h> #define WATCHDOG_NAME "ALi_M1535" #define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ @@ -34,13 +35,13 @@ static int timeout = WATCHDOG_TIMEOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (0 < timeout < 18000, default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); + __stringify(WATCHDOG_TIMEOUT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* * ali_start - start watchdog countdown
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c index 03a559b..e9611c7 100644 --- a/drivers/watchdog/alim7101_wdt.c +++ b/drivers/watchdog/alim7101_wdt.c
@@ -36,6 +36,7 @@ #include <linux/pci.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> #define WDT_ENABLE 0x9C @@ -64,7 +65,7 @@ static int timeout = WATCHDOG_TIMEOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); + __stringify(WATCHDOG_TIMEOUT) ")"); static int use_gpio; /* Use the pic (for a1d revision alim7101) */ module_param(use_gpio, int, 0); @@ -82,7 +83,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* * Whack the dog
diff --git a/drivers/watchdog/arm_smc_wdt.c b/drivers/watchdog/arm_smc_wdt.c index bbba23a..c73ed1d 100644 --- a/drivers/watchdog/arm_smc_wdt.c +++ b/drivers/watchdog/arm_smc_wdt.c
@@ -13,6 +13,7 @@ #include <linux/moduleparam.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/types.h> #include <linux/watchdog.h> #include <uapi/linux/psci.h> @@ -191,7 +192,7 @@ MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Julius Werner <jwerner@chromium.org>");
diff --git a/drivers/watchdog/armada_37xx_wdt.c b/drivers/watchdog/armada_37xx_wdt.c index a17a791..d62b02c 100644 --- a/drivers/watchdog/armada_37xx_wdt.c +++ b/drivers/watchdog/armada_37xx_wdt.c
@@ -16,6 +16,7 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/regmap.h> +#include <linux/stringify.h> #include <linux/types.h> #include <linux/watchdog.h> @@ -70,7 +71,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct armada_37xx_watchdog { struct watchdog_device wdt;
diff --git a/drivers/watchdog/aspeed_wdt.c b/drivers/watchdog/aspeed_wdt.c index 48454ac..d4bd41c 100644 --- a/drivers/watchdog/aspeed_wdt.c +++ b/drivers/watchdog/aspeed_wdt.c
@@ -17,12 +17,13 @@ #include <linux/of_irq.h> #include <linux/platform_device.h> #include <linux/regmap.h> +#include <linux/stringify.h> #include <linux/watchdog.h> static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct aspeed_wdt_scu { const char *compatible; u32 reset_status_reg;
diff --git a/drivers/watchdog/at91rm9200_wdt.c b/drivers/watchdog/at91rm9200_wdt.c index d5afcc6..8c292d2 100644 --- a/drivers/watchdog/at91rm9200_wdt.c +++ b/drivers/watchdog/at91rm9200_wdt.c
@@ -23,6 +23,7 @@ #include <linux/platform_device.h> #include <linux/reboot.h> #include <linux/regmap.h> +#include <linux/stringify.h> #include <linux/types.h> #include <linux/watchdog.h> #include <linux/uaccess.h> @@ -36,13 +37,13 @@ static struct regmap *regmap_st; module_param(wdt_time, int, 0); MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default=" - __MODULE_STRING(WDT_DEFAULT_TIME) ")"); + __stringify(WDT_DEFAULT_TIME) ")"); #ifdef CONFIG_WATCHDOG_NOWAYOUT module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); #endif
diff --git a/drivers/watchdog/at91sam9_wdt.c b/drivers/watchdog/at91sam9_wdt.c index 80ba04d..f966da6 100644 --- a/drivers/watchdog/at91sam9_wdt.c +++ b/drivers/watchdog/at91sam9_wdt.c
@@ -32,6 +32,7 @@ #include <linux/uaccess.h> #include <linux/of.h> #include <linux/of_irq.h> +#include <linux/stringify.h> #include "at91sam9_wdt.h" @@ -70,12 +71,12 @@ static int heartbeat; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds. " - "(default = " __MODULE_STRING(WDT_HEARTBEAT) ")"); + "(default = " __stringify(WDT_HEARTBEAT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " - "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + "(default=" __stringify(WATCHDOG_NOWAYOUT) ")"); #define to_wdt(wdd) container_of(wdd, struct at91wdt, wdd) struct at91wdt {
diff --git a/drivers/watchdog/atcwdt200_wdt.c b/drivers/watchdog/atcwdt200_wdt.c index 7e757c2..ceedc3f 100644 --- a/drivers/watchdog/atcwdt200_wdt.c +++ b/drivers/watchdog/atcwdt200_wdt.c
@@ -19,6 +19,7 @@ #include <linux/pm.h> #include <linux/pm_runtime.h> #include <linux/regmap.h> +#include <linux/stringify.h> #include <linux/watchdog.h> /* Register definitions */ @@ -570,11 +571,11 @@ module_platform_driver(atcwdt_driver); module_param(timeout, uint, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=" - __MODULE_STRING(ATCWDT_TIMEOUT) ")"); + __stringify(ATCWDT_TIMEOUT) ")"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("CL Wang <cl634@andestech.com>");
diff --git a/drivers/watchdog/ath79_wdt.c b/drivers/watchdog/ath79_wdt.c index 7df703e..02783c1 100644 --- a/drivers/watchdog/ath79_wdt.c +++ b/drivers/watchdog/ath79_wdt.c
@@ -32,6 +32,7 @@ #include <linux/of.h> #include <linux/of_platform.h> #include <linux/uaccess.h> +#include <linux/stringify.h> #define DRIVER_NAME "ath79-wdt" @@ -50,12 +51,12 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " - "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + "(default=" __stringify(WATCHDOG_NOWAYOUT) ")"); static int timeout = WDT_TIMEOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds " - "(default=" __MODULE_STRING(WDT_TIMEOUT) "s)"); + "(default=" __stringify(WDT_TIMEOUT) "s)"); static unsigned long wdt_flags;
diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c index 6fd8b1b..1a0fc66 100644 --- a/drivers/watchdog/bcm2835_wdt.c +++ b/drivers/watchdog/bcm2835_wdt.c
@@ -20,6 +20,7 @@ #include <linux/of_address.h> #include <linux/of_platform.h> #include <linux/reboot.h> +#include <linux/stringify.h> #define PM_RSTC 0x1c #define PM_RSTS 0x20 @@ -229,7 +230,7 @@ MODULE_PARM_DESC(heartbeat, "Initial watchdog heartbeat in seconds"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); MODULE_ALIAS("platform:bcm2835-wdt"); MODULE_AUTHOR("Lubomir Rintel <lkundrak@v3.sk>");
diff --git a/drivers/watchdog/bcm47xx_wdt.c b/drivers/watchdog/bcm47xx_wdt.c index e13ec09..0d7e8a8 100644 --- a/drivers/watchdog/bcm47xx_wdt.c +++ b/drivers/watchdog/bcm47xx_wdt.c
@@ -21,6 +21,7 @@ #include <linux/watchdog.h> #include <linux/timer.h> #include <linux/jiffies.h> +#include <linux/stringify.h> #define DRV_NAME "bcm47xx_wdt" @@ -33,12 +34,12 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog time in seconds. (default=" - __MODULE_STRING(WDT_DEFAULT_TIME) ")"); + __stringify(WDT_DEFAULT_TIME) ")"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static inline struct bcm47xx_wdt *bcm47xx_wdt_get(struct watchdog_device *wdd) {
diff --git a/drivers/watchdog/bcm7038_wdt.c b/drivers/watchdog/bcm7038_wdt.c index e038dd6..1117026 100644 --- a/drivers/watchdog/bcm7038_wdt.c +++ b/drivers/watchdog/bcm7038_wdt.c
@@ -12,6 +12,7 @@ #include <linux/platform_device.h> #include <linux/platform_data/bcm7038_wdt.h> #include <linux/pm.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define WDT_START_1 0xff00 @@ -228,7 +229,7 @@ module_platform_driver(bcm7038_wdt_driver); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("Driver for Broadcom 7038 SoCs Watchdog"); MODULE_AUTHOR("Justin Chen");
diff --git a/drivers/watchdog/booke_wdt.c b/drivers/watchdog/booke_wdt.c index 1b1fb389..1224d17 100644 --- a/drivers/watchdog/booke_wdt.c +++ b/drivers/watchdog/booke_wdt.c
@@ -12,6 +12,7 @@ #include <linux/module.h> #include <linux/smp.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #include <asm/reg_booke.h> @@ -43,7 +44,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); #ifdef CONFIG_PPC_E500
diff --git a/drivers/watchdog/cadence_wdt.c b/drivers/watchdog/cadence_wdt.c index ad46b33..55a7c08 100644 --- a/drivers/watchdog/cadence_wdt.c +++ b/drivers/watchdog/cadence_wdt.c
@@ -15,6 +15,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define CDNS_WDT_DEFAULT_TIMEOUT 10 @@ -52,12 +53,12 @@ static int nowayout = WATCHDOG_NOWAYOUT; module_param(wdt_timeout, int, 0644); MODULE_PARM_DESC(wdt_timeout, "Watchdog time in seconds. (default=" - __MODULE_STRING(CDNS_WDT_DEFAULT_TIMEOUT) ")"); + __stringify(CDNS_WDT_DEFAULT_TIMEOUT) ")"); module_param(nowayout, int, 0644); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /** * struct cdns_wdt - Watchdog device structure @@ -359,7 +360,7 @@ static int cdns_wdt_probe(struct platform_device *pdev) * @dev: handle to the device structure. * Return: 0 always. */ -static int __maybe_unused cdns_wdt_suspend(struct device *dev) +static int cdns_wdt_suspend(struct device *dev) { struct cdns_wdt *wdt = dev_get_drvdata(dev); @@ -377,7 +378,7 @@ static int __maybe_unused cdns_wdt_suspend(struct device *dev) * @dev: handle to the device structure. * Return: 0 on success, errno otherwise. */ -static int __maybe_unused cdns_wdt_resume(struct device *dev) +static int cdns_wdt_resume(struct device *dev) { int ret; struct cdns_wdt *wdt = dev_get_drvdata(dev); @@ -394,7 +395,7 @@ static int __maybe_unused cdns_wdt_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(cdns_wdt_pm_ops, cdns_wdt_suspend, cdns_wdt_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(cdns_wdt_pm_ops, cdns_wdt_suspend, cdns_wdt_resume); static const struct of_device_id cdns_wdt_of_match[] = { { .compatible = "cdns,wdt-r1p2", }, @@ -408,7 +409,7 @@ static struct platform_driver cdns_wdt_driver = { .driver = { .name = "cdns-wdt", .of_match_table = cdns_wdt_of_match, - .pm = &cdns_wdt_pm_ops, + .pm = pm_sleep_ptr(&cdns_wdt_pm_ops), }, };
diff --git a/drivers/watchdog/cgbc_wdt.c b/drivers/watchdog/cgbc_wdt.c index 702b055..a90e6af 100644 --- a/drivers/watchdog/cgbc_wdt.c +++ b/drivers/watchdog/cgbc_wdt.c
@@ -11,6 +11,7 @@ #include <linux/limits.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #include <linux/mfd/cgbc.h> @@ -38,19 +39,19 @@ static unsigned int timeout; module_param(timeout, uint, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (>=0, default=" - __MODULE_STRING(CGBC_WDT_DEFAULT_TIMEOUT) ")"); + __stringify(CGBC_WDT_DEFAULT_TIMEOUT) ")"); static unsigned int pretimeout = CGBC_WDT_DEFAULT_PRETIMEOUT; module_param(pretimeout, uint, 0); MODULE_PARM_DESC(pretimeout, "Watchdog pretimeout in seconds. (>=0, default=" - __MODULE_STRING(CGBC_WDT_DEFAULT_PRETIMEOUT) ")"); + __stringify(CGBC_WDT_DEFAULT_PRETIMEOUT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct cgbc_wdt_data { struct cgbc_device_data *cgbc;
diff --git a/drivers/watchdog/da9052_wdt.c b/drivers/watchdog/da9052_wdt.c index afb7887c..959cba0 100644 --- a/drivers/watchdog/da9052_wdt.c +++ b/drivers/watchdog/da9052_wdt.c
@@ -17,6 +17,7 @@ #include <linux/types.h> #include <linux/kernel.h> #include <linux/jiffies.h> +#include <linux/stringify.h> #include <linux/mfd/da9052/reg.h> #include <linux/mfd/da9052/da9052.h> @@ -34,13 +35,13 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static int timeout; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (default = " - __MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")"); + __stringify(WDT_DEFAULT_TIMEOUT) ")"); static const struct { u8 reg_val;
diff --git a/drivers/watchdog/da9055_wdt.c b/drivers/watchdog/da9055_wdt.c index 9d5a2009..cbb8785 100644 --- a/drivers/watchdog/da9055_wdt.c +++ b/drivers/watchdog/da9055_wdt.c
@@ -15,6 +15,7 @@ #include <linux/platform_device.h> #include <linux/watchdog.h> #include <linux/delay.h> +#include <linux/stringify.h> #include <linux/mfd/da9055/core.h> #include <linux/mfd/da9055/reg.h> @@ -23,7 +24,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); #define DA9055_DEF_TIMEOUT 4 #define DA9055_TWDMIN 256
diff --git a/drivers/watchdog/da9062_wdt.c b/drivers/watchdog/da9062_wdt.c index 4d55865..3d7bf2f 100644 --- a/drivers/watchdog/da9062_wdt.c +++ b/drivers/watchdog/da9062_wdt.c
@@ -248,7 +248,7 @@ static int da9062_wdt_probe(struct platform_device *pdev) return devm_watchdog_register_device(dev, &wdt->wdtdev); } -static int __maybe_unused da9062_wdt_suspend(struct device *dev) +static int da9062_wdt_suspend(struct device *dev) { struct watchdog_device *wdd = dev_get_drvdata(dev); struct da9062_watchdog *wdt = watchdog_get_drvdata(wdd); @@ -262,7 +262,7 @@ static int __maybe_unused da9062_wdt_suspend(struct device *dev) return 0; } -static int __maybe_unused da9062_wdt_resume(struct device *dev) +static int da9062_wdt_resume(struct device *dev) { struct watchdog_device *wdd = dev_get_drvdata(dev); struct da9062_watchdog *wdt = watchdog_get_drvdata(wdd); @@ -276,14 +276,14 @@ static int __maybe_unused da9062_wdt_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(da9062_wdt_pm_ops, +static DEFINE_SIMPLE_DEV_PM_OPS(da9062_wdt_pm_ops, da9062_wdt_suspend, da9062_wdt_resume); static struct platform_driver da9062_wdt_driver = { .probe = da9062_wdt_probe, .driver = { .name = "da9062-watchdog", - .pm = &da9062_wdt_pm_ops, + .pm = pm_sleep_ptr(&da9062_wdt_pm_ops), .of_match_table = da9062_compatible_id_table, }, };
diff --git a/drivers/watchdog/davinci_wdt.c b/drivers/watchdog/davinci_wdt.c index 6ea0434..074e95c 100644 --- a/drivers/watchdog/davinci_wdt.c +++ b/drivers/watchdog/davinci_wdt.c
@@ -19,6 +19,7 @@ #include <linux/device.h> #include <linux/clk.h> #include <linux/err.h> +#include <linux/stringify.h> #define MODULE_NAME "DAVINCI-WDT: " @@ -120,7 +121,7 @@ static unsigned int davinci_wdt_get_timeleft(struct watchdog_device *wdd) u32 val; struct davinci_wdt_device *davinci_wdt = watchdog_get_drvdata(wdd); - /* if timeout has occured then return 0 */ + /* if timeout has occurred then return 0 */ val = ioread32(davinci_wdt->base + WDTCR); if (val & WDFLAG) return 0; @@ -250,8 +251,8 @@ MODULE_DESCRIPTION("DaVinci Watchdog Driver"); module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat period in seconds from 1 to " - __MODULE_STRING(MAX_HEARTBEAT) ", default " - __MODULE_STRING(DEFAULT_HEARTBEAT)); + __stringify(MAX_HEARTBEAT) ", default " + __stringify(DEFAULT_HEARTBEAT)); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:davinci-wdt");
diff --git a/drivers/watchdog/db8500_wdt.c b/drivers/watchdog/db8500_wdt.c index 70ccea1..7e11c28 100644 --- a/drivers/watchdog/db8500_wdt.c +++ b/drivers/watchdog/db8500_wdt.c
@@ -15,6 +15,7 @@ #include <linux/uaccess.h> #include <linux/watchdog.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/mfd/db8500-prcmu.h> @@ -27,13 +28,13 @@ static unsigned int timeout = WATCHDOG_TIMEOUT; module_param(timeout, uint, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) "."); + __stringify(WATCHDOG_TIMEOUT) "."); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static int db8500_wdt_start(struct watchdog_device *wdd) {
diff --git a/drivers/watchdog/dw_wdt.c b/drivers/watchdog/dw_wdt.c index 3903144..c1d40d7 100644 --- a/drivers/watchdog/dw_wdt.c +++ b/drivers/watchdog/dw_wdt.c
@@ -27,6 +27,7 @@ #include <linux/platform_device.h> #include <linux/pm.h> #include <linux/reset.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define WDOG_CONTROL_REG_OFFSET 0x00 @@ -66,7 +67,7 @@ static const u32 dw_wdt_fix_tops[DW_WDT_NUM_TOPS] = { static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " - "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + "(default=" __stringify(WATCHDOG_NOWAYOUT) ")"); enum dw_wdt_rmod { DW_WDT_RMOD_RESET = 1,
diff --git a/drivers/watchdog/ebc-c384_wdt.c b/drivers/watchdog/ebc-c384_wdt.c index 8ef4b0d..39cc1f7 100644 --- a/drivers/watchdog/ebc-c384_wdt.c +++ b/drivers/watchdog/ebc-c384_wdt.c
@@ -13,6 +13,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/types.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define MODULE_NAME "ebc-c384_wdt" @@ -30,12 +31,12 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static unsigned timeout; module_param(timeout, uint, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); + __stringify(WATCHDOG_TIMEOUT) ")"); static int ebc_c384_wdt_start(struct watchdog_device *wdev) {
diff --git a/drivers/watchdog/eurotechwdt.c b/drivers/watchdog/eurotechwdt.c index 10c647b..4d671c4 100644 --- a/drivers/watchdog/eurotechwdt.c +++ b/drivers/watchdog/eurotechwdt.c
@@ -56,6 +56,7 @@ #include <linux/init.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> static unsigned long eurwdt_is_open; @@ -77,7 +78,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* * Some symbolic names
diff --git a/drivers/watchdog/exar_wdt.c b/drivers/watchdog/exar_wdt.c index db62c97..553be15 100644 --- a/drivers/watchdog/exar_wdt.c +++ b/drivers/watchdog/exar_wdt.c
@@ -14,6 +14,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/slab.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define DRV_NAME "exar_wdt" @@ -70,13 +71,13 @@ static int timeout = WATCHDOG_TIMEOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<=timeout<=15300, default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) "."); + __stringify(WATCHDOG_TIMEOUT) "."); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static int exar_sio_enter(const unsigned short config_port, const unsigned char key)
diff --git a/drivers/watchdog/f71808e_wdt.c b/drivers/watchdog/f71808e_wdt.c index 6a16d3d..2790061 100644 --- a/drivers/watchdog/f71808e_wdt.c +++ b/drivers/watchdog/f71808e_wdt.c
@@ -14,6 +14,7 @@ #include <linux/ioport.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define DRVNAME "f71808e_wdt" @@ -81,20 +82,20 @@ static int timeout = WATCHDOG_TIMEOUT; /* default timeout in seconds */ module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=" - __MODULE_STRING(WATCHDOG_MAX_TIMEOUT) " (default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); + __stringify(WATCHDOG_MAX_TIMEOUT) " (default=" + __stringify(WATCHDOG_TIMEOUT) ")"); static unsigned int pulse_width = WATCHDOG_PULSE_WIDTH; module_param(pulse_width, uint, 0); MODULE_PARM_DESC(pulse_width, "Watchdog signal pulse width. 0(=level), 1, 25, 30, 125, 150, 5000 or 6000 ms" - " (default=" __MODULE_STRING(WATCHDOG_PULSE_WIDTH) ")"); + " (default=" __stringify(WATCHDOG_PULSE_WIDTH) ")"); static unsigned int f71862fg_pin = WATCHDOG_F71862FG_PIN; module_param(f71862fg_pin, uint, 0); MODULE_PARM_DESC(f71862fg_pin, "Watchdog f71862fg reset output pin configuration. Choose pin 56 or 63" - " (default=" __MODULE_STRING(WATCHDOG_F71862FG_PIN)")"); + " (default=" __stringify(WATCHDOG_F71862FG_PIN)")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0444);
diff --git a/drivers/watchdog/gef_wdt.c b/drivers/watchdog/gef_wdt.c index bf6f733..4d39588a 100644 --- a/drivers/watchdog/gef_wdt.c +++ b/drivers/watchdog/gef_wdt.c
@@ -34,6 +34,7 @@ #include <linux/platform_device.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> #include <sysdev/fsl_soc.h> @@ -70,7 +71,7 @@ static DEFINE_SPINLOCK(gef_wdt_spinlock); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static int gef_wdt_toggle_wdc(int enabled_predicate, int field_shift)
diff --git a/drivers/watchdog/geodewdt.c b/drivers/watchdog/geodewdt.c index 5b80ade..437cc0a 100644 --- a/drivers/watchdog/geodewdt.c +++ b/drivers/watchdog/geodewdt.c
@@ -16,6 +16,7 @@ #include <linux/platform_device.h> #include <linux/reboot.h> #include <linux/uaccess.h> +#include <linux/stringify.h> #include <linux/cs5535.h> @@ -34,13 +35,13 @@ static int timeout = WATCHDOG_TIMEOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=131, default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) "."); + __stringify(WATCHDOG_TIMEOUT) "."); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static struct platform_device *geodewdt_platform_device; static unsigned long wdt_flags;
diff --git a/drivers/watchdog/gpio_wdt.c b/drivers/watchdog/gpio_wdt.c index 1abc7d0..2cd79c8 100644 --- a/drivers/watchdog/gpio_wdt.c +++ b/drivers/watchdog/gpio_wdt.c
@@ -11,13 +11,14 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/property.h> +#include <linux/stringify.h> #include <linux/watchdog.h> static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); #define SOFT_TIMEOUT_MIN 1 #define SOFT_TIMEOUT_DEF 60
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c index 8af1fad..7b9eb4e 100644 --- a/drivers/watchdog/hpwdt.c +++ b/drivers/watchdog/hpwdt.c
@@ -20,6 +20,7 @@ #include <linux/pci.h> #include <linux/pci_ids.h> #include <linux/types.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #ifdef CONFIG_HPWDT_NMI_DECODING #include <asm/nmi.h> @@ -432,7 +433,7 @@ MODULE_PARM_DESC(timeout, "Alias of soft_margin"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); module_param(kdumptimeout, int, 0444); MODULE_PARM_DESC(kdumptimeout, "Timeout applied for crash kernel transition in seconds");
diff --git a/drivers/watchdog/i6300esb.c b/drivers/watchdog/i6300esb.c index a30835f..7f08d6d 100644 --- a/drivers/watchdog/i6300esb.c +++ b/drivers/watchdog/i6300esb.c
@@ -37,6 +37,7 @@ #include <linux/ioport.h> #include <linux/uaccess.h> #include <linux/io.h> +#include <linux/stringify.h> /* Module and version information */ #define ESB_MODULE_NAME "i6300ESB timer" @@ -74,19 +75,19 @@ #define ESB_HEARTBEAT_MIN 1 #define ESB_HEARTBEAT_MAX 2046 #define ESB_HEARTBEAT_DEFAULT 30 -#define ESB_HEARTBEAT_RANGE __MODULE_STRING(ESB_HEARTBEAT_MIN) \ - "<heartbeat<" __MODULE_STRING(ESB_HEARTBEAT_MAX) +#define ESB_HEARTBEAT_RANGE __stringify(ESB_HEARTBEAT_MIN) \ + "<heartbeat<" __stringify(ESB_HEARTBEAT_MAX) static int heartbeat; /* in seconds */ module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (" ESB_HEARTBEAT_RANGE - ", default=" __MODULE_STRING(ESB_HEARTBEAT_DEFAULT) ")"); + ", default=" __stringify(ESB_HEARTBEAT_DEFAULT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* internal variables */ struct esb_dev { @@ -264,13 +265,21 @@ static void esb_initdevice(struct esb_dev *edev) */ pci_write_config_word(edev->pdev, ESB_CONFIG_REG, 0x0003); - /* Check that the WDT isn't already locked */ + /* Check the current state of the WDT */ pci_read_config_byte(edev->pdev, ESB_LOCK_REG, &val1); if (val1 & ESB_WDT_LOCK) dev_warn(&edev->pdev->dev, "nowayout already set\n"); - /* Set the timer to watchdog mode and disable it for now */ - pci_write_config_byte(edev->pdev, ESB_LOCK_REG, 0x00); + if (val1 & ESB_WDT_ENABLE) { + /* + * The watchdog is already running, e.g. enabled by + * firmware. Do not stop it, just mark it as running. + */ + set_bit(WDOG_HW_RUNNING, &edev->wdd.status); + } else { + /* Set the timer to watchdog mode and disable it for now */ + pci_write_config_byte(edev->pdev, ESB_LOCK_REG, 0x00); + } /* Check if the watchdog was previously triggered */ esb_unlock_registers(edev); @@ -301,7 +310,10 @@ static int esb_probe(struct pci_dev *pdev, if (!esb_getdevice(edev)) return -ENODEV; - /* Initialize the watchdog and make sure it does not run */ + /* + * Initialize the watchdog, keeping it running if it was already + * started, e.g. by firmware. + */ edev->wdd.info = &esb_info; edev->wdd.ops = &esb_ops; edev->wdd.min_timeout = ESB_HEARTBEAT_MIN;
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 1dec9cd..0a8bf28 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c
@@ -60,6 +60,7 @@ #include <linux/ioport.h> /* For io-port access */ #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ #include <linux/io.h> /* For inb/outb/... */ +#include <linux/stringify.h> /* For __stringify */ #include <linux/platform_data/itco_wdt.h> #include <linux/mfd/intel_pmc_bxt.h> @@ -115,13 +116,13 @@ static int heartbeat = WATCHDOG_TIMEOUT; /* in seconds */ module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog timeout in seconds. " "5..76 (TCO v1) or 3..614 (TCO v2), default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); + __stringify(WATCHDOG_TIMEOUT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static int turn_SMI_watchdog_clear_off = 1; module_param(turn_SMI_watchdog_clear_off, int, 0);
diff --git a/drivers/watchdog/ib700wdt.c b/drivers/watchdog/ib700wdt.c index 5ce6101..3806d86 100644 --- a/drivers/watchdog/ib700wdt.c +++ b/drivers/watchdog/ib700wdt.c
@@ -41,6 +41,7 @@ #include <linux/platform_device.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> static struct platform_device *ibwdt_platform_device; @@ -96,13 +97,13 @@ static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 0<= timeout <=30, default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) "."); + __stringify(WATCHDOG_TIMEOUT) "."); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /*
diff --git a/drivers/watchdog/ibmasr.c b/drivers/watchdog/ibmasr.c index cf845f8..53bd84e 100644 --- a/drivers/watchdog/ibmasr.c +++ b/drivers/watchdog/ibmasr.c
@@ -21,6 +21,7 @@ #include <linux/dmi.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> enum { @@ -413,7 +414,7 @@ module_exit(ibmasr_exit); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); MODULE_DESCRIPTION("IBM Automatic Server Restart driver"); MODULE_AUTHOR("Andrey Panin");
diff --git a/drivers/watchdog/ie6xx_wdt.c b/drivers/watchdog/ie6xx_wdt.c index 5a7bb7e..eda515b 100644 --- a/drivers/watchdog/ie6xx_wdt.c +++ b/drivers/watchdog/ie6xx_wdt.c
@@ -17,6 +17,7 @@ #include <linux/debugfs.h> #include <linux/uaccess.h> #include <linux/spinlock.h> +#include <linux/stringify.h> #define DRIVER_NAME "ie6xx_wdt" @@ -49,14 +50,14 @@ static unsigned int timeout = DEFAULT_TIME; module_param(timeout, uint, 0); MODULE_PARM_DESC(timeout, "Default Watchdog timer setting (" - __MODULE_STRING(DEFAULT_TIME) "s)." + __stringify(DEFAULT_TIME) "s)." "The range is from 1 to 600"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static u8 resetmode = 0x10; module_param(resetmode, byte, 0);
diff --git a/drivers/watchdog/imgpdc_wdt.c b/drivers/watchdog/imgpdc_wdt.c index 65cc839..bb6227c 100644 --- a/drivers/watchdog/imgpdc_wdt.c +++ b/drivers/watchdog/imgpdc_wdt.c
@@ -43,6 +43,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/slab.h> +#include <linux/stringify.h> #include <linux/watchdog.h> /* registers */ @@ -71,12 +72,12 @@ static int heartbeat; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds " - "(default=" __MODULE_STRING(PDC_WDT_DEF_TIMEOUT) ")"); + "(default=" __stringify(PDC_WDT_DEF_TIMEOUT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " - "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + "(default=" __stringify(WATCHDOG_NOWAYOUT) ")"); struct pdc_wdt_dev { struct watchdog_device wdt_dev;
diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c index 4b3a192..58aa5f9 100644 --- a/drivers/watchdog/imx2_wdt.c +++ b/drivers/watchdog/imx2_wdt.c
@@ -29,6 +29,7 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/regmap.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define DRIVER_NAME "imx2-wdt" @@ -79,12 +80,12 @@ struct imx2_wdt_device { static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static unsigned timeout; module_param(timeout, uint, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=" - __MODULE_STRING(IMX2_WDT_DEFAULT_TIME) ")"); + __stringify(IMX2_WDT_DEFAULT_TIME) ")"); static const struct watchdog_info imx2_wdt_info = { .identity = "imx2+ watchdog",
diff --git a/drivers/watchdog/imx7ulp_wdt.c b/drivers/watchdog/imx7ulp_wdt.c index 855dc9d..f619361 100644 --- a/drivers/watchdog/imx7ulp_wdt.c +++ b/drivers/watchdog/imx7ulp_wdt.c
@@ -11,6 +11,7 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/reboot.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define WDOG_CS 0x0 @@ -51,7 +52,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0000); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct imx_wdt_hw_feature { bool prescaler_enable;
diff --git a/drivers/watchdog/imx_sc_wdt.c b/drivers/watchdog/imx_sc_wdt.c index 1280b9b..fc39f9db 100644 --- a/drivers/watchdog/imx_sc_wdt.c +++ b/drivers/watchdog/imx_sc_wdt.c
@@ -11,6 +11,7 @@ #include <linux/moduleparam.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define DEFAULT_TIMEOUT 60 @@ -39,7 +40,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0000); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct imx_sc_wdt_device { struct watchdog_device wdd;
diff --git a/drivers/watchdog/indydog.c b/drivers/watchdog/indydog.c index d3092d2..5268b1f 100644 --- a/drivers/watchdog/indydog.c +++ b/drivers/watchdog/indydog.c
@@ -22,6 +22,7 @@ #include <linux/reboot.h> #include <linux/init.h> #include <linux/uaccess.h> +#include <linux/stringify.h> #include <asm/sgi/mc.h> static unsigned long indydog_alive; @@ -33,7 +34,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static void indydog_start(void) {
diff --git a/drivers/watchdog/intel_oc_wdt.c b/drivers/watchdog/intel_oc_wdt.c index a39892c..d1e9a3f 100644 --- a/drivers/watchdog/intel_oc_wdt.c +++ b/drivers/watchdog/intel_oc_wdt.c
@@ -14,6 +14,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define INTEL_OC_WDT_TOV GENMASK(9, 0) @@ -48,12 +49,12 @@ struct intel_oc_wdt { static int heartbeat; module_param(heartbeat, uint, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds. (default=" - __MODULE_STRING(WDT_HEARTBEAT) ")"); + __stringify(WDT_HEARTBEAT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static int intel_oc_wdt_start(struct watchdog_device *wdd) {
diff --git a/drivers/watchdog/it87_wdt.c b/drivers/watchdog/it87_wdt.c index 1d9f859..087250a 100644 --- a/drivers/watchdog/it87_wdt.c +++ b/drivers/watchdog/it87_wdt.c
@@ -29,6 +29,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/printk.h> +#include <linux/stringify.h> #include <linux/types.h> #include <linux/watchdog.h> @@ -105,13 +106,13 @@ static bool nowayout = DEFAULT_NOWAYOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds, default=" - __MODULE_STRING(DEFAULT_TIMEOUT)); + __stringify(DEFAULT_TIMEOUT)); module_param(testmode, int, 0); MODULE_PARM_DESC(testmode, "Watchdog test mode (1 = no reboot), default=" - __MODULE_STRING(DEFAULT_TESTMODE)); + __stringify(DEFAULT_TESTMODE)); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started, default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT)); + __stringify(WATCHDOG_NOWAYOUT)); /* Superio Chip */
diff --git a/drivers/watchdog/jz4740_wdt.c b/drivers/watchdog/jz4740_wdt.c index 395bde7..9dec1b8 100644 --- a/drivers/watchdog/jz4740_wdt.c +++ b/drivers/watchdog/jz4740_wdt.c
@@ -19,6 +19,7 @@ #include <linux/err.h> #include <linux/of.h> #include <linux/regmap.h> +#include <linux/stringify.h> #define DEFAULT_HEARTBEAT 5 #define MAX_HEARTBEAT 2048 @@ -27,14 +28,14 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static unsigned int heartbeat = DEFAULT_HEARTBEAT; module_param(heartbeat, uint, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat period in seconds from 1 to " - __MODULE_STRING(MAX_HEARTBEAT) ", default " - __MODULE_STRING(DEFAULT_HEARTBEAT)); + __stringify(MAX_HEARTBEAT) ", default " + __stringify(DEFAULT_HEARTBEAT)); struct jz4740_wdt_drvdata { struct watchdog_device wdt;
diff --git a/drivers/watchdog/keembay_wdt.c b/drivers/watchdog/keembay_wdt.c index 7c8e539..76246a7 100644 --- a/drivers/watchdog/keembay_wdt.c +++ b/drivers/watchdog/keembay_wdt.c
@@ -14,6 +14,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/reboot.h> +#include <linux/stringify.h> #include <linux/watchdog.h> /* Non-secure watchdog register offsets */ @@ -39,12 +40,12 @@ static unsigned int timeout = WDT_TIMEOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout period in seconds (default = " - __MODULE_STRING(WDT_TIMEOUT) ")"); + __stringify(WDT_TIMEOUT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default = " - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct keembay_wdt { struct watchdog_device wdd; @@ -250,7 +251,7 @@ static int keembay_wdt_probe(struct platform_device *pdev) return 0; } -static int __maybe_unused keembay_wdt_suspend(struct device *dev) +static int keembay_wdt_suspend(struct device *dev) { struct keembay_wdt *wdt = dev_get_drvdata(dev); @@ -260,7 +261,7 @@ static int __maybe_unused keembay_wdt_suspend(struct device *dev) return 0; } -static int __maybe_unused keembay_wdt_resume(struct device *dev) +static int keembay_wdt_resume(struct device *dev) { struct keembay_wdt *wdt = dev_get_drvdata(dev); @@ -270,7 +271,7 @@ static int __maybe_unused keembay_wdt_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(keembay_wdt_pm_ops, keembay_wdt_suspend, +static DEFINE_SIMPLE_DEV_PM_OPS(keembay_wdt_pm_ops, keembay_wdt_suspend, keembay_wdt_resume); static const struct of_device_id keembay_wdt_match[] = { @@ -284,7 +285,7 @@ static struct platform_driver keembay_wdt_driver = { .driver = { .name = "keembay_wdt", .of_match_table = keembay_wdt_match, - .pm = &keembay_wdt_pm_ops, + .pm = pm_sleep_ptr(&keembay_wdt_pm_ops), }, };
diff --git a/drivers/watchdog/kempld_wdt.c b/drivers/watchdog/kempld_wdt.c index e6c7a29..b4cde48 100644 --- a/drivers/watchdog/kempld_wdt.c +++ b/drivers/watchdog/kempld_wdt.c
@@ -21,6 +21,7 @@ #include <linux/uaccess.h> #include <linux/watchdog.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/mfd/kempld.h> #define KEMPLD_WDT_STAGE_TIMEOUT(x) (0x1b + (x) * 4) @@ -85,19 +86,19 @@ static unsigned int timeout = DEFAULT_TIMEOUT; module_param(timeout, uint, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (>=0, default=" - __MODULE_STRING(DEFAULT_TIMEOUT) ")"); + __stringify(DEFAULT_TIMEOUT) ")"); static unsigned int pretimeout = DEFAULT_PRETIMEOUT; module_param(pretimeout, uint, 0); MODULE_PARM_DESC(pretimeout, "Watchdog pretimeout in seconds. (>=0, default=" - __MODULE_STRING(DEFAULT_PRETIMEOUT) ")"); + __stringify(DEFAULT_PRETIMEOUT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static int kempld_wdt_set_stage_action(struct kempld_wdt_data *wdt_data, struct kempld_wdt_stage *stage,
diff --git a/drivers/watchdog/lenovo_se10_wdt.c b/drivers/watchdog/lenovo_se10_wdt.c index 503e220..1eaf86c 100644 --- a/drivers/watchdog/lenovo_se10_wdt.c +++ b/drivers/watchdog/lenovo_se10_wdt.c
@@ -10,6 +10,7 @@ #include <linux/moduleparam.h> #include <linux/platform_device.h> #include <linux/string.h> +#include <linux/stringify.h> #include <linux/types.h> #include <linux/watchdog.h> @@ -48,13 +49,13 @@ static int timeout; /* in seconds */ module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1 <= timeout <= 255, default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) "."); + __stringify(WATCHDOG_TIMEOUT) "."); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct se10_wdt { struct watchdog_device wdd;
diff --git a/drivers/watchdog/lenovo_se30_wdt.c b/drivers/watchdog/lenovo_se30_wdt.c index 1c73bb7..127ea9a 100644 --- a/drivers/watchdog/lenovo_se30_wdt.c +++ b/drivers/watchdog/lenovo_se30_wdt.c
@@ -13,6 +13,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define IOREGION_OFFSET 4 /* Use EC port 1 */ @@ -28,13 +29,13 @@ static int timeout; /* in seconds */ module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1 <= timeout <= 255, default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) "."); + __stringify(WATCHDOG_TIMEOUT) "."); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); #define LNV_SE30_NAME "lenovo-se30-wdt" #define LNV_SE30_ID 0x0110
diff --git a/drivers/watchdog/lenovo_se30g2_se60_wdt.c b/drivers/watchdog/lenovo_se30g2_se60_wdt.c index f31ecdb..c87abdb 100644 --- a/drivers/watchdog/lenovo_se30g2_se60_wdt.c +++ b/drivers/watchdog/lenovo_se30g2_se60_wdt.c
@@ -10,6 +10,7 @@ #include <linux/moduleparam.h> #include <linux/platform_device.h> #include <linux/string.h> +#include <linux/stringify.h> #include <linux/types.h> #include <linux/watchdog.h> @@ -37,13 +38,13 @@ static int timeout; /* in seconds */ module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1 <= timeout <= 255, default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) "."); + __stringify(WATCHDOG_TIMEOUT) "."); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct se_30g2_60_wdt { struct watchdog_device wdd;
diff --git a/drivers/watchdog/loongson1_wdt.c b/drivers/watchdog/loongson1_wdt.c index 2417519..7f8de11 100644 --- a/drivers/watchdog/loongson1_wdt.c +++ b/drivers/watchdog/loongson1_wdt.c
@@ -9,6 +9,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/watchdog.h> /* Loongson Watchdog Register Definitions */ @@ -19,12 +20,12 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static unsigned int heartbeat; module_param(heartbeat, uint, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (default=" - __MODULE_STRING(DEFAULT_HEARTBEAT) ")"); + __stringify(DEFAULT_HEARTBEAT) ")"); struct ls1x_wdt_pdata { u32 timer_offset;
diff --git a/drivers/watchdog/lpc18xx_wdt.c b/drivers/watchdog/lpc18xx_wdt.c index 3e8e80b..633119e 100644 --- a/drivers/watchdog/lpc18xx_wdt.c +++ b/drivers/watchdog/lpc18xx_wdt.c
@@ -15,6 +15,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/watchdog.h> /* Registers */ @@ -41,12 +42,12 @@ static int heartbeat; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds (default=" - __MODULE_STRING(LPC18XX_WDT_DEF_TIMEOUT) ")"); + __stringify(LPC18XX_WDT_DEF_TIMEOUT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct lpc18xx_wdt_dev { struct watchdog_device wdt_dev;
diff --git a/drivers/watchdog/ma35d1_wdt.c b/drivers/watchdog/ma35d1_wdt.c index 119d58f..ede4bee 100644 --- a/drivers/watchdog/ma35d1_wdt.c +++ b/drivers/watchdog/ma35d1_wdt.c
@@ -20,6 +20,7 @@ #include <linux/platform_device.h> #include <linux/pm_wakeirq.h> #include <linux/property.h> +#include <linux/stringify.h> #include <linux/types.h> #include <linux/watchdog.h> @@ -355,7 +356,7 @@ MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds"); module_param(nowayout, bool, 0); MODULE_PARM_DESC( nowayout, - "Watchdog cannot be stopped once started (default=" __MODULE_STRING( + "Watchdog cannot be stopped once started (default=" __stringify( WATCHDOG_NOWAYOUT) ")"); MODULE_AUTHOR("Zi-Yu Chen <zychennvt@gmail.com>");
diff --git a/drivers/watchdog/max63xx_wdt.c b/drivers/watchdog/max63xx_wdt.c index e9073df..17b19df 100644 --- a/drivers/watchdog/max63xx_wdt.c +++ b/drivers/watchdog/max63xx_wdt.c
@@ -23,6 +23,7 @@ #include <linux/io.h> #include <linux/slab.h> #include <linux/property.h> +#include <linux/stringify.h> #define DEFAULT_HEARTBEAT 60 #define MAX_HEARTBEAT 60 @@ -64,7 +65,7 @@ struct max63xx_wdt { * delay (selected with the "nodelay" parameter). * * I also decided to remove from the tables any timeout smaller than a - * second, as it looked completly overkill... + * second, as it looked completely overkill... */ /* Timeouts in second */ @@ -283,12 +284,12 @@ MODULE_DESCRIPTION("max63xx Watchdog Driver"); module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat period in seconds from 1 to " - __MODULE_STRING(MAX_HEARTBEAT) ", default " - __MODULE_STRING(DEFAULT_HEARTBEAT)); + __stringify(MAX_HEARTBEAT) ", default " + __stringify(DEFAULT_HEARTBEAT)); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); module_param(nodelay, int, 0); MODULE_PARM_DESC(nodelay,
diff --git a/drivers/watchdog/max77620_wdt.c b/drivers/watchdog/max77620_wdt.c index ed5a98c..79148cb 100644 --- a/drivers/watchdog/max77620_wdt.c +++ b/drivers/watchdog/max77620_wdt.c
@@ -18,6 +18,7 @@ #include <linux/platform_device.h> #include <linux/regmap.h> #include <linux/slab.h> +#include <linux/stringify.h> #include <linux/watchdog.h> static bool nowayout = WATCHDOG_NOWAYOUT; @@ -255,7 +256,7 @@ MODULE_DESCRIPTION("Max77620 watchdog timer driver"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " - "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + "(default=" __stringify(WATCHDOG_NOWAYOUT) ")"); MODULE_AUTHOR("Laxman Dewangan <ldewangan@nvidia.com>"); MODULE_AUTHOR("Luca Ceresoli <luca.ceresoli@bootlin.com>");
diff --git a/drivers/watchdog/mena21_wdt.c b/drivers/watchdog/mena21_wdt.c index 99d2359..a762462 100644 --- a/drivers/watchdog/mena21_wdt.c +++ b/drivers/watchdog/mena21_wdt.c
@@ -17,6 +17,7 @@ #include <linux/delay.h> #include <linux/bitops.h> #include <linux/of.h> +#include <linux/stringify.h> #define NUM_GPIOS 6 @@ -37,7 +38,7 @@ struct a21_wdt_drv { static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static unsigned int a21_wdt_get_bootstatus(struct a21_wdt_drv *drv) {
diff --git a/drivers/watchdog/menf21bmc_wdt.c b/drivers/watchdog/menf21bmc_wdt.c index 81ebdfc..bb8eda1 100644 --- a/drivers/watchdog/menf21bmc_wdt.c +++ b/drivers/watchdog/menf21bmc_wdt.c
@@ -11,6 +11,7 @@ #include <linux/watchdog.h> #include <linux/platform_device.h> #include <linux/i2c.h> +#include <linux/stringify.h> #define DEVNAME "menf21bmc_wdt" @@ -28,7 +29,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct menf21bmc_wdt { struct watchdog_device wdt;
diff --git a/drivers/watchdog/menz69_wdt.c b/drivers/watchdog/menz69_wdt.c index 3fe2345..962c686 100644 --- a/drivers/watchdog/menz69_wdt.c +++ b/drivers/watchdog/menz69_wdt.c
@@ -8,6 +8,7 @@ #include <linux/kernel.h> #include <linux/mcb.h> #include <linux/module.h> +#include <linux/stringify.h> #include <linux/watchdog.h> struct men_z069_drv { @@ -29,7 +30,7 @@ struct men_z069_drv { static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static int men_z069_wdt_start(struct watchdog_device *wdt) {
diff --git a/drivers/watchdog/meson_gxbb_wdt.c b/drivers/watchdog/meson_gxbb_wdt.c index a48622d..fb27606 100644 --- a/drivers/watchdog/meson_gxbb_wdt.c +++ b/drivers/watchdog/meson_gxbb_wdt.c
@@ -11,6 +11,7 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/slab.h> +#include <linux/stringify.h> #include <linux/types.h> #include <linux/watchdog.h> @@ -31,12 +32,12 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static unsigned int timeout; module_param(timeout, uint, 0); MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds=" - __MODULE_STRING(DEFAULT_TIMEOUT) ")"); + __stringify(DEFAULT_TIMEOUT) ")"); struct meson_gxbb_wdt { void __iomem *reg_base;
diff --git a/drivers/watchdog/meson_wdt.c b/drivers/watchdog/meson_wdt.c index 44db4eb..80a4f87 100644 --- a/drivers/watchdog/meson_wdt.c +++ b/drivers/watchdog/meson_wdt.c
@@ -15,6 +15,7 @@ #include <linux/moduleparam.h> #include <linux/platform_device.h> #include <linux/property.h> +#include <linux/stringify.h> #include <linux/types.h> #include <linux/watchdog.h> @@ -218,7 +219,7 @@ MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
diff --git a/drivers/watchdog/mixcomwd.c b/drivers/watchdog/mixcomwd.c index 1ecd5c4..db358df 100644 --- a/drivers/watchdog/mixcomwd.c +++ b/drivers/watchdog/mixcomwd.c
@@ -52,6 +52,7 @@ #include <linux/timer.h> #include <linux/uaccess.h> #include <linux/io.h> +#include <linux/stringify.h> /* * We have two types of cards that can be probed: @@ -107,7 +108,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static void mixcomwd_ping(void) {
diff --git a/drivers/watchdog/mpc8xxx_wdt.c b/drivers/watchdog/mpc8xxx_wdt.c index a4b497e..0d5a360 100644 --- a/drivers/watchdog/mpc8xxx_wdt.c +++ b/drivers/watchdog/mpc8xxx_wdt.c
@@ -22,6 +22,7 @@ #include <linux/watchdog.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> #include <sysdev/fsl_soc.h> #define WATCHDOG_TIMEOUT 10 @@ -57,7 +58,7 @@ static u16 timeout; module_param(timeout, ushort, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<timeout<65535, default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); + __stringify(WATCHDOG_TIMEOUT) ")"); static bool reset = 1; module_param(reset, bool, 0); @@ -67,7 +68,7 @@ MODULE_PARM_DESC(reset, static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " - "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + "(default=" __stringify(WATCHDOG_NOWAYOUT) ")"); static void mpc8xxx_wdt_keepalive(struct mpc8xxx_wdt_ddata *ddata) {
diff --git a/drivers/watchdog/msc313e_wdt.c b/drivers/watchdog/msc313e_wdt.c index d62586f..0a68be7 100644 --- a/drivers/watchdog/msc313e_wdt.c +++ b/drivers/watchdog/msc313e_wdt.c
@@ -140,8 +140,8 @@ static int msc313e_wdt_probe(struct platform_device *pdev) return PTR_ERR(priv->clk); } - priv->wdev.info = &msc313e_wdt_ident, - priv->wdev.ops = &msc313e_wdt_ops, + priv->wdev.info = &msc313e_wdt_ident; + priv->wdev.ops = &msc313e_wdt_ops; priv->wdev.parent = dev; priv->wdev.min_timeout = MSC313E_WDT_MIN_TIMEOUT; rate = clk_get_rate(priv->clk); @@ -184,7 +184,7 @@ static int msc313e_wdt_probe(struct platform_device *pdev) return ret; } -static int __maybe_unused msc313e_wdt_suspend(struct device *dev) +static int msc313e_wdt_suspend(struct device *dev) { struct msc313e_wdt_priv *priv = dev_get_drvdata(dev); @@ -194,7 +194,7 @@ static int __maybe_unused msc313e_wdt_suspend(struct device *dev) return 0; } -static int __maybe_unused msc313e_wdt_resume(struct device *dev) +static int msc313e_wdt_resume(struct device *dev) { struct msc313e_wdt_priv *priv = dev_get_drvdata(dev); int ret = 0; @@ -208,13 +208,13 @@ static int __maybe_unused msc313e_wdt_resume(struct device *dev) return ret; } -static SIMPLE_DEV_PM_OPS(msc313e_wdt_pm_ops, msc313e_wdt_suspend, msc313e_wdt_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(msc313e_wdt_pm_ops, msc313e_wdt_suspend, msc313e_wdt_resume); static struct platform_driver msc313e_wdt_driver = { .driver = { .name = "msc313e-wdt", .of_match_table = msc313e_wdt_of_match, - .pm = &msc313e_wdt_pm_ops, + .pm = pm_sleep_ptr(&msc313e_wdt_pm_ops), }, .probe = msc313e_wdt_probe, };
diff --git a/drivers/watchdog/mt7621_wdt.c b/drivers/watchdog/mt7621_wdt.c index db47b13..9e0ebec 100644 --- a/drivers/watchdog/mt7621_wdt.c +++ b/drivers/watchdog/mt7621_wdt.c
@@ -16,6 +16,7 @@ #include <linux/platform_device.h> #include <linux/mfd/syscon.h> #include <linux/regmap.h> +#include <linux/stringify.h> #define SYSC_RSTSTAT 0x38 #define WDT_RST_CAUSE BIT(1) @@ -41,7 +42,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static inline void rt_wdt_w32(void __iomem *base, unsigned int reg, u32 val) {
diff --git a/drivers/watchdog/mtk_wdt.c b/drivers/watchdog/mtk_wdt.c index d9c30e4..1630ab6 100644 --- a/drivers/watchdog/mtk_wdt.c +++ b/drivers/watchdog/mtk_wdt.c
@@ -12,6 +12,7 @@ #include <dt-bindings/reset/mt2712-resets.h> #include <dt-bindings/reset/mediatek,mt6735-wdt.h> #include <dt-bindings/reset/mediatek,mt6795-resets.h> +#include <dt-bindings/reset/mediatek,mt8167-wdt.h> #include <dt-bindings/reset/mt7986-resets.h> #include <dt-bindings/reset/mt8183-resets.h> #include <dt-bindings/reset/mt8186-resets.h> @@ -31,10 +32,12 @@ #include <linux/types.h> #include <linux/watchdog.h> #include <linux/interrupt.h> +#include <linux/stringify.h> #define WDT_MAX_TIMEOUT 31 #define WDT_MIN_TIMEOUT 2 #define WDT_LENGTH_TIMEOUT(n) ((n) << 5) +#define WDT_IRQ_LEVEL_SYNC_US 70 #define WDT_LENGTH 0x04 #define WDT_LENGTH_KEY 0x8 @@ -49,6 +52,7 @@ #define WDT_MODE_EXRST_EN (1 << 2) #define WDT_MODE_IRQ_EN (1 << 3) #define WDT_MODE_AUTO_START (1 << 4) +#define WDT_MODE_IRQ_LEVEL_EN (1 << 5) #define WDT_MODE_DUAL_EN (1 << 6) #define WDT_MODE_CNT_SEL (1 << 8) #define WDT_MODE_KEY 0x22000000 @@ -64,6 +68,7 @@ #define DRV_NAME "mtk-wdt" #define DRV_VERSION "1.0" +#define MT6589_TOPRGU_SW_RST_NUM 12 #define MT7988_TOPRGU_SW_RST_NUM 24 static bool nowayout = WATCHDOG_NOWAYOUT; @@ -72,22 +77,29 @@ static unsigned int timeout; struct mtk_wdt_dev { struct watchdog_device wdt_dev; void __iomem *wdt_base; - spinlock_t lock; /* protects WDT_SWSYSRST reg */ + spinlock_t lock; /* protects WDT_MODE and WDT_SWSYSRST reg */ struct reset_controller_dev rcdev; bool disable_wdt_extrst; bool reset_by_toprgu; bool has_swsysrst_en; + const u8 *toprgu_sw_rst_tb; + int toprgu_sw_rst_num; }; struct mtk_wdt_data { - int toprgu_sw_rst_num; - bool has_swsysrst_en; + const u8 *toprgu_sw_rst_tb; + const int toprgu_sw_rst_num; + const bool has_swsysrst_en; }; static const struct mtk_wdt_data mt2712_data = { .toprgu_sw_rst_num = MT2712_TOPRGU_SW_RST_NUM, }; +static const struct mtk_wdt_data mt6589_data = { + .toprgu_sw_rst_num = MT6589_TOPRGU_SW_RST_NUM, +}; + static const struct mtk_wdt_data mt6735_data = { .toprgu_sw_rst_num = MT6735_TOPRGU_RST_NUM, }; @@ -125,6 +137,29 @@ static const struct mtk_wdt_data mt8195_data = { .toprgu_sw_rst_num = MT8195_TOPRGU_SW_RST_NUM, }; +static const u8 mt8167_toprgu_sw_rst_tb[] = { + [MT8167_TOPRGU_DDRPHY_FLASH_RST] = 0, + [MT8167_TOPRGU_AUD_PAD_RST] = 1, + [MT8167_TOPRGU_MM_RST] = 2, + [MT8167_TOPRGU_MFG_RST] = 3, + [MT8167_TOPRGU_MDSYS_RST] = 4, + [MT8167_TOPRGU_CONN_RST] = 5, + [MT8167_TOPRGU_PAD2CAM_DIG_MIPI_RX_RST] = 6, + [MT8167_TOPRGU_DIG_MIPI_TX_RST] = 7, + [MT8167_TOPRGU_SPI_PAD_MACRO_RST] = 8, + /* The data sheet describes bit 9 as "reserved, unused" */ + [MT8167_TOPRGU_APMIXED_RST] = 10, + [MT8167_TOPRGU_VDEC_RST] = 11, + [MT8167_TOPRGU_CONN_MCU_RST] = 12, + [MT8167_TOPRGU_EFUSE_RST] = 13, + [MT8167_TOPRGU_PWRAP_SPICTL_RST] = 14 +}; + +static const struct mtk_wdt_data mt8167_data = { + .toprgu_sw_rst_tb = mt8167_toprgu_sw_rst_tb, + .toprgu_sw_rst_num = ARRAY_SIZE(mt8167_toprgu_sw_rst_tb), +}; + /** * toprgu_reset_sw_en_unlocked() - enable/disable software control for reset bit * @data: Pointer to instance of driver data. @@ -155,6 +190,15 @@ static int toprgu_reset_update(struct reset_controller_dev *rcdev, struct mtk_wdt_dev *data = container_of(rcdev, struct mtk_wdt_dev, rcdev); + if (data->toprgu_sw_rst_tb) { + if (id >= data->toprgu_sw_rst_num) { + dev_err(rcdev->dev, "Invalid reset ID: %lu (>=%u)\n", + id, data->toprgu_sw_rst_num); + return -EINVAL; + } + id = data->toprgu_sw_rst_tb[id]; + } + spin_lock_irqsave(&data->lock, flags); if (assert && data->has_swsysrst_en) @@ -212,8 +256,6 @@ static int toprgu_register_reset_controller(struct platform_device *pdev, int ret; struct mtk_wdt_dev *mtk_wdt = platform_get_drvdata(pdev); - spin_lock_init(&mtk_wdt->lock); - mtk_wdt->rcdev.owner = THIS_MODULE; mtk_wdt->rcdev.nr_resets = rst_num; mtk_wdt->rcdev.ops = &toprgu_reset_ops; @@ -285,29 +327,19 @@ static int mtk_wdt_set_timeout(struct watchdog_device *wdt_dev, return 0; } -static void mtk_wdt_init(struct watchdog_device *wdt_dev) -{ - struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev); - void __iomem *wdt_base; - - wdt_base = mtk_wdt->wdt_base; - - if (readl(wdt_base + WDT_MODE) & WDT_MODE_EN) { - set_bit(WDOG_HW_RUNNING, &wdt_dev->status); - mtk_wdt_set_timeout(wdt_dev, wdt_dev->timeout); - } -} - static int mtk_wdt_stop(struct watchdog_device *wdt_dev) { struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev); void __iomem *wdt_base = mtk_wdt->wdt_base; + unsigned long flags; u32 reg; + spin_lock_irqsave(&mtk_wdt->lock, flags); reg = readl(wdt_base + WDT_MODE); reg &= ~WDT_MODE_EN; reg |= WDT_MODE_KEY; iowrite32(reg, wdt_base + WDT_MODE); + spin_unlock_irqrestore(&mtk_wdt->lock, flags); return 0; } @@ -317,12 +349,14 @@ static int mtk_wdt_start(struct watchdog_device *wdt_dev) u32 reg; struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev); void __iomem *wdt_base = mtk_wdt->wdt_base; + unsigned long flags; int ret; ret = mtk_wdt_set_timeout(wdt_dev, wdt_dev->timeout); if (ret < 0) return ret; + spin_lock_irqsave(&mtk_wdt->lock, flags); reg = ioread32(wdt_base + WDT_MODE); if (wdt_dev->pretimeout) reg |= (WDT_MODE_IRQ_EN | WDT_MODE_DUAL_EN); @@ -334,16 +368,39 @@ static int mtk_wdt_start(struct watchdog_device *wdt_dev) reg |= WDT_MODE_CNT_SEL; reg |= (WDT_MODE_EN | WDT_MODE_KEY); iowrite32(reg, wdt_base + WDT_MODE); + spin_unlock_irqrestore(&mtk_wdt->lock, flags); return 0; } +static void mtk_wdt_init(struct watchdog_device *wdt_dev) +{ + struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdt_dev); + void __iomem *wdt_base; + + wdt_base = mtk_wdt->wdt_base; + + /* + * The bootloader may have left it in dual mode, where a timeout only + * raises the bark IRQ and the reset comes one timeout later. Apply + * this driver's mode instead, as mtk_wdt_start() does. + */ + if (readl(wdt_base + WDT_MODE) & WDT_MODE_EN) { + set_bit(WDOG_HW_RUNNING, &wdt_dev->status); + mtk_wdt_start(wdt_dev); + } +} + static int mtk_wdt_set_pretimeout(struct watchdog_device *wdd, unsigned int timeout) { struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdd); void __iomem *wdt_base = mtk_wdt->wdt_base; - u32 reg = ioread32(wdt_base + WDT_MODE); + unsigned long flags; + u32 reg; + + spin_lock_irqsave(&mtk_wdt->lock, flags); + reg = ioread32(wdt_base + WDT_MODE); if (timeout && !wdd->pretimeout) { wdd->pretimeout = wdd->timeout / 2; @@ -352,19 +409,54 @@ static int mtk_wdt_set_pretimeout(struct watchdog_device *wdd, wdd->pretimeout = 0; reg &= ~(WDT_MODE_IRQ_EN | WDT_MODE_DUAL_EN); } else { + spin_unlock_irqrestore(&mtk_wdt->lock, flags); return 0; } reg |= WDT_MODE_KEY; iowrite32(reg, wdt_base + WDT_MODE); + spin_unlock_irqrestore(&mtk_wdt->lock, flags); return mtk_wdt_set_timeout(wdd, wdd->timeout); } +static void mtk_wdt_deassert_irq(struct watchdog_device *wdd) +{ + struct mtk_wdt_dev *mtk_wdt = watchdog_get_drvdata(wdd); + void __iomem *wdt_base = mtk_wdt->wdt_base; + unsigned long flags; + u32 reg; + + spin_lock_irqsave(&mtk_wdt->lock, flags); + + reg = ioread32(wdt_base + WDT_MODE); + reg ^= WDT_MODE_IRQ_LEVEL_EN; + iowrite32(reg | WDT_MODE_KEY, wdt_base + WDT_MODE); + + /* + * Wait for two 32 kHz watchdog clock cycles so the IRQ level + * change can propagate across the clock domain. + */ + udelay(WDT_IRQ_LEVEL_SYNC_US); + + reg = ioread32(wdt_base + WDT_MODE); + reg ^= WDT_MODE_IRQ_LEVEL_EN; + iowrite32(reg | WDT_MODE_KEY, wdt_base + WDT_MODE); + + /* + * Flush the posted write before releasing the lock and notifying + * the watchdog core. + */ + ioread32(wdt_base + WDT_MODE); + + spin_unlock_irqrestore(&mtk_wdt->lock, flags); +} + static irqreturn_t mtk_wdt_isr(int irq, void *arg) { struct watchdog_device *wdd = arg; + mtk_wdt_deassert_irq(wdd); watchdog_notify_pretimeout(wdd); return IRQ_HANDLED; @@ -406,6 +498,8 @@ static int mtk_wdt_probe(struct platform_device *pdev) if (!mtk_wdt) return -ENOMEM; + spin_lock_init(&mtk_wdt->lock); + platform_set_drvdata(pdev, mtk_wdt); mtk_wdt->wdt_base = devm_platform_ioremap_resource(pdev, 0); @@ -414,8 +508,8 @@ static int mtk_wdt_probe(struct platform_device *pdev) irq = platform_get_irq_optional(pdev, 0); if (irq > 0) { - err = devm_request_irq(&pdev->dev, irq, mtk_wdt_isr, 0, "wdt_bark", - &mtk_wdt->wdt_dev); + err = devm_request_irq(&pdev->dev, irq, mtk_wdt_isr, IRQF_NO_AUTOEN, + "wdt_bark", &mtk_wdt->wdt_dev); if (err) return err; @@ -440,6 +534,12 @@ static int mtk_wdt_probe(struct platform_device *pdev) watchdog_set_drvdata(&mtk_wdt->wdt_dev, mtk_wdt); + mtk_wdt->disable_wdt_extrst = + of_property_read_bool(dev->of_node, "mediatek,disable-extrst"); + + mtk_wdt->reset_by_toprgu = + of_property_read_bool(dev->of_node, "mediatek,reset-by-toprgu"); + mtk_wdt_init(&mtk_wdt->wdt_dev); watchdog_stop_on_reboot(&mtk_wdt->wdt_dev); @@ -447,25 +547,24 @@ static int mtk_wdt_probe(struct platform_device *pdev) if (unlikely(err)) return err; + if (irq > 0) + enable_irq(irq); + dev_info(dev, "Watchdog enabled (timeout=%d sec, nowayout=%d)\n", mtk_wdt->wdt_dev.timeout, nowayout); wdt_data = of_device_get_match_data(dev); if (wdt_data) { + mtk_wdt->toprgu_sw_rst_num = wdt_data->toprgu_sw_rst_num; + mtk_wdt->toprgu_sw_rst_tb = wdt_data->toprgu_sw_rst_tb; + mtk_wdt->has_swsysrst_en = wdt_data->has_swsysrst_en; + err = toprgu_register_reset_controller(pdev, wdt_data->toprgu_sw_rst_num); if (err) return err; - - mtk_wdt->has_swsysrst_en = wdt_data->has_swsysrst_en; } - mtk_wdt->disable_wdt_extrst = - of_property_read_bool(dev->of_node, "mediatek,disable-extrst"); - - mtk_wdt->reset_by_toprgu = - of_property_read_bool(dev->of_node, "mediatek,reset-by-toprgu"); - return 0; } @@ -493,11 +592,12 @@ static int mtk_wdt_resume(struct device *dev) static const struct of_device_id mtk_wdt_dt_ids[] = { { .compatible = "mediatek,mt2712-wdt", .data = &mt2712_data }, - { .compatible = "mediatek,mt6589-wdt" }, + { .compatible = "mediatek,mt6589-wdt", .data = &mt6589_data }, { .compatible = "mediatek,mt6735-wdt", .data = &mt6735_data }, { .compatible = "mediatek,mt6795-wdt", .data = &mt6795_data }, { .compatible = "mediatek,mt7986-wdt", .data = &mt7986_data }, { .compatible = "mediatek,mt7988-wdt", .data = &mt7988_data }, + { .compatible = "mediatek,mt8167-wdt", .data = &mt8167_data }, { .compatible = "mediatek,mt8183-wdt", .data = &mt8183_data }, { .compatible = "mediatek,mt8186-wdt", .data = &mt8186_data }, { .compatible = "mediatek,mt8188-wdt", .data = &mt8188_data }, @@ -526,7 +626,7 @@ MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Matthias Brugger <matthias.bgg@gmail.com>");
diff --git a/drivers/watchdog/nct6694_wdt.c b/drivers/watchdog/nct6694_wdt.c index bc3689b..169a673 100644 --- a/drivers/watchdog/nct6694_wdt.c +++ b/drivers/watchdog/nct6694_wdt.c
@@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/slab.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define DEVICE_NAME "nct6694-wdt" @@ -50,7 +51,7 @@ MODULE_PARM_DESC(pretimeout, "Watchdog pre-timeout in seconds"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); enum { NCT6694_ACTION_NONE = 0,
diff --git a/drivers/watchdog/ni903x_wdt.c b/drivers/watchdog/ni903x_wdt.c index c72a9ee..68b7c48 100644 --- a/drivers/watchdog/ni903x_wdt.c +++ b/drivers/watchdog/ni903x_wdt.c
@@ -9,6 +9,7 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define NIWD_CONTROL 0x01 @@ -46,13 +47,13 @@ static unsigned int timeout; module_param(timeout, uint, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (default=" - __MODULE_STRING(NIWD_DEFAULT_TIMEOUT) ")"); + __stringify(NIWD_DEFAULT_TIMEOUT) ")"); static int nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, int, S_IRUGO); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static void ni903x_start(struct ni903x_wdt *wdt) {
diff --git a/drivers/watchdog/nic7018_wdt.c b/drivers/watchdog/nic7018_wdt.c index 8169423..2b122ba 100644 --- a/drivers/watchdog/nic7018_wdt.c +++ b/drivers/watchdog/nic7018_wdt.c
@@ -8,6 +8,7 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/types.h> #include <linux/watchdog.h> @@ -34,13 +35,13 @@ static unsigned int timeout; module_param(timeout, uint, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (default=" - __MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")"); + __stringify(WDT_DEFAULT_TIMEOUT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started. (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct nic7018_wdt { u16 io_base;
diff --git a/drivers/watchdog/nv_tco.c b/drivers/watchdog/nv_tco.c index f16cee5..0d671b8 100644 --- a/drivers/watchdog/nv_tco.c +++ b/drivers/watchdog/nv_tco.c
@@ -32,6 +32,7 @@ #include <linux/platform_device.h> #include <linux/uaccess.h> #include <linux/io.h> +#include <linux/stringify.h> #include "nv_tco.h" @@ -55,12 +56,12 @@ static struct platform_device *nv_tco_platform_device; static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (2<heartbeat<39, " - "default=" __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); + "default=" __stringify(WATCHDOG_HEARTBEAT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started" - " (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + " (default=" __stringify(WATCHDOG_NOWAYOUT) ")"); /* * Some TCO specific functions
diff --git a/drivers/watchdog/octeon-wdt-main.c b/drivers/watchdog/octeon-wdt-main.c index 0615bb8..171b46d 100644 --- a/drivers/watchdog/octeon-wdt-main.c +++ b/drivers/watchdog/octeon-wdt-main.c
@@ -55,6 +55,7 @@ #include <linux/cpu.h> #include <linux/irq.h> #include <linux/irqdomain.h> +#include <linux/stringify.h> #include <asm/mipsregs.h> #include <asm/uasm.h> @@ -93,13 +94,13 @@ static int heartbeat = WD_TIMO; module_param(heartbeat, int, 0444); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0 < heartbeat, default=" - __MODULE_STRING(WD_TIMO) ")"); + __stringify(WD_TIMO) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0444); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static int disable; module_param(disable, int, 0444);
diff --git a/drivers/watchdog/of_xilinx_wdt.c b/drivers/watchdog/of_xilinx_wdt.c index 352853e..d6b1adf 100644 --- a/drivers/watchdog/of_xilinx_wdt.c +++ b/drivers/watchdog/of_xilinx_wdt.c
@@ -251,7 +251,7 @@ static int xwdt_probe(struct platform_device *pdev) * @dev: handle to the device structure. * Return: 0 always. */ -static int __maybe_unused xwdt_suspend(struct device *dev) +static int xwdt_suspend(struct device *dev) { struct xwdt_device *xdev = dev_get_drvdata(dev); @@ -267,7 +267,7 @@ static int __maybe_unused xwdt_suspend(struct device *dev) * @dev: handle to the device structure. * Return: 0 on success, errno otherwise. */ -static int __maybe_unused xwdt_resume(struct device *dev) +static int xwdt_resume(struct device *dev) { struct xwdt_device *xdev = dev_get_drvdata(dev); int ret = 0; @@ -278,7 +278,7 @@ static int __maybe_unused xwdt_resume(struct device *dev) return ret; } -static SIMPLE_DEV_PM_OPS(xwdt_pm_ops, xwdt_suspend, xwdt_resume); +static DEFINE_SIMPLE_DEV_PM_OPS(xwdt_pm_ops, xwdt_suspend, xwdt_resume); /* Match table for of_platform binding */ static const struct of_device_id xwdt_of_match[] = { @@ -293,7 +293,7 @@ static struct platform_driver xwdt_driver = { .driver = { .name = WATCHDOG_NAME, .of_match_table = xwdt_of_match, - .pm = &xwdt_pm_ops, + .pm = pm_sleep_ptr(&xwdt_pm_ops), }, };
diff --git a/drivers/watchdog/omap_wdt.c b/drivers/watchdog/omap_wdt.c index 95c7e44..2a6de73 100644 --- a/drivers/watchdog/omap_wdt.c +++ b/drivers/watchdog/omap_wdt.c
@@ -38,6 +38,7 @@ #include <linux/io.h> #include <linux/slab.h> #include <linux/pm_runtime.h> +#include <linux/stringify.h> #include <linux/platform_data/omap-wd-timer.h> #include "omap_wdt.h" @@ -45,7 +46,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " - "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + "(default=" __stringify(WATCHDOG_NOWAYOUT) ")"); static unsigned timer_margin; module_param(timer_margin, uint, 0);
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c index 0ea9468..5d56e93 100644 --- a/drivers/watchdog/orion_wdt.c +++ b/drivers/watchdog/orion_wdt.c
@@ -22,6 +22,7 @@ #include <linux/err.h> #include <linux/of.h> #include <linux/of_device.h> +#include <linux/stringify.h> /* RSTOUT mask register physical address for Orion5x, Kirkwood and Dove */ #define ORION_RSTOUT_MASK_OFFSET 0x20108 @@ -687,7 +688,7 @@ MODULE_PARM_DESC(heartbeat, "Initial watchdog heartbeat in seconds"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); MODULE_LICENSE("GPL v2"); MODULE_ALIAS("platform:orion_wdt");
diff --git a/drivers/watchdog/pc87413_wdt.c b/drivers/watchdog/pc87413_wdt.c index fbf835d..bbd8638 100644 --- a/drivers/watchdog/pc87413_wdt.c +++ b/drivers/watchdog/pc87413_wdt.c
@@ -30,6 +30,7 @@ #include <linux/moduleparam.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> /* #define DEBUG 1 */ @@ -333,7 +334,7 @@ static int pc87413_status(void) * @ppos: pointer to the position to write. No seeks allowed * * A write to a watchdog device is defined as a keepalive signal. Any - * write of data will do, as we we don't define content meaning. + * write of data will do, as we don't define content meaning. */ static ssize_t pc87413_write(struct file *file, const char __user *data, @@ -577,15 +578,15 @@ MODULE_LICENSE("GPL"); module_param_hw(io, int, ioport, 0); MODULE_PARM_DESC(io, MODNAME " I/O port (default: " - __MODULE_STRING(IO_DEFAULT) ")."); + __stringify(IO_DEFAULT) ")."); module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in minutes (default=" - __MODULE_STRING(DEFAULT_TIMEOUT) ")."); + __stringify(DEFAULT_TIMEOUT) ")."); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")");
diff --git a/drivers/watchdog/pcwd.c b/drivers/watchdog/pcwd.c index d4ea7d6..3370a91 100644 --- a/drivers/watchdog/pcwd.c +++ b/drivers/watchdog/pcwd.c
@@ -72,6 +72,7 @@ #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ #include <linux/io.h> /* For inb/outb/... */ +#include <linux/stringify.h> /* For __stringify */ /* Module and version information */ #define WATCHDOG_VERSION "1.20" @@ -203,13 +204,13 @@ static int heartbeat = WATCHDOG_HEARTBEAT; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. " "(2 <= heartbeat <= 7200 or 0=delay-time from dip-switches, default=" - __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); + __stringify(WATCHDOG_HEARTBEAT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* * Internal functions
diff --git a/drivers/watchdog/pcwd_pci.c b/drivers/watchdog/pcwd_pci.c index a489b42..8c232c7 100644 --- a/drivers/watchdog/pcwd_pci.c +++ b/drivers/watchdog/pcwd_pci.c
@@ -47,6 +47,7 @@ #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ #include <linux/io.h> /* For inb/outb/... */ +#include <linux/stringify.h> /* For __stringify */ /* Module and version information */ #define WATCHDOG_VERSION "1.03" @@ -114,7 +115,7 @@ static unsigned long is_active; static char expect_release; /* this is private data for each PCI-PC watchdog card */ static struct { - /* Wether or not the card has a temperature device */ + /* Whether or not the card has a temperature device */ int supports_temp; /* The card's boot status */ int boot_status; @@ -140,12 +141,12 @@ static int heartbeat = WATCHDOG_HEARTBEAT; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. " "(0<heartbeat<65536 or 0=delay-time from dip-switches, default=" - __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); + __stringify(WATCHDOG_HEARTBEAT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* * Internal functions
diff --git a/drivers/watchdog/pcwd_usb.c b/drivers/watchdog/pcwd_usb.c index d7c18c9..fc175aa 100644 --- a/drivers/watchdog/pcwd_usb.c +++ b/drivers/watchdog/pcwd_usb.c
@@ -39,6 +39,7 @@ #include <linux/mutex.h> /* For mutex locking */ #include <linux/hid.h> /* For HID_REQ_SET_REPORT & HID_DT_REPORT */ #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ +#include <linux/stringify.h> /* For __stringify */ /* Module and Version Information */ @@ -57,12 +58,12 @@ static int heartbeat = WATCHDOG_HEARTBEAT; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. " "(0<heartbeat<65536 or 0=delay-time from dip-switches, default=" - __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); + __stringify(WATCHDOG_HEARTBEAT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* The vendor and product id's for the USB-PC Watchdog card */ #define USB_PCWD_VENDOR_ID 0x0c98 @@ -138,7 +139,7 @@ struct usb_pcwd_private { /* true if we received a report after a command */ atomic_t cmd_received; - /* Wether or not the device exists */ + /* Whether or not the device exists */ int exists; /* locks this structure */ struct mutex mtx;
diff --git a/drivers/watchdog/pika_wdt.c b/drivers/watchdog/pika_wdt.c index 87b8988..09fc76a 100644 --- a/drivers/watchdog/pika_wdt.c +++ b/drivers/watchdog/pika_wdt.c
@@ -25,6 +25,7 @@ #include <linux/io.h> #include <linux/of.h> #include <linux/of_address.h> +#include <linux/stringify.h> #define DRV_NAME "PIKA-WDT" @@ -39,12 +40,12 @@ static int heartbeat = WDT_HEARTBEAT; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds. " - "(default = " __MODULE_STRING(WDT_HEARTBEAT) ")"); + "(default = " __stringify(WDT_HEARTBEAT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " - "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + "(default=" __stringify(WATCHDOG_NOWAYOUT) ")"); static struct { void __iomem *fpga;
diff --git a/drivers/watchdog/pm8916_wdt.c b/drivers/watchdog/pm8916_wdt.c index 007ed13..a7ae57f 100644 --- a/drivers/watchdog/pm8916_wdt.c +++ b/drivers/watchdog/pm8916_wdt.c
@@ -233,7 +233,7 @@ static int pm8916_wdt_probe(struct platform_device *pdev) return devm_watchdog_register_device(dev, &wdt->wdev); } -static int __maybe_unused pm8916_wdt_suspend(struct device *dev) +static int pm8916_wdt_suspend(struct device *dev) { struct pm8916_wdt *wdt = dev_get_drvdata(dev); @@ -243,7 +243,7 @@ static int __maybe_unused pm8916_wdt_suspend(struct device *dev) return 0; } -static int __maybe_unused pm8916_wdt_resume(struct device *dev) +static int pm8916_wdt_resume(struct device *dev) { struct pm8916_wdt *wdt = dev_get_drvdata(dev); @@ -253,7 +253,7 @@ static int __maybe_unused pm8916_wdt_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(pm8916_wdt_pm_ops, pm8916_wdt_suspend, +static DEFINE_SIMPLE_DEV_PM_OPS(pm8916_wdt_pm_ops, pm8916_wdt_suspend, pm8916_wdt_resume); static const struct of_device_id pm8916_wdt_id_table[] = { @@ -267,7 +267,7 @@ static struct platform_driver pm8916_wdt_driver = { .driver = { .name = "pm8916-wdt", .of_match_table = pm8916_wdt_id_table, - .pm = &pm8916_wdt_pm_ops, + .pm = pm_sleep_ptr(&pm8916_wdt_pm_ops), }, }; module_platform_driver(pm8916_wdt_driver);
diff --git a/drivers/watchdog/pnx4008_wdt.c b/drivers/watchdog/pnx4008_wdt.c index 87a44a5..a7c3984 100644 --- a/drivers/watchdog/pnx4008_wdt.c +++ b/drivers/watchdog/pnx4008_wdt.c
@@ -30,6 +30,7 @@ #include <linux/of.h> #include <linux/delay.h> #include <linux/reboot.h> +#include <linux/stringify.h> /* WatchDog Timer - Chapter 23 Page 207 */ @@ -237,8 +238,8 @@ MODULE_DESCRIPTION("PNX4008 Watchdog Driver"); module_param(heartbeat, uint, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat period in seconds from 1 to " - __MODULE_STRING(MAX_HEARTBEAT) ", default " - __MODULE_STRING(DEFAULT_HEARTBEAT)); + __stringify(MAX_HEARTBEAT) ", default " + __stringify(DEFAULT_HEARTBEAT)); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout,
diff --git a/drivers/watchdog/pseries-wdt.c b/drivers/watchdog/pseries-wdt.c index e97b943..5f531a0 100644 --- a/drivers/watchdog/pseries-wdt.c +++ b/drivers/watchdog/pseries-wdt.c
@@ -10,6 +10,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/time64.h> #include <linux/watchdog.h> #include <asm/papr-watchdog.h> @@ -26,18 +27,18 @@ static const unsigned long pseries_wdt_action[] = { static unsigned int action = WATCHDOG_ACTION; module_param(action, uint, 0444); MODULE_PARM_DESC(action, "Action taken when watchdog expires (default=" - __MODULE_STRING(WATCHDOG_ACTION) ")"); + __stringify(WATCHDOG_ACTION) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0444); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); #define WATCHDOG_TIMEOUT 60 static unsigned int timeout = WATCHDOG_TIMEOUT; module_param(timeout, uint, 0444); MODULE_PARM_DESC(timeout, "Initial watchdog timeout in seconds (default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); + __stringify(WATCHDOG_TIMEOUT) ")"); struct pseries_wdt { struct watchdog_device wd;
diff --git a/drivers/watchdog/rc32434_wdt.c b/drivers/watchdog/rc32434_wdt.c index 0e5c5c9..5301a93 100644 --- a/drivers/watchdog/rc32434_wdt.c +++ b/drivers/watchdog/rc32434_wdt.c
@@ -27,6 +27,7 @@ #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ #include <linux/io.h> /* For devm_ioremap */ +#include <linux/stringify.h> /* For __stringify */ #include <asm/mach-rc32434/integ.h> /* For the Watchdog registers */ @@ -57,12 +58,12 @@ extern unsigned int idt_cpu_freq; static int timeout = WATCHDOG_TIMEOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout value, in seconds (default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); + __stringify(WATCHDOG_TIMEOUT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* apply or and nand masks to data read from addr and write back */ #define SET_BITS(addr, or, nand) \
diff --git a/drivers/watchdog/renesas_wdt.c b/drivers/watchdog/renesas_wdt.c index 97bcd32..8c0041c 100644 --- a/drivers/watchdog/renesas_wdt.c +++ b/drivers/watchdog/renesas_wdt.c
@@ -16,6 +16,7 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/smp.h> +#include <linux/stringify.h> #include <linux/sys_soc.h> #include <linux/watchdog.h> @@ -44,7 +45,7 @@ static const unsigned int clk_divs[] = { 1, 4, 16, 32, 64, 128, 1024, 4096 }; static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct rwdt_priv { void __iomem *base;
diff --git a/drivers/watchdog/rn5t618_wdt.c b/drivers/watchdog/rn5t618_wdt.c index 87d06d2..14056af 100644 --- a/drivers/watchdog/rn5t618_wdt.c +++ b/drivers/watchdog/rn5t618_wdt.c
@@ -9,6 +9,7 @@ #include <linux/mfd/rn5t618.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define DRIVER_NAME "rn5t618-wdt" @@ -21,7 +22,7 @@ MODULE_PARM_DESC(timeout, "Initial watchdog timeout in seconds"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct rn5t618_wdt { struct watchdog_device wdt_dev;
diff --git a/drivers/watchdog/rt2880_wdt.c b/drivers/watchdog/rt2880_wdt.c index c8edd83..38f31d3 100644 --- a/drivers/watchdog/rt2880_wdt.c +++ b/drivers/watchdog/rt2880_wdt.c
@@ -15,6 +15,7 @@ #include <linux/watchdog.h> #include <linux/moduleparam.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <asm/mach-ralink/ralink_regs.h> @@ -51,7 +52,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static inline void rt_wdt_w32(void __iomem *base, unsigned int reg, u32 val) {
diff --git a/drivers/watchdog/rti_wdt.c b/drivers/watchdog/rti_wdt.c index 7c1bd83..6a64adb 100644 --- a/drivers/watchdog/rti_wdt.c +++ b/drivers/watchdog/rti_wdt.c
@@ -17,6 +17,7 @@ #include <linux/of_reserved_mem.h> #include <linux/platform_device.h> #include <linux/pm_runtime.h> +#include <linux/stringify.h> #include <linux/types.h> #include <linux/watchdog.h> @@ -414,8 +415,8 @@ MODULE_DESCRIPTION("K3 RTI Watchdog Driver"); module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat period in seconds from 1 to " - __MODULE_STRING(MAX_HEARTBEAT) ", default " - __MODULE_STRING(DEFAULT_HEARTBEAT)); + __stringify(MAX_HEARTBEAT) ", default " + __stringify(DEFAULT_HEARTBEAT)); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:rti-wdt");
diff --git a/drivers/watchdog/rzg2l_wdt.c b/drivers/watchdog/rzg2l_wdt.c index 509f9df..592ea7c 100644 --- a/drivers/watchdog/rzg2l_wdt.c +++ b/drivers/watchdog/rzg2l_wdt.c
@@ -14,6 +14,7 @@ #include <linux/platform_device.h> #include <linux/pm_domain.h> #include <linux/pm_runtime.h> +#include <linux/stringify.h> #include <linux/reset.h> #include <linux/units.h> #include <linux/watchdog.h> @@ -41,7 +42,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); enum rz_wdt_type { WDT_RZG2L,
diff --git a/drivers/watchdog/rzv2h_wdt.c b/drivers/watchdog/rzv2h_wdt.c index 83540dd..a8db85e 100644 --- a/drivers/watchdog/rzv2h_wdt.c +++ b/drivers/watchdog/rzv2h_wdt.c
@@ -13,6 +13,7 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/reset.h> +#include <linux/stringify.h> #include <linux/units.h> #include <linux/watchdog.h> @@ -48,7 +49,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); enum rzv2h_wdt_count_source { COUNT_SOURCE_LOCO,
diff --git a/drivers/watchdog/s32g_wdt.c b/drivers/watchdog/s32g_wdt.c index 6422a69..bd87401 100644 --- a/drivers/watchdog/s32g_wdt.c +++ b/drivers/watchdog/s32g_wdt.c
@@ -13,6 +13,7 @@ #include <linux/moduleparam.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define DRIVER_NAME "s32g-swt" @@ -42,12 +43,12 @@ struct s32g_wdt_device { static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static unsigned int timeout_param = S32G_WDT_DEFAULT_TIMEOUT; module_param(timeout_param, uint, 0); MODULE_PARM_DESC(timeout_param, "Watchdog timeout in seconds (default=" - __MODULE_STRING(S32G_WDT_DEFAULT_TIMEOUT) ")"); + __stringify(S32G_WDT_DEFAULT_TIMEOUT) ")"); static bool early_enable; module_param(early_enable, bool, 0);
diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index e31f93d..7053963 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c
@@ -28,6 +28,7 @@ #include <linux/regmap.h> #include <linux/delay.h> #include <linux/math64.h> +#include <linux/stringify.h> #define S3C2410_WTCON 0x00 #define S3C2410_WTDAT 0x04 @@ -154,12 +155,12 @@ module_param(nowayout, bool, 0); module_param(soft_noboot, int, 0); MODULE_PARM_DESC(tmr_margin, "Watchdog tmr_margin in seconds. (default=" - __MODULE_STRING(S3C2410_WATCHDOG_DEFAULT_TIME) ")"); + __stringify(S3C2410_WATCHDOG_DEFAULT_TIME) ")"); MODULE_PARM_DESC(tmr_atboot, "Watchdog is started at boot time if set to 1, default=" - __MODULE_STRING(S3C2410_WATCHDOG_ATBOOT)); + __stringify(S3C2410_WATCHDOG_ATBOOT)); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); MODULE_PARM_DESC(soft_noboot, "Watchdog action, set to 1 to ignore reboots, 0 to reboot (default 0)"); /** @@ -232,6 +233,20 @@ static const struct s3c2410_wdt_variant drv_data_exynos5420 = { QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_PMU_AUTO_DISABLE, }; +/* + * Unlike similar SoCs like GS101, Exynos5515's PMU does not require + * explicit counter enablement. Hence, QUIRK_HAS_PMU_CNT_EN is not set. + */ +static const struct s3c2410_wdt_variant drv_data_exynos5515 = { + .mask_reset_reg = EXYNOSAUTOV920_CLUSTER0_NONCPU_INT_EN, + .mask_bit = 2, + .mask_reset_inv = true, + .rst_stat_reg = EXYNOS5_RST_STAT_REG_OFFSET, + .rst_stat_bit = 24, + .quirks = QUIRK_HAS_WTCLRINT_REG | QUIRK_HAS_PMU_MASK_RESET | \ + QUIRK_HAS_PMU_RST_STAT | QUIRK_HAS_DBGACK_BIT, +}; + static const struct s3c2410_wdt_variant drv_data_exynos7 = { .disable_reg = EXYNOS5_WDT_DISABLE_REG_OFFSET, .mask_reset_reg = EXYNOS5_WDT_MASK_RESET_REG_OFFSET, @@ -379,6 +394,8 @@ static const struct of_device_id s3c2410_wdt_match[] = { .data = &drv_data_exynos5250 }, { .compatible = "samsung,exynos5420-wdt", .data = &drv_data_exynos5420 }, + { .compatible = "samsung,exynos5515-wdt", + .data = &drv_data_exynos5515 }, { .compatible = "samsung,exynos7-wdt", .data = &drv_data_exynos7 }, { .compatible = "samsung,exynos850-wdt",
diff --git a/drivers/watchdog/sama5d4_wdt.c b/drivers/watchdog/sama5d4_wdt.c index ecdd9ae..85efe4d 100644 --- a/drivers/watchdog/sama5d4_wdt.c +++ b/drivers/watchdog/sama5d4_wdt.c
@@ -14,6 +14,7 @@ #include <linux/of_irq.h> #include <linux/platform_device.h> #include <linux/reboot.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #include "at91sam9_wdt.h" @@ -42,12 +43,12 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(wdt_timeout, int, 0); MODULE_PARM_DESC(wdt_timeout, "Watchdog timeout in seconds. (default = " - __MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")"); + __stringify(WDT_DEFAULT_TIMEOUT) ")"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static inline bool wdt_enabled(struct sama5d4_wdt *wdt) {
diff --git a/drivers/watchdog/sbc60xxwdt.c b/drivers/watchdog/sbc60xxwdt.c index 03eaf48..fffe58d 100644 --- a/drivers/watchdog/sbc60xxwdt.c +++ b/drivers/watchdog/sbc60xxwdt.c
@@ -58,6 +58,7 @@ #include <linux/init.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> #define OUR_NAME "sbc60xxwdt" @@ -98,13 +99,13 @@ static int timeout = WATCHDOG_TIMEOUT; /* in seconds, multiplied by HZ to module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); + __stringify(WATCHDOG_TIMEOUT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static void wdt_timer_ping(struct timer_list *); static DEFINE_TIMER(timer, wdt_timer_ping);
diff --git a/drivers/watchdog/sbc7240_wdt.c b/drivers/watchdog/sbc7240_wdt.c index 21a1f0b..077abbd 100644 --- a/drivers/watchdog/sbc7240_wdt.c +++ b/drivers/watchdog/sbc7240_wdt.c
@@ -23,6 +23,7 @@ #include <linux/io.h> #include <linux/uaccess.h> #include <linux/atomic.h> +#include <linux/stringify.h> #define SBC7240_ENABLE_PORT 0x443 #define SBC7240_DISABLE_PORT 0x043 @@ -34,8 +35,8 @@ static int timeout = SBC7240_TIMEOUT; /* in seconds */ module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=" - __MODULE_STRING(SBC7240_MAX_TIMEOUT) ", default=" - __MODULE_STRING(SBC7240_TIMEOUT) ")"); + __stringify(SBC7240_MAX_TIMEOUT) ", default=" + __stringify(SBC7240_TIMEOUT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0);
diff --git a/drivers/watchdog/sbc8360.c b/drivers/watchdog/sbc8360.c index a9fd161..dafef1d 100644 --- a/drivers/watchdog/sbc8360.c +++ b/drivers/watchdog/sbc8360.c
@@ -48,6 +48,7 @@ #include <linux/moduleparam.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> static unsigned long sbc8360_is_open; @@ -199,7 +200,7 @@ MODULE_PARM_DESC(timeout, "Index into timeout table (0-63) (default=27 (60s))"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* * Kernel methods.
diff --git a/drivers/watchdog/sbc_epx_c3.c b/drivers/watchdog/sbc_epx_c3.c index 1d291dc..b17bd1db 100644 --- a/drivers/watchdog/sbc_epx_c3.c +++ b/drivers/watchdog/sbc_epx_c3.c
@@ -25,6 +25,7 @@ #include <linux/ioport.h> #include <linux/uaccess.h> #include <linux/io.h> +#include <linux/stringify.h> static int epx_c3_alive; @@ -33,7 +34,7 @@ static int epx_c3_alive; static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); #define EPXC3_WATCHDOG_CTL_REG 0x1ee /* write 1 to enable, 0 to disable */ #define EPXC3_WATCHDOG_PET_REG 0x1ef /* write anything to pet once enabled */
diff --git a/drivers/watchdog/sbsa_gwdt.c b/drivers/watchdog/sbsa_gwdt.c index e04d42c..3a5ff48 100644 --- a/drivers/watchdog/sbsa_gwdt.c +++ b/drivers/watchdog/sbsa_gwdt.c
@@ -46,6 +46,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/uaccess.h> #include <linux/watchdog.h> #include <asm/arch_timer.h> @@ -103,7 +104,7 @@ static unsigned int timeout; module_param(timeout, uint, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (>=0, default=" - __MODULE_STRING(DEFAULT_TIMEOUT) ")"); + __stringify(DEFAULT_TIMEOUT) ")"); /* * action refers to action taken when watchdog gets WS0 @@ -120,7 +121,12 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, S_IRUGO); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); + +static bool early_enable; +module_param(early_enable, bool, 0); +MODULE_PARM_DESC(early_enable, + "Watchdog is started on module insertion (default=0)"); /* * Arm Base System Architecture 1.0 introduces watchdog v1 which @@ -296,6 +302,7 @@ static int sbsa_gwdt_probe(struct platform_device *pdev) struct sbsa_gwdt *gwdt; int ret, irq; u32 status; + bool early_action; gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL); if (!gwdt) @@ -386,14 +393,23 @@ static int sbsa_gwdt_probe(struct platform_device *pdev) */ sbsa_gwdt_set_timeout(wdd, wdd->timeout); + early_action = early_enable && !(status & SBSA_GWDT_WCS_EN); + if (early_action) { + sbsa_gwdt_start(wdd); + set_bit(WDOG_HW_RUNNING, &wdd->status); + } + watchdog_stop_on_reboot(wdd); ret = devm_watchdog_register_device(dev, wdd); - if (ret) + if (ret) { + if (early_action) + sbsa_gwdt_stop(wdd); return ret; + } dev_info(dev, "Initialized with %ds timeout @ %u Hz, action=%d.%s\n", wdd->timeout, gwdt->clk, action, - status & SBSA_GWDT_WCS_EN ? " [enabled]" : ""); + watchdog_hw_running(wdd) ? " [enabled]" : ""); return 0; }
diff --git a/drivers/watchdog/sc1200wdt.c b/drivers/watchdog/sc1200wdt.c index 1d3300c..34cd574 100644 --- a/drivers/watchdog/sc1200wdt.c +++ b/drivers/watchdog/sc1200wdt.c
@@ -42,6 +42,7 @@ #include <linux/semaphore.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> #define SC1200_MODULE_VER "build 20020303" #define SC1200_MODULE_NAME "sc1200wdt" @@ -92,7 +93,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")");
diff --git a/drivers/watchdog/sch311x_wdt.c b/drivers/watchdog/sch311x_wdt.c index 9670a1e..a2a0b5c 100644 --- a/drivers/watchdog/sch311x_wdt.c +++ b/drivers/watchdog/sch311x_wdt.c
@@ -31,6 +31,7 @@ #include <linux/spinlock.h> /* For spin_lock/spin_unlock/... */ #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ #include <linux/io.h> /* For inb/outb/... */ +#include <linux/stringify.h> /* For __stringify */ /* Module and version information */ #define DRV_NAME "sch311x_wdt" @@ -68,13 +69,13 @@ static int timeout = WATCHDOG_TIMEOUT; /* in seconds */ module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1<= timeout <=15300, default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) "."); + __stringify(WATCHDOG_TIMEOUT) "."); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* * Super-IO functions
diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c index 719f100..8adecf5 100644 --- a/drivers/watchdog/shwdt.c +++ b/drivers/watchdog/shwdt.c
@@ -30,6 +30,7 @@ #include <linux/io.h> #include <linux/clk.h> #include <linux/err.h> +#include <linux/stringify.h> #include <asm/watchdog.h> #define DRV_NAME "sh-wdt" @@ -329,14 +330,14 @@ MODULE_ALIAS("platform:" DRV_NAME); module_param(clock_division_ratio, int, 0); MODULE_PARM_DESC(clock_division_ratio, "Clock division ratio. Valid ranges are from 0x5 (1.31ms) " - "to 0x7 (5.25ms). (default=" __MODULE_STRING(WTCSR_CKS_4096) ")"); + "to 0x7 (5.25ms). (default=" __stringify(WTCSR_CKS_4096) ")"); module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (1 <= heartbeat <= 3600, default=" - __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); + __stringify(WATCHDOG_HEARTBEAT) ")"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")");
diff --git a/drivers/watchdog/simatic-ipc-wdt.c b/drivers/watchdog/simatic-ipc-wdt.c index 1e91f0a..addeecc 100644 --- a/drivers/watchdog/simatic-ipc-wdt.c +++ b/drivers/watchdog/simatic-ipc-wdt.c
@@ -22,6 +22,7 @@ #include <linux/sizes.h> #include <linux/util_macros.h> #include <linux/watchdog.h> +#include <linux/stringify.h> #define WD_ENABLE_IOADR 0x62 #define WD_TRIGGER_IOADR 0x66 @@ -42,7 +43,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0000); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static struct resource gp_status_reg_227e_res = DEFINE_RES_IO_NAMED(GP_STATUS_REG_227E, SZ_1, KBUILD_MODNAME);
diff --git a/drivers/watchdog/sl28cpld_wdt.c b/drivers/watchdog/sl28cpld_wdt.c index c0b5e5f..e32b757 100644 --- a/drivers/watchdog/sl28cpld_wdt.c +++ b/drivers/watchdog/sl28cpld_wdt.c
@@ -10,6 +10,7 @@ #include <linux/platform_device.h> #include <linux/property.h> #include <linux/regmap.h> +#include <linux/stringify.h> #include <linux/watchdog.h> /* @@ -30,7 +31,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static int timeout; module_param(timeout, int, 0);
diff --git a/drivers/watchdog/smsc37b787_wdt.c b/drivers/watchdog/smsc37b787_wdt.c index 9f2c2ab..0ee36ae3 100644 --- a/drivers/watchdog/smsc37b787_wdt.c +++ b/drivers/watchdog/smsc37b787_wdt.c
@@ -55,6 +55,7 @@ #include <linux/spinlock.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> /* enable support for minutes as units? */ @@ -611,4 +612,4 @@ MODULE_PARM_DESC(timeout, "range is 1-255 units, default is 60"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")");
diff --git a/drivers/watchdog/softdog.c b/drivers/watchdog/softdog.c index 0820e35..0ff1259 100644 --- a/drivers/watchdog/softdog.c +++ b/drivers/watchdog/softdog.c
@@ -24,6 +24,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/reboot.h> +#include <linux/stringify.h> #include <linux/types.h> #include <linux/watchdog.h> #include <linux/workqueue.h> @@ -33,13 +34,13 @@ static unsigned int soft_margin = TIMER_MARGIN; /* in seconds */ module_param(soft_margin, uint, 0); MODULE_PARM_DESC(soft_margin, "Watchdog soft_margin in seconds. (0 < soft_margin < 65536, default=" - __MODULE_STRING(TIMER_MARGIN) ")"); + __stringify(TIMER_MARGIN) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static int soft_noboot; module_param(soft_noboot, int, 0);
diff --git a/drivers/watchdog/sp5100_tco.c b/drivers/watchdog/sp5100_tco.c index 72ad596..14d4bff 100644 --- a/drivers/watchdog/sp5100_tco.c +++ b/drivers/watchdog/sp5100_tco.c
@@ -33,12 +33,14 @@ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt #include <linux/init.h> +#include <linux/dmi.h> #include <linux/io.h> #include <linux/ioport.h> #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/pci.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/types.h> #include <linux/watchdog.h> @@ -69,18 +71,18 @@ static struct pci_dev *sp5100_tco_pci; static bool action = WATCHDOG_ACTION; module_param(action, bool, 0); MODULE_PARM_DESC(action, "Action taken when watchdog expires, 0 to reset, 1 to poweroff (default=" - __MODULE_STRING(WATCHDOG_ACTION) ")"); + __stringify(WATCHDOG_ACTION) ")"); #define WATCHDOG_HEARTBEAT 60 /* 60 sec default heartbeat. */ static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (default=" - __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); + __stringify(WATCHDOG_HEARTBEAT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started." - " (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + " (default=" __stringify(WATCHDOG_NOWAYOUT) ")"); /* * Some TCO specific functions @@ -240,6 +242,35 @@ static u32 sp5100_tco_read_pm_reg32(u8 index) return val; } +/* + * The Gigabyte GA-78LMT-USB3 firmware programs the legacy SP5100 watchdog + * MMIO window at 0xfec000f0. This address lies inside the IOAPIC resource, + * so the generic resource reservation fails even though firmware explicitly + * assigns the watchdog to this address. + * + * Keep this exception narrowly scoped to the affected system and firmware + * address. Do not relocate or otherwise reprogram the watchdog. + */ +#define SP5100_WDT_GA78LMT_MMIO 0xfec000f0 + +static const struct dmi_system_id sp5100_tco_unreserved_mmio_dmi[] = { + { + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "Gigabyte Technology Co., Ltd."), + DMI_MATCH(DMI_PRODUCT_NAME, "GA-78LMT-USB3"), + }, + }, + {} +}; + +static bool sp5100_tco_allow_unreserved_mmio(struct sp5100_tco *tco, + u32 mmio_addr) +{ + return tco->tco_reg_layout == sp5100 && + mmio_addr == SP5100_WDT_GA78LMT_MMIO && + dmi_check_system(sp5100_tco_unreserved_mmio_dmi); +} + static u32 sp5100_tco_request_region(struct device *dev, u32 mmio_addr, const char *dev_name) @@ -259,6 +290,7 @@ static u32 sp5100_tco_prepare_base(struct sp5100_tco *tco, const char *dev_name) { struct device *dev = tco->wdd.parent; + bool reserved = false; dev_dbg(dev, "Got 0x%08x from SBResource_MMIO register\n", mmio_addr); @@ -266,11 +298,29 @@ static u32 sp5100_tco_prepare_base(struct sp5100_tco *tco, return -ENODEV; /* Check for MMIO address and alternate MMIO address conflicts */ - if (mmio_addr) - mmio_addr = sp5100_tco_request_region(dev, mmio_addr, dev_name); + if (mmio_addr) { + u32 requested_addr; - if (!mmio_addr && alt_mmio_addr) - mmio_addr = sp5100_tco_request_region(dev, alt_mmio_addr, dev_name); + requested_addr = sp5100_tco_request_region(dev, mmio_addr, + dev_name); + if (requested_addr) { + mmio_addr = requested_addr; + reserved = true; + } else if (sp5100_tco_allow_unreserved_mmio(tco, mmio_addr)) { + dev_info(dev, + "Using firmware watchdog MMIO 0x%08x without reserving it\n", + mmio_addr); + } else { + mmio_addr = 0; + } + } + + if (!mmio_addr && alt_mmio_addr) { + mmio_addr = sp5100_tco_request_region(dev, alt_mmio_addr, + dev_name); + if (mmio_addr) + reserved = true; + } if (!mmio_addr) { dev_err(dev, "Failed to reserve MMIO or alternate MMIO region\n"); @@ -280,7 +330,9 @@ static u32 sp5100_tco_prepare_base(struct sp5100_tco *tco, tco->tcobase = devm_ioremap(dev, mmio_addr, SP5100_WDT_MEM_MAP_SIZE); if (!tco->tcobase) { dev_err(dev, "MMIO address 0x%08x failed mapping\n", mmio_addr); - devm_release_mem_region(dev, mmio_addr, SP5100_WDT_MEM_MAP_SIZE); + if (reserved) + devm_release_mem_region(dev, mmio_addr, + SP5100_WDT_MEM_MAP_SIZE); return -ENOMEM; }
diff --git a/drivers/watchdog/sp805_wdt.c b/drivers/watchdog/sp805_wdt.c index c2125f2..925f121 100644 --- a/drivers/watchdog/sp805_wdt.c +++ b/drivers/watchdog/sp805_wdt.c
@@ -321,27 +321,29 @@ static void sp805_wdt_remove(struct amba_device *adev) watchdog_set_drvdata(&wdt->wdd, NULL); } -static int __maybe_unused sp805_wdt_suspend(struct device *dev) +static int sp805_wdt_suspend(struct device *dev) { struct sp805_wdt *wdt = dev_get_drvdata(dev); - if (watchdog_active(&wdt->wdd)) + if (watchdog_active(&wdt->wdd) || + watchdog_hw_running(&wdt->wdd)) return wdt_disable(&wdt->wdd); return 0; } -static int __maybe_unused sp805_wdt_resume(struct device *dev) +static int sp805_wdt_resume(struct device *dev) { struct sp805_wdt *wdt = dev_get_drvdata(dev); - if (watchdog_active(&wdt->wdd)) + if (watchdog_active(&wdt->wdd) || + watchdog_hw_running(&wdt->wdd)) return wdt_enable(&wdt->wdd); return 0; } -static SIMPLE_DEV_PM_OPS(sp805_wdt_dev_pm_ops, sp805_wdt_suspend, +static DEFINE_SIMPLE_DEV_PM_OPS(sp805_wdt_dev_pm_ops, sp805_wdt_suspend, sp805_wdt_resume); static const struct amba_id sp805_wdt_ids[] = { @@ -361,7 +363,7 @@ MODULE_DEVICE_TABLE(amba, sp805_wdt_ids); static struct amba_driver sp805_wdt_driver = { .drv = { .name = MODULE_NAME, - .pm = &sp805_wdt_dev_pm_ops, + .pm = pm_sleep_ptr(&sp805_wdt_dev_pm_ops), }, .id_table = sp805_wdt_ids, .probe = sp805_wdt_probe,
diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c index 5a3254c..044b4fd 100644 --- a/drivers/watchdog/starfive-wdt.c +++ b/drivers/watchdog/starfive-wdt.c
@@ -12,6 +12,7 @@ #include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/reset.h> +#include <linux/stringify.h> #include <linux/watchdog.h> /* JH7100 Watchdog register define */ @@ -72,12 +73,12 @@ module_param(early_enable, bool, 0); module_param(nowayout, bool, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (default=" - __MODULE_STRING(STARFIVE_WDT_DEFAULT_TIME) ")"); + __stringify(STARFIVE_WDT_DEFAULT_TIME) ")"); MODULE_PARM_DESC(early_enable, "Watchdog is started at boot time if set to 1, default=" - __MODULE_STRING(STARFIVE_WDT_EARLY_ENA)); + __stringify(STARFIVE_WDT_EARLY_ENA)); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct starfive_wdt_variant { unsigned int control; /* Watchdog Control Register for reset enable */
diff --git a/drivers/watchdog/stmp3xxx_rtc_wdt.c b/drivers/watchdog/stmp3xxx_rtc_wdt.c index 0604471..7511599 100644 --- a/drivers/watchdog/stmp3xxx_rtc_wdt.c +++ b/drivers/watchdog/stmp3xxx_rtc_wdt.c
@@ -13,6 +13,7 @@ #include <linux/stmp3xxx_rtc_wdt.h> #include <linux/notifier.h> #include <linux/reboot.h> +#include <linux/stringify.h> #define WDOG_TICK_RATE 1000 /* 1 kHz clock */ #define STMP3XXX_DEFAULT_TIMEOUT 19 @@ -21,8 +22,8 @@ static int heartbeat = STMP3XXX_DEFAULT_TIMEOUT; module_param(heartbeat, uint, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat period in seconds from 1 to " - __MODULE_STRING(STMP3XXX_MAX_TIMEOUT) ", default " - __MODULE_STRING(STMP3XXX_DEFAULT_TIMEOUT)); + __stringify(STMP3XXX_MAX_TIMEOUT) ", default " + __stringify(STMP3XXX_DEFAULT_TIMEOUT)); static int wdt_start(struct watchdog_device *wdd) { @@ -114,7 +115,7 @@ static void stmp3xxx_wdt_remove(struct platform_device *pdev) unregister_reboot_notifier(&wdt_notifier); } -static int __maybe_unused stmp3xxx_wdt_suspend(struct device *dev) +static int stmp3xxx_wdt_suspend(struct device *dev) { struct watchdog_device *wdd = &stmp3xxx_wdd; @@ -124,7 +125,7 @@ static int __maybe_unused stmp3xxx_wdt_suspend(struct device *dev) return 0; } -static int __maybe_unused stmp3xxx_wdt_resume(struct device *dev) +static int stmp3xxx_wdt_resume(struct device *dev) { struct watchdog_device *wdd = &stmp3xxx_wdd; @@ -134,13 +135,13 @@ static int __maybe_unused stmp3xxx_wdt_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(stmp3xxx_wdt_pm_ops, +static DEFINE_SIMPLE_DEV_PM_OPS(stmp3xxx_wdt_pm_ops, stmp3xxx_wdt_suspend, stmp3xxx_wdt_resume); static struct platform_driver stmp3xxx_wdt_driver = { .driver = { .name = "stmp3xxx_rtc_wdt", - .pm = &stmp3xxx_wdt_pm_ops, + .pm = pm_sleep_ptr(&stmp3xxx_wdt_pm_ops), }, .probe = stmp3xxx_wdt_probe, .remove = stmp3xxx_wdt_remove,
diff --git a/drivers/watchdog/stpmic1_wdt.c b/drivers/watchdog/stpmic1_wdt.c index 45d0c54..17f0cde 100644 --- a/drivers/watchdog/stpmic1_wdt.c +++ b/drivers/watchdog/stpmic1_wdt.c
@@ -9,6 +9,7 @@ #include <linux/of.h> #include <linux/regmap.h> #include <linux/slab.h> +#include <linux/stringify.h> #include <linux/watchdog.h> /* WATCHDOG CONTROL REGISTER bit */ @@ -25,7 +26,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct stpmic1_wdt { struct stpmic1 *pmic;
diff --git a/drivers/watchdog/sun4v_wdt.c b/drivers/watchdog/sun4v_wdt.c index 8db86ad..ad56d77 100644 --- a/drivers/watchdog/sun4v_wdt.c +++ b/drivers/watchdog/sun4v_wdt.c
@@ -15,6 +15,7 @@ #include <linux/kernel.h> #include <linux/module.h> #include <linux/moduleparam.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #include <asm/hypervisor.h> #include <asm/mdesc.h> @@ -27,12 +28,12 @@ static unsigned int timeout; module_param(timeout, uint, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=" - __MODULE_STRING(WDT_TIMEOUT) ")"); + __stringify(WDT_TIMEOUT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, S_IRUGO); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static int sun4v_wdt_stop(struct watchdog_device *wdd) {
diff --git a/drivers/watchdog/sunplus_wdt.c b/drivers/watchdog/sunplus_wdt.c index ae0c11a..f2e4590 100644 --- a/drivers/watchdog/sunplus_wdt.c +++ b/drivers/watchdog/sunplus_wdt.c
@@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/reset.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define WDT_CTRL 0x00 @@ -38,7 +39,7 @@ MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct sp_wdt_priv { struct watchdog_device wdev;
diff --git a/drivers/watchdog/sunxi_wdt.c b/drivers/watchdog/sunxi_wdt.c index 3db3452..1e55c5f 100644 --- a/drivers/watchdog/sunxi_wdt.c +++ b/drivers/watchdog/sunxi_wdt.c
@@ -20,6 +20,7 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/types.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define WDT_MAX_TIMEOUT 16 @@ -357,7 +358,7 @@ MODULE_PARM_DESC(timeout, "Watchdog heartbeat in seconds"); module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " - "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + "(default=" __stringify(WATCHDOG_NOWAYOUT) ")"); MODULE_LICENSE("GPL"); MODULE_AUTHOR("Carlo Caione <carlo.caione@gmail.com>");
diff --git a/drivers/watchdog/tegra_wdt.c b/drivers/watchdog/tegra_wdt.c index d5de6c0..6b3f65c 100644 --- a/drivers/watchdog/tegra_wdt.c +++ b/drivers/watchdog/tegra_wdt.c
@@ -9,6 +9,7 @@ #include <linux/io.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/watchdog.h> /* minimum and maximum watchdog trigger timeout, in seconds */ @@ -67,13 +68,13 @@ static int heartbeat = WDT_HEARTBEAT; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeats in seconds. (default = " - __MODULE_STRING(WDT_HEARTBEAT) ")"); + __stringify(WDT_HEARTBEAT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static int tegra_wdt_start(struct watchdog_device *wdd) {
diff --git a/drivers/watchdog/tqmx86_wdt.c b/drivers/watchdog/tqmx86_wdt.c index 83860e9..1da45a3 100644 --- a/drivers/watchdog/tqmx86_wdt.c +++ b/drivers/watchdog/tqmx86_wdt.c
@@ -14,6 +14,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/timer.h> +#include <linux/stringify.h> #include <linux/watchdog.h> /* default timeout (secs) */ @@ -23,7 +24,7 @@ static unsigned int timeout; module_param(timeout, uint, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=4096, default=" - __MODULE_STRING(WDT_TIMEOUT) ")"); + __stringify(WDT_TIMEOUT) ")"); struct tqmx86_wdt { struct watchdog_device wdd; void __iomem *io_base;
diff --git a/drivers/watchdog/ts4800_wdt.c b/drivers/watchdog/ts4800_wdt.c index 24b1ad52..1bfc8db 100644 --- a/drivers/watchdog/ts4800_wdt.c +++ b/drivers/watchdog/ts4800_wdt.c
@@ -12,13 +12,14 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/regmap.h> +#include <linux/stringify.h> #include <linux/watchdog.h> static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* possible feed values */ #define TS4800_WDT_FEED_2S 0x1
diff --git a/drivers/watchdog/twl4030_wdt.c b/drivers/watchdog/twl4030_wdt.c index 69a6226..d5e06dc 100644 --- a/drivers/watchdog/twl4030_wdt.c +++ b/drivers/watchdog/twl4030_wdt.c
@@ -12,13 +12,14 @@ #include <linux/watchdog.h> #include <linux/platform_device.h> #include <linux/mfd/twl.h> +#include <linux/stringify.h> #define TWL4030_WATCHDOG_CFG_REG_OFFS 0x3 static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " - "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + "(default=" __stringify(WATCHDOG_NOWAYOUT) ")"); static int twl4030_wdt_write(unsigned char val) {
diff --git a/drivers/watchdog/txx9wdt.c b/drivers/watchdog/txx9wdt.c index 3053498..161a779 100644 --- a/drivers/watchdog/txx9wdt.c +++ b/drivers/watchdog/txx9wdt.c
@@ -16,6 +16,7 @@ #include <linux/clk.h> #include <linux/err.h> #include <linux/io.h> +#include <linux/stringify.h> #include <asm/txx9tmr.h> #define WD_TIMER_CCD 7 /* 1/256 */ @@ -27,14 +28,14 @@ static unsigned int timeout = TIMER_MARGIN; /* in seconds */ module_param(timeout, uint, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. " - "(0<timeout<((2^" __MODULE_STRING(TXX9_TIMER_BITS) ")/(IMCLK/256)), " - "default=" __MODULE_STRING(TIMER_MARGIN) ")"); + "(0<timeout<((2^" __stringify(TXX9_TIMER_BITS) ")/(IMCLK/256)), " + "default=" __stringify(TIMER_MARGIN) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " - "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + "(default=" __stringify(WATCHDOG_NOWAYOUT) ")"); static struct txx9_tmr_reg __iomem *txx9wdt_reg; static struct clk *txx9_imclk;
diff --git a/drivers/watchdog/uniphier_wdt.c b/drivers/watchdog/uniphier_wdt.c index 8e9242c..d09fb2a 100644 --- a/drivers/watchdog/uniphier_wdt.c +++ b/drivers/watchdog/uniphier_wdt.c
@@ -13,6 +13,7 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/regmap.h> +#include <linux/stringify.h> #include <linux/watchdog.h> /* WDT timer setting register */ @@ -245,12 +246,12 @@ module_platform_driver(uniphier_wdt_driver); module_param(timeout, uint, 0000); MODULE_PARM_DESC(timeout, "Watchdog timeout seconds in power of 2. (0 < timeout < 128, default=" - __MODULE_STRING(WDT_DEFAULT_TIMEOUT) ")"); + __stringify(WDT_DEFAULT_TIMEOUT) ")"); module_param(nowayout, bool, 0000); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); MODULE_AUTHOR("Keiji Hayashibara <hayashibara.keiji@socionext.com>"); MODULE_DESCRIPTION("UniPhier Watchdog Device Driver");
diff --git a/drivers/watchdog/via_wdt.c b/drivers/watchdog/via_wdt.c index be4ca61..effa9bc 100644 --- a/drivers/watchdog/via_wdt.c +++ b/drivers/watchdog/via_wdt.c
@@ -18,6 +18,7 @@ #include <linux/jiffies.h> #include <linux/module.h> #include <linux/pci.h> +#include <linux/stringify.h> #include <linux/timer.h> #include <linux/watchdog.h> @@ -56,12 +57,12 @@ static int timeout = WDT_TIMEOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds, between 1 and 1023 " - "(default = " __MODULE_STRING(WDT_TIMEOUT) ")"); + "(default = " __stringify(WDT_TIMEOUT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " - "(default = " __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + "(default = " __stringify(WATCHDOG_NOWAYOUT) ")"); static struct watchdog_device wdt_dev; static struct resource wdt_res;
diff --git a/drivers/watchdog/visconti_wdt.c b/drivers/watchdog/visconti_wdt.c index 7795e7f..fc4f0d4 100644 --- a/drivers/watchdog/visconti_wdt.c +++ b/drivers/watchdog/visconti_wdt.c
@@ -11,6 +11,7 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define WDT_CNT 0x00 @@ -29,7 +30,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC( nowayout, - "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT)")"); + "Watchdog cannot be stopped once started (default=" __stringify(WATCHDOG_NOWAYOUT)")"); struct visconti_wdt_priv { struct watchdog_device wdev;
diff --git a/drivers/watchdog/w83627hf_wdt.c b/drivers/watchdog/w83627hf_wdt.c index db77599..5aa4d9c 100644 --- a/drivers/watchdog/w83627hf_wdt.c +++ b/drivers/watchdog/w83627hf_wdt.c
@@ -35,6 +35,7 @@ #include <linux/init.h> #include <linux/io.h> #include <linux/dmi.h> +#include <linux/stringify.h> #define WATCHDOG_NAME "w83627hf/thf/hg/dhg WDT" #define WATCHDOG_TIMEOUT 60 /* 60 sec default timeout */ @@ -55,13 +56,13 @@ static int timeout; /* in seconds */ module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1 <= timeout <= 255, default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) "."); + __stringify(WATCHDOG_TIMEOUT) "."); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static int early_disable; module_param(early_disable, int, 0);
diff --git a/drivers/watchdog/w83877f_wdt.c b/drivers/watchdog/w83877f_wdt.c index 53db59e..3187ea9d1 100644 --- a/drivers/watchdog/w83877f_wdt.c +++ b/drivers/watchdog/w83877f_wdt.c
@@ -54,6 +54,7 @@ #include <linux/init.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> #define OUR_NAME "w83877f_wdt" @@ -84,14 +85,14 @@ static int timeout = WATCHDOG_TIMEOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. (1<=timeout<=3600, default=" - __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); + __stringify(WATCHDOG_TIMEOUT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static void wdt_timer_ping(struct timer_list *); static DEFINE_TIMER(timer, wdt_timer_ping);
diff --git a/drivers/watchdog/w83977f_wdt.c b/drivers/watchdog/w83977f_wdt.c index 3776030..019fbf6 100644 --- a/drivers/watchdog/w83977f_wdt.c +++ b/drivers/watchdog/w83977f_wdt.c
@@ -25,6 +25,7 @@ #include <linux/reboot.h> #include <linux/uaccess.h> #include <linux/io.h> +#include <linux/stringify.h> #define WATCHDOG_VERSION "1.00" @@ -49,7 +50,7 @@ static DEFINE_SPINLOCK(spinlock); module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (15..7635), default=" - __MODULE_STRING(DEFAULT_TIMEOUT) ")"); + __stringify(DEFAULT_TIMEOUT) ")"); module_param(testmode, int, 0); MODULE_PARM_DESC(testmode, "Watchdog testmode (1 = no reboot), default=0"); @@ -57,7 +58,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* * Start the watchdog
diff --git a/drivers/watchdog/wafer5823wdt.c b/drivers/watchdog/wafer5823wdt.c index 2911093..c564d51f 100644 --- a/drivers/watchdog/wafer5823wdt.c +++ b/drivers/watchdog/wafer5823wdt.c
@@ -36,6 +36,7 @@ #include <linux/spinlock.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> #define WATCHDOG_NAME "Wafer 5823 WDT" #define PFX WATCHDOG_NAME ": " @@ -61,13 +62,13 @@ static int timeout = WD_TIMO; /* in seconds */ module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds. 1 <= timeout <= 255, default=" - __MODULE_STRING(WD_TIMO) "."); + __stringify(WD_TIMO) "."); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static void wafwdt_ping(void) {
diff --git a/drivers/watchdog/watchdog_core.c b/drivers/watchdog/watchdog_core.c index 38c1e63..2948fe5 100644 --- a/drivers/watchdog/watchdog_core.c +++ b/drivers/watchdog/watchdog_core.c
@@ -314,10 +314,7 @@ static int ___watchdog_register_device(struct watchdog_device *wdd) /* Module parameter to force watchdog policy on reboot. */ if (stop_on_reboot != -1) { - if (stop_on_reboot) - set_bit(WDOG_STOP_ON_REBOOT, &wdd->status); - else - clear_bit(WDOG_STOP_ON_REBOOT, &wdd->status); + assign_bit(WDOG_STOP_ON_REBOOT, &wdd->status, stop_on_reboot); } if (test_bit(WDOG_STOP_ON_REBOOT, &wdd->status)) {
diff --git a/drivers/watchdog/watchdog_dev.c b/drivers/watchdog/watchdog_dev.c index d789500..e8c1fcb 100644 --- a/drivers/watchdog/watchdog_dev.c +++ b/drivers/watchdog/watchdog_dev.c
@@ -44,6 +44,7 @@ #include <linux/types.h> /* For standard types (like size_t) */ #include <linux/watchdog.h> /* For watchdog specific items */ #include <linux/uaccess.h> /* For copy_to_user/put_user/... */ +#include <linux/stringify.h> /* For __stringify */ #include "watchdog_core.h" #include "watchdog_pretimeout.h" @@ -305,6 +306,10 @@ static int watchdog_stop(struct watchdog_device *wdd) if (wdd->ops->stop) { clear_bit(WDOG_HW_RUNNING, &wdd->status); err = wdd->ops->stop(wdd); + if (err < 0) { + pr_err("watchdog%d: Failed to stop watchdog: %pe\n", + wdd->id, ERR_PTR(err)); + } trace_watchdog_stop(wdd, err); } else { set_bit(WDOG_HW_RUNNING, &wdd->status); @@ -1314,9 +1319,9 @@ int watchdog_dev_resume(struct watchdog_device *wdd) module_param(handle_boot_enabled, bool, 0444); MODULE_PARM_DESC(handle_boot_enabled, "Watchdog core auto-updates boot enabled watchdogs before userspace takes over (default=" - __MODULE_STRING(IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED)) ")"); + __stringify(IS_ENABLED(CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED)) ")"); module_param(open_timeout, uint, 0644); MODULE_PARM_DESC(open_timeout, "Maximum time (in seconds, 0 means infinity) for userspace to take over a running watchdog (default=" - __MODULE_STRING(CONFIG_WATCHDOG_OPEN_TIMEOUT) ")"); + __stringify(CONFIG_WATCHDOG_OPEN_TIMEOUT) ")");
diff --git a/drivers/watchdog/wdat_wdt.c b/drivers/watchdog/wdat_wdt.c index 55ea16e..a418da4 100644 --- a/drivers/watchdog/wdat_wdt.c +++ b/drivers/watchdog/wdat_wdt.c
@@ -13,6 +13,7 @@ #include <linux/module.h> #include <linux/platform_device.h> #include <linux/pm.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #define MAX_WDAT_ACTIONS ACPI_WDAT_ACTION_RESERVED @@ -54,14 +55,14 @@ struct wdat_wdt { static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); #define WDAT_DEFAULT_TIMEOUT 30 static int timeout = WDAT_DEFAULT_TIMEOUT; module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (default=" - __MODULE_STRING(WDAT_DEFAULT_TIMEOUT) ")"); + __stringify(WDAT_DEFAULT_TIMEOUT) ")"); static int wdat_wdt_read(struct wdat_wdt *wdat, const struct wdat_instruction *instr, u32 *value)
diff --git a/drivers/watchdog/wdt.c b/drivers/watchdog/wdt.c index 3980d60..71517a9 100644 --- a/drivers/watchdog/wdt.c +++ b/drivers/watchdog/wdt.c
@@ -43,6 +43,7 @@ #include <linux/init.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> #include "wd501p.h" @@ -60,13 +61,13 @@ static int wd_heartbeat; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0 < heartbeat < 65536, default=" - __MODULE_STRING(WD_TIMO) ")"); + __stringify(WD_TIMO) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* You must set these - there is no sane way to probe for this board. */ static int io = 0x240; @@ -311,7 +312,7 @@ static irqreturn_t wdt_interrupt(int irq, void *dev_id) * @ppos: pointer to the position to write. No seeks allowed * * A write to a watchdog device is defined as a keepalive signal. Any - * write of data will do, as we we don't define content meaning. + * write of data will do, as we don't define content meaning. */ static ssize_t wdt_write(struct file *file, const char __user *buf, @@ -406,7 +407,7 @@ static long wdt_ioctl(struct file *file, unsigned int cmd, unsigned long arg) * open and on opening we load the counters. Counter zero is a 100Hz * cascade, into counter 1 which downcounts to reboot. When the counter * triggers counter 2 downcounts the length of the reset pulse which - * set set to be as long as possible. + * set to be as long as possible. */ static int wdt_open(struct inode *inode, struct file *file)
diff --git a/drivers/watchdog/wdt977.c b/drivers/watchdog/wdt977.c index 4f449ac..0d2e1e0c 100644 --- a/drivers/watchdog/wdt977.c +++ b/drivers/watchdog/wdt977.c
@@ -34,6 +34,7 @@ #include <linux/reboot.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> #include <asm/mach-types.h> @@ -59,7 +60,7 @@ static DEFINE_SPINLOCK(spinlock); module_param(timeout, int, 0); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds (60..15300, default=" - __MODULE_STRING(DEFAULT_TIMEOUT) ")"); + __stringify(DEFAULT_TIMEOUT) ")"); module_param(testmode, int, 0); MODULE_PARM_DESC(testmode, "Watchdog testmode (1 = no reboot), default=0"); @@ -67,7 +68,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* * Start the watchdog @@ -298,7 +299,7 @@ static int wdt977_release(struct inode *inode, struct file *file) * @ppos: pointer to the position to write. No seeks allowed * * A write to a watchdog device is defined as a keepalive signal. Any - * write of data will do, as we we don't define content meaning. + * write of data will do, as we don't define content meaning. */ static ssize_t wdt977_write(struct file *file, const char __user *buf,
diff --git a/drivers/watchdog/wdt_pci.c b/drivers/watchdog/wdt_pci.c index 3918a60..dd5944c 100644 --- a/drivers/watchdog/wdt_pci.c +++ b/drivers/watchdog/wdt_pci.c
@@ -49,6 +49,7 @@ #include <linux/pci.h> #include <linux/io.h> #include <linux/uaccess.h> +#include <linux/stringify.h> #define WDT_IS_PCI @@ -72,13 +73,13 @@ static int wd_heartbeat; module_param(heartbeat, int, 0); MODULE_PARM_DESC(heartbeat, "Watchdog heartbeat in seconds. (0<heartbeat<65536, default=" - __MODULE_STRING(WD_TIMO) ")"); + __stringify(WD_TIMO) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); /* Support for the Fan Tachometer on the PCI-WDT501 */ static int tachometer; @@ -347,7 +348,7 @@ static irqreturn_t wdtpci_interrupt(int irq, void *dev_id) * @ppos: pointer to the position to write. No seeks allowed * * A write to a watchdog device is defined as a keepalive signal. Any - * write of data will do, as we we don't define content meaning. + * write of data will do, as we don't define content meaning. */ static ssize_t wdtpci_write(struct file *file, const char __user *buf, @@ -443,7 +444,7 @@ static long wdtpci_ioctl(struct file *file, unsigned int cmd, * open and on opening we load the counters. Counter zero is a 100Hz * cascade, into counter 1 which downcounts to reboot. When the counter * triggers counter 2 downcounts the length of the reset pulse which - * set set to be as long as possible. + * set to be as long as possible. */ static int wdtpci_open(struct inode *inode, struct file *file)
diff --git a/drivers/watchdog/wm831x_wdt.c b/drivers/watchdog/wm831x_wdt.c index d96ad8f..1aeb532 100644 --- a/drivers/watchdog/wm831x_wdt.c +++ b/drivers/watchdog/wm831x_wdt.c
@@ -13,6 +13,7 @@ #include <linux/platform_device.h> #include <linux/watchdog.h> #include <linux/uaccess.h> +#include <linux/stringify.h> #include <linux/mfd/wm831x/core.h> #include <linux/mfd/wm831x/pdata.h> @@ -22,7 +23,7 @@ static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); struct wm831x_wdt_drvdata { struct watchdog_device wdt;
diff --git a/drivers/watchdog/wm8350_wdt.c b/drivers/watchdog/wm8350_wdt.c index c82c1b7..5eca195 100644 --- a/drivers/watchdog/wm8350_wdt.c +++ b/drivers/watchdog/wm8350_wdt.c
@@ -14,13 +14,14 @@ #include <linux/platform_device.h> #include <linux/watchdog.h> #include <linux/uaccess.h> +#include <linux/stringify.h> #include <linux/mfd/wm8350/core.h> static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static DEFINE_MUTEX(wdt_mutex);
diff --git a/drivers/watchdog/xen_wdt.c b/drivers/watchdog/xen_wdt.c index b343f42..3bc323d 100644 --- a/drivers/watchdog/xen_wdt.c +++ b/drivers/watchdog/xen_wdt.c
@@ -17,6 +17,7 @@ #include <linux/module.h> #include <linux/moduleparam.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #include <xen/xen.h> #include <asm/xen/hypercall.h> @@ -30,12 +31,12 @@ static time64_t wdt_expires; static unsigned int timeout; module_param(timeout, uint, S_IRUGO); MODULE_PARM_DESC(timeout, "Watchdog timeout in seconds " - "(default=" __MODULE_STRING(WATCHDOG_TIMEOUT) ")"); + "(default=" __stringify(WATCHDOG_TIMEOUT) ")"); static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, S_IRUGO); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started " - "(default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + "(default=" __stringify(WATCHDOG_NOWAYOUT) ")"); static inline time64_t set_timeout(struct watchdog_device *wdd) {
diff --git a/drivers/watchdog/xilinx_wwdt.c b/drivers/watchdog/xilinx_wwdt.c index 799ce8d..b7cdf81 100644 --- a/drivers/watchdog/xilinx_wwdt.c +++ b/drivers/watchdog/xilinx_wwdt.c
@@ -12,6 +12,7 @@ #include <linux/math64.h> #include <linux/module.h> #include <linux/platform_device.h> +#include <linux/stringify.h> #include <linux/watchdog.h> /* Max timeout is calculated at 100MHz source clock */ @@ -47,11 +48,11 @@ static int closed_window_percent; module_param(wwdt_timeout, int, 0); MODULE_PARM_DESC(wwdt_timeout, "Watchdog time in seconds. (default=" - __MODULE_STRING(XWWDT_DEFAULT_TIMEOUT) ")"); + __stringify(XWWDT_DEFAULT_TIMEOUT) ")"); module_param(closed_window_percent, int, 0); MODULE_PARM_DESC(closed_window_percent, "Watchdog closed window percentage. (default=" - __MODULE_STRING(XWWDT_CLOSE_WINDOW_PERCENT) ")"); + __stringify(XWWDT_CLOSE_WINDOW_PERCENT) ")"); /** * struct xwwdt_device - Watchdog device structure * @base: base io address of WDT device
diff --git a/drivers/watchdog/ziirave_wdt.c b/drivers/watchdog/ziirave_wdt.c index f3bb935..10d4eaa 100644 --- a/drivers/watchdog/ziirave_wdt.c +++ b/drivers/watchdog/ziirave_wdt.c
@@ -18,6 +18,7 @@ #include <linux/slab.h> #include <linux/sysfs.h> #include <linux/types.h> +#include <linux/stringify.h> #include <linux/watchdog.h> #include <linux/unaligned.h> @@ -94,7 +95,7 @@ MODULE_PARM_DESC(reset_duration, static bool nowayout = WATCHDOG_NOWAYOUT; module_param(nowayout, bool, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); + __stringify(WATCHDOG_NOWAYOUT) ")"); static int ziirave_wdt_revision(struct i2c_client *client, struct ziirave_wdt_rev *rev, u8 command)
diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt index daeac48..e36cd94 100644 --- a/fs/Kconfig.binfmt +++ b/fs/Kconfig.binfmt
@@ -58,7 +58,7 @@ config BINFMT_ELF_FDPIC bool "Kernel support for FDPIC ELF binaries" default y if !BINFMT_ELF - depends on ARM || ((M68K || RISCV || SUPERH || XTENSA) && !MMU) + depends on ARM || ((M68K || RISCV || SUPERH || UML || XTENSA) && !MMU) select ELFCORE help ELF FDPIC binaries are based on ELF, but allow the individual load
diff --git a/include/crypto/aes.h b/include/crypto/aes.h index 9fe8681..fa5c3d3 100644 --- a/include/crypto/aes.h +++ b/include/crypto/aes.h
@@ -177,6 +177,19 @@ static inline int aes_check_keylen(size_t keylen) int aes_expandkey(struct crypto_aes_ctx *ctx, const u8 *in_key, unsigned int key_len); +/** + * aes_zeroize_ctx - Clear a crypto_aes_ctx structure + * @ctx: The location of the context that should be zeroized + * + * Explicitly fills the crypto_aes_ctx with zeroes. This should be done + * once the context is not required anymore to avoid that its contents + * are leaked on the stack or heap (if not using kfree_sensitive()). + */ +static inline void aes_zeroize_ctx(struct crypto_aes_ctx *ctx) +{ + memzero_explicit(ctx, sizeof(*ctx)); +} + /* * The following functions are temporarily exported for use by the AES mode * implementations in arch/$(SRCARCH)/crypto/. These exports will go away when
diff --git a/include/dt-bindings/arm/qcom,ids.h b/include/dt-bindings/arm/qcom,ids.h index 2cf433f..1352970 100644 --- a/include/dt-bindings/arm/qcom,ids.h +++ b/include/dt-bindings/arm/qcom,ids.h
@@ -209,6 +209,7 @@ #define QCOM_ID_IPQ8172 397 #define QCOM_ID_IPQ8173 398 #define QCOM_ID_IPQ8174 399 +#define QCOM_ID_SM7250 400 #define QCOM_ID_IPQ6018 402 #define QCOM_ID_IPQ6028 403 #define QCOM_ID_SDM429W 416 @@ -300,8 +301,10 @@ #define QCOM_ID_QCS9075 676 #define QCOM_ID_QCS615 680 #define QCOM_ID_SA8797P 690 +#define QCOM_ID_SM8975 707 #define QCOM_ID_CQ7790M 731 #define QCOM_ID_CQ7790S 732 +#define QCOM_ID_SM8950 735 #define QCOM_ID_CQ2390M 756 #define QCOM_ID_CQ2390S 758 #define QCOM_ID_IQ2390S 759
diff --git a/include/dt-bindings/arm/ux500_pm_domains.h b/include/dt-bindings/arm/ux500_pm_domains.h index 9bd764f..f7a9fc1 100644 --- a/include/dt-bindings/arm/ux500_pm_domains.h +++ b/include/dt-bindings/arm/ux500_pm_domains.h
@@ -8,8 +8,21 @@ #define _DT_BINDINGS_ARM_UX500_PM_DOMAINS_H #define DOMAIN_VAPE 0 +#define DOMAIN_VARM 1 +#define DOMAIN_VMODEM 2 +#define DOMAIN_VPLL 3 +#define DOMAIN_VSMPS1 4 +#define DOMAIN_VSMPS2 5 +#define DOMAIN_VSMPS3 6 +#define DOMAIN_VRF1 7 +#define DOMAIN_SVA_MMDSP 8 +#define DOMAIN_SVA_PIPE 9 +#define DOMAIN_SIA_MMDSP 10 +#define DOMAIN_SIA_PIPE 11 +#define DOMAIN_SGA 12 +#define DOMAIN_B2R2_MCDE 13 +#define DOMAIN_ESRAM_12 14 +#define DOMAIN_ESRAM_34 15 -/* Number of PM domains. */ -#define NR_DOMAINS (DOMAIN_VAPE + 1) #endif
diff --git a/include/dt-bindings/clock/qcom,eliza-cambistmclkcc.h b/include/dt-bindings/clock/qcom,eliza-cambistmclkcc.h new file mode 100644 index 0000000..7b8b285 --- /dev/null +++ b/include/dt-bindings/clock/qcom,eliza-cambistmclkcc.h
@@ -0,0 +1,32 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_CAM_BIST_MCLK_CC_ELIZA_H +#define _DT_BINDINGS_CLK_QCOM_CAM_BIST_MCLK_CC_ELIZA_H + +/* CAM_BIST_MCLK_CC clocks */ +#define CAM_BIST_MCLK_CC_MCLK0_CLK 0 +#define CAM_BIST_MCLK_CC_MCLK0_CLK_SRC 1 +#define CAM_BIST_MCLK_CC_MCLK1_CLK 2 +#define CAM_BIST_MCLK_CC_MCLK1_CLK_SRC 3 +#define CAM_BIST_MCLK_CC_MCLK2_CLK 4 +#define CAM_BIST_MCLK_CC_MCLK2_CLK_SRC 5 +#define CAM_BIST_MCLK_CC_MCLK3_CLK 6 +#define CAM_BIST_MCLK_CC_MCLK3_CLK_SRC 7 +#define CAM_BIST_MCLK_CC_MCLK4_CLK 8 +#define CAM_BIST_MCLK_CC_MCLK4_CLK_SRC 9 +#define CAM_BIST_MCLK_CC_MCLK5_CLK 10 +#define CAM_BIST_MCLK_CC_MCLK5_CLK_SRC 11 +#define CAM_BIST_MCLK_CC_MCLK6_CLK 12 +#define CAM_BIST_MCLK_CC_MCLK6_CLK_SRC 13 +#define CAM_BIST_MCLK_CC_MCLK7_CLK 14 +#define CAM_BIST_MCLK_CC_MCLK7_CLK_SRC 15 +#define CAM_BIST_MCLK_CC_PLL0 16 +#define CAM_BIST_MCLK_CC_PLL_TEST_CLK 17 +#define CAM_BIST_MCLK_CC_PLL_TEST_DIV_CLK_SRC 18 +#define CAM_BIST_MCLK_CC_SLEEP_CLK 19 +#define CAM_BIST_MCLK_CC_SLEEP_CLK_SRC 20 + +#endif
diff --git a/include/dt-bindings/clock/qcom,eliza-camcc.h b/include/dt-bindings/clock/qcom,eliza-camcc.h new file mode 100644 index 0000000..d85ef97 --- /dev/null +++ b/include/dt-bindings/clock/qcom,eliza-camcc.h
@@ -0,0 +1,151 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_CAM_CC_ELIZA_H +#define _DT_BINDINGS_CLK_QCOM_CAM_CC_ELIZA_H + +/* CAM_CC clocks */ +#define CAM_CC_CAM_TOP_AHB_CLK 0 +#define CAM_CC_CAM_TOP_FAST_AHB_CLK 1 +#define CAM_CC_CAMNOC_DCD_XO_CLK 2 +#define CAM_CC_CAMNOC_NRT_AXI_CLK 3 +#define CAM_CC_CAMNOC_NRT_CRE_CLK 4 +#define CAM_CC_CAMNOC_NRT_IPE_NPS_CLK 5 +#define CAM_CC_CAMNOC_NRT_OFE_ANCHOR_CLK 6 +#define CAM_CC_CAMNOC_NRT_OFE_HDR_CLK 7 +#define CAM_CC_CAMNOC_NRT_OFE_MAIN_CLK 8 +#define CAM_CC_CAMNOC_RT_AXI_CLK 9 +#define CAM_CC_CAMNOC_RT_AXI_CLK_SRC 10 +#define CAM_CC_CAMNOC_RT_IFE_LITE_CLK 11 +#define CAM_CC_CAMNOC_RT_TFE_0_BAYER_CLK 12 +#define CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK 13 +#define CAM_CC_CAMNOC_RT_TFE_1_BAYER_CLK 14 +#define CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK 15 +#define CAM_CC_CAMNOC_RT_TFE_2_BAYER_CLK 16 +#define CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK 17 +#define CAM_CC_CAMNOC_XO_CLK 18 +#define CAM_CC_CCI_0_CLK 19 +#define CAM_CC_CCI_0_CLK_SRC 20 +#define CAM_CC_CCI_1_CLK 21 +#define CAM_CC_CCI_1_CLK_SRC 22 +#define CAM_CC_CCI_2_CLK 23 +#define CAM_CC_CCI_2_CLK_SRC 24 +#define CAM_CC_CORE_AHB_CLK 25 +#define CAM_CC_CPHY_RX_CLK_SRC 26 +#define CAM_CC_CRE_AHB_CLK 27 +#define CAM_CC_CRE_CLK 28 +#define CAM_CC_CRE_CLK_SRC 29 +#define CAM_CC_CSI0PHYTIMER_CLK 30 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC 31 +#define CAM_CC_CSI1PHYTIMER_CLK 32 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC 33 +#define CAM_CC_CSI2PHYTIMER_CLK 34 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC 35 +#define CAM_CC_CSI3PHYTIMER_CLK 36 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC 37 +#define CAM_CC_CSI4PHYTIMER_CLK 38 +#define CAM_CC_CSI4PHYTIMER_CLK_SRC 39 +#define CAM_CC_CSI5PHYTIMER_CLK 40 +#define CAM_CC_CSI5PHYTIMER_CLK_SRC 41 +#define CAM_CC_CSID_CLK 42 +#define CAM_CC_CSID_CLK_SRC 43 +#define CAM_CC_CSID_CSIPHY_RX_CLK 44 +#define CAM_CC_CSIPHY0_CLK 45 +#define CAM_CC_CSIPHY1_CLK 46 +#define CAM_CC_CSIPHY2_CLK 47 +#define CAM_CC_CSIPHY3_CLK 48 +#define CAM_CC_CSIPHY4_CLK 49 +#define CAM_CC_CSIPHY5_CLK 50 +#define CAM_CC_DRV_AHB_CLK 51 +#define CAM_CC_DRV_XO_CLK 52 +#define CAM_CC_FAST_AHB_CLK_SRC 53 +#define CAM_CC_GDSC_CLK 54 +#define CAM_CC_ICP_0_AHB_CLK 55 +#define CAM_CC_ICP_0_CLK 56 +#define CAM_CC_ICP_0_CLK_SRC 57 +#define CAM_CC_ICP_1_AHB_CLK 58 +#define CAM_CC_ICP_1_CLK 59 +#define CAM_CC_ICP_1_CLK_SRC 60 +#define CAM_CC_IFE_LITE_AHB_CLK 61 +#define CAM_CC_IFE_LITE_CLK 62 +#define CAM_CC_IFE_LITE_CLK_SRC 63 +#define CAM_CC_IFE_LITE_CPHY_RX_CLK 64 +#define CAM_CC_IFE_LITE_CSID_CLK 65 +#define CAM_CC_IFE_LITE_CSID_CLK_SRC 66 +#define CAM_CC_IPE_NPS_AHB_CLK 67 +#define CAM_CC_IPE_NPS_CLK 68 +#define CAM_CC_IPE_NPS_CLK_SRC 69 +#define CAM_CC_IPE_NPS_FAST_AHB_CLK 70 +#define CAM_CC_IPE_PPS_CLK 71 +#define CAM_CC_IPE_PPS_FAST_AHB_CLK 72 +#define CAM_CC_JPEG_0_CLK 73 +#define CAM_CC_JPEG_1_CLK 74 +#define CAM_CC_JPEG_CLK_SRC 75 +#define CAM_CC_OFE_AHB_CLK 76 +#define CAM_CC_OFE_ANCHOR_CLK 77 +#define CAM_CC_OFE_ANCHOR_FAST_AHB_CLK 78 +#define CAM_CC_OFE_CLK_SRC 79 +#define CAM_CC_OFE_HDR_CLK 80 +#define CAM_CC_OFE_HDR_FAST_AHB_CLK 81 +#define CAM_CC_OFE_MAIN_CLK 82 +#define CAM_CC_OFE_MAIN_FAST_AHB_CLK 83 +#define CAM_CC_PLL0 84 +#define CAM_CC_PLL0_OUT_EVEN 85 +#define CAM_CC_PLL0_OUT_ODD 86 +#define CAM_CC_PLL1 87 +#define CAM_CC_PLL1_OUT_EVEN 88 +#define CAM_CC_PLL2 89 +#define CAM_CC_PLL2_OUT_EVEN 90 +#define CAM_CC_PLL3 91 +#define CAM_CC_PLL3_OUT_EVEN 92 +#define CAM_CC_PLL4 93 +#define CAM_CC_PLL4_OUT_EVEN 94 +#define CAM_CC_PLL5 95 +#define CAM_CC_PLL5_OUT_EVEN 96 +#define CAM_CC_PLL6 97 +#define CAM_CC_PLL6_OUT_EVEN 98 +#define CAM_CC_PLL6_OUT_ODD 99 +#define CAM_CC_QDSS_DEBUG_CLK 100 +#define CAM_CC_QDSS_DEBUG_CLK_SRC 101 +#define CAM_CC_QDSS_DEBUG_XO_CLK 102 +#define CAM_CC_SLEEP_CLK 103 +#define CAM_CC_SLEEP_CLK_SRC 104 +#define CAM_CC_SLOW_AHB_CLK_SRC 105 +#define CAM_CC_TFE_0_BAYER_CLK 106 +#define CAM_CC_TFE_0_BAYER_FAST_AHB_CLK 107 +#define CAM_CC_TFE_0_CLK_SRC 108 +#define CAM_CC_TFE_0_MAIN_CLK 109 +#define CAM_CC_TFE_0_MAIN_FAST_AHB_CLK 110 +#define CAM_CC_TFE_1_BAYER_CLK 111 +#define CAM_CC_TFE_1_BAYER_FAST_AHB_CLK 112 +#define CAM_CC_TFE_1_CLK_SRC 113 +#define CAM_CC_TFE_1_MAIN_CLK 114 +#define CAM_CC_TFE_1_MAIN_FAST_AHB_CLK 115 +#define CAM_CC_TFE_2_BAYER_CLK 116 +#define CAM_CC_TFE_2_BAYER_FAST_AHB_CLK 117 +#define CAM_CC_TFE_2_CLK_SRC 118 +#define CAM_CC_TFE_2_MAIN_CLK 119 +#define CAM_CC_TFE_2_MAIN_FAST_AHB_CLK 120 +#define CAM_CC_XO_CLK_SRC 121 + +/* CAM_CC power domains */ +#define CAM_CC_IPE_0_GDSC 0 +#define CAM_CC_OFE_GDSC 1 +#define CAM_CC_TFE_0_GDSC 2 +#define CAM_CC_TFE_1_GDSC 3 +#define CAM_CC_TFE_2_GDSC 4 +#define CAM_CC_TITAN_TOP_GDSC 5 + +/* CAM_CC resets */ +#define CAM_CC_DRV_BCR 0 +#define CAM_CC_ICP_BCR 1 +#define CAM_CC_IPE_0_BCR 2 +#define CAM_CC_OFE_BCR 3 +#define CAM_CC_QDSS_DEBUG_BCR 4 +#define CAM_CC_TFE_0_BCR 5 +#define CAM_CC_TFE_1_BCR 6 +#define CAM_CC_TFE_2_BCR 7 + +#endif
diff --git a/include/dt-bindings/clock/qcom,eliza-gpucc.h b/include/dt-bindings/clock/qcom,eliza-gpucc.h new file mode 100644 index 0000000..c3d9b78 --- /dev/null +++ b/include/dt-bindings/clock/qcom,eliza-gpucc.h
@@ -0,0 +1,51 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_ELIZA_H +#define _DT_BINDINGS_CLK_QCOM_GPU_CC_ELIZA_H + +/* GPU_CC clocks */ +#define GPU_CC_AHB_CLK 0 +#define GPU_CC_CRC_AHB_CLK 1 +#define GPU_CC_CX_ACCU_SHIFT_CLK 2 +#define GPU_CC_CX_FF_CLK 3 +#define GPU_CC_CX_GMU_CLK 4 +#define GPU_CC_CXO_AON_CLK 5 +#define GPU_CC_CXO_CLK 6 +#define GPU_CC_DEMET_CLK 7 +#define GPU_CC_DEMET_DIV_CLK_SRC 8 +#define GPU_CC_FF_CLK_SRC 9 +#define GPU_CC_FREQ_MEASURE_CLK 10 +#define GPU_CC_GMU_CLK_SRC 11 +#define GPU_CC_HLOS1_VOTE_GPU_SMMU_CLK 12 +#define GPU_CC_HUB_AON_CLK 13 +#define GPU_CC_HUB_CLK_SRC 14 +#define GPU_CC_HUB_CX_INT_CLK 15 +#define GPU_CC_MEMNOC_GFX_CLK 16 +#define GPU_CC_MND1X_0_GFX3D_CLK 17 +#define GPU_CC_MND1X_1_GFX3D_CLK 18 +#define GPU_CC_PLL0 19 +#define GPU_CC_PLL1 20 +#define GPU_CC_SLEEP_CLK 21 +#define GPU_CC_XO_CLK_SRC 22 +#define GPU_CC_XO_DIV_CLK_SRC 23 + +/* GPU_CC power domains */ +#define GPU_CC_CX_GDSC 0 +#define GPU_CC_GX_GDSC 1 + +/* GPU_CC resets */ +#define GPU_CC_ACD_BCR 0 +#define GPU_CC_CB_BCR 1 +#define GPU_CC_CX_BCR 2 +#define GPU_CC_FAST_HUB_BCR 3 +#define GPU_CC_FF_BCR 4 +#define GPU_CC_GFX3D_AON_BCR 5 +#define GPU_CC_GMU_BCR 6 +#define GPU_CC_GX_BCR 7 +#define GPU_CC_RBCPR_BCR 8 +#define GPU_CC_XO_BCR 9 + +#endif
diff --git a/include/dt-bindings/clock/qcom,eliza-videocc.h b/include/dt-bindings/clock/qcom,eliza-videocc.h new file mode 100644 index 0000000..1e92225 --- /dev/null +++ b/include/dt-bindings/clock/qcom,eliza-videocc.h
@@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_VIDEO_CC_ELIZA_H +#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_ELIZA_H + +/* VIDEO_CC clocks */ +#define VIDEO_CC_AHB_CLK 0 +#define VIDEO_CC_AHB_CLK_SRC 1 +#define VIDEO_CC_MVS0_CLK 2 +#define VIDEO_CC_MVS0_CLK_SRC 3 +#define VIDEO_CC_MVS0_DIV_CLK_SRC 4 +#define VIDEO_CC_MVS0_SHIFT_CLK 5 +#define VIDEO_CC_MVS0C_CLK 6 +#define VIDEO_CC_MVS0C_DIV2_DIV_CLK_SRC 7 +#define VIDEO_CC_MVS0C_SHIFT_CLK 8 +#define VIDEO_CC_PLL0 9 +#define VIDEO_CC_SLEEP_CLK 10 +#define VIDEO_CC_SLEEP_CLK_SRC 11 +#define VIDEO_CC_XO_CLK 12 +#define VIDEO_CC_XO_CLK_SRC 13 + +/* VIDEO_CC power domains */ +#define VIDEO_CC_MVS0_GDSC 0 +#define VIDEO_CC_MVS0C_GDSC 1 + +/* VIDEO_CC resets */ +#define VIDEO_CC_INTERFACE_BCR 0 +#define VIDEO_CC_MVS0_CLK_ARES 1 +#define VIDEO_CC_MVS0_BCR 2 +#define VIDEO_CC_MVS0C_CLK_ARES 3 +#define VIDEO_CC_MVS0C_BCR 4 +#define VIDEO_CC_XO_CLK_ARES 5 + +#endif
diff --git a/include/dt-bindings/clock/qcom,hawi-camcc.h b/include/dt-bindings/clock/qcom,hawi-camcc.h new file mode 100644 index 0000000..6ef7317 --- /dev/null +++ b/include/dt-bindings/clock/qcom,hawi-camcc.h
@@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_CAM_CC_HAWI_H +#define _DT_BINDINGS_CLK_QCOM_CAM_CC_HAWI_H + +/* CAM_CC clocks */ +#define CAM_CC_CAM_TOP_AHB_CLK 0 +#define CAM_CC_CAM_TOP_FAST_AHB_CLK 1 +#define CAM_CC_CAMNOC_DCD_XO_CLK 2 +#define CAM_CC_CAMNOC_NRT_AXI_CLK 3 +#define CAM_CC_CAMNOC_NRT_CRE_CLK 4 +#define CAM_CC_CAMNOC_NRT_IPE_NPS_CLK 5 +#define CAM_CC_CAMNOC_NRT_IPE_SCALERS_CLK 6 +#define CAM_CC_CAMNOC_NRT_OFE_MAIN_CLK 7 +#define CAM_CC_CAMNOC_NRT_SQPF_CLK 8 +#define CAM_CC_CAMNOC_RT_AXI_CLK 9 +#define CAM_CC_CAMNOC_RT_AXI_CLK_SRC 10 +#define CAM_CC_CAMNOC_RT_IFE_LITE_CLK 11 +#define CAM_CC_CAMNOC_RT_TFE_0_MAIN_CLK 12 +#define CAM_CC_CAMNOC_RT_TFE_1_MAIN_CLK 13 +#define CAM_CC_CAMNOC_RT_TFE_2_MAIN_CLK 14 +#define CAM_CC_CCI_0_CLK 15 +#define CAM_CC_CCI_0_CLK_SRC 16 +#define CAM_CC_CCI_1_CLK 17 +#define CAM_CC_CCI_1_CLK_SRC 18 +#define CAM_CC_CCI_2_CLK 19 +#define CAM_CC_CCI_2_CLK_SRC 20 +#define CAM_CC_CORE_AHB_CLK 21 +#define CAM_CC_CPHY_RX_CLK_SRC 22 +#define CAM_CC_CRE_AHB_CLK 23 +#define CAM_CC_CRE_CLK 24 +#define CAM_CC_CRE_CLK_SRC 25 +#define CAM_CC_CSI0PHYTIMER_CLK 26 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC 27 +#define CAM_CC_CSI1PHYTIMER_CLK 28 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC 29 +#define CAM_CC_CSI2PHYTIMER_CLK 30 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC 31 +#define CAM_CC_CSI3PHYTIMER_CLK 32 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC 33 +#define CAM_CC_CSI4PHYTIMER_CLK 34 +#define CAM_CC_CSI4PHYTIMER_CLK_SRC 35 +#define CAM_CC_CSI5PHYTIMER_CLK 36 +#define CAM_CC_CSI5PHYTIMER_CLK_SRC 37 +#define CAM_CC_CSID_CLK 38 +#define CAM_CC_CSID_CLK_SRC 39 +#define CAM_CC_CSID_CSIPHY_RX_CLK 40 +#define CAM_CC_CSIPHY0_CLK 41 +#define CAM_CC_CSIPHY1_CLK 42 +#define CAM_CC_CSIPHY2_CLK 43 +#define CAM_CC_CSIPHY3_CLK 44 +#define CAM_CC_CSIPHY4_CLK 45 +#define CAM_CC_CSIPHY5_CLK 46 +#define CAM_CC_CX_GDSC_CLK 47 +#define CAM_CC_DRV_AHB_CLK 48 +#define CAM_CC_DRV_XO_CLK 49 +#define CAM_CC_FAST_AHB_CLK_SRC 50 +#define CAM_CC_GDSC_CLK 51 +#define CAM_CC_ICP_0_AHB_CLK 52 +#define CAM_CC_ICP_0_CLK 53 +#define CAM_CC_ICP_0_CLK_SRC 54 +#define CAM_CC_ICP_1_AHB_CLK 55 +#define CAM_CC_ICP_1_CLK 56 +#define CAM_CC_ICP_1_CLK_SRC 57 +#define CAM_CC_IFE_LITE_AHB_CLK 58 +#define CAM_CC_IFE_LITE_CLK 59 +#define CAM_CC_IFE_LITE_CLK_SRC 60 +#define CAM_CC_IFE_LITE_CPHY_RX_CLK 61 +#define CAM_CC_IFE_LITE_CSID_CLK 62 +#define CAM_CC_IFE_LITE_CSID_CLK_SRC 63 +#define CAM_CC_IPE_NPS_AHB_CLK 64 +#define CAM_CC_IPE_NPS_CLK 65 +#define CAM_CC_IPE_NPS_CLK_SRC 66 +#define CAM_CC_IPE_NPS_FAST_AHB_CLK 67 +#define CAM_CC_IPE_PPS_CLK 68 +#define CAM_CC_IPE_PPS_FAST_AHB_CLK 69 +#define CAM_CC_IPE_SCALERS_CLK 70 +#define CAM_CC_IPE_SCALERS_FAST_AHB_CLK 71 +#define CAM_CC_JPEG_CLK 72 +#define CAM_CC_JPEG_CLK_SRC 73 +#define CAM_CC_MMSS_AHB_CLK 74 +#define CAM_CC_OFE_AHB_CLK 75 +#define CAM_CC_OFE_ANCHOR_CLK 76 +#define CAM_CC_OFE_ANCHOR_FAST_AHB_CLK 77 +#define CAM_CC_OFE_CLK_SRC 78 +#define CAM_CC_OFE_HDR_CLK 79 +#define CAM_CC_OFE_HDR_FAST_AHB_CLK 80 +#define CAM_CC_OFE_MAIN_CLK 81 +#define CAM_CC_OFE_MAIN_FAST_AHB_CLK 82 +#define CAM_CC_OFE_MP_CLK 83 +#define CAM_CC_OFE_MP_FAST_AHB_CLK 84 +#define CAM_CC_PLL0 85 +#define CAM_CC_PLL0_OUT_EVEN 86 +#define CAM_CC_PLL0_OUT_ODD 87 +#define CAM_CC_PLL1 88 +#define CAM_CC_PLL1_OUT_EVEN 89 +#define CAM_CC_PLL2 90 +#define CAM_CC_PLL2_OUT_EVEN 91 +#define CAM_CC_PLL3 92 +#define CAM_CC_PLL3_OUT_EVEN 93 +#define CAM_CC_PLL4 94 +#define CAM_CC_PLL4_OUT_EVEN 95 +#define CAM_CC_PLL5 96 +#define CAM_CC_PLL5_OUT_EVEN 97 +#define CAM_CC_PLL6 98 +#define CAM_CC_PLL6_OUT_EVEN 99 +#define CAM_CC_PLL6_OUT_ODD 100 +#define CAM_CC_PLL7 101 +#define CAM_CC_PLL8 102 +#define CAM_CC_PLL8_OUT_EVEN 103 +#define CAM_CC_QDSS_DEBUG_CLK 104 +#define CAM_CC_QDSS_DEBUG_CLK_SRC 105 +#define CAM_CC_QDSS_DEBUG_XO_CLK 106 +#define CAM_CC_SLEEP_CLK 107 +#define CAM_CC_SLOW_AHB_CLK_SRC 108 +#define CAM_CC_SQPF_AHB_CLK 109 +#define CAM_CC_SQPF_CLK 110 +#define CAM_CC_SQPF_CLK_SRC 111 +#define CAM_CC_SQPF_FAST_AHB_CLK 112 +#define CAM_CC_TFE_0_BAYER_CLK 113 +#define CAM_CC_TFE_0_BAYER_FAST_AHB_CLK 114 +#define CAM_CC_TFE_0_CLK_SRC 115 +#define CAM_CC_TFE_0_MAIN_CLK 116 +#define CAM_CC_TFE_0_MAIN_FAST_AHB_CLK 117 +#define CAM_CC_TFE_1_BAYER_CLK 118 +#define CAM_CC_TFE_1_BAYER_FAST_AHB_CLK 119 +#define CAM_CC_TFE_1_CLK_SRC 120 +#define CAM_CC_TFE_1_MAIN_CLK 121 +#define CAM_CC_TFE_1_MAIN_FAST_AHB_CLK 122 +#define CAM_CC_TFE_2_BAYER_CLK 123 +#define CAM_CC_TFE_2_BAYER_FAST_AHB_CLK 124 +#define CAM_CC_TFE_2_CLK_SRC 125 +#define CAM_CC_TFE_2_MAIN_CLK 126 +#define CAM_CC_TFE_2_MAIN_FAST_AHB_CLK 127 +#define CAM_CC_TITAN_CAMNOC_XO_CLK 128 +#define CAM_CC_TITAN_MNOC_HF_CLK 129 +#define CAM_CC_TITAN_MNOC_SF_CLK 130 +#define CAM_CC_TRACENOC_TPDM_1_CMB_CLK 131 +#define CAM_CC_XO_CLK_SRC 132 + +/* CAM_CC power domains */ +#define CAM_CC_IPE_0_GDSC 0 +#define CAM_CC_OFE_GDSC 1 +#define CAM_CC_SQPF_GDSC 2 +#define CAM_CC_TFE_0_GDSC 3 +#define CAM_CC_TFE_1_GDSC 4 +#define CAM_CC_TFE_2_GDSC 5 +#define CAM_CC_TITAN_TOP_CX_GDSC 6 +#define CAM_CC_TITAN_TOP_GDSC 7 + +/* CAM_CC resets */ +#define CAM_CC_DRV_BCR 0 +#define CAM_CC_ICP_BCR 1 +#define CAM_CC_IPE_0_BCR 2 +#define CAM_CC_OFE_BCR 3 +#define CAM_CC_QDSS_DEBUG_BCR 4 +#define CAM_CC_SQPF_BCR 5 +#define CAM_CC_TFE_0_BCR 6 +#define CAM_CC_TFE_1_BCR 7 +#define CAM_CC_TFE_2_BCR 8 + +#endif
diff --git a/include/dt-bindings/clock/qcom,hawi-gpucc.h b/include/dt-bindings/clock/qcom,hawi-gpucc.h new file mode 100644 index 0000000..1815347 --- /dev/null +++ b/include/dt-bindings/clock/qcom,hawi-gpucc.h
@@ -0,0 +1,47 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_GPU_CC_HAWI_H +#define _DT_BINDINGS_CLK_QCOM_GPU_CC_HAWI_H + +/* GPU_CC clocks */ +#define GPU_CC_AHB_CLK 0 +#define GPU_CC_CB_CLK 1 +#define GPU_CC_CX_ACCU_SHIFT_CLK 2 +#define GPU_CC_CX_GMU_CLK 3 +#define GPU_CC_CXO_AON_CLK 4 +#define GPU_CC_CXO_CLK 5 +#define GPU_CC_DEMET_CLK 6 +#define GPU_CC_DPM_CLK 7 +#define GPU_CC_FREQ_MEASURE_CLK 8 +#define GPU_CC_GMU_CLK_SRC 9 +#define GPU_CC_GPU_SMMU_VOTE_CLK 10 +#define GPU_CC_GX_ACCU_SHIFT_CLK 11 +#define GPU_CC_HUB_AON_CLK 12 +#define GPU_CC_HUB_CLK_SRC 13 +#define GPU_CC_HUB_CX_INT_CLK 14 +#define GPU_CC_HUB_DIV_CLK_SRC 15 +#define GPU_CC_MEMNOC_GFX_CLK 16 +#define GPU_CC_MXG_AHB_CLK 17 +#define GPU_CC_MXG_XO_CLK 18 +#define GPU_CC_PLL0 19 +#define GPU_CC_RSCC_HUB_AON_CLK 20 +#define GPU_CC_RSCC_XO_AON_CLK 21 +#define GPU_CC_SLEEP_CLK 22 + +/* GPU_CC power domains */ +#define GPU_CC_CX_GDSC 0 +#define GPU_CC_MXG_GDSC 1 + +/* GPU_CC resets */ +#define GPU_CC_CB_BCR 0 +#define GPU_CC_CX_BCR 1 +#define GPU_CC_FAST_HUB_BCR 2 +#define GPU_CC_GMU_BCR 3 +#define GPU_CC_GX_BCR 4 +#define GPU_CC_MXG_BCR 5 +#define GPU_CC_XO_BCR 6 + +#endif
diff --git a/include/dt-bindings/clock/qcom,nord-camcc.h b/include/dt-bindings/clock/qcom,nord-camcc.h new file mode 100644 index 0000000..655fef2 --- /dev/null +++ b/include/dt-bindings/clock/qcom,nord-camcc.h
@@ -0,0 +1,167 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef _DT_BINDINGS_CLK_QCOM_CAM_CC_NORD_H +#define _DT_BINDINGS_CLK_QCOM_CAM_CC_NORD_H + +/* CAM_CC clocks */ +#define CAM_CC_CAMNOC_DCD_XO_CLK 0 +#define CAM_CC_CAMNOC_NRT_AXI_CLK 1 +#define CAM_CC_CAMNOC_RT_AXI_CLK 2 +#define CAM_CC_CAMNOC_RT_AXI_CLK_SRC 3 +#define CAM_CC_CAMNOC_XO_CLK 4 +#define CAM_CC_CCI_0_CLK 5 +#define CAM_CC_CCI_0_CLK_SRC 6 +#define CAM_CC_CCI_1_CLK 7 +#define CAM_CC_CCI_1_CLK_SRC 8 +#define CAM_CC_CCI_2_CLK 9 +#define CAM_CC_CCI_2_CLK_SRC 10 +#define CAM_CC_CCI_3_CLK 11 +#define CAM_CC_CCI_3_CLK_SRC 12 +#define CAM_CC_CCI_4_CLK 13 +#define CAM_CC_CCI_4_CLK_SRC 14 +#define CAM_CC_CCU_FAST_AHB_CLK 15 +#define CAM_CC_CORE_AHB_CLK 16 +#define CAM_CC_CPHY_RX_CLK_SRC 17 +#define CAM_CC_CSI0PHYTIMER_CLK 18 +#define CAM_CC_CSI0PHYTIMER_CLK_SRC 19 +#define CAM_CC_CSI1PHYTIMER_CLK 20 +#define CAM_CC_CSI1PHYTIMER_CLK_SRC 21 +#define CAM_CC_CSI2PHYTIMER_CLK 22 +#define CAM_CC_CSI2PHYTIMER_CLK_SRC 23 +#define CAM_CC_CSI3PHYTIMER_CLK 24 +#define CAM_CC_CSI3PHYTIMER_CLK_SRC 25 +#define CAM_CC_CSI4PHYTIMER_CLK 26 +#define CAM_CC_CSI4PHYTIMER_CLK_SRC 27 +#define CAM_CC_CSID_CLK 28 +#define CAM_CC_CSID_CLK_SRC 29 +#define CAM_CC_CSID_CSIPHY_RX_CLK 30 +#define CAM_CC_CSIPHY0_CLK 31 +#define CAM_CC_CSIPHY1_CLK 32 +#define CAM_CC_CSIPHY2_CLK 33 +#define CAM_CC_CSIPHY3_CLK 34 +#define CAM_CC_CSIPHY4_CLK 35 +#define CAM_CC_FAST_AHB_CLK_SRC 36 +#define CAM_CC_GDSC_CLK 37 +#define CAM_CC_ICP_0_AHB_CLK 38 +#define CAM_CC_ICP_0_CLK 39 +#define CAM_CC_ICP_0_CLK_SRC 40 +#define CAM_CC_ICP_1_AHB_CLK 41 +#define CAM_CC_ICP_1_CLK 42 +#define CAM_CC_ICP_1_CLK_SRC 43 +#define CAM_CC_IFE_0_MAIN_CLK 44 +#define CAM_CC_IFE_0_MAIN_CLK_SRC 45 +#define CAM_CC_IFE_0_MAIN_FAST_AHB_CLK 46 +#define CAM_CC_IFE_0_PCP_CLK 47 +#define CAM_CC_IFE_0_PCP_FAST_AHB_CLK 48 +#define CAM_CC_IFE_0_SCALAR_CLK 49 +#define CAM_CC_IFE_0_SCALAR_FAST_AHB_CLK 50 +#define CAM_CC_IFE_0_TMC_CLK 51 +#define CAM_CC_IFE_0_TMC_FAST_AHB_CLK 52 +#define CAM_CC_IFE_1_MAIN_CLK 53 +#define CAM_CC_IFE_1_MAIN_CLK_SRC 54 +#define CAM_CC_IFE_1_MAIN_FAST_AHB_CLK 55 +#define CAM_CC_IFE_1_PCP_CLK 56 +#define CAM_CC_IFE_1_PCP_FAST_AHB_CLK 57 +#define CAM_CC_IFE_1_SCALAR_CLK 58 +#define CAM_CC_IFE_1_SCALAR_FAST_AHB_CLK 59 +#define CAM_CC_IFE_1_TMC_CLK 60 +#define CAM_CC_IFE_1_TMC_FAST_AHB_CLK 61 +#define CAM_CC_IFE_2_MAIN_CLK 62 +#define CAM_CC_IFE_2_MAIN_CLK_SRC 63 +#define CAM_CC_IFE_2_MAIN_FAST_AHB_CLK 64 +#define CAM_CC_IFE_2_PCP_CLK 65 +#define CAM_CC_IFE_2_PCP_FAST_AHB_CLK 66 +#define CAM_CC_IFE_2_SCALAR_CLK 67 +#define CAM_CC_IFE_2_SCALAR_FAST_AHB_CLK 68 +#define CAM_CC_IFE_2_TMC_CLK 69 +#define CAM_CC_IFE_2_TMC_FAST_AHB_CLK 70 +#define CAM_CC_IFE_LITE_AHB_CLK 71 +#define CAM_CC_IFE_LITE_CLK 72 +#define CAM_CC_IFE_LITE_CLK_SRC 73 +#define CAM_CC_IFE_LITE_CPHY_RX_CLK 74 +#define CAM_CC_IFE_LITE_CSID_CLK 75 +#define CAM_CC_IFE_LITE_CSID_CLK_SRC 76 +#define CAM_CC_IPE_0_AHB_CLK 77 +#define CAM_CC_IPE_0_CLK 78 +#define CAM_CC_IPE_0_CLK_SRC 79 +#define CAM_CC_IPE_0_FAST_AHB_CLK 80 +#define CAM_CC_IPE_1_AHB_CLK 81 +#define CAM_CC_IPE_1_CLK 82 +#define CAM_CC_IPE_1_CLK_SRC 83 +#define CAM_CC_IPE_1_FAST_AHB_CLK 84 +#define CAM_CC_PLL0 85 +#define CAM_CC_PLL0_OUT_EVEN 86 +#define CAM_CC_PLL0_OUT_ODD 87 +#define CAM_CC_PLL2 88 +#define CAM_CC_PLL2_OUT_EVEN 89 +#define CAM_CC_PLL3 90 +#define CAM_CC_PLL3_OUT_EVEN 91 +#define CAM_CC_PLL4 92 +#define CAM_CC_PLL4_OUT_EVEN 93 +#define CAM_CC_PLL5 94 +#define CAM_CC_PLL5_OUT_EVEN 95 +#define CAM_CC_PLL6 96 +#define CAM_CC_PLL6_OUT_EVEN 97 +#define CAM_CC_QDSS_DEBUG_CLK 98 +#define CAM_CC_QDSS_DEBUG_CLK_SRC 99 +#define CAM_CC_QDSS_DEBUG_XO_CLK 100 +#define CAM_CC_QUP_AHBM_CLK 101 +#define CAM_CC_QUP_AHBM_CLK_SRC 102 +#define CAM_CC_QUP_CORE_2X_CLK 103 +#define CAM_CC_QUP_CORE_2X_CLK_SRC 104 +#define CAM_CC_QUP_CORE_2X_DIV_CLK_SRC 105 +#define CAM_CC_QUP_CORE_CLK 106 +#define CAM_CC_QUP_SE_CLK 107 +#define CAM_CC_QUP_SE_CLK_SRC 108 +#define CAM_CC_QUP_SLEEP_CLK 109 +#define CAM_CC_SFE_LITE_0_CLK 110 +#define CAM_CC_SFE_LITE_0_FAST_AHB_CLK 111 +#define CAM_CC_SFE_LITE_1_CLK 112 +#define CAM_CC_SFE_LITE_1_FAST_AHB_CLK 113 +#define CAM_CC_SFE_LITE_2_CLK 114 +#define CAM_CC_SFE_LITE_2_FAST_AHB_CLK 115 +#define CAM_CC_SLEEP_CLK 116 +#define CAM_CC_SLEEP_CLK_SRC 117 +#define CAM_CC_SLOW_AHB_CLK_SRC 118 +#define CAM_CC_SM_OBS_CLK 119 +#define CAM_CC_TOP_AHB_CLK 120 +#define CAM_CC_TOP_FAST_AHB_CLK 121 +#define CAM_CC_TOP_IFE_0_CLK 122 +#define CAM_CC_TOP_IFE_1_CLK 123 +#define CAM_CC_TOP_IFE_2_CLK 124 +#define CAM_CC_TOP_IFE_LITE_CLK 125 +#define CAM_CC_TOP_IPE_0_CLK 126 +#define CAM_CC_TOP_IPE_1_CLK 127 +#define CAM_CC_TOP_QUP_AHBM_CLK 128 +#define CAM_CC_TOP_SFE_LITE_0_CLK 129 +#define CAM_CC_TOP_SFE_LITE_1_CLK 130 +#define CAM_CC_TOP_SFE_LITE_2_CLK 131 +#define CAM_CC_TPG_CSIPHY_RX_CLK 132 +#define CAM_CC_XO_CLK_SRC 133 + +/* CAM_CC power domains */ +#define CAM_CC_IFE_0_GDSC 0 +#define CAM_CC_IFE_1_GDSC 1 +#define CAM_CC_IFE_2_GDSC 2 +#define CAM_CC_IPE_0_GDSC 3 +#define CAM_CC_IPE_1_GDSC 4 +#define CAM_CC_TITAN_TOP_GDSC 5 + +/* CAM_CC resets */ +#define CAM_CC_CCU_BCR 0 +#define CAM_CC_ICP_0_BCR 1 +#define CAM_CC_ICP_1_BCR 2 +#define CAM_CC_IFE_0_BCR 3 +#define CAM_CC_IFE_1_BCR 4 +#define CAM_CC_IFE_2_BCR 5 +#define CAM_CC_IPE_0_BCR 6 +#define CAM_CC_IPE_1_BCR 7 +#define CAM_CC_QDSS_DEBUG_BCR 8 +#define CAM_CC_SFE_LITE_0_BCR 9 +#define CAM_CC_SFE_LITE_1_BCR 10 +#define CAM_CC_SFE_LITE_2_BCR 11 + +#endif
diff --git a/include/dt-bindings/clock/qcom,nord-nwgcc.h b/include/dt-bindings/clock/qcom,nord-nwgcc.h index b6253dd..8beaa12 100644 --- a/include/dt-bindings/clock/qcom,nord-nwgcc.h +++ b/include/dt-bindings/clock/qcom,nord-nwgcc.h
@@ -65,5 +65,8 @@ #define NW_GCC_GPU_2_BCR 6 #define NW_GCC_GPU_BCR 7 #define NW_GCC_VIDEO_BCR 8 +#define NW_GCC_VIDEO_AXI0_CLK_ARES 9 +#define NW_GCC_VIDEO_AXI0C_CLK_ARES 10 +#define NW_GCC_VIDEO_AXI1_CLK_ARES 11 #endif
diff --git a/include/dt-bindings/clock/renesas,r8a774a3-cpg-mssr.h b/include/dt-bindings/clock/renesas,r8a774a3-cpg-mssr.h new file mode 100644 index 0000000..09121a3 --- /dev/null +++ b/include/dt-bindings/clock/renesas,r8a774a3-cpg-mssr.h
@@ -0,0 +1,59 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2026 Renesas Electronics Corp. + */ +#ifndef __DT_BINDINGS_CLOCK_RENESAS_R8A774A3_CPG_MSSR_H__ +#define __DT_BINDINGS_CLOCK_RENESAS_R8A774A3_CPG_MSSR_H__ + +#include <dt-bindings/clock/renesas-cpg-mssr.h> + +/* r8a774a3 CPG Core Clocks */ +#define R8A774A3_CLK_Z 0 +#define R8A774A3_CLK_Z2 1 +#define R8A774A3_CLK_ZG 2 +#define R8A774A3_CLK_ZTR 3 +#define R8A774A3_CLK_ZTRD2 4 +#define R8A774A3_CLK_ZT 5 +#define R8A774A3_CLK_ZX 6 +#define R8A774A3_CLK_S0D1 7 +#define R8A774A3_CLK_S0D2 8 +#define R8A774A3_CLK_S0D3 9 +#define R8A774A3_CLK_S0D4 10 +#define R8A774A3_CLK_S0D6 11 +#define R8A774A3_CLK_S0D8 12 +#define R8A774A3_CLK_S0D12 13 +#define R8A774A3_CLK_S1D2 14 +#define R8A774A3_CLK_S1D4 15 +#define R8A774A3_CLK_S2D1 16 +#define R8A774A3_CLK_S2D2 17 +#define R8A774A3_CLK_S2D4 18 +#define R8A774A3_CLK_S3D1 19 +#define R8A774A3_CLK_S3D2 20 +#define R8A774A3_CLK_S3D4 21 +#define R8A774A3_CLK_LB 22 +#define R8A774A3_CLK_CL 23 +#define R8A774A3_CLK_ZB3 24 +#define R8A774A3_CLK_ZB3D2 25 +#define R8A774A3_CLK_ZB3D4 26 +#define R8A774A3_CLK_CR 27 +#define R8A774A3_CLK_CRD2 28 +#define R8A774A3_CLK_SD0H 29 +#define R8A774A3_CLK_SD0 30 +#define R8A774A3_CLK_SD1H 31 +#define R8A774A3_CLK_SD1 32 +#define R8A774A3_CLK_SD2H 33 +#define R8A774A3_CLK_SD2 34 +#define R8A774A3_CLK_SD3H 35 +#define R8A774A3_CLK_SD3 36 +#define R8A774A3_CLK_RPC 37 +#define R8A774A3_CLK_RPCD2 38 +#define R8A774A3_CLK_MSO 39 +#define R8A774A3_CLK_CANFD 40 +#define R8A774A3_CLK_HDMI 41 +#define R8A774A3_CLK_CSI0 42 +#define R8A774A3_CLK_CP 43 +#define R8A774A3_CLK_CPEX 44 +#define R8A774A3_CLK_R 45 +#define R8A774A3_CLK_OSC 46 + +#endif /* __DT_BINDINGS_CLOCK_RENESAS_R8A774A3_CPG_MSSR_H__ */
diff --git a/include/dt-bindings/clock/renesas,r8a78000-cpg.h b/include/dt-bindings/clock/renesas,r8a78000-cpg.h index 7fd09a3..14b3885 100644 --- a/include/dt-bindings/clock/renesas,r8a78000-cpg.h +++ b/include/dt-bindings/clock/renesas,r8a78000-cpg.h
@@ -10,5 +10,7 @@ #define R8A78000_CPG_SGASYNCD4_PERW_BUS 0 #define R8A78000_CPG_SGASYNCD8_PERW_BUS 1 #define R8A78000_CPG_SGASYNCD16_PERW_BUS 2 +#define R8A78000_CPG_MSO_SCP_MAIN 3 +#define R8A78000_CPG_MSOCK_PERW_BUS 4 #endif /* __DT_BINDINGS_CLOCK_RENESAS_R8A78000_CPG_H__ */
diff --git a/include/dt-bindings/clock/starfive,jhb100-crg.h b/include/dt-bindings/clock/starfive,jhb100-crg.h new file mode 100644 index 0000000..4270bfa --- /dev/null +++ b/include/dt-bindings/clock/starfive,jhb100-crg.h
@@ -0,0 +1,554 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* + * Copyright (C) 2024 StarFive Technology Co., Ltd. + * Author: Changhuang Liang <changhuang.liang@starfivetech.com> + * + */ + +#ifndef __DT_BINDINGS_CLOCK_STARFIVE_JHB100_H__ +#define __DT_BINDINGS_CLOCK_STARFIVE_JHB100_H__ + +/* SYS0PLL clocks */ +#define JHB100_SYS0PLL_PLL2_OUT 0 +#define JHB100_SYS0PLL_PLL3_OUT 1 +#define JHB100_SYS0PLL_PLL4_OUT 2 +#define JHB100_SYS0PLL_PLL5_OUT 3 + +/* PER0PLL clocks */ +#define JHB100_PER0PLL_PLL6_OUT 0 + +/* PER1PLL clocks */ +#define JHB100_PER1PLL_PLL7_OUT 0 + +/* SYS0CRG clocks */ +#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_MAIN 17 +#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_CFG 18 + +#define JHB100_SYS0CLK_PCIE_REF_CML 20 +#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_DATA_INIT 21 +#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_CFG_INIT 22 +#define JHB100_SYS0CLK_BMCPCIERP_NCNOC_TARG 23 + +#define JHB100_SYS0CLK_BMCPCIERP_PCU 26 +#define JHB100_SYS0CLK_HOSTSS0_NCNOC_CFG 27 +#define JHB100_SYS0CLK_HOSTSS0_NCNOC_DATA 28 +#define JHB100_SYS0CLK_HOSTSS0_PHY_SCAN_400 29 +#define JHB100_SYS0CLK_GPIO_ESPI0_EXT 30 + +#define JHB100_SYS0CLK_BMCUSB_NCNOC_INIT 34 +#define JHB100_SYS0CLK_BMCUSB_NCNOC_TARG 35 +#define JHB100_SYS0CLK_BMCUSB_SCANCLK 36 +#define JHB100_SYS0CLK_BMCUSB_480M_SCANCLK 37 + +#define JHB100_SYS0CLK_VCE_NCNOC_INIT 50 +#define JHB100_SYS0CLK_VCE_NCNOC_TARG 51 +#define JHB100_SYS0CLK_BMCPER2_NCNOC_INIT 52 +#define JHB100_SYS0CLK_BMCPER2_NCNOC_TARG 53 +#define JHB100_SYS0CLK_BMCPER2_CFG_400 54 +#define JHB100_SYS0CLK_BMCPER2_CFG_125 55 + +#define JHB100_SYS0CLK_HOSTSS1_NCNOC_DATA 58 +#define JHB100_SYS0CLK_HOSTSS1_PHY_SCAN_400 59 +#define JHB100_SYS0CLK_HOSTSS1_PHY_SCAN_400_ICG_BUF 60 +#define JHB100_SYS0CLK_NPU_NCNOC_INIT 61 +#define JHB100_SYS0CLK_VOUT_NCNOC_INIT 62 +#define JHB100_SYS0CLK_VOUT_AUX 63 + +#define JHB100_SYS0CLK_BMCPER3_NCNOC_INIT 65 +#define JHB100_SYS0CLK_HOSTUSB_NCNOC_INIT 66 +#define JHB100_SYS0CLK_HOSTUSBCMN_CFG_480 67 +#define JHB100_SYS0CLK_BMCPER1_NCNOC_INIT 68 +#define JHB100_SYS0CLK_BMCPER1_CFG_800 69 +#define JHB100_SYS0CLK_BMCPER0_NCNOC_INIT 70 +#define JHB100_SYS0CLK_BMCPER0_CFG_400 71 +#define JHB100_SYS0CLK_BMCPER0_CFG_800 72 +#define JHB100_SYS0CLK_GPU0_NCNOC_INIT 73 +#define JHB100_SYS0CLK_GPU1_NCNOC_INIT 74 + +/* SYS1CRG clocks */ +#define JHB100_SYS1CLK_APB_MAIN_SYS1 0 +#define JHB100_SYS1CLK_APB_SENSOR_ICG_BUF 1 + +#define JHB100_SYS1CLK_GPIO_ESPI1_EXT 5 + +#define JHB100_SYS1CLK_HOSTSS1_NCNOC_CFG 7 +#define JHB100_SYS1CLK_HOSTSS1_PHY_SCAN_1000_ICG_BUF 8 +#define JHB100_SYS1CLK_NPU_NCNOC_CFG 9 +#define JHB100_SYS1CLK_NPU_CORE_DIV 10 +#define JHB100_SYS1CLK_DOM_NPU_CORE_CLK 11 +#define JHB100_SYS1CLK_DOM_NPU_BUS_CLK 12 +#define JHB100_SYS1CLK_DOM_NPU_INIT_CLK 13 +#define JHB100_SYS1CLK_DOM_NPU_OSC_CLK 14 +#define JHB100_SYS1CLK_VOUT_NCNOC_TARG 15 +#define JHB100_SYS1CLK_VOUT_PIX0 16 +#define JHB100_SYS1CLK_VOUT_PIX1 17 +#define JHB100_SYS1CLK_BMCPER3_NCNOC_TARG 18 +#define JHB100_SYS1CLK_BMCPER3_CFG_125 19 + +/* SYS2CRG clocks */ +#define JHB100_SYS2CLK_JTAGM0_HCLK 3 +#define JHB100_SYS2CLK_JTAGM1_HCLK 4 +#define JHB100_SYS2CLK_JTAGM0_ATPG 5 +#define JHB100_SYS2CLK_JTAGM1_ATPG 6 +#define JHB100_SYS2CLK_JTAGM0_ATPG_TCLOCK 7 +#define JHB100_SYS2CLK_JTAGM1_ATPG_TCLOCK 8 +#define JHB100_SYS2CLK_JTAG0_MST_WRAP_HCLK 9 +#define JHB100_SYS2CLK_JTAG0_MST_WRAP_CLK_JTAG 10 +#define JHB100_SYS2CLK_JTAG0_MST_WRAP_APB_PCLK 11 +#define JHB100_SYS2CLK_JTAG0_MST_WRAP_ATPG_TCLOCK 12 +#define JHB100_SYS2CLK_JTAG1_MST_WRAP_HCLK 13 +#define JHB100_SYS2CLK_JTAG1_MST_WRAP_CLK_JTAG 14 +#define JHB100_SYS2CLK_JTAG1_MST_WRAP_APB_PCLK 15 +#define JHB100_SYS2CLK_JTAG1_MST_WRAP_ATPG_TCLOCK 16 +#define JHB100_SYS2CLK_HOSTUSB_NCNOC_TARG 17 +#define JHB100_SYS2CLK_HOSTUSBCMN_CFG_500 18 +#define JHB100_SYS2CLK_BMCPER1_NCNOC_TARG 19 +#define JHB100_SYS2CLK_BMCPER1_CFG_250 20 +#define JHB100_SYS2CLK_BMCPER1_CFG_143_DFT 21 +#define JHB100_SYS2CLK_BMCPER1_CFG_143 22 +#define JHB100_SYS2CLK_BMCPER0_NCNOC_TARG 23 +#define JHB100_SYS2CLK_GPU0_NCNOC_TARG 24 +#define JHB100_SYS2CLK_GPU0_BUS_CLK 25 +#define JHB100_SYS2CLK_GPU0_APB_CLK 26 +#define JHB100_SYS2CLK_GPU0_OSC_CLK 27 +#define JHB100_SYS2CLK_GPU1_NCNOC_TARG 28 +#define JHB100_SYS2CLK_GPU1_BUS_CLK 29 +#define JHB100_SYS2CLK_GPU1_APB_CLK 30 +#define JHB100_SYS2CLK_GPU1_OSC_CLK 31 +#define JHB100_SYS2CLK_MAIN_ICG_EN_JTAG0 32 +#define JHB100_SYS2CLK_MAIN_ICG_EN_JTAG1 33 + +/* PER0CRG clocks */ +#define JHB100_PER0CLK_CDR_I3C0 0 +#define JHB100_PER0CLK_CDR_I3C1 1 +#define JHB100_PER0CLK_CDR_I3C2 2 +#define JHB100_PER0CLK_CDR_I3C3 3 +#define JHB100_PER0CLK_CDR_I3C4 4 +#define JHB100_PER0CLK_CDR_I3C5 5 +#define JHB100_PER0CLK_CDR_I3C6 6 +#define JHB100_PER0CLK_CDR_I3C7 7 +#define JHB100_PER0CLK_CDR_I3C8 8 +#define JHB100_PER0CLK_CDR_I3C9 9 +#define JHB100_PER0CLK_CDR_I3C10 10 +#define JHB100_PER0CLK_CDR_I3C11 11 +#define JHB100_PER0CLK_CDR_I3C12 12 +#define JHB100_PER0CLK_CDR_I3C13 13 +#define JHB100_PER0CLK_CDR_I3C14 14 +#define JHB100_PER0CLK_CDR_I3C15 15 +#define JHB100_PER0CLK_200 16 +#define JHB100_PER0CLK_600_DIV6 17 +#define JHB100_PER0CLK_600_DIV6_DIV5 18 +#define JHB100_PER0CLK_TIMER0_DUALTIMER0 19 +#define JHB100_PER0CLK_TIMER1_DUALTIMER0 20 +#define JHB100_PER0CLK_TIMER0_DUALTIMER1 21 +#define JHB100_PER0CLK_TIMER1_DUALTIMER1 22 +#define JHB100_PER0CLK_TIMER0_DUALTIMER2 23 +#define JHB100_PER0CLK_TIMER1_DUALTIMER2 24 +#define JHB100_PER0CLK_1200_PH0_LVDS0 25 +#define JHB100_PER0CLK_1200_PH0_LVDS1 26 +#define JHB100_PER0CLK_1200_CORE0 27 +#define JHB100_PER0CLK_1200_CORE1 28 +#define JHB100_PER0CLK_1200_SHIFT90_LVDS0 29 +#define JHB100_PER0CLK_1200_SHIFT90_LVDS1 30 +#define JHB100_PER0CLK_1200_DIV5_CORE0 31 +#define JHB100_PER0CLK_1200_DIV5_CORE1 32 +#define JHB100_PER0CLK_PH0_LTPI0 33 + +#define JHB100_PER0CLK_PH0_LTPI1 35 + +#define JHB100_PER0CLK_PH90_LTPI0 37 + +#define JHB100_PER0CLK_PH90_LTPI1 39 + +#define JHB100_PER0CLK_240_CORE_LTPI0 41 + +#define JHB100_PER0CLK_240_CORE_LTPI1 43 + +#define JHB100_PER0CLK_AXI_DMA_I2C_INIT 45 +#define JHB100_PER0CLK_AXI_DMA_I3C_INIT 46 +#define JHB100_PER0CLK_AXI_DMA_UART_INIT 47 +#define JHB100_PER0CLK_CORE_DMAC0 48 +#define JHB100_PER0CLK_CORE_DMAC1 49 +#define JHB100_PER0CLK_CORE_DMAC2 50 + +#define JHB100_PER0CLK_HDR_TX_I3C0 78 +#define JHB100_PER0CLK_HDR_TX_I3C1 79 +#define JHB100_PER0CLK_HDR_TX_I3C2 80 +#define JHB100_PER0CLK_HDR_TX_I3C3 81 +#define JHB100_PER0CLK_HDR_TX_I3C4 82 +#define JHB100_PER0CLK_HDR_TX_I3C5 83 +#define JHB100_PER0CLK_HDR_TX_I3C6 84 +#define JHB100_PER0CLK_HDR_TX_I3C7 85 +#define JHB100_PER0CLK_HDR_TX_I3C8 86 +#define JHB100_PER0CLK_HDR_TX_I3C9 87 +#define JHB100_PER0CLK_HDR_TX_I3C10 88 +#define JHB100_PER0CLK_HDR_TX_I3C11 89 +#define JHB100_PER0CLK_HDR_TX_I3C12 90 +#define JHB100_PER0CLK_HDR_TX_I3C13 91 +#define JHB100_PER0CLK_HDR_TX_I3C14 92 +#define JHB100_PER0CLK_HDR_TX_I3C15 93 +#define JHB100_PER0CLK_CORE_I2C0 94 +#define JHB100_PER0CLK_CORE_I2C1 95 +#define JHB100_PER0CLK_CORE_I2C2 96 +#define JHB100_PER0CLK_CORE_I2C3 97 +#define JHB100_PER0CLK_CORE_I2C4 98 +#define JHB100_PER0CLK_CORE_I2C5 99 +#define JHB100_PER0CLK_CORE_I2C6 100 +#define JHB100_PER0CLK_CORE_I2C7 101 +#define JHB100_PER0CLK_CORE_I2C8 102 +#define JHB100_PER0CLK_CORE_I2C9 103 +#define JHB100_PER0CLK_CORE_I2C10 104 +#define JHB100_PER0CLK_CORE_I2C11 105 +#define JHB100_PER0CLK_CORE_I2C12 106 +#define JHB100_PER0CLK_CORE_I2C13 107 +#define JHB100_PER0CLK_CORE_I2C14 108 +#define JHB100_PER0CLK_CORE_I2C15 109 + +#define JHB100_PER0CLK_WDOGCLK_WDT0 126 +#define JHB100_PER0CLK_WDOGCLK_WDT1 127 +#define JHB100_PER0CLK_WDOGCLK_WDT2 128 +#define JHB100_PER0CLK_WDOGCLK_WDT3 129 +#define JHB100_PER0CLK_WDOGCLK_WDT_EXTERNAL 130 +#define JHB100_PER0CLK_SCLK_UART4 131 +#define JHB100_PER0CLK_SCLK_UART5 132 +#define JHB100_PER0CLK_SCLK_UART6 133 +#define JHB100_PER0CLK_SCLK_UART7 134 +#define JHB100_PER0CLK_SCLK_UART8 135 +#define JHB100_PER0CLK_SCLK_UART9 136 +#define JHB100_PER0CLK_SCLK_UART10 137 +#define JHB100_PER0CLK_SCLK_UART11 138 +#define JHB100_PER0CLK_SCLK_UART12 139 +#define JHB100_PER0CLK_SCLK_UART13 140 +#define JHB100_PER0CLK_SCLK_UART14 141 + +#define JHB100_PER0CLK_PCLK_DMA_UART_CFG 148 +#define JHB100_PER0CLK_PCLK_DMA_I2C_CFG 149 +#define JHB100_PER0CLK_PCLK_DMA_I3C_CFG 150 +#define JHB100_PER0CLK_PCLK_DUALTIMER0 151 +#define JHB100_PER0CLK_PCLK_DUALTIMER1 152 +#define JHB100_PER0CLK_PCLK_DUALTIMER2 153 + +#define JHB100_PER0CLK_HCLK_TRNG 156 +#define JHB100_PER0CLK_APB_I2C0 157 +#define JHB100_PER0CLK_APB_I2C1 158 +#define JHB100_PER0CLK_APB_I2C2 159 +#define JHB100_PER0CLK_APB_I2C3 160 +#define JHB100_PER0CLK_APB_I2C4 161 +#define JHB100_PER0CLK_APB_I2C5 162 +#define JHB100_PER0CLK_APB_I2C6 163 +#define JHB100_PER0CLK_APB_I2C7 164 +#define JHB100_PER0CLK_APB_I2C8 165 +#define JHB100_PER0CLK_APB_I2C9 166 +#define JHB100_PER0CLK_APB_I2C10 167 +#define JHB100_PER0CLK_APB_I2C11 168 +#define JHB100_PER0CLK_APB_I2C12 169 +#define JHB100_PER0CLK_APB_I2C13 170 +#define JHB100_PER0CLK_APB_I2C14 171 +#define JHB100_PER0CLK_APB_I2C15 172 +#define JHB100_PER0CLK_APB_I2CF0 173 +#define JHB100_PER0CLK_APB_I2CF1 174 +#define JHB100_PER0CLK_APB_I2CF2 175 +#define JHB100_PER0CLK_APB_I2CF3 176 +#define JHB100_PER0CLK_APB_I2CF4 177 +#define JHB100_PER0CLK_APB_I2CF5 178 +#define JHB100_PER0CLK_APB_I2CF6 179 +#define JHB100_PER0CLK_APB_I2CF7 180 +#define JHB100_PER0CLK_APB_I2CF8 181 +#define JHB100_PER0CLK_APB_I2CF9 182 +#define JHB100_PER0CLK_APB_I2CF10 183 +#define JHB100_PER0CLK_APB_I2CF11 184 +#define JHB100_PER0CLK_APB_I2CF12 185 +#define JHB100_PER0CLK_APB_I2CF13 186 +#define JHB100_PER0CLK_APB_I2CF14 187 +#define JHB100_PER0CLK_APB_I2CF15 188 +#define JHB100_PER0CLK_APB_I3C0 189 +#define JHB100_PER0CLK_APB_I3C1 190 +#define JHB100_PER0CLK_APB_I3C2 191 +#define JHB100_PER0CLK_APB_I3C3 192 +#define JHB100_PER0CLK_APB_I3C4 193 +#define JHB100_PER0CLK_APB_I3C5 194 +#define JHB100_PER0CLK_APB_I3C6 195 +#define JHB100_PER0CLK_APB_I3C7 196 +#define JHB100_PER0CLK_APB_I3C8 197 +#define JHB100_PER0CLK_APB_I3C9 198 +#define JHB100_PER0CLK_APB_I3C10 199 +#define JHB100_PER0CLK_APB_I3C11 200 +#define JHB100_PER0CLK_APB_I3C12 201 +#define JHB100_PER0CLK_APB_I3C13 202 +#define JHB100_PER0CLK_APB_I3C14 203 +#define JHB100_PER0CLK_APB_I3C15 204 +#define JHB100_PER0CLK_APB_UART0 205 +#define JHB100_PER0CLK_APB_UART1 206 +#define JHB100_PER0CLK_APB_UART2 207 +#define JHB100_PER0CLK_APB_UART3 208 +#define JHB100_PER0CLK_APB_UART4 209 +#define JHB100_PER0CLK_APB_UART5 210 +#define JHB100_PER0CLK_APB_UART6 211 +#define JHB100_PER0CLK_APB_UART7 212 +#define JHB100_PER0CLK_APB_UART8 213 +#define JHB100_PER0CLK_APB_UART9 214 +#define JHB100_PER0CLK_APB_UART10 215 +#define JHB100_PER0CLK_APB_UART11 216 +#define JHB100_PER0CLK_APB_UART12 217 +#define JHB100_PER0CLK_APB_UART13 218 +#define JHB100_PER0CLK_APB_UART14 219 +#define JHB100_PER0CLK_DMA_I3C0 220 +#define JHB100_PER0CLK_DMA_I3C1 221 +#define JHB100_PER0CLK_DMA_I3C2 222 +#define JHB100_PER0CLK_DMA_I3C3 223 +#define JHB100_PER0CLK_DMA_I3C4 224 +#define JHB100_PER0CLK_DMA_I3C5 225 +#define JHB100_PER0CLK_DMA_I3C6 226 +#define JHB100_PER0CLK_DMA_I3C7 227 +#define JHB100_PER0CLK_DMA_I3C8 228 +#define JHB100_PER0CLK_DMA_I3C9 229 +#define JHB100_PER0CLK_DMA_I3C10 230 +#define JHB100_PER0CLK_DMA_I3C11 231 +#define JHB100_PER0CLK_DMA_I3C12 232 +#define JHB100_PER0CLK_DMA_I3C13 233 +#define JHB100_PER0CLK_DMA_I3C14 234 +#define JHB100_PER0CLK_DMA_I3C15 235 +#define JHB100_PER0CLK_CORE_I3C0 236 +#define JHB100_PER0CLK_CORE_I3C1 237 +#define JHB100_PER0CLK_CORE_I3C2 238 +#define JHB100_PER0CLK_CORE_I3C3 239 +#define JHB100_PER0CLK_CORE_I3C4 240 +#define JHB100_PER0CLK_CORE_I3C5 241 +#define JHB100_PER0CLK_CORE_I3C6 242 +#define JHB100_PER0CLK_CORE_I3C7 243 +#define JHB100_PER0CLK_CORE_I3C8 244 +#define JHB100_PER0CLK_CORE_I3C9 245 +#define JHB100_PER0CLK_CORE_I3C10 246 +#define JHB100_PER0CLK_CORE_I3C11 247 +#define JHB100_PER0CLK_CORE_I3C12 248 +#define JHB100_PER0CLK_CORE_I3C13 249 +#define JHB100_PER0CLK_CORE_I3C14 250 +#define JHB100_PER0CLK_CORE_I3C15 251 +#define JHB100_PER0CLK_DMAC_AXI_PERIPH0_HS_CLK_I2C 252 +#define JHB100_PER0CLK_MAIN_ICG_EN_I3C0 253 +#define JHB100_PER0CLK_MAIN_ICG_EN_I3C1 254 +#define JHB100_PER0CLK_MAIN_ICG_EN_I3C2 255 +#define JHB100_PER0CLK_MAIN_ICG_EN_I3C3 256 +#define JHB100_PER0CLK_MAIN_ICG_EN_I3C4 257 +#define JHB100_PER0CLK_MAIN_ICG_EN_I3C5 258 +#define JHB100_PER0CLK_MAIN_ICG_EN_I3C6 259 +#define JHB100_PER0CLK_MAIN_ICG_EN_I3C7 260 +#define JHB100_PER0CLK_MAIN_ICG_EN_I3C8 261 +#define JHB100_PER0CLK_MAIN_ICG_EN_I3C9 262 +#define JHB100_PER0CLK_MAIN_ICG_EN_I3C10 263 +#define JHB100_PER0CLK_MAIN_ICG_EN_I3C11 264 +#define JHB100_PER0CLK_MAIN_ICG_EN_I3C12 265 +#define JHB100_PER0CLK_MAIN_ICG_EN_I3C13 266 +#define JHB100_PER0CLK_MAIN_ICG_EN_I3C14 267 +#define JHB100_PER0CLK_MAIN_ICG_EN_I3C15 268 +#define JHB100_PER0CLK_MAIN_ICG_EN_DUALTIMER0 269 +#define JHB100_PER0CLK_MAIN_ICG_EN_DUALTIMER1 270 +#define JHB100_PER0CLK_MAIN_ICG_EN_DUALTIMER2 271 +#define JHB100_PER0CLK_MAIN_ICG_EN_LTPI0 272 +#define JHB100_PER0CLK_MAIN_ICG_EN_LTPI1 273 +#define JHB100_PER0CLK_MAIN_ICG_EN_DMAC_I2C 274 +#define JHB100_PER0CLK_MAIN_ICG_EN_DMAC_I3C 275 +#define JHB100_PER0CLK_MAIN_ICG_EN_DMAC_UART 276 +#define JHB100_PER0CLK_MAIN_ICG_EN_SOL4 277 +#define JHB100_PER0CLK_MAIN_ICG_EN_SOL5 278 +#define JHB100_PER0CLK_MAIN_ICG_EN_SOL6 279 +#define JHB100_PER0CLK_MAIN_ICG_EN_SOL7 280 +#define JHB100_PER0CLK_MAIN_ICG_EN_SOL8 281 +#define JHB100_PER0CLK_MAIN_ICG_EN_SOL9 282 +#define JHB100_PER0CLK_MAIN_ICG_EN_SOL10 283 +#define JHB100_PER0CLK_MAIN_ICG_EN_SOL11 284 +#define JHB100_PER0CLK_MAIN_ICG_EN_SOL12 285 +#define JHB100_PER0CLK_MAIN_ICG_EN_SOL13 286 +#define JHB100_PER0CLK_MAIN_ICG_EN_SOL14 287 + +#define JHB100_PER0CLK_MAIN_ICG_EN_I2C0 304 +#define JHB100_PER0CLK_MAIN_ICG_EN_I2C1 305 +#define JHB100_PER0CLK_MAIN_ICG_EN_I2C2 306 +#define JHB100_PER0CLK_MAIN_ICG_EN_I2C3 307 +#define JHB100_PER0CLK_MAIN_ICG_EN_I2C4 308 +#define JHB100_PER0CLK_MAIN_ICG_EN_I2C5 309 +#define JHB100_PER0CLK_MAIN_ICG_EN_I2C6 310 +#define JHB100_PER0CLK_MAIN_ICG_EN_I2C7 311 +#define JHB100_PER0CLK_MAIN_ICG_EN_I2C8 312 +#define JHB100_PER0CLK_MAIN_ICG_EN_I2C9 313 +#define JHB100_PER0CLK_MAIN_ICG_EN_I2C10 314 +#define JHB100_PER0CLK_MAIN_ICG_EN_I2C11 315 +#define JHB100_PER0CLK_MAIN_ICG_EN_I2C12 316 +#define JHB100_PER0CLK_MAIN_ICG_EN_I2C13 317 +#define JHB100_PER0CLK_MAIN_ICG_EN_I2C14 318 +#define JHB100_PER0CLK_MAIN_ICG_EN_I2C15 319 +#define JHB100_PER0CLK_MAIN_ICG_EN_WDT0 320 +#define JHB100_PER0CLK_MAIN_ICG_EN_WDT1 321 +#define JHB100_PER0CLK_MAIN_ICG_EN_WDT2 322 +#define JHB100_PER0CLK_MAIN_ICG_EN_WDT3 323 +#define JHB100_PER0CLK_MAIN_ICG_EN_WDT_EXTERNAL 324 +#define JHB100_PER0CLK_MAIN_ICG_EN_UART4 325 +#define JHB100_PER0CLK_MAIN_ICG_EN_UART5 326 +#define JHB100_PER0CLK_MAIN_ICG_EN_UART6 327 +#define JHB100_PER0CLK_MAIN_ICG_EN_UART7 328 +#define JHB100_PER0CLK_MAIN_ICG_EN_UART8 329 +#define JHB100_PER0CLK_MAIN_ICG_EN_UART9 330 +#define JHB100_PER0CLK_MAIN_ICG_EN_UART10 331 +#define JHB100_PER0CLK_MAIN_ICG_EN_UART11 332 +#define JHB100_PER0CLK_MAIN_ICG_EN_UART12 333 +#define JHB100_PER0CLK_MAIN_ICG_EN_UART13 334 +#define JHB100_PER0CLK_MAIN_ICG_EN_UART14 335 +#define JHB100_PER0CLK_MAIN_ICG_EN_LDO0 336 +#define JHB100_PER0CLK_MAIN_ICG_EN_LDO1 337 +#define JHB100_PER0CLK_MAIN_ICG_EN_SENSORS_PERIPH0 338 +#define JHB100_PER0CLK_MAIN_ICG_EN_SENSORS_DMAC 339 +#define JHB100_PER0CLK_MAIN_ICG_EN_TRNG 340 + +/* PER1CRG clocks */ +#define JHB100_PER1CLK_100 0 +#define JHB100_PER1CLK_1 1 +#define JHB100_PER1CLK_200_DIVN0 2 +#define JHB100_PER1CLK_200_DIVN1 3 +#define JHB100_PER1CLK_200_DIVN2 4 +#define JHB100_PER1CLK_200_DIVN3 5 +#define JHB100_PER1CLK_200_CCLK_DIV 6 + +#define JHB100_PER1CLK_SGPIO0_PCLK 15 +#define JHB100_PER1CLK_SGPIO0_DCLK 16 +#define JHB100_PER1CLK_SGPIO1_PCLK 17 +#define JHB100_PER1CLK_SGPIO1_DCLK 18 + +#define JHB100_PER1CLK_EMMC0_BCLK 22 + +#define JHB100_PER1CLK_EMMC0_CCLK 25 + +#define JHB100_PER1CLK_DMAC1_1CH_CORE 29 + +#define JHB100_PER1CLK_DMAC1_1CH_ACLK 31 + +#define JHB100_PER1CLK_DMAC2_1CH_CORE 33 + +#define JHB100_PER1CLK_DMAC2_1CH_ACLK 35 + +#define JHB100_PER1CLK_DMAC3_1CH_CORE 37 + +#define JHB100_PER1CLK_DMAC3_1CH_ACLK 39 + +#define JHB100_PER1CLK_DMAC0_2CH_CORE 41 + +#define JHB100_PER1CLK_DMAC0_2CH_ACLK 43 + +#define JHB100_PER1CLK_UFS_REF 45 +#define JHB100_PER1CLK_UFS_300 46 +#define JHB100_PER1CLK_UFS_150 47 +#define JHB100_PER1CLK_UFS_400 48 +#define JHB100_PER1CLK_UFS_75 49 +#define JHB100_PER1CLK_UFS_37_5 50 +#define JHB100_PER1CLK_UFS_7_5 51 +#define JHB100_PER1CLK_UFS_1_875 52 +#define JHB100_PER1CLK_UFS_7_143 53 +#define JHB100_PER1CLK_UFS_3_5715 54 + +#define JHB100_PER1CLK_MAIN_ICG_EN_SFC0 63 +#define JHB100_PER1CLK_MAIN_ICG_EN_SFC1 64 +#define JHB100_PER1CLK_MAIN_ICG_EN_SFC2 65 +#define JHB100_PER1CLK_MAIN_ICG_EN_SPI0 66 +#define JHB100_PER1CLK_MAIN_ICG_EN_SGPIO0 67 +#define JHB100_PER1CLK_MAIN_ICG_EN_SGPIO1 68 +#define JHB100_PER1CLK_MAIN_ICG_EN_SENSORS_PERIPH1 69 +#define JHB100_PER1CLK_MAIN_ICG_EN_EMMC0 70 +#define JHB100_PER1CLK_MAIN_ICG_EN_DMAC_SFC0 71 +#define JHB100_PER1CLK_MAIN_ICG_EN_DMAC_SFC1 72 +#define JHB100_PER1CLK_MAIN_ICG_EN_DMAC_SFC2 73 +#define JHB100_PER1CLK_MAIN_ICG_EN_DMAC_SPI0 74 +#define JHB100_PER1CLK_MAIN_ICG_EN_RAS 75 +#define JHB100_PER1CLK_MAIN_ICG_EN_UFS 76 + +/* PER2CRG clocks */ +#define JHB100_PER2CLK_300 0 +#define JHB100_PER2CLK_100 1 +#define JHB100_PER2CLK_50 2 +#define JHB100_PER2CLK_GMAC2_RMII_50 3 +#define JHB100_PER2CLK_CAN0_CORE_DIV 4 +#define JHB100_PER2CLK_CAN1_CORE_DIV 5 +#define JHB100_PER2CLK_CAN0_TIMER 6 +#define JHB100_PER2CLK_CAN1_TIMER 7 + +#define JHB100_PER2CLK_RTC_CORE_DIV 11 +#define JHB100_PER2CLK_GMAC2_RMII_MUX_DLY 12 +#define JHB100_PER2CLK_GMAC2_RMII_DIV 13 + +#define JHB100_PER2CLK_GMAC2_RGMII_125_MUX 15 +#define JHB100_PER2CLK_GMAC2_RGMII_DIV 16 +#define JHB100_PER2CLK_GMAC2_TX_MUX 17 +#define JHB100_PER2CLK_GMAC2_TX_180_BUF 18 +#define JHB100_PER2CLK_GMAC2_RX_MUX_DLY 19 +#define JHB100_PER2CLK_GMAC2_RX_180_BUF 20 +#define JHB100_PER2CLK_GMAC2_TXCK_MUX_DLY 21 +#define JHB100_PER2CLK_GMAC3_TX_125_MUX 22 +#define JHB100_PER2CLK_GMAC3_RX_125_MUX 23 +#define JHB100_PER2CLK_GMAC3_TX_DIV 24 +#define JHB100_PER2CLK_GMAC3_RX_DIV 25 +#define JHB100_PER2CLK_SENSORS_PERIPH2 26 + +#define JHB100_PER2CLK_FAN_TACH_PCLK 33 + +#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_TX_I 44 +#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_RX_I 45 +#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_TX_180_I 46 +#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_RX_180_I 47 +#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_PTP_REF_I 48 +#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_RMII_I 49 +#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_CSR_I 50 +#define JHB100_PER2CLK_ETHER0_RMIIANDRGMII_ACLK_I 51 +#define JHB100_PER2CLK_RMIIANDRGMII_IOMUX_GMAC2_TXCK 52 +#define JHB100_PER2CLK_ETHER1_SGMII_TX_I 53 +#define JHB100_PER2CLK_ETHER1_SGMII_RX_I 54 +#define JHB100_PER2CLK_ETHER1_SGMII_TX_125_I 55 +#define JHB100_PER2CLK_ETHER1_SGMII_RX_125_I 56 +#define JHB100_PER2CLK_ETHER1_SGMII_PTP_REF_I 57 +#define JHB100_PER2CLK_ETHER1_SGMII_CSR_I 58 +#define JHB100_PER2CLK_ETHER1_SGMII_ACLK_I 59 +#define JHB100_PER2CLK_ETHER1_SGMII_PHY_PCLK_I 60 +#define JHB100_PER2CLK_ETHER1_SGMII_REF_25_I 61 +#define JHB100_PER2CLK_MAIN_ICG_EN_CAN0 62 +#define JHB100_PER2CLK_MAIN_ICG_EN_CAN1 63 + +#define JHB100_PER2CLK_MAIN_ICG_EN_DMAC_8CH 65 +#define JHB100_PER2CLK_MAIN_ICG_EN_RTC_SCAN 66 +#define JHB100_PER2CLK_MAIN_ICG_EN_ADC0 67 +#define JHB100_PER2CLK_MAIN_ICG_EN_ADC1 68 +#define JHB100_PER2CLK_MAIN_ICG_EN_GMAC2 69 +#define JHB100_PER2CLK_MAIN_ICG_EN_GMAC3 70 + +/* PER3CRG clocks */ +#define JHB100_PER3CLK_300 0 +#define JHB100_PER3CLK_200 1 +#define JHB100_PER3CLK_GMAC1_PTP_REF 2 +#define JHB100_PER3CLK_GMAC1_TX_125_MUX 3 +#define JHB100_PER3CLK_GMAC1_TX 4 +#define JHB100_PER3CLK_GMAC1_RX_125_MUX 5 +#define JHB100_PER3CLK_GMAC1_RX 6 +#define JHB100_PER3CLK_GMAC0_PTP_REF 7 +#define JHB100_PER3CLK_GMAC0_RMII_PLL 8 +#define JHB100_PER3CLK_GMAC0_RMII_MUX 9 +#define JHB100_PER3CLK_GMAC0_RMII_MUX_DIV2 10 + +#define JHB100_PER3CLK_ETHER0_RMII_CLK_TX_I 17 +#define JHB100_PER3CLK_ETHER0_RMII_CLK_RX_I 18 +#define JHB100_PER3CLK_ETHER0_RMII_CLK_PTP_REF_I 19 +#define JHB100_PER3CLK_ETHER0_RMII_CLK_RMII_I 20 +#define JHB100_PER3CLK_ETHER0_RMII_CLK_CSR_I 21 +#define JHB100_PER3CLK_ETHER0_RMII_ACLK_I 22 +#define JHB100_PER3CLK_GMAC0_RMII_RCLKO 23 +#define JHB100_PER3CLK_ETHER0_SGMII_CLK_TX_I 24 +#define JHB100_PER3CLK_ETHER0_SGMII_CLK_RX_I 25 +#define JHB100_PER3CLK_ETHER0_SGMII_CLK_TX_125_I 26 +#define JHB100_PER3CLK_ETHER0_SGMII_CLK_RX_125_I 27 +#define JHB100_PER3CLK_ETHER0_SGMII_CLK_PTP_REF_I 28 +#define JHB100_PER3CLK_ETHER0_SGMII_CLK_REF_25_I 29 +#define JHB100_PER3CLK_ETHER0_SGMII_CLK_CSR_I 30 +#define JHB100_PER3CLK_ETHER0_SGMII_ACLK_I 31 +#define JHB100_PER3CLK_ETHER0_SGMII_PHY_PCLK_I 32 +#define JHB100_PER3CLK_MAIN_ICG_EN_SENSORS_PERIPH3 33 +#define JHB100_PER3CLK_MAIN_ICG_EN_PECI0 34 +#define JHB100_PER3CLK_MAIN_ICG_EN_PECI1 35 +#define JHB100_PER3CLK_MAIN_ICG_EN_GMAC0 36 +#define JHB100_PER3CLK_MAIN_ICG_EN_GMAC1 37 + +#endif /* __DT_BINDINGS_CLOCK_STARFIVE_JHB100_H__ */
diff --git a/include/dt-bindings/interconnect/qcom,ipq9650.h b/include/dt-bindings/interconnect/qcom,ipq9650.h new file mode 100644 index 0000000..023a387 --- /dev/null +++ b/include/dt-bindings/interconnect/qcom,ipq9650.h
@@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +#ifndef INTERCONNECT_QCOM_IPQ9650_H +#define INTERCONNECT_QCOM_IPQ9650_H + +#define MASTER_ANOC_PCIE0 0 +#define SLAVE_ANOC_PCIE0 1 +#define MASTER_CNOC_PCIE0 2 +#define SLAVE_CNOC_PCIE0 3 +#define MASTER_ANOC_PCIE1 4 +#define SLAVE_ANOC_PCIE1 5 +#define MASTER_CNOC_PCIE1 6 +#define SLAVE_CNOC_PCIE1 7 +#define MASTER_ANOC_PCIE2 8 +#define SLAVE_ANOC_PCIE2 9 +#define MASTER_CNOC_PCIE2 10 +#define SLAVE_CNOC_PCIE2 11 +#define MASTER_ANOC_PCIE3 12 +#define SLAVE_ANOC_PCIE3 13 +#define MASTER_CNOC_PCIE3 14 +#define SLAVE_CNOC_PCIE3 15 +#define MASTER_ANOC_PCIE4 16 +#define SLAVE_ANOC_PCIE4 17 +#define MASTER_CNOC_PCIE4 18 +#define SLAVE_CNOC_PCIE4 19 +#define MASTER_SNOC_USB 20 +#define SLAVE_SNOC_USB 21 + +#endif /* INTERCONNECT_QCOM_IPQ9650_H */
diff --git a/include/dt-bindings/power/qcom,rpmhpd.h b/include/dt-bindings/power/qcom,rpmhpd.h index 07bd2a7..92c8408 100644 --- a/include/dt-bindings/power/qcom,rpmhpd.h +++ b/include/dt-bindings/power/qcom,rpmhpd.h
@@ -32,6 +32,7 @@ #define RPMHPD_GBX 22 #define RPMHPD_NSP3 23 #define RPMHPD_GFX1 24 +#define RPMHPD_NMXC 25 /* RPMh Power Domain performance levels */ #define RPMH_REGULATOR_LEVEL_RETENTION 16
diff --git a/include/dt-bindings/power/renesas,r8a774a3-sysc.h b/include/dt-bindings/power/renesas,r8a774a3-sysc.h new file mode 100644 index 0000000..ddee681 --- /dev/null +++ b/include/dt-bindings/power/renesas,r8a774a3-sysc.h
@@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */ +/* + * Copyright (C) 2026 Renesas Electronics Corp. + */ +#ifndef __DT_BINDINGS_POWER_RENESAS_R8A774A3_SYSC_H__ +#define __DT_BINDINGS_POWER_RENESAS_R8A774A3_SYSC_H__ + +/* + * These power domain indices match the numbers of the interrupt bits + * representing the power areas in the various Interrupt Registers + * (e.g. SYSCISR, Interrupt Status Register) + */ + +#define R8A774A3_PD_CA57_CPU0 0 +#define R8A774A3_PD_CA57_CPU1 1 +#define R8A774A3_PD_CA53_CPU0 5 +#define R8A774A3_PD_CA53_CPU1 6 +#define R8A774A3_PD_CA53_CPU2 7 +#define R8A774A3_PD_CA53_CPU3 8 +#define R8A774A3_PD_CA57_SCU 12 +#define R8A774A3_PD_A3VC 14 +#define R8A774A3_PD_3DG_A 17 +#define R8A774A3_PD_3DG_B 18 +#define R8A774A3_PD_CA53_SCU 21 +#define R8A774A3_PD_A2VC1 26 + +/* Always-on power area */ +#define R8A774A3_PD_ALWAYS_ON 32 + +#endif /* __DT_BINDINGS_POWER_RENESAS_R8A774A3_SYSC_H__ */
diff --git a/include/dt-bindings/reset/mediatek,mt8167-wdt.h b/include/dt-bindings/reset/mediatek,mt8167-wdt.h new file mode 100644 index 0000000..1a24bfe --- /dev/null +++ b/include/dt-bindings/reset/mediatek,mt8167-wdt.h
@@ -0,0 +1,21 @@ +/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ +#ifndef _DT_BINDINGS_RESET_MEDIATEK_MT8167_WDT_H_ +#define _DT_BINDINGS_RESET_MEDIATEK_MT8167_WDT_H_ + +/* TOPRGU reset IDs */ +#define MT8167_TOPRGU_DDRPHY_FLASH_RST 0 +#define MT8167_TOPRGU_AUD_PAD_RST 1 +#define MT8167_TOPRGU_MM_RST 2 +#define MT8167_TOPRGU_MFG_RST 3 +#define MT8167_TOPRGU_MDSYS_RST 4 +#define MT8167_TOPRGU_CONN_RST 5 +#define MT8167_TOPRGU_PAD2CAM_DIG_MIPI_RX_RST 6 +#define MT8167_TOPRGU_DIG_MIPI_TX_RST 7 +#define MT8167_TOPRGU_SPI_PAD_MACRO_RST 8 +#define MT8167_TOPRGU_APMIXED_RST 9 +#define MT8167_TOPRGU_VDEC_RST 10 +#define MT8167_TOPRGU_CONN_MCU_RST 11 +#define MT8167_TOPRGU_EFUSE_RST 12 +#define MT8167_TOPRGU_PWRAP_SPICTL_RST 13 + +#endif /* _DT_BINDINGS_RESET_MEDIATEK_MT8167_WDT_H_ */
diff --git a/include/dt-bindings/reset/starfive,jhb100-crg.h b/include/dt-bindings/reset/starfive,jhb100-crg.h new file mode 100644 index 0000000..1489bb0 --- /dev/null +++ b/include/dt-bindings/reset/starfive,jhb100-crg.h
@@ -0,0 +1,189 @@ +/* SPDX-License-Identifier: GPL-2.0 OR MIT */ +/* + * Copyright (C) 2024 StarFive Technology Co., Ltd. + * Author: Changhuang Liang <changhuang.liang@starfivetech.com> + * + */ + +#ifndef __DT_BINDINGS_RESET_STARFIVE_JHB100_CRG_H__ +#define __DT_BINDINGS_RESET_STARFIVE_JHB100_CRG_H__ + +/* SYS0CRG resets */ +#define JHB100_SYS0RST_RESOURCE_ARB 0 +#define JHB100_SYS0RST_SYS0_IOMUX_PRESETN 1 +#define JHB100_SYS0RST_SYS0H_IOMUX_PRESETN 2 +#define JHB100_SYS0RST_RST_ADAPTOR_TIMEOUT_RSTN 3 +#define JHB100_SYS0RST_BMCPCIERP_RSTN_BUS 4 +#define JHB100_SYS0RST_BMCPCIERP_RSTN_CRG 5 +#define JHB100_SYS0RST_HOSTSS0_RSTN_BUS_ESPI 6 +#define JHB100_SYS0RST_HOSTSS0_RSTN_BUS_PCIE 7 +#define JHB100_SYS0RST_HOSTSS0_RSTN_CRG 8 +#define JHB100_SYS0RST_BMCPERIPH2_RSTN_CRG 9 +#define JHB100_SYS0RST_BMCPERIPH2_RSTN_BUS 10 +#define JHB100_SYS0RST_VCE_RSTN_CRG 11 +#define JHB100_SYS0RST_VCE_RSTN_BUS 12 +#define JHB100_SYS0RST_BMCUSB_RSTN_BUS 13 +#define JHB100_SYS0RST_BMCUSB_RSTN_CRG 14 + +/* SYS1CRG resets */ +#define JHB100_SYS1RST_SYS1_IOMUX_PRESETN 0 +#define JHB100_SYS1RST_MAIN_RSTN_CHIPTOP_SENSOR 1 +#define JHB100_SYS1RST_VOUT_RSTN_HOST0 2 +#define JHB100_SYS1RST_VOUT_RSTN_HOST1 3 +#define JHB100_SYS1RST_HOSTSS1_RSTN_BUS_ESPI 4 +#define JHB100_SYS1RST_HOSTSS1_RSTN_BUS_PCIE 5 +#define JHB100_SYS1RST_HOSTSS1_RSTN_CRG 6 +#define JHB100_SYS1RST_BMCPERIPH3_RSTN_CRG 7 +#define JHB100_SYS1RST_BMCPERIPH3_RSTN_BUS 8 + +/* SYS2CRG resets */ +#define JHB100_SYS2RST_JTAG0_MST_WRAP_HRESETN 0 +#define JHB100_SYS2RST_JTAG0_MST_WRAP_APB_PRESETN 1 +#define JHB100_SYS2RST_JTAG1_MST_WRAP_HRESETN 2 +#define JHB100_SYS2RST_JTAG1_MST_WRAP_APB_PRESETN 3 +#define JHB100_SYS2RST_HUSBCMN_HOSTCMN_RSTN_BUS_NCNOC_INIT 4 +#define JHB100_SYS2RST_HUSBCMN_RSTN_HOSTCMN_CRG 5 +#define JHB100_SYS2RST_HUSBCMN_HOSTUSB0_RSTN_BUS_NCNOC_BMC_TARG 6 +#define JHB100_SYS2RST_HUSBCMN_HOSTUSB0_RSTN_BUS_NCNOC_HOST_TARG 7 +#define JHB100_SYS2RST_HUSBCMN_RSTN_BMC_CRG 8 +#define JHB100_SYS2RST_HUSBCMN_RSTN_HOSTUSB0_CRG 9 +#define JHB100_SYS2RST_HUSBCMN_HOSTUSB1_RSTN_BUS_NCNOC_BMC_TARG 10 +#define JHB100_SYS2RST_HUSBCMN_HOSTUSB1_RSTN_BUS_NCNOC_HOST_TARG 11 +#define JHB100_SYS2RST_HUSBCMN_RSTN_HOSTUSB1_CRG 12 +#define JHB100_SYS2RST_BMCPERIPH1_RSTN_CRG 13 +#define JHB100_SYS2RST_BMCPERIPH1_RSTN_BUS 14 +#define JHB100_SYS2RST_BMCPERIPH0_RSTN_CRG 15 +#define JHB100_SYS2RST_BMCPERIPH0_RSTN_BUS 16 +#define JHB100_SYS2RST_GPU0_RSTN_CRG 17 +#define JHB100_SYS2RST_GPU0_RSTN_BUS 18 +#define JHB100_SYS2RST_GPU0_HOST_PCIE_RST_N 19 +#define JHB100_SYS2RST_GPU1_RSTN_CRG 20 +#define JHB100_SYS2RST_GPU1_RSTN_BUS 21 +#define JHB100_SYS2RST_GPU1_HOST_PCIE_RST_N 22 + +/* PER0CRG resets */ +#define JHB100_PER0RST_MAIN_RSTN_UART4 0 +#define JHB100_PER0RST_MAIN_RSTN_UART5 1 +#define JHB100_PER0RST_MAIN_RSTN_UART6 2 +#define JHB100_PER0RST_MAIN_RSTN_UART7 3 +#define JHB100_PER0RST_MAIN_RSTN_UART8 4 +#define JHB100_PER0RST_MAIN_RSTN_UART9 5 +#define JHB100_PER0RST_MAIN_RSTN_UART10 6 +#define JHB100_PER0RST_MAIN_RSTN_UART11 7 +#define JHB100_PER0RST_MAIN_RSTN_UART12 8 +#define JHB100_PER0RST_MAIN_RSTN_UART13 9 +#define JHB100_PER0RST_MAIN_RSTN_UART14 10 +#define JHB100_PER0RST_MAIN_RSTN_I2C0 11 +#define JHB100_PER0RST_MAIN_RSTN_I2C1 12 +#define JHB100_PER0RST_MAIN_RSTN_I2C2 13 +#define JHB100_PER0RST_MAIN_RSTN_I2C3 14 +#define JHB100_PER0RST_MAIN_RSTN_I2C4 15 +#define JHB100_PER0RST_MAIN_RSTN_I2C5 16 +#define JHB100_PER0RST_MAIN_RSTN_I2C6 17 +#define JHB100_PER0RST_MAIN_RSTN_I2C7 18 +#define JHB100_PER0RST_MAIN_RSTN_I2C8 19 +#define JHB100_PER0RST_MAIN_RSTN_I2C9 20 +#define JHB100_PER0RST_MAIN_RSTN_I2C10 21 +#define JHB100_PER0RST_MAIN_RSTN_I2C11 22 +#define JHB100_PER0RST_MAIN_RSTN_I2C12 23 +#define JHB100_PER0RST_MAIN_RSTN_I2C13 24 +#define JHB100_PER0RST_MAIN_RSTN_I2C14 25 +#define JHB100_PER0RST_MAIN_RSTN_I2C15 26 +#define JHB100_PER0RST_MAIN_RSTN_I3C0 27 +#define JHB100_PER0RST_MAIN_RSTN_I3C1 28 +#define JHB100_PER0RST_MAIN_RSTN_I3C2 29 +#define JHB100_PER0RST_MAIN_RSTN_I3C3 30 +#define JHB100_PER0RST_MAIN_RSTN_I3C4 31 +#define JHB100_PER0RST_MAIN_RSTN_I3C5 32 +#define JHB100_PER0RST_MAIN_RSTN_I3C6 33 +#define JHB100_PER0RST_MAIN_RSTN_I3C7 34 +#define JHB100_PER0RST_MAIN_RSTN_I3C8 35 +#define JHB100_PER0RST_MAIN_RSTN_I3C9 36 +#define JHB100_PER0RST_MAIN_RSTN_I3C10 37 +#define JHB100_PER0RST_MAIN_RSTN_I3C11 38 +#define JHB100_PER0RST_MAIN_RSTN_I3C12 39 +#define JHB100_PER0RST_MAIN_RSTN_I3C13 40 +#define JHB100_PER0RST_MAIN_RSTN_I3C14 41 +#define JHB100_PER0RST_MAIN_RSTN_I3C15 42 +#define JHB100_PER0RST_MAIN_RSTN_WDT0 43 +#define JHB100_PER0RST_MAIN_RSTN_WDT1 44 +#define JHB100_PER0RST_MAIN_RSTN_WDT2 45 +#define JHB100_PER0RST_MAIN_RSTN_WDT3 46 +#define JHB100_PER0RST_MAIN_RSTN_WDT4 47 +#define JHB100_PER0RST_MAIN_RSTN_DUALTIMER0 48 +#define JHB100_PER0RST_MAIN_RSTN_DUALTIMER1 49 +#define JHB100_PER0RST_MAIN_RSTN_DUALTIMER2 50 +#define JHB100_PER0RST_MAIN_RSTN_TRNG 51 +#define JHB100_PER0RST_MAIN_RSTN_DMAC0 52 +#define JHB100_PER0RST_MAIN_RSTN_DMAC1 53 +#define JHB100_PER0RST_MAIN_RSTN_DMAC2 54 +#define JHB100_PER0RST_MAIN_RSTN_LTPI0 55 +#define JHB100_PER0RST_MAIN_RSTN_LTPI1 56 +#define JHB100_PER0RST_MAIN_RSTN_SOL4 57 +#define JHB100_PER0RST_MAIN_RSTN_SOL5 58 +#define JHB100_PER0RST_MAIN_RSTN_SOL6 59 +#define JHB100_PER0RST_MAIN_RSTN_SOL7 60 +#define JHB100_PER0RST_MAIN_RSTN_SOL8 61 +#define JHB100_PER0RST_MAIN_RSTN_SOL9 62 +#define JHB100_PER0RST_MAIN_RSTN_SOL10 63 +#define JHB100_PER0RST_MAIN_RSTN_SOL11 64 +#define JHB100_PER0RST_MAIN_RSTN_SOL12 65 +#define JHB100_PER0RST_MAIN_RSTN_SOL13 66 +#define JHB100_PER0RST_MAIN_RSTN_SOL14 67 +#define JHB100_PER0RST_MAIN_RSTN_LDO0 68 +#define JHB100_PER0RST_MAIN_RSTN_LDO1 69 +#define JHB100_PER0RST_MAIN_RSTN_PERIPH0_SENSORS 70 +#define JHB100_PER0RST_MAIN_RSTN_DMAC0_SENSORS 71 +#define JHB100_PER0RST_SYSCON_PRESETN 72 +#define JHB100_PER0RST_GPIO_IOMUX_PRESETN 73 +#define JHB100_PER0RST_UART_MUX_REG_WRAP 74 + +/* PER1CRG resets */ +#define JHB100_PER1RST_IOMUX_PRESETN 0 +#define JHB100_PER1RST_SYSCON_PRESETN 1 +#define JHB100_PER1RST_MAIN_RSTN_SFC0 2 +#define JHB100_PER1RST_MAIN_RSTN_SFC1 3 +#define JHB100_PER1RST_MAIN_RSTN_SFC2 4 +#define JHB100_PER1RST_MAIN_RSTN_SPI0 5 +#define JHB100_PER1RST_MAIN_RSTN_PERIPH1_SENSORS 6 +#define JHB100_PER1RST_MAIN_RSTN_SGPIO0 7 +#define JHB100_PER1RST_MAIN_RSTN_SGPIO1 8 +#define JHB100_PER1RST_MAIN_RSTN_EMMC0 9 +#define JHB100_PER1RST_MAIN_RSTN_UFS 10 +#define JHB100_PER1RST_MAIN_RSTN_UFS_PHY 11 +#define JHB100_PER1RST_MAIN_RSTN_DMAC_SFC0 12 +#define JHB100_PER1RST_MAIN_RSTN_DMAC_SFC1 13 +#define JHB100_PER1RST_MAIN_RSTN_DMAC_SFC2 14 +#define JHB100_PER1RST_MAIN_RSTN_DMAC_SPI0 15 +#define JHB100_PER1RST_MAIN_RSTN_PERIPH1_RAS 16 + +/* PER2CRG resets */ +#define JHB100_PER2RST_IOMUX_PRESETN 0 +#define JHB100_PER2RST_POK_IOMUX_PRESETN 1 +#define JHB100_PER2RST_SYSREG_RSTN 2 +#define JHB100_PER2RST_MAIN_RSTN_CAN0 3 +#define JHB100_PER2RST_MAIN_RSTN_CAN1 4 +#define JHB100_PER2RST_FAN_TACH_PRESETN 5 +#define JHB100_PER2RST_MAIN_RSTN_GMAC2 6 +#define JHB100_PER2RST_MAIN_RSTN_GMAC3 7 +#define JHB100_PER2RST_MAIN_RSTN_DMAC_8CH 8 +#define JHB100_PER2RST_MAIN_RSTN_RTC 9 +#define JHB100_PER2RST_ADC0_PRESETN 10 +#define JHB100_PER2RST_ADC0_IOMUX_PRESETN 11 +#define JHB100_PER2RST_ADC1_PRESETN 12 +#define JHB100_PER2RST_ADC1_IOMUX_PRESETN 13 +#define JHB100_PER2RST_MAIN_RSTN_PERIPH2_SENSORS 14 + +/* PER3CRG resets */ +#define JHB100_PER3RST_SYSREG_RSTN 0 +#define JHB100_PER3RST_MAIN_RSTN_GMAC0 1 +#define JHB100_PER3RST_MAIN_RSTN_GMAC1 2 +#define JHB100_PER3RST_MAIN_RSTN_PECI0 3 +#define JHB100_PER3RST_MAIN_RSTN_PECI1 4 +#define JHB100_PER3RST_MAIN_RSTN_PERIPH3_SENSORS 5 +#define JHB100_PER3RST_IOMUX_PRESETN 6 + +/* PCIERP SYSCON resets */ +#define JHB100_PCIERP_SYSCONRST_PE2RST_OUT 0 + +#endif /* __DT_BINDINGS_RESET_STARFIVE_JHB100_CRG_H__ */
diff --git a/include/keys/trusted-type.h b/include/keys/trusted-type.h index 9f99404..3db61b5 100644 --- a/include/keys/trusted-type.h +++ b/include/keys/trusted-type.h
@@ -39,17 +39,6 @@ struct trusted_key_payload { struct trusted_key_options { uint16_t keytype; - uint32_t keyhandle; - unsigned char keyauth[TPM_DIGEST_SIZE]; - uint32_t blobauth_len; - unsigned char blobauth[TPM_DIGEST_SIZE]; - uint32_t pcrinfo_len; - unsigned char pcrinfo[MAX_PCRINFO_SIZE]; - int pcrlock; - uint32_t hash; - uint32_t policydigest_len; - unsigned char policydigest[MAX_DIGEST_SIZE]; - uint32_t policyhandle; void *private; };
diff --git a/include/keys/trusted_tpm.h b/include/keys/trusted_tpm.h index 3a0fa3bc8..9a83269 100644 --- a/include/keys/trusted_tpm.h +++ b/include/keys/trusted_tpm.h
@@ -6,6 +6,20 @@ extern struct trusted_key_ops trusted_key_tpm_ops; +struct trusted_key_tpm { + u32 keyhandle; + unsigned char keyauth[TPM_DIGEST_SIZE]; + u32 blobauth_len; + unsigned char blobauth[TPM_DIGEST_SIZE]; + u32 pcrinfo_len; + unsigned char pcrinfo[MAX_PCRINFO_SIZE]; + int pcrlock; + u32 hash; + u32 policydigest_len; + unsigned char policydigest[MAX_DIGEST_SIZE]; + u32 policyhandle; +}; + int tpm2_seal_trusted(struct tpm_chip *chip, struct trusted_key_payload *payload, struct trusted_key_options *options);
diff --git a/include/kunit/test.h b/include/kunit/test.h index da5312e..31d5495 100644 --- a/include/kunit/test.h +++ b/include/kunit/test.h
@@ -400,11 +400,10 @@ struct kunit_suite_set kunit_merge_suite_sets(struct kunit_suite_set init_suite_ const void *kunit_array_gen_params(struct kunit *test, const void *prev, char *desc); #if IS_BUILTIN(CONFIG_KUNIT) -int kunit_run_all_tests(void); +void kunit_run_all_tests(void); #else -static inline int kunit_run_all_tests(void) +static inline void kunit_run_all_tests(void) { - return 0; } #endif /* IS_BUILTIN(CONFIG_KUNIT) */
diff --git a/include/linux/ccp.h b/include/linux/ccp.h index 868924d..e6c5992 100644 --- a/include/linux/ccp.h +++ b/include/linux/ccp.h
@@ -26,7 +26,7 @@ struct ccp_cmd; /** * ccp_present - check if a CCP device is present * - * Returns zero if a CCP device is present, -ENODEV otherwise. + * Returns: zero if a CCP device is present, -ENODEV otherwise. */ int ccp_present(void); @@ -38,7 +38,7 @@ int ccp_present(void); /** * ccp_version - get the version of the CCP * - * Returns a positive version number, or zero if no CCP + * Returns: a positive version number, or zero if no CCP */ unsigned int ccp_version(void); @@ -61,9 +61,9 @@ unsigned int ccp_version(void); * will be -EINPROGRESS. Any other "err" value during callback is * the result of the operation. * - * The cmd has been successfully queued if: - * the return code is -EINPROGRESS or - * the return code is -EBUSY and CCP_CMD_MAY_BACKLOG flag is set + * Returns: The cmd has been successfully queued if: + * * the return code is -EINPROGRESS or + * * the return code is -EBUSY and CCP_CMD_MAY_BACKLOG flag is set */ int ccp_enqueue_cmd(struct ccp_cmd *cmd); @@ -89,7 +89,7 @@ static inline int ccp_enqueue_cmd(struct ccp_cmd *cmd) /***** AES engine *****/ /** - * ccp_aes_type - AES key size + * enum ccp_aes_type - AES key size * * @CCP_AES_TYPE_128: 128-bit key * @CCP_AES_TYPE_192: 192-bit key @@ -99,11 +99,12 @@ enum ccp_aes_type { CCP_AES_TYPE_128 = 0, CCP_AES_TYPE_192, CCP_AES_TYPE_256, + /* private: */ CCP_AES_TYPE__LAST, }; /** - * ccp_aes_mode - AES operation mode + * enum ccp_aes_mode - AES operation mode * * @CCP_AES_MODE_ECB: ECB mode * @CCP_AES_MODE_CBC: CBC mode @@ -111,6 +112,10 @@ enum ccp_aes_type { * @CCP_AES_MODE_CFB: CFB mode * @CCP_AES_MODE_CTR: CTR mode * @CCP_AES_MODE_CMAC: CMAC mode + * @CCP_AES_MODE_GHASH: GHASH mode + * @CCP_AES_MODE_GCTR: GCTR mode + * @CCP_AES_MODE_GCM: GCM mode + * @CCP_AES_MODE_GMAC: GMAC mode */ enum ccp_aes_mode { CCP_AES_MODE_ECB = 0, @@ -123,11 +128,12 @@ enum ccp_aes_mode { CCP_AES_MODE_GCTR, CCP_AES_MODE_GCM, CCP_AES_MODE_GMAC, + /* private: */ CCP_AES_MODE__LAST, }; /** - * ccp_aes_mode - AES operation mode + * enum ccp_aes_action - AES operation mode * * @CCP_AES_ACTION_DECRYPT: AES decrypt operation * @CCP_AES_ACTION_ENCRYPT: AES encrypt operation @@ -135,6 +141,7 @@ enum ccp_aes_mode { enum ccp_aes_action { CCP_AES_ACTION_DECRYPT = 0, CCP_AES_ACTION_ENCRYPT, + /* private: */ CCP_AES_ACTION__LAST, }; /* Overloaded field */ @@ -146,6 +153,7 @@ enum ccp_aes_action { * @type: AES operation key size * @mode: AES operation mode * @action: AES operation (decrypt/encrypt) + * @authsize: AES block request size * @key: key to be used for this AES operation * @key_len: length in bytes of key * @iv: IV to be used for this AES operation @@ -156,6 +164,7 @@ enum ccp_aes_action { * @cmac_final: indicates final operation when running in CMAC mode * @cmac_key: K1/K2 key used in final CMAC operation * @cmac_key_len: length in bytes of cmac_key + * @aad_len: length in bytes of Additional Authenticated Data * * Variables required to be set when calling ccp_enqueue_cmd(): * - type, mode, action, key, key_len, src, dst, src_len @@ -192,7 +201,7 @@ struct ccp_aes_engine { /***** XTS-AES engine *****/ /** - * ccp_xts_aes_unit_size - XTS unit size + * enum ccp_xts_aes_unit_size - XTS unit size * * @CCP_XTS_AES_UNIT_SIZE_16: Unit size of 16 bytes * @CCP_XTS_AES_UNIT_SIZE_512: Unit size of 512 bytes @@ -206,11 +215,13 @@ enum ccp_xts_aes_unit_size { CCP_XTS_AES_UNIT_SIZE_1024, CCP_XTS_AES_UNIT_SIZE_2048, CCP_XTS_AES_UNIT_SIZE_4096, + /* private: */ CCP_XTS_AES_UNIT_SIZE__LAST, }; /** * struct ccp_xts_aes_engine - CCP XTS AES operation + * @type: ccp_aes_type - AES key size * @action: AES operation (decrypt/encrypt) * @unit_size: unit size of the XTS operation * @key: key to be used for this XTS AES operation @@ -247,11 +258,13 @@ struct ccp_xts_aes_engine { /***** SHA engine *****/ /** - * ccp_sha_type - type of SHA operation + * enum ccp_sha_type - type of SHA operation * * @CCP_SHA_TYPE_1: SHA-1 operation * @CCP_SHA_TYPE_224: SHA-224 operation * @CCP_SHA_TYPE_256: SHA-256 operation + * @CCP_SHA_TYPE_384: SHA-384 operation + * @CCP_SHA_TYPE_512: SHA-512 operation */ enum ccp_sha_type { CCP_SHA_TYPE_1 = 1, @@ -259,6 +272,7 @@ enum ccp_sha_type { CCP_SHA_TYPE_256, CCP_SHA_TYPE_384, CCP_SHA_TYPE_512, + /* private: */ CCP_SHA_TYPE__LAST, }; @@ -384,7 +398,7 @@ struct ccp_rsa_engine { /***** Passthru engine *****/ /** - * ccp_passthru_bitwise - type of bitwise passthru operation + * enum ccp_passthru_bitwise - type of bitwise passthru operation * * @CCP_PASSTHRU_BITWISE_NOOP: no bitwise operation performed * @CCP_PASSTHRU_BITWISE_AND: perform bitwise AND of src with mask @@ -398,11 +412,12 @@ enum ccp_passthru_bitwise { CCP_PASSTHRU_BITWISE_OR, CCP_PASSTHRU_BITWISE_XOR, CCP_PASSTHRU_BITWISE_MASK, + /* private: */ CCP_PASSTHRU_BITWISE__LAST, }; /** - * ccp_passthru_byteswap - type of byteswap passthru operation + * enum ccp_passthru_byteswap - type of byteswap passthru operation * * @CCP_PASSTHRU_BYTESWAP_NOOP: no byte swapping performed * @CCP_PASSTHRU_BYTESWAP_32BIT: swap bytes within 32-bit words @@ -412,6 +427,7 @@ enum ccp_passthru_byteswap { CCP_PASSTHRU_BYTESWAP_NOOP = 0, CCP_PASSTHRU_BYTESWAP_32BIT, CCP_PASSTHRU_BYTESWAP_256BIT, + /* private: */ CCP_PASSTHRU_BYTESWAP__LAST, }; @@ -450,8 +466,8 @@ struct ccp_passthru_engine { * @byte_swap: byteswap operation to perform * @mask: mask to be applied to data * @mask_len: length in bytes of mask - * @src: data to be used for this operation - * @dst: data produced by this operation + * @src_dma: data to be used for this operation + * @dst_dma: data produced by this operation * @src_len: length in bytes of data used for this operation * @final: indicate final pass-through operation * @@ -478,7 +494,7 @@ struct ccp_passthru_nomap_engine { #define CCP_ECC_MAX_OUTPUTS 3 /** - * ccp_ecc_function - type of ECC function + * enum ccp_ecc_function - type of ECC function * * @CCP_ECC_FUNCTION_MMUL_384BIT: 384-bit modular multiplication * @CCP_ECC_FUNCTION_MADD_384BIT: 384-bit modular addition @@ -564,8 +580,9 @@ struct ccp_ecc_point_math { * @function: ECC function to perform * @mod: ECC modulus * @mod_len: length in bytes of modulus - * @mm: module math parameters - * @pm: point math parameters + * @u: union for math parameters + * @u.mm: module math parameters + * @u.pm: point math parameters * @ecc_result: result of the ECC operation * * Variables required to be set when calling ccp_enqueue_cmd(): @@ -589,11 +606,11 @@ struct ccp_ecc_engine { /** - * ccp_engine - CCP operation identifiers + * enum ccp_engine - CCP operation identifiers * * @CCP_ENGINE_AES: AES operation - * @CCP_ENGINE_XTS_AES: 128-bit XTS AES operation - * @CCP_ENGINE_RSVD1: unused + * @CCP_ENGINE_XTS_AES_128: 128-bit XTS AES operation + * @CCP_ENGINE_DES3: 3DES operation * @CCP_ENGINE_SHA: SHA operation * @CCP_ENGINE_RSA: RSA operation * @CCP_ENGINE_PASSTHRU: pass-through operation @@ -609,6 +626,7 @@ enum ccp_engine { CCP_ENGINE_PASSTHRU, CCP_ENGINE_ZLIB_DECOMPRESS, CCP_ENGINE_ECC, + /* private: */ CCP_ENGINE__LAST, };
diff --git a/include/linux/cgroup-defs.h b/include/linux/cgroup-defs.h index 3754d69..cbfe893 100644 --- a/include/linux/cgroup-defs.h +++ b/include/linux/cgroup-defs.h
@@ -556,6 +556,14 @@ struct cgroup { struct cgroup_subsys_state __rcu *subsys[CGROUP_SUBSYS_COUNT]; /* + * Effective css for each subsystem: the css of the nearest ancestor, + * including this cgroup, that has the subsystem enabled, or the root + * css if the subsystem isn't bound to this hierarchy. Updated under + * cgroup_mutex and read under RCU. + */ + struct cgroup_subsys_state __rcu *e_css[CGROUP_SUBSYS_COUNT]; + + /* * Keep track of total number of dying CSSes at and below this cgroup. * Protected by cgroup_mutex. */
diff --git a/include/linux/device-id/apr.h b/include/linux/device-id/apr.h deleted file mode 100644 index f282608..0000000 --- a/include/linux/device-id/apr.h +++ /dev/null
@@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef LINUX_DEVICE_ID_APR_H -#define LINUX_DEVICE_ID_APR_H - -#ifdef __KERNEL__ -#include <linux/types.h> -typedef unsigned long kernel_ulong_t; -#endif - -#define APR_NAME_SIZE 32 -#define APR_MODULE_PREFIX "apr:" - -struct apr_device_id { - char name[APR_NAME_SIZE]; - __u32 domain_id; - __u32 svc_id; - __u32 svc_version; - kernel_ulong_t driver_data; /* Data private to the driver */ -}; - -#endif /* ifndef LINUX_DEVICE_ID_APR_H */
diff --git a/include/linux/device-id/scmi.h b/include/linux/device-id/scmi.h new file mode 100644 index 0000000..1b4ccfa --- /dev/null +++ b/include/linux/device-id/scmi.h
@@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef LINUX_DEVICE_ID_SCMI_H +#define LINUX_DEVICE_ID_SCMI_H + +#ifdef __KERNEL__ +#include <linux/types.h> +#endif + +#define SCMI_NAME_SIZE 32 +#define SCMI_MODULE_PREFIX "scmi:" + +struct scmi_device_id { + __u8 protocol_id; + char name[SCMI_NAME_SIZE]; +}; + +#endif /* ifndef LINUX_DEVICE_ID_SCMI_H */
diff --git a/include/linux/firmware/qcom/qcom_scm.h b/include/linux/firmware/qcom/qcom_scm.h index 5747bd1..a0a6bc0 100644 --- a/include/linux/firmware/qcom/qcom_scm.h +++ b/include/linux/firmware/qcom/qcom_scm.h
@@ -64,35 +64,6 @@ bool qcom_scm_is_available(void); int qcom_scm_set_cold_boot_addr(void *entry); int qcom_scm_set_warm_boot_addr(void *entry); void qcom_scm_cpu_power_down(u32 flags); -int qcom_scm_set_remote_state(u32 state, u32 id); - -struct qcom_scm_pas_context { - struct device *dev; - u32 pas_id; - phys_addr_t mem_phys; - size_t mem_size; - void *ptr; - dma_addr_t phys; - ssize_t size; - bool use_tzmem; -}; - -struct qcom_scm_pas_context *devm_qcom_scm_pas_context_alloc(struct device *dev, - u32 pas_id, - phys_addr_t mem_phys, - size_t mem_size); -int qcom_scm_pas_init_image(u32 pas_id, const void *metadata, size_t size, - struct qcom_scm_pas_context *ctx); -void qcom_scm_pas_metadata_release(struct qcom_scm_pas_context *ctx); -int qcom_scm_pas_mem_setup(u32 pas_id, phys_addr_t addr, phys_addr_t size); -int qcom_scm_pas_auth_and_reset(u32 pas_id); -int qcom_scm_pas_shutdown(u32 pas_id); -bool qcom_scm_pas_supported(u32 pas_id); -struct resource_table *qcom_scm_pas_get_rsc_table(struct qcom_scm_pas_context *ctx, - void *input_rt, size_t input_rt_size, - size_t *output_rt_size); - -int qcom_scm_pas_prepare_and_auth_reset(struct qcom_scm_pas_context *ctx); int qcom_scm_io_readl(phys_addr_t addr, unsigned int *val); int qcom_scm_io_writel(phys_addr_t addr, unsigned int val);
diff --git a/include/linux/firmware/xlnx-zynqmp-ufs.h b/include/linux/firmware/xlnx-zynqmp-ufs.h index d3538dd..00383dd 100644 --- a/include/linux/firmware/xlnx-zynqmp-ufs.h +++ b/include/linux/firmware/xlnx-zynqmp-ufs.h
@@ -9,17 +9,17 @@ #define __FIRMWARE_XLNX_ZYNQMP_UFS_H__ #if IS_REACHABLE(CONFIG_ZYNQMP_FIRMWARE) -int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready); -int zynqmp_pm_is_sram_init_done(bool *is_done); +int zynqmp_pm_wait_mphy_tx_rx_config_ready(u32 timeout_us); +int zynqmp_pm_wait_sram_init_done(u32 timeout_us); int zynqmp_pm_set_sram_bypass(void); int zynqmp_pm_get_ufs_calibration_values(u32 *val); #else -static inline int zynqmp_pm_is_mphy_tx_rx_config_ready(bool *is_ready) +static inline int zynqmp_pm_wait_mphy_tx_rx_config_ready(u32 timeout_us) { return -ENODEV; } -static inline int zynqmp_pm_is_sram_init_done(bool *is_done) +static inline int zynqmp_pm_wait_sram_init_done(u32 timeout_us) { return -ENODEV; }
diff --git a/include/linux/firmware/xlnx-zynqmp.h b/include/linux/firmware/xlnx-zynqmp.h index f4b3df6..41a1cd8 100644 --- a/include/linux/firmware/xlnx-zynqmp.h +++ b/include/linux/firmware/xlnx-zynqmp.h
@@ -277,11 +277,6 @@ enum rpu_oper_mode { PM_RPU_MODE_SPLIT = 1, }; -enum rpu_boot_mem { - PM_RPU_BOOTMEM_LOVEC = 0, - PM_RPU_BOOTMEM_HIVEC = 1, -}; - enum rpu_tcm_comb { PM_RPU_TCM_SPLIT = 0, PM_RPU_TCM_COMB = 1,
diff --git a/include/linux/fsl/mc.h b/include/linux/fsl/mc.h index c25f0f7..0b2c0eb 100644 --- a/include/linux/fsl/mc.h +++ b/include/linux/fsl/mc.h
@@ -336,7 +336,7 @@ struct fsl_mc_io { u16 flags; u32 portal_size; phys_addr_t portal_phys_addr; - void __iomem *portal_virt_addr; + void __iomem *portal_virt_addr __counted_by_ptr(portal_size); struct fsl_mc_device *dpmcp_dev; union { /*
diff --git a/include/linux/gpio/driver.h b/include/linux/gpio/driver.h index 1751143..4077dc6 100644 --- a/include/linux/gpio/driver.h +++ b/include/linux/gpio/driver.h
@@ -359,6 +359,10 @@ struct gpio_irq_chip { * @set_config: optional hook for all kinds of settings. Uses the same * packed config format as generic pinconf. Must return 0 on success and * a negative error number on failure. + * @get_config: optional hook to read back a setting. Takes the packed + * generic pinconf parameter to query and returns its bare argument in + * the same variable, like pinctrl_gpio_get_config(). Must return 0 on + * success and a negative error number on failure. * @to_irq: optional hook supporting non-static gpiod_to_irq() mappings; * implementation may not sleep * @dbg_show: optional routine to show contents in debugfs; default code @@ -434,6 +438,9 @@ struct gpio_chip { int (*set_config)(struct gpio_chip *gc, unsigned int offset, unsigned long config); + int (*get_config)(struct gpio_chip *gc, + unsigned int offset, + unsigned long *config); int (*to_irq)(struct gpio_chip *gc, unsigned int offset); @@ -708,6 +715,8 @@ int gpiochip_generic_request(struct gpio_chip *gc, unsigned int offset); void gpiochip_generic_free(struct gpio_chip *gc, unsigned int offset); int gpiochip_generic_config(struct gpio_chip *gc, unsigned int offset, unsigned long config); +int gpiochip_generic_get_config(struct gpio_chip *gc, unsigned int offset, + unsigned long *config); /** * struct gpio_pin_range - pin range controlled by a gpio chip
diff --git a/include/linux/gpio/legacy.h b/include/linux/gpio/legacy.h index 557ef63..4001208 100644 --- a/include/linux/gpio/legacy.h +++ b/include/linux/gpio/legacy.h
@@ -63,10 +63,6 @@ static inline int gpio_get_value_cansleep(unsigned gpio) { return gpiod_get_raw_value_cansleep(gpio_to_desc(gpio)); } -static inline void gpio_set_value_cansleep(unsigned gpio, int value) -{ - gpiod_set_raw_value_cansleep(gpio_to_desc(gpio), value); -} static inline int gpio_get_value(unsigned gpio) { @@ -148,12 +144,6 @@ static inline int gpio_get_value_cansleep(unsigned gpio) return 0; } -static inline void gpio_set_value_cansleep(unsigned gpio, int value) -{ - /* GPIO can never have been requested or set as output */ - WARN_ON(1); -} - static inline int gpio_to_irq(unsigned gpio) { /* GPIO can never have been requested or set as input */
diff --git a/include/linux/gpio/regmap.h b/include/linux/gpio/regmap.h index 6f52c14..6fe0877 100644 --- a/include/linux/gpio/regmap.h +++ b/include/linux/gpio/regmap.h
@@ -46,6 +46,7 @@ enum gpio_regmap_operation { * @parent: The parent device * @regmap: The regmap used to access the registers * given, the name of the device is used + * @pm_dev: (Optional) Device to use for runtime power management. * @fwnode: (Optional) The firmware node. * If not given, the fwnode of the parent is used. * @label: (Optional) Descriptive name for GPIO controller. @@ -117,6 +118,7 @@ enum gpio_regmap_operation { struct gpio_regmap_config { struct device *parent; struct regmap *regmap; + struct device *pm_dev; struct fwnode_handle *fwnode; const char *label;
diff --git a/include/linux/hiddev.h b/include/linux/hiddev.h index 2164c03..8e9f8a3 100644 --- a/include/linux/hiddev.h +++ b/include/linux/hiddev.h
@@ -13,6 +13,7 @@ #ifndef _HIDDEV_H #define _HIDDEV_H +#include <linux/refcount.h> #include <uapi/linux/hiddev.h> @@ -24,6 +25,7 @@ struct hiddev { int minor; int exist; int open; + refcount_t refcount; struct mutex existancelock; wait_queue_head_t wait; struct hid_device *hid;
diff --git a/include/linux/hisi_acc_qm.h b/include/linux/hisi_acc_qm.h index f7570a4..f2885d6 100644 --- a/include/linux/hisi_acc_qm.h +++ b/include/linux/hisi_acc_qm.h
@@ -196,7 +196,7 @@ struct qm_dev_dfx { }; struct dfx_diff_registers { - u32 *regs; + u32 *regs __counted_by_ptr(reg_len); u32 reg_offset; u32 reg_len; }; @@ -332,9 +332,9 @@ struct hisi_qm_cap_record { struct hisi_qm_cap_tables { u32 qm_cap_size; - struct hisi_qm_cap_record *qm_cap_table; + struct hisi_qm_cap_record *qm_cap_table __counted_by_ptr(qm_cap_size); u32 dev_cap_size; - struct hisi_qm_cap_record *dev_cap_table; + struct hisi_qm_cap_record *dev_cap_table __counted_by_ptr(dev_cap_size); }; struct hisi_qm_list {
diff --git a/include/linux/i2c.h b/include/linux/i2c.h index 14ab4d3..f3192ab 100644 --- a/include/linux/i2c.h +++ b/include/linux/i2c.h
@@ -174,8 +174,23 @@ i2c_smbus_write_word_swapped(const struct i2c_client *client, } /* Returns the number of read bytes */ -s32 i2c_smbus_read_block_data(const struct i2c_client *client, - u8 command, u8 *values); +s32 __i2c_smbus_read_block_data(const struct i2c_client *client, + u8 command, u8 length, u8 *values); +/* + * This monstrosity allows to call i2c_smbus_read_block_data() with either + * 3 or 4 arguments and will be removed once all users have been switched + * to the 4 argument version. + */ +#define __i2c_smbus_read_block_data_3arg(client, cmd, values) \ + __i2c_smbus_read_block_data(client, cmd, I2C_SMBUS_BLOCK_MAX, values) +#define __i2c_smbus_read_block_data_4arg(client, cmd, length, values) \ + __i2c_smbus_read_block_data(client, cmd, length, values) +#define __i2c_smbus_read_block_data_impl(_1, _2, _3, _4, impl, ...) impl +#define i2c_smbus_read_block_data(client, cmd, varargs...) \ + __i2c_smbus_read_block_data_impl(client, cmd, varargs, \ + __i2c_smbus_read_block_data_4arg, \ + __i2c_smbus_read_block_data_3arg) \ + (client, cmd, varargs) s32 i2c_smbus_write_block_data(const struct i2c_client *client, u8 command, u8 length, const u8 *values); /* Returns the number of read bytes */ @@ -919,8 +934,8 @@ static inline u32 i2c_get_functionality(struct i2c_adapter *adap) return adap->algo->functionality(adap); } -/* Return 1 if adapter supports everything we need, 0 if not. */ -static inline int i2c_check_functionality(struct i2c_adapter *adap, u32 func) +/* Return true if adapter supports everything we need, false if not. */ +static inline bool i2c_check_functionality(struct i2c_adapter *adap, u32 func) { return (func & i2c_get_functionality(adap)) == func; }
diff --git a/include/linux/input/samsung-keypad.h b/include/linux/input/samsung-keypad.h deleted file mode 100644 index ab6b9711..0000000 --- a/include/linux/input/samsung-keypad.h +++ /dev/null
@@ -1,39 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-or-later */ -/* - * Samsung Keypad platform data definitions - * - * Copyright (C) 2010 Samsung Electronics Co.Ltd - * Author: Joonyoung Shim <jy0922.shim@samsung.com> - */ - -#ifndef __SAMSUNG_KEYPAD_H -#define __SAMSUNG_KEYPAD_H - -#include <linux/input/matrix_keypad.h> - -#define SAMSUNG_MAX_ROWS 8 -#define SAMSUNG_MAX_COLS 8 - -/** - * struct samsung_keypad_platdata - Platform device data for Samsung Keypad. - * @keymap_data: pointer to &matrix_keymap_data. - * @rows: number of keypad row supported. - * @cols: number of keypad col supported. - * @no_autorepeat: disable key autorepeat. - * @wakeup: controls whether the device should be set up as wakeup source. - * @cfg_gpio: configure the GPIO. - * - * Initialisation data specific to either the machine or the platform - * for the device driver to use or call-back when configuring gpio. - */ -struct samsung_keypad_platdata { - const struct matrix_keymap_data *keymap_data; - unsigned int rows; - unsigned int cols; - bool no_autorepeat; - bool wakeup; - - void (*cfg_gpio)(unsigned int rows, unsigned int cols); -}; - -#endif /* __SAMSUNG_KEYPAD_H */
diff --git a/include/linux/key-type.h b/include/linux/key-type.h index bb97bd3..c4f329b 100644 --- a/include/linux/key-type.h +++ b/include/linux/key-type.h
@@ -161,6 +161,7 @@ struct key_type { const void *in, const void *in2); /* internal fields */ + atomic64_t index_id; /* Opaque keyring index ID */ struct list_head link; /* link in types list */ struct lock_class_key lock_class; /* key->sem lock class */ } __randomize_layout;
diff --git a/include/linux/key.h b/include/linux/key.h index 81b8f05..e40b526 100644 --- a/include/linux/key.h +++ b/include/linux/key.h
@@ -107,6 +107,7 @@ struct keyring_name; struct key_tag { struct rcu_head rcu; + atomic64_t index_id; /* Opaque keyring index ID */ refcount_t usage; bool removed; /* T when subject removed */ }; @@ -129,6 +130,8 @@ struct keyring_index_key { struct key_type *type; struct key_tag *domain_tag; /* Domain of operation */ const char *description; + u64 type_id; /* Cached index IDs */ + u64 domain_id; }; union key_payload { @@ -251,6 +254,8 @@ struct key { struct key_type *type; /* type of key */ struct key_tag *domain_tag; /* Domain of operation */ char *description; + u64 type_id; + u64 domain_id; }; };
diff --git a/include/linux/landlock.h b/include/linux/landlock.h index 004cbd0..0ee4880 100644 --- a/include/linux/landlock.h +++ b/include/linux/landlock.h
@@ -13,14 +13,16 @@ #include <uapi/linux/landlock.h> /* - * Access-right and scope names, shared between the audit records (get_blocker() - * in security/landlock/audit.c) and the trace events + * Access-right, scope, and permission names, shared between the audit records + * (get_blocker() in security/landlock/audit.c) and the trace events * (include/trace/events/landlock.h). A consumer defines * _LANDLOCK_NAME_ENTRY(mask, name) before expanding a list and undefines it * afterwards: audit maps each entry to a "[bit] = name" slot for O(1) lookup, * the trace events map it to a __print_flags() { mask, name } pair. The bit * value lives only in the LANDLOCK_* UAPI constant each entry references. - * Names are unprefixed; audit prepends the "fs."/"net."/"scope." category. + * Access-right and scope names are unprefixed; audit prepends the + * "fs."/"net."/"scope." category. Permission entries carry an action and a + * domain for the qualified and bare views below. */ #define _LANDLOCK_ACCESS_FS_NAMES \ _LANDLOCK_NAME_ENTRY(LANDLOCK_ACCESS_FS_EXECUTE, "execute"), \ @@ -53,4 +55,25 @@ "abstract_unix_socket"), \ _LANDLOCK_NAME_ENTRY(LANDLOCK_SCOPE_SIGNAL, "signal") +#define _LANDLOCK_PERMISSION_NAMESPACE_NAME "namespace" +#define _LANDLOCK_PERMISSION_CAPABILITY_NAME "capability" + +#define _LANDLOCK_PERMISSION_LIST(entry) \ + entry(LANDLOCK_PERMISSION_NAMESPACE_USE, "use", \ + _LANDLOCK_PERMISSION_NAMESPACE_NAME), \ + entry(LANDLOCK_PERMISSION_CAPABILITY_USE, "use", \ + _LANDLOCK_PERMISSION_CAPABILITY_NAME) + +#define _LANDLOCK_PERMISSION_QUALIFIED_ENTRY(mask, action, domain) \ + _LANDLOCK_NAME_ENTRY(mask, domain "." action) + +#define _LANDLOCK_PERMISSION_BARE_ENTRY(mask, action, ...) \ + _LANDLOCK_NAME_ENTRY(mask, action) + +#define _LANDLOCK_PERMISSION_NAMES \ + _LANDLOCK_PERMISSION_LIST(_LANDLOCK_PERMISSION_QUALIFIED_ENTRY) + +#define _LANDLOCK_PERMISSION_BLOCKER_NAMES \ + _LANDLOCK_PERMISSION_LIST(_LANDLOCK_PERMISSION_BARE_ENTRY) + #endif /* _LINUX_LANDLOCK_H */
diff --git a/include/linux/mailbox/riscv-rpmi-message.h b/include/linux/mailbox/riscv-rpmi-message.h index e135c65..d5362b5 100644 --- a/include/linux/mailbox/riscv-rpmi-message.h +++ b/include/linux/mailbox/riscv-rpmi-message.h
@@ -93,6 +93,7 @@ static inline int rpmi_to_linux_error(int rpmi_error) /* RPMI service group IDs */ #define RPMI_SRVGRP_SYSTEM_MSI 0x00002 #define RPMI_SRVGRP_CLOCK 0x00008 +#define RPMI_SRVGRP_DEVICE_POWER 0x00009 /* RPMI clock service IDs */ enum rpmi_clock_service_id { @@ -119,6 +120,16 @@ enum rpmi_sysmsi_service_id { RPMI_SYSMSI_SRV_ID_MAX_COUNT }; +/* RPMI device power service IDs */ +enum rpmi_device_power_service_id { + RPMI_DP_SRV_ENABLE_NOTIFICATION = 0x01, + RPMI_DP_SRV_GET_NUM_DOMAINS = 0x02, + RPMI_DP_SRV_GET_ATTRS = 0x03, + RPMI_DP_SRV_SET_STATE = 0x04, + RPMI_DP_SRV_GET_STATE = 0x05, + RPMI_DP_SRV_ID_MAX_COUNT, +}; + /* RPMI Linux mailbox attribute IDs */ enum rpmi_mbox_attribute_id { RPMI_MBOX_ATTR_SPEC_VERSION,
diff --git a/include/linux/mfd/88pm886.h b/include/linux/mfd/88pm886.h index 2c24dd3..9e96d2c 100644 --- a/include/linux/mfd/88pm886.h +++ b/include/linux/mfd/88pm886.h
@@ -2,6 +2,7 @@ #ifndef __MFD_88PM886_H #define __MFD_88PM886_H +#include <linux/bits.h> #include <linux/i2c.h> #include <linux/regmap.h> @@ -130,6 +131,12 @@ #define PM886_GPADC_INDEX_TO_BIAS_uA(i) (1 + (i) * 5) /* Battery block register definitions */ +#define PM886_REG_BATTERY_CONFIG1 0x28 +#define PM886_REG_VBUS_EN BIT(7) + +#define PM886_REG_BOOST_CONFIG1 0x6b +#define PM886_REG_BOOST_MASK GENMASK(2, 0) + #define PM886_REG_CLS_CONFIG1 0x71 struct pm886_chip {
diff --git a/include/linux/mfd/rohm-bd73800.h b/include/linux/mfd/rohm-bd73800.h new file mode 100644 index 0000000..c6c0d45 --- /dev/null +++ b/include/linux/mfd/rohm-bd73800.h
@@ -0,0 +1,306 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +/* + * Copyright 2026 ROHM Semiconductors. + * + * Author: Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com> + */ + +#ifndef _MFD_BD73800_H +#define _MFD_BD73800_H + +#include <linux/regmap.h> + +enum { + BD73800_BUCK1 = 0, + BD73800_BUCK2, + BD73800_BUCK3, + BD73800_BUCK4, + BD73800_BUCK5, + BD73800_BUCK6, + BD73800_BUCK7, + BD73800_BUCK8, + BD73800_LDO1, + BD73800_LDO2, + BD73800_LDO3, + BD73800_LDO4, +}; + +/* + * All regulators except BUCK 5 have full 8-bit register of valid voltage + * values, including 0. + */ +#define BD73800_NUM_VOLTS (0xff + 1) +/* + * BUCK 5 has two sets of voltage ranges, both having valid voltage selectors + * from 0x0 to 0x7f + */ +#define BD73800_BUCK5_VOLTS (0x80 + 0x80) + +/* BD73800 interrupts */ +enum { + /* INT_STAT_1 register IRQs, ADC and RTC */ + BD73800_INT_ADC_ACCUM_DONE, + BD73800_INT_ADC_ACCUM_OVF, + BD73800_INT_ADC_ACCUM_VAL, + BD73800_INT_ADC_ACCUM_TW, + BD73800_INT_ADC_POW_VAL, + BD73800_INT_RTC0, + BD73800_INT_RTC1, + BD73800_INT_RTC2, + + /* BUCK reg interrupts */ + /* INT_STAT_2 IRQs */ + BD73800_INT_BUCK1_DVS_DONE, + BD73800_INT_BUCK2_DVS_DONE, + BD73800_INT_BUCK3_DVS_DONE, + BD73800_INT_BUCK4_DVS_DONE, + BD73800_INT_BUCK5_DVS_DONE, + BD73800_INT_BUCK6_DVS_DONE, + BD73800_INT_BUCK7_DVS_DONE, + BD73800_INT_BUCK8_DVS_DONE, + /* INT_STAT_3 IRQs */ + BD73800_INT_BUCK1_OCP, + BD73800_INT_BUCK2_OCP, + BD73800_INT_BUCK3_OCP, + BD73800_INT_BUCK4_OCP, + BD73800_INT_BUCK5_OCP, + BD73800_INT_BUCK6_OCP, + BD73800_INT_BUCK7_OCP, + BD73800_INT_BUCK8_OCP, + + /* INT_STAT_4 IRQs, power-button, WDG and reset */ + BD73800_INT_PBTN_LONG_PRESS, + BD73800_INT_PBTN_MID_PRESS, + /* + * The SHORT_PUSH is generated when button is first pressed (longer + * than configured time limit), and then released before the MID_PRESS + * time limit. The SHORT_PRESS is generated immediately when button is + * pressed for longer than configured limit, whether it is released or + * not. + */ + BD73800_INT_PBTN_SHORT_PUSH, + BD73800_INT_PBTN_SHORT_PRESS, + BD73800_INT_WDG, + BD73800_INT_SWRESET, + BD73800_INT_SEQ_DONE, + + /* INT_STAT_5 IRQs, GPIO */ + BD73800_INT_GPIO1, + BD73800_INT_GPIO2, + BD73800_INT_GPIO3, + BD73800_INT_GPIO4, +}; + +#define BD73800_MASK_RUN_EN BIT(2) +#define BD73800_MASK_SUSP_EN BIT(1) +#define BD73800_MASK_IDLE_EN BIT(0) +#define BD73800_MASK_VOLT GENMASK(7, 0) +#define BD73800_MASK_BUCK5_VOLT GENMASK(6, 0) +#define BD73800_MASK_RAMP_DELAY GENMASK(2, 1) +#define BD73800_BUCK5_RANGE_MASK BIT(7) + +/* BD73800 registers */ +enum { + BD73800_REG_PRODUCT_ID = 0x0, + BD73800_REG_MANUFACTURER_ID, + BD73800_REG_REVISION, + BD73800_REG_NVMVERSION, + BD73800_REG_POR_REASON, + BD73800_REG_RESET_REASON1, + BD73800_REG_RESET_REASON2, + BD73800_REG_RESET_REASON3, + BD73800_REG_POW_STATE, + BD73800_REG_WRST_SEL, + BD73800_REG_PS_CTRL_1, + BD73800_REG_PS_CTRL_2, + BD73800_REG_RCVCFG, + BD73800_REG_RCVNUM, + BD73800_REG_CRDCFG, /* 0x0f, followed by undocumented reg */ + + BD73800_REG_BUCK1_ON = 0x11, + BD73800_REG_BUCK1_MODE, + BD73800_REG_BUCK1_VOLT_RUN, + BD73800_REG_BUCK1_VOLT_IDLE, + BD73800_REG_BUCK1_VOLT_SUSP, /* 0x15, followed by undocumented reg */ + + BD73800_REG_BUCK2_ON = 0x17, + BD73800_REG_BUCK2_MODE, + BD73800_REG_BUCK2_VOLT_RUN, + BD73800_REG_BUCK2_VOLT_IDLE, + BD73800_REG_BUCK2_VOLT_SUSP, /* 0x1b */ + + BD73800_REG_BUCK3_ON = 0x1d, + BD73800_REG_BUCK3_MODE, + BD73800_REG_BUCK3_VOLT_RUN, + BD73800_REG_BUCK3_VOLT_IDLE, + BD73800_REG_BUCK3_VOLT_SUSP, /* 0x21 */ + + BD73800_REG_BUCK4_ON = 0x23, + BD73800_REG_BUCK4_MODE, + BD73800_REG_BUCK4_VOLT_RUN, + BD73800_REG_BUCK4_VOLT_IDLE, + BD73800_REG_BUCK4_VOLT_SUSP, /* 0x27 */ + + BD73800_REG_BUCK5_ON = 0x29, + BD73800_REG_BUCK5_MODE, + BD73800_REG_BUCK5_VOLT_RUN, + BD73800_REG_BUCK5_VOLT_IDLE, + BD73800_REG_BUCK5_VOLT_SUSP, /* 0x2d */ + + BD73800_REG_BUCK6_ON = 0x2f, + BD73800_REG_BUCK6_MODE, + BD73800_REG_BUCK6_VOLT_RUN, + BD73800_REG_BUCK6_VOLT_IDLE, + BD73800_REG_BUCK6_VOLT_SUSP, /* 0x33 */ + + BD73800_REG_BUCK7_ON = 0x35, + BD73800_REG_BUCK7_MODE, + BD73800_REG_BUCK7_VOLT_RUN, + BD73800_REG_BUCK7_VOLT_IDLE, + BD73800_REG_BUCK7_VOLT_SUSP, /* 0x39 */ + + BD73800_REG_BUCK8_ON = 0x3b, + BD73800_REG_BUCK8_MODE, + BD73800_REG_BUCK8_VOLT_RUN, + BD73800_REG_BUCK8_VOLT_IDLE, + BD73800_REG_BUCK8_VOLT_SUSP, /* 0x3f */ + + BD73800_REG_LDO1_ON = 0x41, + BD73800_REG_LDO1_VOLT, + BD73800_REG_LDO1_MODE, + BD73800_REG_LDO2_ON, + BD73800_REG_LDO2_VOLT, + BD73800_REG_LDO2_MODE, + BD73800_REG_LDO3_ON, + BD73800_REG_LDO3_VOLT, + BD73800_REG_LDO3_MODE, + BD73800_REG_LDO4_ON, + BD73800_REG_LDO4_VOLT, + BD73800_REG_LDO4_MODE, /* 0x4c */ + + BD73800_REG_GPO_OUT = 0x4e, + BD73800_REG_OUT32K = 0x50, + BD73800_REG_RTC_SEC, + BD73800_REG_RTC_MIN, + BD73800_REG_RTC_HOUR, + BD73800_REG_RTC_WEEK, + BD73800_REG_RTC_DAY, + BD73800_REG_RTC_MONTH, + BD73800_REG_RTC_YEAR, + BD73800_REG_RTC_ALM0_SEC, + BD73800_REG_RTC_ALM0_MIN, + BD73800_REG_RTC_ALM0_HOUR, + BD73800_REG_RTC_ALM0_WEEK, + BD73800_REG_RTC_ALM0_DAY, + BD73800_REG_RTC_ALM0_MONTH, + BD73800_REG_RTC_ALM0_YEAR, + BD73800_REG_RTC_ALM1_SEC, + BD73800_REG_RTC_ALM1_MIN, + BD73800_REG_RTC_ALM1_HOUR, + BD73800_REG_RTC_ALM1_WEEK, + BD73800_REG_RTC_ALM1_DAY, + BD73800_REG_RTC_ALM1_MONTH, + BD73800_REG_RTC_ALM1_YEAR, + BD73800_REG_RTC_ALM2, + BD73800_REG_RTC_CONF, /* 0x69 */ + + BD73800_REG_ADC_CTRL_1 = 0x6b, + BD73800_REG_ADC_CTRL_2, + BD73800_REG_ADC_ACCUM_NUM2, + BD73800_REG_ADC_ACCUM_NUM1, + BD73800_REG_ADC_ACCUM_NUM0, + BD73800_REG_ADC_ACCUM_KICK, + BD73800_REG_ADC_ACCUM_CNT2, + BD73800_REG_ADC_ACCUM_CNT1, + BD73800_REG_ADC_ACCUM_CNT0, + BD73800_REG_ADC_ACCUM_VAL2, + BD73800_REG_ADC_ACCUM_VAL1, + BD73800_REG_ADC_ACCUM_VAL0, + BD73800_REG_ADC_VOL_VAL1, + BD73800_REG_ADC_VOL_VAL0, + BD73800_REG_ADC_CUR_VAL1, + BD73800_REG_ADC_CUR_VAL0, + BD73800_REG_ADC_POW_VAL1, + BD73800_REG_ADC_POW_VAL0, + BD73800_REG_ADC_TEMP_VAL1, + BD73800_REG_ADC_TEMP_VAL0, + BD73800_REG_ADC_ACCUM_VAL_INT_TH4, + BD73800_REG_ADC_ACCUM_VAL_INT_TH3, + BD73800_REG_ADC_ACCUM_VAL_INT_TH2, + BD73800_REG_ADC_ACCUM_VAL_INT_TH1, + BD73800_REG_ADC_ACCUM_VAL_INT_TH0, + BD73800_REG_ADC_WARN_TEMP_INT_TH1, + BD73800_REG_ADC_WARN_TEMP_INT_TH0, + BD73800_REG_ADC_POW_VAL_INT_TH1, + BD73800_REG_ADC_POW_VAL_INT_TH0, /* 0x89 */ + + BD73800_REG_PBTN_CONF = 0x8b, + + BD73800_REG_INT_MAIN_EN = 0x8f, + BD73800_REG_INT_1_EN, + BD73800_REG_INT_2_EN, + BD73800_REG_INT_3_EN, + BD73800_REG_INT_4_EN, + BD73800_REG_INT_5_EN, /* 0x94 */ + + BD73800_REG_INT_MAIN_STAT = 0x96, + BD73800_REG_INT_1_STAT, + BD73800_REG_INT_2_STAT, + BD73800_REG_INT_3_STAT, + BD73800_REG_INT_4_STAT, + BD73800_REG_INT_5_STAT, /* 0x9b */ + + BD73800_REG_INT_MAIN_SRC = 0x9d, + BD73800_REG_INT_1_SRC, + BD73800_REG_INT_2_SRC, + BD73800_REG_INT_3_SRC, + BD73800_REG_INT_4_SRC, + BD73800_REG_INT_5_SRC, /* 0xa2 */ + + BD73800_REG_RST_MASK = 0xaf, + BD73800_MAX_REGISTER, +}; + +#define BD73800_REG_RTC_START BD73800_REG_RTC_SEC +#define BD73800_REG_RTC_ALM_START BD73800_REG_RTC_ALM0_SEC + +/* BD73800 IRQ register masks */ + +#define BD73800_INT_MAIN_EN_ALL GENMASK(4, 0) +#define BD73800_INT_ADC_ACCUM_DONE_MASK BIT(0) +#define BD73800_INT_ADC_ACCUM_OVF_MASK BIT(1) +#define BD73800_INT_ADC_ACCUM_VAL_MASK BIT(2) +#define BD73800_INT_ADC_ACCUM_TW_MASK BIT(3) +#define BD73800_INT_ADC_POW_VAL_MASK BIT(4) +#define BD73800_INT_RTC0_MASK BIT(5) +#define BD73800_INT_RTC1_MASK BIT(6) +#define BD73800_INT_RTC2_MASK BIT(7) +#define BD73800_INT_BUCK1_DVS_DONE_MASK BIT(0) +#define BD73800_INT_BUCK2_DVS_DONE_MASK BIT(1) +#define BD73800_INT_BUCK3_DVS_DONE_MASK BIT(2) +#define BD73800_INT_BUCK4_DVS_DONE_MASK BIT(3) +#define BD73800_INT_BUCK5_DVS_DONE_MASK BIT(4) +#define BD73800_INT_BUCK6_DVS_DONE_MASK BIT(5) +#define BD73800_INT_BUCK7_DVS_DONE_MASK BIT(6) +#define BD73800_INT_BUCK8_DVS_DONE_MASK BIT(7) +#define BD73800_INT_BUCK1_OCP_MASK BIT(0) +#define BD73800_INT_BUCK2_OCP_MASK BIT(1) +#define BD73800_INT_BUCK3_OCP_MASK BIT(2) +#define BD73800_INT_BUCK4_OCP_MASK BIT(3) +#define BD73800_INT_BUCK5_OCP_MASK BIT(4) +#define BD73800_INT_BUCK6_OCP_MASK BIT(5) +#define BD73800_INT_BUCK7_OCP_MASK BIT(6) +#define BD73800_INT_BUCK8_OCP_MASK BIT(7) +#define BD73800_INT_PBTN_LONG_PRESS_MASK BIT(0) +#define BD73800_INT_PBTN_MID_PRESS_MASK BIT(1) +#define BD73800_INT_PBTN_SHORT_PUSH_MASK BIT(2) +#define BD73800_INT_PBTN_SHORT_PRESS_MASK BIT(3) +#define BD73800_INT_WDG_MASK BIT(4) +#define BD73800_INT_SWRESET_MASK BIT(5) +#define BD73800_INT_SEQ_DONE_MASK BIT(6) +#define BD73800_INT_GPIO1_MASK BIT(0) +#define BD73800_INT_GPIO2_MASK BIT(1) +#define BD73800_INT_GPIO3_MASK BIT(2) +#define BD73800_INT_GPIO4_MASK BIT(3) + +#endif /* _MFD_BD73800_H */
diff --git a/include/linux/mfd/rohm-generic.h b/include/linux/mfd/rohm-generic.h index 0a28491..3ec8742 100644 --- a/include/linux/mfd/rohm-generic.h +++ b/include/linux/mfd/rohm-generic.h
@@ -17,6 +17,7 @@ enum rohm_chip_type { ROHM_CHIP_TYPE_BD71837, ROHM_CHIP_TYPE_BD71847, ROHM_CHIP_TYPE_BD72720, + ROHM_CHIP_TYPE_BD73800, ROHM_CHIP_TYPE_BD96801, ROHM_CHIP_TYPE_BD96802, ROHM_CHIP_TYPE_BD96805,
diff --git a/include/linux/micrel_phy.h b/include/linux/micrel_phy.h index 9c6f981..bb71b25 100644 --- a/include/linux/micrel_phy.h +++ b/include/linux/micrel_phy.h
@@ -47,11 +47,6 @@ #define MICREL_PHY_FXEN BIT(1) #define MICREL_KSZ8_P1_ERRATA BIT(2) -#define MICREL_KSZ9021_EXTREG_CTRL 0xB -#define MICREL_KSZ9021_EXTREG_DATA_WRITE 0xC -#define MICREL_KSZ9021_RGMII_CLK_CTRL_PAD_SCEW 0x104 -#define MICREL_KSZ9021_RGMII_RX_DATA_PAD_SCEW 0x105 - /* Device specific MII_BMCR (Reg 0) bits */ /* 1 = HP Auto MDI/MDI-X mode, 0 = Microchip Auto MDI/MDI-X mode */ #define KSZ886X_BMCR_HP_MDIX BIT(5)
diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index ba84f02..032c018 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h
@@ -23,6 +23,7 @@ struct mmc_ios { unsigned int clock; /* clock rate */ unsigned short vdd; unsigned int power_delay_ms; /* waiting for stable power */ + unsigned int power_off_delay_us; /* waiting for power discharge */ /* vdd stores the bit number of the selected voltage range from below. */ @@ -463,6 +464,7 @@ struct mmc_host { #define MMC_CAP2_CRYPTO 0 #endif #define MMC_CAP2_ALT_GPT_TEGRA (1 << 28) /* Host with eMMC that has GPT entry at a non-standard location */ +#define MMC_CAP2_CRYPTO_NO_REPROG (1 << 29) /* Host handles inline crypto key reprogramming */ bool uhs2_sd_tran; /* UHS-II flag for SD_TRAN state */ bool uhs2_app_cmd; /* UHS-II flag for APP command */ @@ -583,11 +585,9 @@ struct mmc_host { struct device_node; -struct mmc_host *mmc_alloc_host(int extra, struct device *); struct mmc_host *devm_mmc_alloc_host(struct device *dev, int extra); int mmc_add_host(struct mmc_host *); void mmc_remove_host(struct mmc_host *); -void mmc_free_host(struct mmc_host *); void mmc_of_parse_clk_phase(struct device *dev, struct mmc_clk_phase_map *map); int mmc_of_parse(struct mmc_host *host); @@ -753,6 +753,8 @@ static inline int mmc_card_uhs2_hd_mode(struct mmc_host *host) int mmc_sd_switch(struct mmc_card *card, bool mode, int group, u8 value, u8 *resp); int mmc_send_status(struct mmc_card *card, u32 *status); +int mmc_send_tuning_timeout(struct mmc_host *host, u32 opcode, int *cmd_error, + u32 timeout_ms); int mmc_send_tuning(struct mmc_host *host, u32 opcode, int *cmd_error); int mmc_send_abort_tuning(struct mmc_host *host, u32 opcode); int mmc_get_ext_csd(struct mmc_card *card, u8 **new_ext_csd);
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index 318c4b5..d1581bb 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h
@@ -15,7 +15,6 @@ #include "device-id/acpi.h" #include "device-id/amba.h" #include "device-id/ap.h" -#include "device-id/apr.h" #include "device-id/arm_smccc.h" #include "device-id/auxiliary.h" #include "device-id/bcma.h"
diff --git a/include/linux/notifier.h b/include/linux/notifier.h index 01b6c9d..4eeae97 100644 --- a/include/linux/notifier.h +++ b/include/linux/notifier.h
@@ -46,6 +46,7 @@ * often but notifier_blocks will seldom be removed. */ +struct device; struct notifier_block; typedef int (*notifier_fn_t)(struct notifier_block *nb, @@ -145,8 +146,14 @@ extern void srcu_init_notifier_head(struct srcu_notifier_head *nh); extern int atomic_notifier_chain_register(struct atomic_notifier_head *nh, struct notifier_block *nb); +int devm_atomic_notifier_chain_register(struct device *dev, + struct atomic_notifier_head *nh, + struct notifier_block *nb); extern int blocking_notifier_chain_register(struct blocking_notifier_head *nh, struct notifier_block *nb); +int devm_blocking_notifier_chain_register(struct device *dev, + struct blocking_notifier_head *nh, + struct notifier_block *nb); extern int raw_notifier_chain_register(struct raw_notifier_head *nh, struct notifier_block *nb); extern int srcu_notifier_chain_register(struct srcu_notifier_head *nh,
diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h index 11b8f0b..7be49d4 100644 --- a/include/linux/pinctrl/consumer.h +++ b/include/linux/pinctrl/consumer.h
@@ -107,14 +107,14 @@ static inline int pinctrl_gpio_get_config(struct gpio_chip *gc, unsigned int offset, unsigned long *config) { - return 0; + return -ENOTSUPP; } static inline int pinctrl_gpio_set_config(struct gpio_chip *gc, unsigned int offset, unsigned long config) { - return 0; + return -ENOTSUPP; } static inline struct pinctrl * __must_check pinctrl_get(struct device *dev)
diff --git a/include/linux/pm_domain.h b/include/linux/pm_domain.h index f925614..14e0e34 100644 --- a/include/linux/pm_domain.h +++ b/include/linux/pm_domain.h
@@ -121,6 +121,14 @@ struct dev_pm_domain_list { * powered-off until the ->sync_state() callback is * invoked. This flag informs genpd to allow a * power-off without waiting for ->sync_state(). + * + * GENPD_FLAG_POWER_UNKNOWN: Use this flag to inform genpd that its initial + * status for the PM domain is set to powered off, + * which may not correctly reflect the state of the + * HW, as it's unknown. If the PM domain becomes + * powered on during boot, genpd will prevent it + * from being powered off until the ->sync_state + * callback is invoked for it. */ #define GENPD_FLAG_PM_CLK (1U << 0) #define GENPD_FLAG_IRQ_SAFE (1U << 1) @@ -133,6 +141,7 @@ struct dev_pm_domain_list { #define GENPD_FLAG_DEV_NAME_FW (1U << 8) #define GENPD_FLAG_NO_SYNC_STATE (1U << 9) #define GENPD_FLAG_NO_STAY_ON (1U << 10) +#define GENPD_FLAG_POWER_UNKNOWN (1U << 11) enum gpd_status { GENPD_STATE_ON = 0, /* PM domain is on */
diff --git a/include/linux/pm_qos.h b/include/linux/pm_qos.h index 6cea445..439a9e7 100644 --- a/include/linux/pm_qos.h +++ b/include/linux/pm_qos.h
@@ -37,6 +37,8 @@ enum pm_qos_flags_status { #define PM_QOS_LATENCY_TOLERANCE_NO_CONSTRAINT (-1) #define PM_QOS_FLAG_NO_POWER_OFF (1 << 0) +/* latency value applies to system-wide suspend/s2idle */ +#define PM_QOS_FLAG_LATENCY_SYS (2 << 0) enum pm_qos_type { PM_QOS_UNITIALIZED, @@ -217,6 +219,12 @@ static inline s32 dev_pm_qos_raw_resume_latency(struct device *dev) PM_QOS_RESUME_LATENCY_NO_CONSTRAINT : pm_qos_read_value(&dev->power.qos->resume_latency); } + +static inline s32 dev_pm_qos_raw_flags(struct device *dev) +{ + return IS_ERR_OR_NULL(dev->power.qos) ? + 0 : READ_ONCE(dev->power.qos->flags.effective_flags); +} #else static inline enum pm_qos_flags_status __dev_pm_qos_flags(struct device *dev, s32 mask) @@ -298,6 +306,7 @@ static inline s32 dev_pm_qos_raw_resume_latency(struct device *dev) { return PM_QOS_RESUME_LATENCY_NO_CONSTRAINT; } +static inline s32 dev_pm_qos_raw_flags(struct device *dev) { return 0; } #endif static inline int freq_qos_request_active(struct freq_qos_request *req)
diff --git a/include/linux/psp-sev.h b/include/linux/psp-sev.h index 03a7978..fab6222 100644 --- a/include/linux/psp-sev.h +++ b/include/linux/psp-sev.h
@@ -49,7 +49,7 @@ #define SEV_FW_BLOB_MAX_SIZE 0x4000 /* 16KB */ -/** +/* * SEV platform state */ enum sev_state { @@ -60,7 +60,7 @@ enum sev_state { SEV_STATE_MAX }; -/** +/* * SEV platform and guest management commands */ enum sev_cmd { @@ -157,6 +157,7 @@ enum sev_cmd { * struct sev_data_init - INIT command parameters * * @flags: processing flags + * @reserved: reserved * @tmr_address: system physical address used for SEV-ES * @tmr_len: len of tmr_address */ @@ -174,6 +175,7 @@ struct sev_data_init { * @flags: processing flags * @tmr_address: system physical address used for SEV-ES * @tmr_len: len of tmr_address + * @reserved: reserved * @nv_address: system physical address used for PSP NV storage * @nv_len: len of nv_address */ @@ -201,12 +203,13 @@ struct sev_data_pek_csr { } __packed; /** - * struct sev_data_cert_import - PEK_CERT_IMPORT command parameters + * struct sev_data_pek_cert_import - PEK_CERT_IMPORT command parameters * - * @pek_address: PEK certificate chain - * @pek_len: len of PEK certificate - * @oca_address: OCA certificate chain - * @oca_len: len of OCA certificate + * @pek_cert_address: PEK certificate chain + * @pek_cert_len: len of PEK certificate + * @reserved: reserved + * @oca_cert_address: OCA certificate chain + * @oca_cert_len: len of OCA certificate */ struct sev_data_pek_cert_import { u64 pek_cert_address; /* In */ @@ -240,8 +243,9 @@ struct sev_data_get_id { /** * struct sev_data_pdh_cert_export - PDH_CERT_EXPORT command parameters * - * @pdh_address: PDH certificate address - * @pdh_len: len of PDH certificate + * @pdh_cert_address: PDH certificate address + * @pdh_cert_len: len of PDH certificate + * @reserved: reserved * @cert_chain_address: PDH certificate chain * @cert_chain_len: len of PDH certificate chain */ @@ -304,6 +308,7 @@ struct sev_data_guest_status { * @policy: guest launch policy * @dh_cert_address: physical address of DH certificate blob * @dh_cert_len: len of DH certificate blob + * @reserved: reserved * @session_address: physical address of session parameters * @session_len: len of session parameters */ @@ -321,6 +326,7 @@ struct sev_data_launch_start { * struct sev_data_launch_update_data - LAUNCH_UPDATE_DATA command parameter * * @handle: handle of the VM to update + * @reserved: reserved * @len: len of memory to be encrypted * @address: physical address of memory region to encrypt */ @@ -335,6 +341,7 @@ struct sev_data_launch_update_data { * struct sev_data_launch_update_vmsa - LAUNCH_UPDATE_VMSA command * * @handle: handle of the VM + * @reserved: reserved * @address: physical address of memory region to encrypt * @len: len of memory region to encrypt */ @@ -349,6 +356,7 @@ struct sev_data_launch_update_vmsa { * struct sev_data_launch_measure - LAUNCH_MEASURE command parameters * * @handle: handle of the VM to process + * @reserved: reserved * @address: physical address containing the measurement blob * @len: len of measurement blob */ @@ -363,10 +371,13 @@ struct sev_data_launch_measure { * struct sev_data_launch_secret - LAUNCH_SECRET command parameters * * @handle: handle of the VM to process + * @reserved1: reserved * @hdr_address: physical address containing the packet header * @hdr_len: len of packet header + * @reserved2: reserved * @guest_address: system physical address of guest memory region * @guest_len: len of guest_paddr + * @reserved3: reserved * @trans_address: physical address of transport memory buffer * @trans_len: len of transport memory buffer */ @@ -399,10 +410,13 @@ struct sev_data_launch_finish { * @policy: policy information for the VM * @pdh_cert_address: physical address containing PDH certificate * @pdh_cert_len: len of PDH certificate + * @reserved1: reserved * @plat_certs_address: physical address containing platform certificate * @plat_certs_len: len of platform certificate + * @reserved2: reserved * @amd_certs_address: physical address containing AMD certificate * @amd_certs_len: len of AMD certificate + * @reserved3: reserved * @session_address: physical address containing Session data * @session_len: len of session data */ @@ -423,13 +437,16 @@ struct sev_data_send_start { } __packed; /** - * struct sev_data_send_update - SEND_UPDATE_DATA command + * struct sev_data_send_update_data - SEND_UPDATE_DATA command * * @handle: handle of the VM to process + * @reserved1: reserved * @hdr_address: physical address containing packet header * @hdr_len: len of packet header + * @reserved2: reserved * @guest_address: physical address of guest memory region to send * @guest_len: len of guest memory region to send + * @reserved3: reserved * @trans_address: physical address of host memory region * @trans_len: len of host memory region */ @@ -447,13 +464,15 @@ struct sev_data_send_update_data { } __packed; /** - * struct sev_data_send_update - SEND_UPDATE_VMSA command + * struct sev_data_send_update_vmsa - SEND_UPDATE_VMSA command * * @handle: handle of the VM to process * @hdr_address: physical address containing packet header * @hdr_len: len of packet header + * @reserved2: reserved * @guest_address: physical address of guest memory region to send * @guest_len: len of guest memory region to send + * @reserved3: reserved * @trans_address: physical address of host memory region * @trans_len: len of host memory region */ @@ -491,8 +510,10 @@ struct sev_data_send_cancel { * struct sev_data_receive_start - RECEIVE_START command parameters * * @handle: handle of the VM to perform receive operation + * @policy: policy information for the VM * @pdh_cert_address: system physical address containing PDH certificate blob * @pdh_cert_len: len of PDH certificate blob + * @reserved1: reserved * @session_address: system physical address containing session blob * @session_len: len of session blob */ @@ -510,10 +531,13 @@ struct sev_data_receive_start { * struct sev_data_receive_update_data - RECEIVE_UPDATE_DATA command parameters * * @handle: handle of the VM to update + * @reserved1: reserved * @hdr_address: physical address containing packet header blob * @hdr_len: len of packet header + * @reserved2: reserved * @guest_address: system physical address of guest memory region * @guest_len: len of guest memory region + * @reserved3: reserved * @trans_address: system physical address of transport buffer * @trans_len: len of transport buffer */ @@ -534,10 +558,13 @@ struct sev_data_receive_update_data { * struct sev_data_receive_update_vmsa - RECEIVE_UPDATE_VMSA command parameters * * @handle: handle of the VM to update + * @reserved1: reserved * @hdr_address: physical address containing packet header blob * @hdr_len: len of packet header + * @reserved2: reserved * @guest_address: system physical address of guest memory region * @guest_len: len of guest memory region + * @reserved3: reserved * @trans_address: system physical address of transport buffer * @trans_len: len of transport buffer */ @@ -567,6 +594,7 @@ struct sev_data_receive_finish { * struct sev_data_dbg - DBG_ENCRYPT/DBG_DECRYPT command parameters * * @handle: handle of the VM to perform debug operation + * @reserved: reserved * @src_addr: source address of data to operate on * @dst_addr: destination address of data to operate on * @len: len of data to operate on @@ -583,6 +611,7 @@ struct sev_data_dbg { * struct sev_data_attestation_report - SEV_ATTESTATION_REPORT command parameters * * @handle: handle of the VM + * @reserved: reserved * @mnonce: a random nonce that will be included in the report. * @address: physical address where the report will be copied. * @len: length of the physical buffer. @@ -781,9 +810,14 @@ struct sev_data_snp_guest_request { * * @init_rmp: indicate that the RMP should be initialized. * @list_paddr_en: indicate that list_paddr is valid + * @rapl_dis: whether RAPL is disabled + * @ciphertext_hiding_en: whether ciphertext hiding is enabled + * @tio_en: Indicates that SNP_INIT_EX initialized the RMP for SEV-TIO * @rsvd: reserved * @rsvd1: reserved * @list_paddr: system physical address of range list + * @max_snp_asid: When non-zero, enable ciphertext hiding and specify the + * maximum ASID that can be used for an SEV-SNP guest. * @rsvd2: reserved */ struct sev_data_snp_init_ex { @@ -841,7 +875,7 @@ struct sev_data_snp_shutdown_ex { } __packed; /** - * struct sev_platform_init_args + * struct sev_platform_init_args - parameters for sev_platform_init() * * @error: SEV firmware error code * @probe: True if this is being called as part of CCP module probe, which @@ -879,12 +913,12 @@ struct sev_data_snp_feature_info { } __packed; /** - * struct feature_info - FEATURE_INFO structure + * struct snp_feature_info - FEATURE_INFO structure * * @eax: output of SNP_FEATURE_INFO command * @ebx: output of SNP_FEATURE_INFO command * @ecx: output of SNP_FEATURE_INFO command - * #edx: output of SNP_FEATURE_INFO command + * @edx: output of SNP_FEATURE_INFO command */ struct snp_feature_info { u32 eax; @@ -954,7 +988,7 @@ struct sev_data_snp_verify_mitigation_dst { } __packed; /** - * struct sev_snp_tcb_version_genoa_milan + * struct sev_snp_tcb_version_genoa_milan - v1 SVN payload * * @boot_loader: SVN of PSP bootloader * @tee: SVN of PSP operating system @@ -971,7 +1005,7 @@ struct sev_snp_tcb_version_genoa_milan { }; /** - * struct sev_snp_tcb_version_turin + * struct sev_snp_tcb_version_turin - v2 SVN payload * * @fmc: SVN of FMC firmware * @boot_loader: SVN of PSP bootloader @@ -1037,9 +1071,9 @@ int sev_platform_status(struct sev_user_data_status *status, int *error); * behalf of userspace. The caller must pass a valid SEV file descriptor * so that we know that it has access to SEV device. * - * @filep - SEV device file pointer - * @cmd - command to issue - * @data - command buffer + * @filep: SEV device file pointer + * @id: command to issue + * @data: command buffer * @error: SEV command return code * * Returns: @@ -1056,8 +1090,8 @@ int sev_issue_cmd_external_user(struct file *filep, unsigned int id, /** * sev_guest_deactivate - perform SEV DEACTIVATE command * - * @deactivate: sev_data_deactivate structure to be processed - * @sev_ret: sev command return code + * @data: sev_data_deactivate structure to be processed + * @error: sev command return code * * Returns: * 0 if the sev successfully processed the command @@ -1071,8 +1105,8 @@ int sev_guest_deactivate(struct sev_data_deactivate *data, int *error); /** * sev_guest_activate - perform SEV ACTIVATE command * - * @activate: sev_data_activate structure to be processed - * @sev_ret: sev command return code + * @data: sev_data_activate structure to be processed + * @error: sev command return code * * Returns: * 0 if the sev successfully processed the command @@ -1086,7 +1120,7 @@ int sev_guest_activate(struct sev_data_activate *data, int *error); /** * sev_guest_df_flush - perform SEV DF_FLUSH command * - * @sev_ret: sev command return code + * @error: sev command return code * * Returns: * 0 if the sev successfully processed the command @@ -1100,8 +1134,8 @@ int sev_guest_df_flush(int *error); /** * sev_guest_decommission - perform SEV DECOMMISSION command * - * @decommission: sev_data_decommission structure to be processed - * @sev_ret: sev command return code + * @data: sev_data_decommission structure to be processed + * @error: sev command return code * * Returns: * 0 if the sev successfully processed the command
diff --git a/include/linux/pwrseq/consumer.h b/include/linux/pwrseq/consumer.h index 16fad5f..b69117a 100644 --- a/include/linux/pwrseq/consumer.h +++ b/include/linux/pwrseq/consumer.h
@@ -25,6 +25,8 @@ int pwrseq_disable(struct pwrseq_desc *desc); struct device *pwrseq_to_device(struct pwrseq_desc *desc); +bool pwrseq_is_controllable(struct pwrseq_desc *desc); + #else /* CONFIG_POWER_SEQUENCING */ static inline struct pwrseq_desc * __must_check @@ -58,6 +60,11 @@ static inline struct device *pwrseq_to_device(struct pwrseq_desc *desc) return NULL; } +static inline bool pwrseq_is_controllable(struct pwrseq_desc *desc) +{ + return false; +} + #endif /* CONFIG_POWER_SEQUENCING */ #endif /* __POWER_SEQUENCING_CONSUMER_H__ */
diff --git a/include/linux/pwrseq/provider.h b/include/linux/pwrseq/provider.h index 33b3d2c..7285ad9 100644 --- a/include/linux/pwrseq/provider.h +++ b/include/linux/pwrseq/provider.h
@@ -6,12 +6,15 @@ #ifndef __POWER_SEQUENCING_PROVIDER_H__ #define __POWER_SEQUENCING_PROVIDER_H__ +#include <linux/types.h> + struct device; struct module; struct pwrseq_device; typedef int (*pwrseq_power_state_func)(struct pwrseq_device *); typedef int (*pwrseq_match_func)(struct pwrseq_device *, struct device *); +typedef bool (*pwrseq_is_controllable_func)(struct pwrseq_device *); #define PWRSEQ_NO_MATCH 0 #define PWRSEQ_MATCH_OK 1 @@ -43,11 +46,16 @@ struct pwrseq_unit_data { * the state lock has been released. It's useful for implementing * boot-up delays without blocking other users from powering up * using the same power sequencer. + * @is_controllable: Optional callback checking whether enabling/disabling this + * target actually controls power (for example when the + * controlling GPIO is wired up). If not provided, the + * target's power is assumed to be always controllable. */ struct pwrseq_target_data { const char *name; const struct pwrseq_unit_data *unit; pwrseq_power_state_func post_enable; + pwrseq_is_controllable_func is_controllable; }; /**
diff --git a/include/linux/regulator/driver.h b/include/linux/regulator/driver.h index cc6ce70..55cc5191 100644 --- a/include/linux/regulator/driver.h +++ b/include/linux/regulator/driver.h
@@ -362,7 +362,7 @@ enum regulator_type { * @off_on_delay: guard time (in uS), before re-enabling a regulator * * @poll_enabled_time: The polling interval (in uS) to use while checking that - * the regulator was actually enabled. Max upto enable_time. + * the regulator was actually enabled. Max up to enable_time. * * @of_map_mode: Maps a hardware mode defined in a DeviceTree to a standard mode */
diff --git a/include/linux/regulator/lp872x.h b/include/linux/regulator/lp872x.h deleted file mode 100644 index b62e45a..0000000 --- a/include/linux/regulator/lp872x.h +++ /dev/null
@@ -1,86 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * Copyright 2012 Texas Instruments - * - * Author: Milo(Woogyom) Kim <milo.kim@ti.com> - */ - -#ifndef __LP872X_REGULATOR_H__ -#define __LP872X_REGULATOR_H__ - -#include <linux/regulator/machine.h> -#include <linux/platform_device.h> -#include <linux/gpio/consumer.h> - -#define LP872X_MAX_REGULATORS 9 - -#define LP8720_ENABLE_DELAY 200 -#define LP8725_ENABLE_DELAY 30000 - -enum lp872x_regulator_id { - LP8720_ID_BASE, - LP8720_ID_LDO1 = LP8720_ID_BASE, - LP8720_ID_LDO2, - LP8720_ID_LDO3, - LP8720_ID_LDO4, - LP8720_ID_LDO5, - LP8720_ID_BUCK, - - LP8725_ID_BASE, - LP8725_ID_LDO1 = LP8725_ID_BASE, - LP8725_ID_LDO2, - LP8725_ID_LDO3, - LP8725_ID_LDO4, - LP8725_ID_LDO5, - LP8725_ID_LILO1, - LP8725_ID_LILO2, - LP8725_ID_BUCK1, - LP8725_ID_BUCK2, - - LP872X_ID_MAX, -}; - -enum lp872x_dvs_sel { - SEL_V1, - SEL_V2, -}; - -/** - * lp872x_dvs - * @gpio : gpio descriptor for dvs control - * @vsel : dvs selector for buck v1 or buck v2 register - * @init_state : initial dvs pin state - */ -struct lp872x_dvs { - struct gpio_desc *gpio; - enum lp872x_dvs_sel vsel; - enum gpiod_flags init_state; -}; - -/** - * lp872x_regdata - * @id : regulator id - * @init_data : init data for each regulator - */ -struct lp872x_regulator_data { - enum lp872x_regulator_id id; - struct regulator_init_data *init_data; -}; - -/** - * lp872x_platform_data - * @general_config : the value of LP872X_GENERAL_CFG register - * @update_config : if LP872X_GENERAL_CFG register is updated, set true - * @regulator_data : platform regulator id and init data - * @dvs : dvs data for buck voltage control - * @enable_gpio : gpio descriptor for enable control - */ -struct lp872x_platform_data { - u8 general_config; - bool update_config; - struct lp872x_regulator_data regulator_data[LP872X_MAX_REGULATORS]; - struct lp872x_dvs *dvs; - struct gpio_desc *enable_gpio; -}; - -#endif
diff --git a/include/linux/regulator/pca9450.h b/include/linux/regulator/pca9450.h index 0df8b3c..bf94df5 100644 --- a/include/linux/regulator/pca9450.h +++ b/include/linux/regulator/pca9450.h
@@ -210,9 +210,11 @@ enum { #define LDO5L_EN_MASK 0xC0 #define LDO5LOUT_MASK 0x0F -#define LDO5H_EN_MASK 0xC0 #define LDO5HOUT_MASK 0x0F +/* LDO ENMODE value: ON in RUN, OFF while PMIC_STBY_REQ is asserted */ +#define LDO_ENMODE_ONREQ_STBYREQ 0x80 + /* PCA9450_REG_IRQ bits */ #define IRQ_PWRON 0x80 #define IRQ_WDOGB 0x40
diff --git a/include/linux/rhashtable-types.h b/include/linux/rhashtable-types.h index 57c11ec..3576b8f 100644 --- a/include/linux/rhashtable-types.h +++ b/include/linux/rhashtable-types.h
@@ -70,6 +70,12 @@ struct rhashtable_params { rht_obj_cmpfn_t obj_cmpfn; }; +struct rhashtable_lockdep_keys { + struct lock_class_key lock_key; + struct lock_class_key mutex_key; + struct lock_class_key bucket_key; +}; + /** * struct rhashtable - Hash table handle * @tbl: Bucket table @@ -97,6 +103,9 @@ struct rhashtable { #ifdef CONFIG_MEM_ALLOC_PROFILING struct alloc_tag *alloc_tag; #endif +#ifdef CONFIG_LOCKDEP + struct lock_class_key *lockdep_key; +#endif }; /** @@ -138,24 +147,77 @@ struct rhashtable_iter { int __rhashtable_init_noprof(struct rhashtable *ht, const struct rhashtable_params *params, - struct lock_class_key *key); + struct rhashtable_lockdep_keys *keys); #define rhashtable_init_noprof(ht, params) \ ({ \ - static struct lock_class_key __key; \ + static struct rhashtable_lockdep_keys __keys; \ \ - __rhashtable_init_noprof(ht, params, &__key); \ + __rhashtable_init_noprof(ht, params, &__keys); \ }) + +/** + * rhashtable_init - initialize a new hash table + * @ht: hash table to be initialized + * @params: configuration parameters + * + * Initializes a new hash table based on the provided configuration + * parameters. A table can be configured either with a variable or + * fixed length key: + * + * Configuration Example 1: Fixed length keys + * struct test_obj { + * int key; + * void * my_member; + * struct rhash_head node; + * }; + * + * struct rhashtable_params params = { + * .head_offset = offsetof(struct test_obj, node), + * .key_offset = offsetof(struct test_obj, key), + * .key_len = sizeof(int), + * .hashfn = jhash, + * }; + * + * Configuration Example 2: Variable length keys + * struct test_obj { + * [...] + * struct rhash_head node; + * }; + * + * u32 my_hash_fn(const void *data, u32 len, u32 seed) + * { + * struct test_obj *obj = data; + * + * return [... hash ...]; + * } + * + * struct rhashtable_params params = { + * .head_offset = offsetof(struct test_obj, node), + * .hashfn = jhash, + * .obj_hashfn = my_hash_fn, + * }; + */ #define rhashtable_init(...) alloc_hooks(rhashtable_init_noprof(__VA_ARGS__)) int __rhltable_init_noprof(struct rhltable *hlt, const struct rhashtable_params *params, - struct lock_class_key *key); + struct rhashtable_lockdep_keys *keys); #define rhltable_init_noprof(hlt, params) \ ({ \ - static struct lock_class_key __key; \ + static struct rhashtable_lockdep_keys __keys; \ \ - __rhltable_init_noprof(hlt, params, &__key); \ + __rhltable_init_noprof(hlt, params, &__keys); \ }) + +/** + * rhltable_init - initialize a new hash list table + * @hlt: hash list table to be initialized + * @params: configuration parameters + * + * Initializes a new hash list table. + * + * See documentation for rhashtable_init. + */ #define rhltable_init(...) alloc_hooks(rhltable_init_noprof(__VA_ARGS__)) #endif /* _LINUX_RHASHTABLE_TYPES_H */
diff --git a/include/linux/rhashtable.h b/include/linux/rhashtable.h index 57a2a29..70dac92 100644 --- a/include/linux/rhashtable.h +++ b/include/linux/rhashtable.h
@@ -319,18 +319,6 @@ static inline struct rhash_lock_head __rcu **rht_bucket_insert( * When we write to a bucket without unlocking, we use rht_assign_locked(). */ -static inline unsigned long rht_lock(struct bucket_table *tbl, - struct rhash_lock_head __rcu **bkt) - __acquires(__bitlock(0, bkt)) -{ - unsigned long flags; - - local_irq_save(flags); - bit_spin_lock(0, (unsigned long *)bkt); - lock_map_acquire(&tbl->dep_map); - return flags; -} - static inline unsigned long rht_lock_nested(struct bucket_table *tbl, struct rhash_lock_head __rcu **bucket, unsigned int subclass) @@ -344,6 +332,13 @@ static inline unsigned long rht_lock_nested(struct bucket_table *tbl, return flags; } +static inline unsigned long rht_lock(struct bucket_table *tbl, + struct rhash_lock_head __rcu **bkt) + __acquires(__bitlock(0, bkt)) +{ + return rht_lock_nested(tbl, bkt, 0); +} + static inline void rht_unlock(struct bucket_table *tbl, struct rhash_lock_head __rcu **bkt, unsigned long flags) @@ -598,13 +593,23 @@ static inline void rht_assign_unlock(struct bucket_table *tbl, for (pos = list; pos && rht_entry(tpos, pos, member); \ pos = rcu_dereference_all(pos->next)) -static inline int rhashtable_compare(struct rhashtable_compare_arg *arg, - const void *obj) +/* + * Use constant params from inlined callers to specialize memcmp(). If params + * isn't constant, it must be equal to ht->p. + */ +static __always_inline int rhashtable_compare(struct rhashtable_compare_arg *arg, + const void *obj, + const struct rhashtable_params params) { struct rhashtable *ht = arg->ht; const char *ptr = obj; - return memcmp(ptr + ht->p.key_offset, arg->key, ht->p.key_len); + if (!__builtin_constant_p(params.key_len)) + return memcmp(ptr + ht->p.key_offset, arg->key, + ht->p.key_len); + + return memcmp(ptr + params.key_offset, arg->key, + params.key_len ? : ht->p.key_len); } /* Internal function, do not use. */ @@ -632,7 +637,7 @@ static __always_inline struct rhash_head *__rhashtable_lookup( rht_for_each_rcu_from(he, __rht_ptr_rcu(bkt, freq), tbl, hash) { if (params.obj_cmpfn ? params.obj_cmpfn(&arg, rht_obj(ht, he)) : - rhashtable_compare(&arg, rht_obj(ht, he))) + rhashtable_compare(&arg, rht_obj(ht, he), params)) continue; return he; } @@ -797,7 +802,7 @@ static __always_inline void *__rhashtable_insert_fast( if (!key || (params.obj_cmpfn ? params.obj_cmpfn(&arg, rht_obj(ht, head)) : - rhashtable_compare(&arg, rht_obj(ht, head)))) { + rhashtable_compare(&arg, rht_obj(ht, head), params))) { pprev = &head->next; continue; }
diff --git a/include/linux/sched/ext.h b/include/linux/sched/ext.h index 36c0479..efd635a 100644 --- a/include/linux/sched/ext.h +++ b/include/linux/sched/ext.h
@@ -91,7 +91,7 @@ struct scx_dispatch_q { struct rhash_head hash_node; struct llist_node free_node; struct scx_sched *sched; - struct scx_dsq_pcpu __percpu *pcpu; + struct scx_dsq_pcpu __percpu *pcpu_user; struct rcu_head rcu; }; @@ -104,6 +104,7 @@ enum scx_ent_flags { SCX_TASK_SUB_INIT = 1 << 4, /* task being initialized for a sub sched */ SCX_TASK_IMMED = 1 << 5, /* task is on local DSQ with %SCX_ENQ_IMMED */ SCX_TASK_PROTECTED = 1 << 6, /* slice and DSQ head position protected */ + SCX_TASK_RUN_TRACKED = 1 << 7, /* task is in an ops.running()/stopping() session */ /* * Bits 8 to 10 are used to carry task state: @@ -136,6 +137,7 @@ enum scx_ent_flags { * IMMED reenqueued due to failed ENQ_IMMED * PREEMPTED preempted while running * CAP sub-sched cap miss, see p->scx.reenq_reason_* + * PROXY proxy state prevented a remote DSQ transfer */ SCX_TASK_REENQ_REASON_SHIFT = 12, SCX_TASK_REENQ_REASON_BITS = 3, @@ -146,6 +148,7 @@ enum scx_ent_flags { SCX_TASK_REENQ_IMMED = 2 << SCX_TASK_REENQ_REASON_SHIFT, SCX_TASK_REENQ_PREEMPTED = 3 << SCX_TASK_REENQ_REASON_SHIFT, SCX_TASK_REENQ_CAP = 4 << SCX_TASK_REENQ_REASON_SHIFT, + SCX_TASK_REENQ_PROXY = 5 << SCX_TASK_REENQ_REASON_SHIFT, /* iteration cursor, not a task */ SCX_TASK_CURSOR = 1 << 31, @@ -154,6 +157,7 @@ enum scx_ent_flags { /* scx_entity.dsq_flags */ enum scx_ent_dsq_flags { SCX_TASK_DSQ_ON_PRIQ = 1 << 0, /* task is queued on the priority queue of a dsq */ + SCX_TASK_DSQ_REENQ = 1 << 1, /* marked by scx_bpf_dsq_reenq_task() */ }; enum scx_dsq_lnode_flags { @@ -197,9 +201,19 @@ struct sched_ext_entity { u64 ddsp_slice; u64 ddsp_vtime; struct scx_dsq_list_node dsq_list; /* dispatch order */ - struct rb_node dsq_priq; /* p->scx.dsq_vtime order */ u32 dsq_seq; u32 dsq_flags; /* protected by DSQ lock */ + + /* + * Used to order tasks when dispatching to the vtime-ordered priority + * queue of a dsq. This is usually set through + * scx_bpf_dsq_insert_vtime() but can also be modified directly by the + * BPF scheduler. Modifying it while a task is queued on a dsq may + * mangle the ordering and is not recommended. Kept next to @dsq_priq + * as rbtree insertion reads both on every visited node. + */ + u64 dsq_vtime; + struct rb_node dsq_priq; /* p->scx.dsq_vtime order */ u32 flags; /* protected by rq lock */ u32 weight; u32 reenq_cnt; /* reenqueues since last run */ @@ -226,7 +240,7 @@ struct sched_ext_entity { u64 tid; struct rhash_head tid_hash_node; /* see SCX_OPS_TID_TO_TASK */ - /* BPF scheduler modifiable fields */ + /* BPF scheduler modifiable fields, along with @dsq_vtime above */ /* * Runtime budget in nsecs - how long the task may hold its cpu. Owned @@ -242,15 +256,6 @@ struct sched_ext_entity { u64 slice; /* - * Used to order tasks when dispatching to the vtime-ordered priority - * queue of a dsq. This is usually set through - * scx_bpf_dsq_insert_vtime() but can also be modified directly by the - * BPF scheduler. Modifying it while a task is queued on a dsq may - * mangle the ordering and is not recommended. - */ - u64 dsq_vtime; - - /* * Out-of-band slice request from scx_bpf_task_set_slice() when the * caller does not hold the rq lock, applied under the rq lock at the * next slice consideration. One atomic64 packs the pending flag, the @@ -279,6 +284,14 @@ struct sched_ext_entity { */ bool disallow; /* reject switching into SCX */ + /* + * If set, depletion of this task's slice at the scheduler tick requests + * lazy instead of immediate rescheduling. Initialized from + * %SCX_OPS_LAZY_RESCHED immediately before ops.enable() and may be + * modified afterwards with scx_bpf_task_set_lazy_resched(). + */ + bool lazy_resched; + /* cold fields */ #ifdef CONFIG_EXT_GROUP_SCHED struct cgroup *cgrp_moving_from; @@ -324,7 +337,7 @@ struct scx_task_group { u64 bw_period_us; u64 bw_quota_us; u64 bw_burst_us; - bool idle; + bool sched_idle; #endif };
diff --git a/include/linux/scmi_protocol.h b/include/linux/scmi_protocol.h index 5ab73b1..3f7cc35 100644 --- a/include/linux/scmi_protocol.h +++ b/include/linux/scmi_protocol.h
@@ -9,6 +9,7 @@ #define _LINUX_SCMI_PROTOCOL_H #include <linux/bitfield.h> +#include <linux/device-id/scmi.h> #include <linux/device.h> #include <linux/notifier.h> #include <linux/types.h> @@ -528,22 +529,25 @@ struct scmi_sensor_proto_ops { u32 sensor_id, u32 sensor_config); }; +struct scmi_reset_domain_info { + char name[SCMI_MAX_STR_SIZE]; + u32 latency_us; +}; + /** * struct scmi_reset_proto_ops - represents the various operations provided * by SCMI Reset Protocol * * @num_domains_get: get the count of reset domains provided by SCMI - * @name_get: gets the name of a reset domain - * @latency_get: gets the reset latency for the specified reset domain + * @info_get: gets the information of the specified reset domain * @reset: resets the specified reset domain * @assert: explicitly assert reset signal of the specified reset domain * @deassert: explicitly deassert reset signal of the specified reset domain */ struct scmi_reset_proto_ops { int (*num_domains_get)(const struct scmi_protocol_handle *ph); - const char *(*name_get)(const struct scmi_protocol_handle *ph, - u32 domain); - int (*latency_get)(const struct scmi_protocol_handle *ph, u32 domain); + const struct scmi_reset_domain_info __must_check *(*info_get) + (const struct scmi_protocol_handle *ph, u32 domain); int (*reset)(const struct scmi_protocol_handle *ph, u32 domain); int (*assert)(const struct scmi_protocol_handle *ph, u32 domain); int (*deassert)(const struct scmi_protocol_handle *ph, u32 domain); @@ -930,6 +934,7 @@ enum scmi_std_protocol { SCMI_PROTOCOL_VOLTAGE = 0x17, SCMI_PROTOCOL_POWERCAP = 0x18, SCMI_PROTOCOL_PINCTRL = 0x19, + SCMI_PROTOCOL_TELEMETRY = 0x1B, }; enum scmi_system_events { @@ -951,11 +956,6 @@ struct scmi_device { #define to_scmi_dev(d) container_of_const(d, struct scmi_device, dev) -struct scmi_device_id { - u8 protocol_id; - const char *name; -}; - struct scmi_driver { const char *name; int (*probe)(struct scmi_device *sdev);
diff --git a/include/linux/soc/qcom/apr.h b/include/linux/soc/qcom/apr.h index 909e84f..2e42310 100644 --- a/include/linux/soc/qcom/apr.h +++ b/include/linux/soc/qcom/apr.h
@@ -5,7 +5,6 @@ #include <linux/spinlock.h> #include <linux/device.h> -#include <linux/device-id/apr.h> #include <dt-bindings/soc/qcom,apr.h> #include <dt-bindings/soc/qcom,gpr.h> @@ -135,6 +134,8 @@ struct pkt_router_svc { typedef struct pkt_router_svc gpr_port_t; +#define APR_NAME_SIZE 32 + struct apr_device { struct device dev; uint16_t svc_id; @@ -158,7 +159,6 @@ struct apr_driver { const struct apr_resp_pkt *d); gpr_port_cb gpr_callback; struct device_driver driver; - const struct apr_device_id *id_table; }; typedef struct apr_driver gpr_driver_t;
diff --git a/include/linux/soc/qcom/geni-se.h b/include/linux/soc/qcom/geni-se.h index 5f18d28..645609b 100644 --- a/include/linux/soc/qcom/geni-se.h +++ b/include/linux/soc/qcom/geni-se.h
@@ -568,7 +568,7 @@ void geni_se_tx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len); void geni_se_rx_dma_unprep(struct geni_se *se, dma_addr_t iova, size_t len); -int geni_icc_get(struct geni_se *se, const char *icc_ddr); +int geni_icc_get(struct geni_se *se); int geni_icc_set_bw(struct geni_se *se); int geni_icc_set_bw_ab(struct geni_se *se, u32 core_ab, u32 cfg_ab, u32 ddr_ab);
diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h index f3ed63e..713cb02 100644 --- a/include/linux/soc/qcom/llcc-qcom.h +++ b/include/linux/soc/qcom/llcc-qcom.h
@@ -74,6 +74,7 @@ #define LLCC_CAMSRTIP 73 #define LLCC_CAMRTRF 74 #define LLCC_CAMSRTRF 75 +#define LLCC_GPU_LITTLE 80 #define LLCC_OOBM_NS 81 #define LLCC_OOBM_S 82 #define LLCC_VIDEO_APV 83 @@ -85,7 +86,12 @@ #define LLCC_CAM_OFE_STROV 93 #define LLCC_CPUSS_HEU 94 #define LLCC_PCIE_TCU 97 +#define LLCC_GPUHTW_LITTLE 98 #define LLCC_MDM_PNG_FIXED 100 +#define LLCC_PPE_RXDESC 101 +#define LLCC_PPE_RXFILL 102 +#define LLCC_WLAN_5G 103 +#define LLCC_WLAN_6G 104 /** * struct llcc_slice_desc - Cache slice descriptor
diff --git a/include/linux/soc/qcom/ubwc.h b/include/linux/soc/qcom/ubwc.h index f3a7036..b09ae05 100644 --- a/include/linux/soc/qcom/ubwc.h +++ b/include/linux/soc/qcom/ubwc.h
@@ -36,6 +36,7 @@ struct qcom_ubwc_cfg_data { #define UBWC_4_3 0x40030000 #define UBWC_5_0 0x50000000 #define UBWC_6_0 0x60000000 +#define UBWC_7_0 0x70000000 #if IS_ENABLED(CONFIG_QCOM_UBWC_CONFIG) const struct qcom_ubwc_cfg_data *qcom_ubwc_config_get_data(void); @@ -108,6 +109,8 @@ static inline u32 qcom_ubwc_swizzle(const struct qcom_ubwc_cfg_data *cfg) static inline u32 qcom_ubwc_version_tag(const struct qcom_ubwc_cfg_data *cfg) { + if (cfg->ubwc_enc_version >= UBWC_7_0) + return 6; if (cfg->ubwc_enc_version >= UBWC_6_0) return 5; if (cfg->ubwc_enc_version >= UBWC_5_0)
diff --git a/include/linux/soc/ti/k3-ringacc.h b/include/linux/soc/ti/k3-ringacc.h index 39b022b9..7b7fc23 100644 --- a/include/linux/soc/ti/k3-ringacc.h +++ b/include/linux/soc/ti/k3-ringacc.h
@@ -57,13 +57,13 @@ struct k3_ringacc; struct k3_ring; /** - * enum k3_ring_cfg - RA ring configuration structure + * struct k3_ring_cfg - RA ring configuration structure * * @size: Ring size, number of elements * @elm_size: Ring element size * @mode: Ring operational mode * @flags: Ring configuration flags. Possible values: - * @K3_RINGACC_RING_SHARED: when set allows to request the same ring + * %K3_RINGACC_RING_SHARED: when set allows to request the same ring * few times. It's usable when the same ring is used as Free Host PD ring * for different flows, for example. * Note: Locking should be done by consumer if required @@ -88,11 +88,10 @@ struct k3_ring_cfg { /** * of_k3_ringacc_get_by_phandle - find a RA by phandle property * @np: device node - * @propname: property name containing phandle on RA node + * @property: property name containing phandle on RA node * - * Returns pointer on the RA - struct k3_ringacc - * or -ENODEV if not found, - * or -EPROBE_DEFER if not yet registered + * Return: Pointer to the RA, or ERR_PTR(-ENODEV) if the phandle cannot + * be resolved, or ERR_PTR(-EPROBE_DEFER) if the RA is not yet registered. */ struct k3_ringacc *of_k3_ringacc_get_by_phandle(struct device_node *np, const char *property); @@ -103,10 +102,8 @@ struct k3_ringacc *of_k3_ringacc_get_by_phandle(struct device_node *np, * k3_ringacc_request_ring - request ring from ringacc * @ringacc: pointer on ringacc * @id: ring id or K3_RINGACC_RING_ID_ANY for any general purpose ring - * @flags: - * @K3_RINGACC_RING_USE_PROXY: if set - proxy will be allocated and - * used to access ring memory. Sopported only for rings in - * Message/Credentials/Queue mode. + * @flags: Set %K3_RINGACC_RING_USE_PROXY to allocate a proxy for + * accessing ring memory in Message mode. * * Returns pointer on the Ring - struct k3_ring * or NULL in case of failure. @@ -126,8 +123,9 @@ int k3_ringacc_request_rings_pair(struct k3_ringacc *ringacc, */ void k3_ringacc_ring_reset(struct k3_ring *ring); /** - * k3_ringacc_ring_reset - ring reset for DMA rings + * k3_ringacc_ring_reset_dma - ring reset for DMA rings * @ring: pointer on Ring + * @occ: occupancy used by the DMA reset quirk, or zero to read it from hardware * * Resets ring internal state ((hw)occ, (hw)idx). Should be used for rings * which are read by K3 UDMA, like TX or Free Host PD rings. @@ -217,8 +215,8 @@ int k3_ringacc_ring_push(struct k3_ring *ring, void *elem); * @ring: pointer on ring * @elem: pointer on ring element buffer * - * Push one ring element from the ring head. Size of the ring element is - * determined by ring configuration &struct k3_ring_cfg elm_size.. + * Pop one ring element from the ring head. Size of the ring element is + * determined by ring configuration &struct k3_ring_cfg elm_size. * * Returns 0 on success, errno otherwise. */ @@ -242,7 +240,7 @@ int k3_ringacc_ring_push_head(struct k3_ring *ring, void *elem); * @ring: pointer on ring * @elem: pointer on ring element buffer * - * Push one ring element from the ring tail. Size of the ring element is + * Pop one ring element from the ring tail. Size of the ring element is * determined by ring configuration &struct k3_ring_cfg elm_size. * * Returns 0 on success, errno otherwise. @@ -256,7 +254,10 @@ u32 k3_ringacc_get_tisci_dev_id(struct k3_ring *ring); struct ti_sci_handle; /** - * struct struct k3_ringacc_init_data - Initialization data for DMA rings + * struct k3_ringacc_init_data - Initialization data for DMA rings + * @tisci: TI SCI firmware handle + * @tisci_dev_id: TI SCI device ID of the DMA controller + * @num_rings: Total number of available rings */ struct k3_ringacc_init_data { const struct ti_sci_handle *tisci;
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h index 88d17fc..fb4baa0 100644 --- a/include/linux/spi/spi.h +++ b/include/linux/spi/spi.h
@@ -169,6 +169,12 @@ extern void spi_transfer_cs_change_delay_exec(struct spi_message *msg, * @cs_inactive: delay to be introduced by the controller after CS is * deasserted. If @cs_change_delay is used from @spi_transfer, then the * two delays will be added up. + * @rx_sample_delay_ns: Delay in nanoseconds by which the controller should + * postpone sampling the incoming data, relative to the sampling point it + * uses by default. Describes the board rather than the device, namely the + * flight time of the clock and data signals between controller and + * device, and comes from the "rx-sample-delay-ns" property. Zero when the + * property is absent. * @chip_select: Array of physical chipselect, spi->chipselect[i] gives * the corresponding physical CS for logical CS i. * @num_chipselect: Number of physical chipselects used. @@ -235,6 +241,9 @@ struct spi_device { struct spi_delay cs_hold; struct spi_delay cs_inactive; + /* Additional delay before the incoming data is sampled, in ns */ + u32 rx_sample_delay_ns; + u8 chip_select[SPI_DEVICE_CS_CNT_MAX]; u8 num_chipselect;
diff --git a/include/math-emu/op-common.h b/include/math-emu/op-common.h index 8ce066c..1d1ce5c 100644 --- a/include/math-emu/op-common.h +++ b/include/math-emu/op-common.h
@@ -135,6 +135,24 @@ do { \ else \ { \ /* we've got a denormalized number */ \ + int _FP_PACK_CANONICAL_is_tiny = 1; \ + if (_FP_TININESS_AFTER_ROUNDING && X##_e == 0) \ + { \ + /* Architectures that detect tininess after rounding \ + only signal underflow if the result is still \ + subnormal once rounded as if the exponent range \ + were unbounded. Round a copy to find out. */ \ + FP_DECL_##fs(_FP_PACK_CANONICAL_T); \ + /* The class field is not used by the rounding below, \ + and is unused entirely where this block is dead. */ \ + (void)_FP_PACK_CANONICAL_T##_c; \ + _FP_FRAC_COPY_##wc(_FP_PACK_CANONICAL_T, X); \ + _FP_PACK_CANONICAL_T##_s = X##_s; \ + _FP_PACK_CANONICAL_T##_e = X##_e; \ + _FP_ROUND(wc, _FP_PACK_CANONICAL_T); \ + if (_FP_FRAC_OVERP_##wc(fs, _FP_PACK_CANONICAL_T)) \ + _FP_PACK_CANONICAL_is_tiny = 0; \ + } \ X##_e = -X##_e + 1; \ if (X##_e <= _FP_WFRACBITS_##fs) \ { \ @@ -161,8 +179,9 @@ do { \ _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \ } \ } \ - if ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) || \ - (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW)) \ + if (_FP_PACK_CANONICAL_is_tiny \ + && ((FP_CUR_EXCEPTIONS & FP_EX_INEXACT) || \ + (FP_TRAPPING_EXCEPTIONS & FP_EX_UNDERFLOW))) \ FP_SET_EXCEPTION(FP_EX_UNDERFLOW); \ } \ else \
diff --git a/include/math-emu/soft-fp.h b/include/math-emu/soft-fp.h index 5650c16..02ada0a 100644 --- a/include/math-emu/soft-fp.h +++ b/include/math-emu/soft-fp.h
@@ -31,6 +31,14 @@ #include <endian.h> #endif +/* Whether the architecture determines tininess of a floating-point + result after rounding rather than before it. IEEE 754 permits either + but requires the same choice for every operation, so this has to agree + with what the hardware does for the results it produces itself. */ +#ifndef _FP_TININESS_AFTER_ROUNDING +#define _FP_TININESS_AFTER_ROUNDING 0 +#endif + #define _FP_WORKBITS 3 #define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3) #define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2)
diff --git a/include/soc/fsl/qe/qe.h b/include/soc/fsl/qe/qe.h index 8f967d15..7f0e416 100644 --- a/include/soc/fsl/qe/qe.h +++ b/include/soc/fsl/qe/qe.h
@@ -24,6 +24,7 @@ #include <linux/types.h> struct device; +struct gpio_desc; #define QE_NUM_OF_SNUM 256 /* There are 256 serial number in QE */ #define QE_NUM_OF_BRGS 16 @@ -193,12 +194,13 @@ static inline int par_io_data_set(u8 port, u8 pin, u8 val) { return -ENOSYS; } */ struct qe_pin; #ifdef CONFIG_QE_GPIO -extern struct qe_pin *qe_pin_request(struct device *dev, int index); +extern struct qe_pin *qe_pin_request(struct device *dev, struct gpio_desc *gpiod); extern void qe_pin_free(struct qe_pin *qe_pin); extern void qe_pin_set_gpio(struct qe_pin *qe_pin); extern void qe_pin_set_dedicated(struct qe_pin *pin); #else -static inline struct qe_pin *qe_pin_request(struct device *dev, int index) +static inline struct qe_pin * +qe_pin_request(struct device *dev, struct gpio_desc *gpiod) { return ERR_PTR(-ENOSYS); }
diff --git a/include/soc/imx/cpu.h b/include/soc/imx/cpu.h index 0bf610a..8c53150 100644 --- a/include/soc/imx/cpu.h +++ b/include/soc/imx/cpu.h
@@ -30,7 +30,7 @@ #define MXC_CPU_VF600 0x600 #define MXC_CPU_VF610 (MXC_CPU_VF600 | MXC_CPU_VFx10) -#ifndef __ASSEMBLY__ +#ifndef __ASSEMBLER__ extern unsigned int __mxc_cpu_type; #endif
diff --git a/include/soc/tegra/fuse.h b/include/soc/tegra/fuse.h index c4f7a1b..14822f9 100644 --- a/include/soc/tegra/fuse.h +++ b/include/soc/tegra/fuse.h
@@ -33,6 +33,7 @@ enum tegra_revision { TEGRA_REVISION_A03, TEGRA_REVISION_A03p, TEGRA_REVISION_A04, + TEGRA_REVISION_B01, TEGRA_REVISION_MAX, };
diff --git a/include/trace/events/landlock.h b/include/trace/events/landlock.h index 9e172ea..6d9d9e7 100644 --- a/include/trace/events/landlock.h +++ b/include/trace/events/landlock.h
@@ -36,6 +36,8 @@ static_assert(sizeof(access_mask_t) <= sizeof(u64)); TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY); TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_FS_ACCESS); TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_NET_ACCESS); +TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_NAMESPACE); +TRACE_DEFINE_ENUM(LANDLOCK_REQUEST_CAPABILITY); #ifdef CREATE_TRACE_POINTS @@ -276,13 +278,14 @@ static inline const char *__trace_landlock_print_layers( * Every denial event shares three fields. domain is the ID of the * innermost domain that blocked the access. same_exec tells whether the * current task is the same executable that entered that domain. logged is - * the domain's audit-logging decision for this denial (its log_status is - * enabled and the per-execution flag selected by same_exec is set); a - * stateless ftrace filter can select the denials the domain submits to - * audit with logged==1, without reconstructing it from the per-execution - * log flags. Denial events order their fields as domain, same_exec, - * logged, then blockers (deny_access events only), then the type-specific - * object fields, then any variable-length field. + * the complete audit-submission selection for this denial: the domain's + * log_status and per-execution flag, per-object or per-member quiet rules, + * and request-specific no-audit options. This excludes global audit state + * and audit-side filters. A stateless ftrace filter can select the denials + * the domain submits to audit with logged==1, without reconstructing those + * inputs. Denial events order their shared fields as domain, same_exec, + * and logged. Access and permission denial events follow these with the + * blockers verdict input, type-specific fields, and any variable-length field. * * Relational referents * ~~~~~~~~~~~~~~~~~~~~~ @@ -302,9 +305,9 @@ static inline const char *__trace_landlock_print_layers( * Blocker fields * ~~~~~~~~~~~~~~ * - * The filesystem and network blocker arguments identify the request type - * and carry its final missing access subset when applicable. The type - * determines how to interpret the access value. + * Blocker arguments identify the request type and carry its final missing + * access subset when applicable. The type determines how to interpret the + * access value. */ /* @@ -343,26 +346,31 @@ TRACE_EVENT(landlock_create_ruleset, TP_ARGS(ruleset), TP_STRUCT__entry( - __field( u64, ruleset_id ) - __field( u64, ruleset_version ) - __field( access_mask_t, handled_fs ) - __field( access_mask_t, handled_net ) - __field( access_mask_t, scoped ) + __field( u64, ruleset_id ) + __field( u64, ruleset_version ) + __field( access_mask_t, handled_fs ) + __field( access_mask_t, handled_net ) + __field( access_mask_t, scoped ) + __field( access_mask_t, handled_permissions ) ), TP_fast_assign( __entry->ruleset_id = ruleset->id; __entry->ruleset_version = ruleset->version; - __entry->handled_fs = ruleset->handled_masks.fs; - __entry->handled_net = ruleset->handled_masks.net; - __entry->scoped = ruleset->handled_masks.scope; + __entry->handled_fs = ruleset->layer.handled.fs; + __entry->handled_net = ruleset->layer.handled.net; + __entry->scoped = ruleset->layer.handled.scope; + __entry->handled_permissions = + ruleset->layer.handled.permissions; ), - TP_printk("ruleset=%llx.%llu handled_fs=%s handled_net=%s scoped=%s", + TP_printk("ruleset=%llx.%llu handled_fs=%s handled_net=%s scoped=%s handled_permissions=%s", __entry->ruleset_id, __entry->ruleset_version, __print_flags(__entry->handled_fs, "|", _LANDLOCK_ACCESS_FS_NAMES), __print_flags(__entry->handled_net, "|", _LANDLOCK_ACCESS_NET_NAMES), - __print_flags(__entry->scoped, "|", _LANDLOCK_SCOPE_NAMES)) + __print_flags(__entry->scoped, "|", _LANDLOCK_SCOPE_NAMES), + __print_flags(__entry->handled_permissions, "|", + _LANDLOCK_PERMISSION_NAMES)) ); /** @@ -497,6 +505,103 @@ TRACE_EVENT(landlock_add_rule_net_port, ); /** + * landlock_add_rule_namespace - Namespace rule added to a ruleset + * + * @ruleset: Source ruleset (never NULL). + * @flags: Complete validated landlock_add_rule_flags value supplied by this + * successful call, not the rule's accumulated quiet state. + * @permissions: Validated permission mask from the rule attribute. + * @allowed_namespace_types: Effective known namespace types allowed by this + * call, using CLONE_NEW* values. + * @quiet_namespace_types: Effective known namespace types quieted by this + * call, using CLONE_NEW* values. + * + * Emitted by sys_landlock_add_rule() under the modified ruleset's lock, so + * the reported ruleset is a stable snapshot that no concurrent writer can + * change. + */ +TRACE_EVENT(landlock_add_rule_namespace, + + TP_PROTO(const struct landlock_ruleset *ruleset, u32 flags, + u64 permissions, u64 allowed_namespace_types, + u64 quiet_namespace_types), + + TP_ARGS(ruleset, flags, permissions, allowed_namespace_types, + quiet_namespace_types), + + TP_STRUCT__entry( + __field( u64, ruleset_id ) + __field( u64, ruleset_version ) + __field( access_mask_t, permissions ) + __field( u64, allowed_namespace_types ) + __field( u64, quiet_namespace_types ) + ), + + TP_fast_assign( + lockdep_assert_held(&ruleset->lock); + __entry->ruleset_id = ruleset->id; + __entry->ruleset_version = ruleset->version; + __entry->permissions = permissions; + __entry->allowed_namespace_types = allowed_namespace_types; + __entry->quiet_namespace_types = quiet_namespace_types; + ), + + TP_printk("ruleset=%llx.%llu permissions=%s allowed_namespace_types=0x%llx quiet_namespace_types=0x%llx", + __entry->ruleset_id, __entry->ruleset_version, + __print_flags(__entry->permissions, "|", + _LANDLOCK_PERMISSION_NAMES), + __entry->allowed_namespace_types, + __entry->quiet_namespace_types) +); + +/** + * landlock_add_rule_capability - Capability rule added to a ruleset + * + * @ruleset: Source ruleset (never NULL). + * @flags: Complete validated landlock_add_rule_flags value supplied by this + * successful call, not the rule's accumulated quiet state. + * @permissions: Validated permission mask from the rule attribute. + * @allowed_capabilities: Effective known capabilities allowed by this call. + * @quiet_capabilities: Effective known capabilities quieted by this call. + * + * Emitted by sys_landlock_add_rule() under the modified ruleset's lock, so + * the reported ruleset is a stable snapshot that no concurrent writer can + * change. + */ +TRACE_EVENT(landlock_add_rule_capability, + + TP_PROTO(const struct landlock_ruleset *ruleset, u32 flags, + u64 permissions, u64 allowed_capabilities, + u64 quiet_capabilities), + + TP_ARGS(ruleset, flags, permissions, allowed_capabilities, + quiet_capabilities), + + TP_STRUCT__entry( + __field( u64, ruleset_id ) + __field( u64, ruleset_version ) + __field( access_mask_t, permissions ) + __field( u64, allowed_capabilities ) + __field( u64, quiet_capabilities ) + ), + + TP_fast_assign( + lockdep_assert_held(&ruleset->lock); + __entry->ruleset_id = ruleset->id; + __entry->ruleset_version = ruleset->version; + __entry->permissions = permissions; + __entry->allowed_capabilities = allowed_capabilities; + __entry->quiet_capabilities = quiet_capabilities; + ), + + TP_printk("ruleset=%llx.%llu permissions=%s allowed_capabilities=0x%llx quiet_capabilities=0x%llx", + __entry->ruleset_id, __entry->ruleset_version, + __print_flags(__entry->permissions, "|", + _LANDLOCK_PERMISSION_NAMES), + __entry->allowed_capabilities, __entry->quiet_capabilities) +); + +/** * landlock_create_domain - New domain created * * @domain: Newly created domain (never NULL, immutable after creation). @@ -874,6 +979,105 @@ TRACE_EVENT(landlock_deny_access_net, ); /** + * landlock_deny_permission_namespace - Namespace use denied + * + * @hierarchy: Denying domain's hierarchy node (never NULL); its id is the + * domain field. + * @same_exec: Whether the current task entered the denying domain itself. + * @logged: Whether this denial was selected for audit logging. + * @blockers: Request type and final missing permission subset (never NULL). + * @namespace_type: CLONE_NEW* namespace type that was denied. + * @namespace_id: Namespace ID, or 0 when creation was denied. + * + * Emitted when a Landlock domain denies namespace use. + */ +TRACE_EVENT(landlock_deny_permission_namespace, + + TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec, + bool logged, const struct landlock_blockers *blockers, + u32 namespace_type, u64 namespace_id), + + TP_ARGS(hierarchy, same_exec, logged, blockers, namespace_type, + namespace_id), + + TP_STRUCT__entry( + __field( u64, domain_id ) + __field( bool, same_exec ) + __field( bool, logged ) + __field( enum landlock_request_type, blockers_type ) + __field( access_mask_t, blockers_access ) + __field( u32, namespace_type ) + __field( u64, namespace_id ) + ), + + TP_fast_assign( + __entry->domain_id = hierarchy->id; + __entry->same_exec = same_exec; + __entry->logged = logged; + __entry->blockers_type = blockers->type; + __entry->blockers_access = blockers->access; + __entry->namespace_type = namespace_type; + __entry->namespace_id = namespace_id; + ), + + TP_printk("domain=%llx same_exec=%d logged=%d blockers=%s namespace_type=0x%x namespace_id=%llu", + __entry->domain_id, __entry->same_exec, __entry->logged, + __entry->blockers_type == LANDLOCK_REQUEST_NAMESPACE ? + __print_flags(__entry->blockers_access, "|", + _LANDLOCK_PERMISSION_BLOCKER_NAMES) : + "unknown", + __entry->namespace_type, __entry->namespace_id) +); + +/** + * landlock_deny_permission_capability - Capability use denied + * + * @hierarchy: Denying domain's hierarchy node (never NULL); its id is the + * domain field. + * @same_exec: Whether the current task entered the denying domain itself. + * @logged: Whether this denial was selected for audit logging. + * @blockers: Request type and final missing permission subset (never NULL). + * @capability: CAP_* number that was denied. + * + * Emitted when a Landlock domain denies capability use, except for checks + * made with CAP_OPT_NOAUDIT, which are denied without emitting this event. + */ +TRACE_EVENT(landlock_deny_permission_capability, + + TP_PROTO(const struct landlock_hierarchy *hierarchy, bool same_exec, + bool logged, const struct landlock_blockers *blockers, + int capability), + + TP_ARGS(hierarchy, same_exec, logged, blockers, capability), + + TP_STRUCT__entry( + __field( u64, domain_id ) + __field( bool, same_exec ) + __field( bool, logged ) + __field( enum landlock_request_type, blockers_type ) + __field( access_mask_t, blockers_access ) + __field( int, capability ) + ), + + TP_fast_assign( + __entry->domain_id = hierarchy->id; + __entry->same_exec = same_exec; + __entry->logged = logged; + __entry->blockers_type = blockers->type; + __entry->blockers_access = blockers->access; + __entry->capability = capability; + ), + + TP_printk("domain=%llx same_exec=%d logged=%d blockers=%s capability=%d", + __entry->domain_id, __entry->same_exec, __entry->logged, + __entry->blockers_type == LANDLOCK_REQUEST_CAPABILITY ? + __print_flags(__entry->blockers_access, "|", + _LANDLOCK_PERMISSION_BLOCKER_NAMES) : + "unknown", + __entry->capability) +); + +/** * landlock_deny_ptrace - Ptrace access denied by a Landlock domain * * @hierarchy: Denying domain's hierarchy node (never NULL); its id is the
diff --git a/include/trace/events/scmi.h b/include/trace/events/scmi.h index 703b7bb..b421c25 100644 --- a/include/trace/events/scmi.h +++ b/include/trace/events/scmi.h
@@ -7,8 +7,6 @@ #include <linux/tracepoint.h> -#define TRACE_SCMI_MAX_TAG_LEN 6 - TRACE_EVENT(scmi_fc_call, TP_PROTO(u8 protocol_id, u8 msg_id, u32 res_id, u32 val1, u32 val2), TP_ARGS(protocol_id, msg_id, res_id, val1, val2), @@ -156,7 +154,7 @@ TRACE_EVENT(scmi_msg_dump, __field(u8, channel_id) __field(u8, protocol_id) __field(u8, msg_id) - __array(char, tag, TRACE_SCMI_MAX_TAG_LEN) + __string(tag, tag) __field(u16, seq) __field(int, status) __field(size_t, len) @@ -168,7 +166,7 @@ TRACE_EVENT(scmi_msg_dump, __entry->channel_id = channel_id; __entry->protocol_id = protocol_id; __entry->msg_id = msg_id; - strscpy(__entry->tag, tag, TRACE_SCMI_MAX_TAG_LEN); + __assign_str(tag); __entry->seq = seq; __entry->status = status; __entry->len = len; @@ -177,7 +175,7 @@ TRACE_EVENT(scmi_msg_dump, TP_printk("id=%d ch=%02X pt=%02X t=%s msg_id=%02X seq=%04X s=%d pyld=%s", __entry->id, __entry->channel_id, __entry->protocol_id, - __entry->tag, __entry->msg_id, __entry->seq, __entry->status, + __get_str(tag), __entry->msg_id, __entry->seq, __entry->status, __print_hex_str(__get_dynamic_array(cmd), __entry->len)) ); #endif /* _TRACE_SCMI_H */
diff --git a/include/trace/events/workqueue.h b/include/trace/events/workqueue.h index b0de2bc..5b820ff 100644 --- a/include/trace/events/workqueue.h +++ b/include/trace/events/workqueue.h
@@ -9,6 +9,7 @@ #include <linux/workqueue.h> struct pool_workqueue; +struct worker_pool; /** * workqueue_queue_work - called when a work gets queued @@ -126,7 +127,152 @@ TRACE_EVENT(workqueue_execute_end, TP_printk("work struct %p: function %ps", __entry->work, __entry->function) ); +/** + * workqueue_cpu_intensive - called when a work item exceeds cpu_intensive threshold + * @pwq: pointer to struct pool_workqueue + * @work: pointer to struct work_struct + * @function: pointer to worker function + * @duration_us: CPU time consumed in microseconds + * + * This event occurs when a concurrency-managed work item runs for longer + * than wq_cpu_intensive_thresh_us without sleeping and is excluded from + * concurrency management to prevent stalling other work items. + */ +TRACE_EVENT(workqueue_cpu_intensive, + + TP_PROTO(struct pool_workqueue *pwq, struct work_struct *work, + work_func_t function, u64 duration_us), + + TP_ARGS(pwq, work, function, duration_us), + + TP_STRUCT__entry( + __field( void *, work ) + __field( void *, function ) + __string( workqueue, pwq->wq->name ) + __field( int, cpu ) + __field( u64, duration_us ) + ), + + TP_fast_assign( + __entry->work = work; + __entry->function = function; + __assign_str(workqueue); + __entry->cpu = pwq->pool->cpu; + __entry->duration_us = duration_us; + ), + + TP_printk("work struct=%p function=%ps workqueue=%s cpu=%d duration_us=%llu", + __entry->work, __entry->function, __get_str(workqueue), + __entry->cpu, __entry->duration_us) +); + +/** + * workqueue_mayday - called when a pool_workqueue sends mayday to rescuer + * @pwq: pointer to struct pool_workqueue + * + * This event occurs when a worker pool fails to create a new worker and + * requests the workqueue's rescuer thread to process pending works. + */ +TRACE_EVENT(workqueue_mayday, + + TP_PROTO(struct pool_workqueue *pwq), + + TP_ARGS(pwq), + + TP_STRUCT__entry( + __string( workqueue, pwq->wq->name ) + __field( int, pool_id ) + __field( int, cpu ) + __field( int, nr_active ) + ), + + TP_fast_assign( + __assign_str(workqueue); + __entry->pool_id = pwq->pool->id; + __entry->cpu = pwq->pool->cpu; + __entry->nr_active = pwq->nr_active; + ), + + TP_printk("workqueue=%s pool_id=%d cpu=%d nr_active=%d", + __get_str(workqueue), __entry->pool_id, __entry->cpu, + __entry->nr_active) +); + +/** + * workqueue_rescued - called when a work item is assigned to a rescuer + * @pwq: pointer to struct pool_workqueue + * @work: pointer to struct work_struct + * @function: pointer to worker function + * + * This event occurs when a work item is claimed by a rescuer thread + * to guarantee forward progress. + */ +TRACE_EVENT(workqueue_rescued, + + TP_PROTO(struct pool_workqueue *pwq, struct work_struct *work, + work_func_t function), + + TP_ARGS(pwq, work, function), + + TP_STRUCT__entry( + __field( void *, work ) + __field( void *, function ) + __string( workqueue, pwq->wq->name ) + __field( int, cpu ) + ), + + TP_fast_assign( + __entry->work = work; + __entry->function = function; + __assign_str(workqueue); + __entry->cpu = pwq->pool->cpu; + ), + + TP_printk("work struct=%p function=%ps workqueue=%s cpu=%d", + __entry->work, __entry->function, __get_str(workqueue), + __entry->cpu) +); + +/** + * workqueue_bh_budget_yield - called when a BH worker yields due to budget exhaustion + * @pool: pointer to struct worker_pool + * @restarts: number of restarts executed + * @timeout: whether execution hit the time limit (BH_WORKER_JIFFIES) + * @highpri: whether this is a high-priority BH pool + * + * This event occurs when a bottom-half (BH) worker pool running in softirq + * context exhausts its execution time slice or restart limit and must yield + * execution. + */ +TRACE_EVENT(workqueue_bh_budget_yield, + + TP_PROTO(struct worker_pool *pool, int restarts, bool timeout, bool highpri), + + TP_ARGS(pool, restarts, timeout, highpri), + + TP_STRUCT__entry( + __field( int, pool_id ) + __field( int, cpu ) + __field( int, restarts ) + __field( bool, timeout ) + __field( bool, highpri ) + ), + + TP_fast_assign( + __entry->pool_id = pool->id; + __entry->cpu = pool->cpu; + __entry->restarts = restarts; + __entry->timeout = timeout; + __entry->highpri = highpri; + ), + + TP_printk("pool_id=%d cpu=%d restarts=%d timeout=%d highpri=%d", + __entry->pool_id, __entry->cpu, __entry->restarts, + __entry->timeout, __entry->highpri) +); + #endif /* _TRACE_WORKQUEUE_H */ /* This part must be outside protection */ #include <trace/define_trace.h> +
diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h index cceda3b..24510e5 100644 --- a/include/uapi/linux/landlock.h +++ b/include/uapi/linux/landlock.h
@@ -33,14 +33,14 @@ * (and that they have tested with a kernel that supported them all). * * @quiet_access_fs and @quiet_access_net are bitmasks of actions for which a - * denial by this layer will not trigger a log if the corresponding object (or - * its children, for filesystem rules) is marked with the "quiet" bit via - * %LANDLOCK_ADD_RULE_QUIET, even if logging would normally take place per + * denial by this layer will not trigger an audit record if the corresponding + * object (or its children, for filesystem rules) is marked with the "quiet" bit + * via %LANDLOCK_ADD_RULE_QUIET, even if logging would normally take place per * landlock_restrict_self() flags. @quiet_scoped is similar, except that it * does not require marking any objects as quiet - if the ruleset is created * with any bits set in @quiet_scoped, then denial of such scoped resources will - * not trigger any log. These 3 fields are available since Landlock ABI version - * 10. + * not trigger an audit record. These three fields are available since Landlock + * ABI version 10. * * @quiet_access_fs, @quiet_access_net and @quiet_scoped must be a subset of * @handled_access_fs, @handled_access_net and @scoped respectively. @@ -66,18 +66,24 @@ struct landlock_ruleset_attr { __u64 scoped; /** * @quiet_access_fs: Bitmask of filesystem actions which should not be - * logged if per-object quiet flag is set. + * submitted to audit if the per-object quiet flag is set. */ __u64 quiet_access_fs; /** * @quiet_access_net: Bitmask of network actions which should not be - * logged if per-object quiet flag is set. + * submitted to audit if the per-object quiet flag is set. */ __u64 quiet_access_net; /** - * @quiet_scoped: Bitmask of scoped actions which should not be logged. + * @quiet_scoped: Bitmask of scoped actions which should not be + * submitted to audit. */ __u64 quiet_scoped; + /** + * @handled_permissions: Bitmask of handled permissions (cf. `Permission + * flags`_). + */ + __u64 handled_permissions; }; /** @@ -228,6 +234,15 @@ enum landlock_rule_type { * landlock_net_port_attr . */ LANDLOCK_RULE_NET_PORT, + /** + * @LANDLOCK_RULE_NAMESPACE: Type of a &struct landlock_namespace_attr . + */ + LANDLOCK_RULE_NAMESPACE, + /** + * @LANDLOCK_RULE_CAPABILITY: Type of a &struct + * landlock_capability_attr . + */ + LANDLOCK_RULE_CAPABILITY, }; /** @@ -282,6 +297,77 @@ struct landlock_net_port_attr { }; /** + * struct landlock_namespace_attr - Namespace type definition + * + * Argument of sys_landlock_add_rule() with %LANDLOCK_RULE_NAMESPACE. + */ +struct landlock_namespace_attr { + /** + * @permissions: Must be set to %LANDLOCK_PERMISSION_NAMESPACE_USE. + */ + __u64 permissions; + /** + * @allowed_namespace_types: Bitmask of namespace types (``CLONE_NEW*`` + * flags) to allow under this rule. Unknown bits are silently ignored + * for forward compatibility. + */ + __u64 allowed_namespace_types; + /** + * @quiet_namespace_types: Bitmask of namespace types (``CLONE_NEW*`` + * flags) whose denial by this layer should not be submitted to audit, + * even when landlock_restrict_self() enables audit logging. Only audit + * records attributed to this layer are suppressed; denial tracepoints + * still fire (see `Permission flags`_). Bits also set in + * @allowed_namespace_types have no effect, since an allowed type is + * never denied. Unknown bits are silently ignored. + * + * At least one of @allowed_namespace_types or @quiet_namespace_types + * must be non-zero, otherwise the call returns ``-ENOMSG``. The + * non-zero check runs on the raw input before unknown-bit masking, so a + * rule that sets only bits unknown to the running kernel succeeds but + * has no runtime effect. Programs should omit this rule when they + * neither allow nor quiet a namespace type. + */ + __u64 quiet_namespace_types; +}; + +/** + * struct landlock_capability_attr - Capability definition + * + * Argument of sys_landlock_add_rule() with %LANDLOCK_RULE_CAPABILITY. + */ +struct landlock_capability_attr { + /** + * @permissions: Must be set to %LANDLOCK_PERMISSION_CAPABILITY_USE. + */ + __u64 permissions; + /** + * @allowed_capabilities: Bitmask of capabilities (``1ULL << CAP_*``) to + * allow under this rule. Bits above ``CAP_LAST_CAP`` are silently + * ignored for forward compatibility. + */ + __u64 allowed_capabilities; + /** + * @quiet_capabilities: Bitmask of capabilities (``1ULL << CAP_*``) + * whose denial by this layer should not be submitted to audit, even if + * audit logging would normally take place per landlock_restrict_self() + * flags. Only audit records attributed to this layer are suppressed; + * denial tracepoints still fire (see `Permission flags`_). Bits also + * set in @allowed_capabilities have no effect, since an allowed + * capability is never denied. Bits above ``CAP_LAST_CAP`` are silently + * ignored. + * + * At least one of @allowed_capabilities or @quiet_capabilities must be + * non-zero, otherwise the call returns ``-ENOMSG``. The non-zero check + * runs on the raw input before unknown-bit masking, so a rule that sets + * only bits unknown to the running kernel (above ``CAP_LAST_CAP``) + * succeeds but has no runtime effect. Programs should omit this rule + * when they neither allow nor quiet a capability. + */ + __u64 quiet_capabilities; +}; + +/** * DOC: fs_access * * A set of actions on kernel objects may be defined by an attribute (e.g. @@ -507,4 +593,41 @@ struct landlock_net_port_attr { #define LANDLOCK_SCOPE_SIGNAL (1ULL << 1) /* clang-format on*/ +/** + * DOC: permission + * + * Permission flags + * ~~~~~~~~~~~~~~~~ + * + * These flags restrict the use of members of a category, each member being + * identified by a constant from another kernel subsystem (e.g. CLONE_NEW* + * namespace types, CAP_* capabilities). A flag covers every kernel path that + * uses a member of its category, and members that no rule explicitly allows are + * denied. Values unknown to the running kernel are silently accepted for + * forward compatibility and stay denied by default. See + * Documentation/security/landlock.rst for design details. + * + * When a ruleset handles multiple permissions whose operations overlap (e.g. a + * non-user namespace needs both its namespace type and CAP_SYS_ADMIN), the + * operation is allowed only if each handled permission independently allows it. + * See Documentation/userspace-api/landlock.rst. + * + * - %LANDLOCK_PERMISSION_NAMESPACE_USE: Restrict the use of specific namespace + * types: creation (:manpage:`unshare(2)`, :manpage:`clone(2)`, + * :manpage:`clone3(2)`), joining (:manpage:`setns(2)`), and acquiring an fd + * reference (:manpage:`open_tree(2)`, :manpage:`fsmount(2)`). A process in a + * Landlock domain that handles this permission is denied from using namespace + * types that are not explicitly allowed by a %LANDLOCK_RULE_NAMESPACE rule. + * Support added in Landlock ABI version 12. + * - %LANDLOCK_PERMISSION_CAPABILITY_USE: Restrict the use of specific Linux + * capabilities. A process in a Landlock domain that handles this permission + * is denied from exercising capabilities that are not explicitly allowed by a + * %LANDLOCK_RULE_CAPABILITY rule. This hook is purely restrictive: it can + * deny capabilities that the kernel would otherwise grant, but it can never + * grant capabilities that the kernel already denied. Support added in + * Landlock ABI version 12. + */ +#define LANDLOCK_PERMISSION_NAMESPACE_USE (1ULL << 0) +#define LANDLOCK_PERMISSION_CAPABILITY_USE (1ULL << 1) + #endif /* _UAPI_LINUX_LANDLOCK_H */
diff --git a/include/uapi/linux/psp-sev.h b/include/uapi/linux/psp-sev.h index 52dae70..536626a 100644 --- a/include/uapi/linux/psp-sev.h +++ b/include/uapi/linux/psp-sev.h
@@ -15,7 +15,7 @@ #include <linux/types.h> -/** +/* * SEV platform commands */ enum { @@ -36,7 +36,7 @@ enum { SEV_MAX, }; -/** +/* * SEV Firmware status code */ typedef enum { @@ -109,8 +109,8 @@ typedef enum { /** * struct sev_user_data_status - PLATFORM_STATUS command parameters * - * @major: major API version - * @minor: minor API version + * @api_major: major API version + * @api_minor: minor API version * @state: platform state * @flags: platform config flags * @build: firmware build id for API version @@ -139,12 +139,12 @@ struct sev_user_data_pek_csr { } __packed; /** - * struct sev_user_data_cert_import - PEK_CERT_IMPORT command parameters + * struct sev_user_data_pek_cert_import - PEK_CERT_IMPORT command parameters * - * @pek_address: PEK certificate chain - * @pek_len: length of PEK certificate - * @oca_address: OCA certificate chain - * @oca_len: length of OCA certificate + * @pek_cert_address: PEK certificate chain + * @pek_cert_len: length of PEK certificate + * @oca_cert_address: OCA certificate chain + * @oca_cert_len: length of OCA certificate */ struct sev_user_data_pek_cert_import { __u64 pek_cert_address; /* In */ @@ -156,8 +156,8 @@ struct sev_user_data_pek_cert_import { /** * struct sev_user_data_pdh_cert_export - PDH_CERT_EXPORT command parameters * - * @pdh_address: PDH certificate address - * @pdh_len: length of PDH certificate + * @pdh_cert_address: PDH certificate address + * @pdh_cert_len: length of PDH certificate * @cert_chain_address: PDH certificate chain * @cert_chain_len: length of PDH certificate chain */ @@ -248,7 +248,7 @@ struct sev_user_data_snp_config { } __packed; /** - * struct sev_data_snp_vlek_load - SNP_VLEK_LOAD structure + * struct sev_user_data_snp_vlek_load - SNP_VLEK_LOAD structure * * @len: length of the command buffer read by the PSP * @vlek_wrapped_version: version of wrapped VLEK hashstick (Must be 0h) @@ -264,7 +264,7 @@ struct sev_user_data_snp_vlek_load { } __packed; /** - * struct sev_user_data_snp_vlek_wrapped_vlek_hashstick - Wrapped VLEK data + * struct sev_user_data_snp_wrapped_vlek_hashstick - Wrapped VLEK data * * @data: Opaque data provided by AMD KDS (as described in SEV-SNP Firmware ABI * 1.54, SNP_VLEK_LOAD)
diff --git a/include/uapi/linux/tee.h b/include/uapi/linux/tee.h index 5203977..76815b0 100644 --- a/include/uapi/linux/tee.h +++ b/include/uapi/linux/tee.h
@@ -385,24 +385,6 @@ struct tee_iocl_supp_send_arg { struct tee_ioctl_buf_data) /** - * struct tee_ioctl_shm_register_data - Shared memory register argument - * @addr: [in] Start address of shared memory to register - * @length: [in/out] Length of shared memory to register - * @flags: [in/out] Flags to/from registration. - * @id: [out] Identifier of the shared memory - * - * The flags field should currently be zero as input. Updated by the call - * with actual flags as defined by TEE_IOCTL_SHM_* above. - * This structure is used as argument for TEE_IOC_SHM_REGISTER below. - */ -struct tee_ioctl_shm_register_data { - __u64 addr; - __u64 length; - __u32 flags; - __s32 id; -}; - -/** * struct tee_ioctl_shm_register_fd_data - Shared memory registering argument * @fd: [in] File descriptor identifying dmabuf reference * @size: [out] Size of referenced memory @@ -426,7 +408,7 @@ struct tee_ioctl_shm_register_fd_data { * Returns a file descriptor on success or < 0 on failure * * The returned file descriptor refers to the shared memory object in the - * kernel. The supplied file deccriptor can be closed if it's not needed + * kernel. The supplied file descriptor can be closed if it's not needed * for other purposes. The shared memory is freed when the descriptor is * closed. */ @@ -434,13 +416,31 @@ struct tee_ioctl_shm_register_fd_data { struct tee_ioctl_shm_register_fd_data) /** + * struct tee_ioctl_shm_register_data - Shared memory register argument + * @addr: [in] Start address of shared memory to register + * @length: [in/out] Length of shared memory to register + * @flags: [in/out] Flags to/from registration. + * @id: [out] Identifier of the shared memory + * + * The flags field should currently be zero as input. Updated by the call + * with actual flags as defined by TEE_IOCTL_SHM_* above. + * This structure is used as argument for TEE_IOC_SHM_REGISTER below. + */ +struct tee_ioctl_shm_register_data { + __u64 addr; + __u64 length; + __u32 flags; + __s32 id; +}; + +/** * TEE_IOC_SHM_REGISTER - Register shared memory argument * * Registers shared memory between the user space process and secure OS. * * Returns a file descriptor on success or < 0 on failure * - * The shared memory is unregisterred when the descriptor is closed. + * The shared memory is unregistered when the descriptor is closed. */ #define TEE_IOC_SHM_REGISTER _IOWR(TEE_IOC_MAGIC, TEE_IOC_BASE + 9, \ struct tee_ioctl_shm_register_data)
diff --git a/init/Kconfig b/init/Kconfig index 046ae0b..b31aa29 100644 --- a/init/Kconfig +++ b/init/Kconfig
@@ -743,8 +743,6 @@ bool "Proxy Execution" # Avoid some build failures w/ PREEMPT_RT until it can be fixed depends on !PREEMPT_RT - # Need to investigate how to inform sched_ext of split contexts - depends on !SCHED_CLASS_EXT # Not particularly useful until we get to multi-rq proxying depends on EXPERT help
diff --git a/kernel/cgroup/cgroup-internal.h b/kernel/cgroup/cgroup-internal.h index 5879712..f2684f9 100644 --- a/kernel/cgroup/cgroup-internal.h +++ b/kernel/cgroup/cgroup-internal.h
@@ -254,7 +254,7 @@ void cgroup_procs_write_finish(struct task_struct *task, enum cgroup_attach_lock_mode lock_mode) __releases(&cgroup_threadgroup_rwsem); -void cgroup_lock_and_drain_offline(struct cgroup *cgrp); +int cgroup_lock_and_drain_offline(struct cgroup *cgrp); int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name, umode_t mode); int cgroup_rmdir(struct kernfs_node *kn);
diff --git a/kernel/cgroup/cgroup-v1.c b/kernel/cgroup/cgroup-v1.c index a4337c9..6825db7 100644 --- a/kernel/cgroup/cgroup-v1.c +++ b/kernel/cgroup/cgroup-v1.c
@@ -506,8 +506,8 @@ static ssize_t __cgroup1_procs_write(struct kernfs_open_file *of, enum cgroup_attach_lock_mode lock_mode; cgrp = cgroup_kn_lock_live(of->kn, false); - if (!cgrp) - return -ENODEV; + if (IS_ERR(cgrp)) + return PTR_ERR(cgrp); task = cgroup_procs_write_start(buf, threadgroup, &lock_mode); ret = PTR_ERR_OR_ZERO(task); @@ -569,8 +569,8 @@ static ssize_t cgroup_release_agent_write(struct kernfs_open_file *of, return -EPERM; cgrp = cgroup_kn_lock_live(of->kn, false); - if (!cgrp) - return -ENODEV; + if (IS_ERR(cgrp)) + return PTR_ERR(cgrp); spin_lock(&release_agent_path_lock); strscpy(cgrp->root->release_agent_path, strstrip(buf), sizeof(cgrp->root->release_agent_path)); @@ -605,10 +605,7 @@ static u64 cgroup_read_notify_on_release(struct cgroup_subsys_state *css, static int cgroup_write_notify_on_release(struct cgroup_subsys_state *css, struct cftype *cft, u64 val) { - if (val) - set_bit(CGRP_NOTIFY_ON_RELEASE, &css->cgroup->flags); - else - clear_bit(CGRP_NOTIFY_ON_RELEASE, &css->cgroup->flags); + assign_bit(CGRP_NOTIFY_ON_RELEASE, &css->cgroup->flags, val); return 0; } @@ -621,10 +618,7 @@ static u64 cgroup_clone_children_read(struct cgroup_subsys_state *css, static int cgroup_clone_children_write(struct cgroup_subsys_state *css, struct cftype *cft, u64 val) { - if (val) - set_bit(CGRP_CPUSET_CLONE_CHILDREN, &css->cgroup->flags); - else - clear_bit(CGRP_CPUSET_CLONE_CHILDREN, &css->cgroup->flags); + assign_bit(CGRP_CPUSET_CLONE_CHILDREN, &css->cgroup->flags, val); return 0; } @@ -1097,7 +1091,9 @@ int cgroup1_reconfigure(struct fs_context *fc) int ret = 0; u32 added_mask, removed_mask; - cgroup_lock_and_drain_offline(&cgrp_dfl_root.cgrp); + ret = cgroup_lock_and_drain_offline(&cgrp_dfl_root.cgrp); + if (unlikely(ret)) + return ret; /* See what subsystems are wanted */ ret = check_cgroupfs_options(fc); @@ -1262,7 +1258,9 @@ int cgroup1_get_tree(struct fs_context *fc) if (!ns_capable(ctx->ns->user_ns, CAP_SYS_ADMIN)) return -EPERM; - cgroup_lock_and_drain_offline(&cgrp_dfl_root.cgrp); + ret = cgroup_lock_and_drain_offline(&cgrp_dfl_root.cgrp); + if (unlikely(ret)) + return ret; ret = cgroup1_root_to_use(fc); if (!ret && !percpu_ref_tryget_live(&ctx->root->cgrp.self.refcnt))
diff --git a/kernel/cgroup/cgroup.c b/kernel/cgroup/cgroup.c index 227d097..1463424 100644 --- a/kernel/cgroup/cgroup.c +++ b/kernel/cgroup/cgroup.c
@@ -548,20 +548,11 @@ static struct cgroup_subsys_state *cgroup_e_css_by_mask(struct cgroup *cgrp, struct cgroup_subsys_state *cgroup_e_css(struct cgroup *cgrp, struct cgroup_subsys *ss) { - struct cgroup_subsys_state *css; - if (!CGROUP_HAS_SUBSYS_CONFIG) return NULL; - do { - css = cgroup_css(cgrp, ss); - - if (css) - return css; - cgrp = cgroup_parent(cgrp); - } while (cgrp); - - return init_css_set.subsys[ss->id]; + return rcu_dereference_check(cgrp->e_css[ss->id], + lockdep_is_held(&cgroup_mutex)); } /** @@ -585,17 +576,10 @@ struct cgroup_subsys_state *cgroup_get_e_css(struct cgroup *cgrp, rcu_read_lock(); - do { - css = cgroup_css(cgrp, ss); + css = cgroup_e_css(cgrp, ss); + while (!css_tryget_online(css)) + css = cgroup_e_css(cgroup_parent(css->cgroup), ss); - if (css && css_tryget_online(css)) - goto out_unlock; - cgrp = cgroup_parent(cgrp); - } while (cgrp); - - css = init_css_set.subsys[ss->id]; - css_get(css); -out_unlock: rcu_read_unlock(); return css; } @@ -1379,7 +1363,10 @@ static void cgroup_destroy_root(struct cgroup_root *root) trace_cgroup_destroy_root(root); - cgroup_lock_and_drain_offline(&cgrp_dfl_root.cgrp); + /* runs off a workqueue, no signal can interrupt the drain */ + ret = cgroup_lock_and_drain_offline(&cgrp_dfl_root.cgrp); + if (WARN_ON_ONCE(ret)) + cgroup_lock(); BUG_ON(atomic_read(&root->nr_cgrps)); BUG_ON(!list_empty(&cgrp->self.children)); @@ -1685,9 +1672,10 @@ void cgroup_kn_unlock(struct kernfs_node *kn) * This helper is to be used by a cgroup kernfs method currently servicing * @kn. It breaks the active protection, performs cgroup locking and * verifies that the associated cgroup is alive. Returns the cgroup if - * alive; otherwise, %NULL. A successful return should be undone by a - * matching cgroup_kn_unlock() invocation. If @drain_offline is %true, the - * cgroup is drained of offlining csses before return. + * alive; otherwise, an ERR_PTR value. A successful return should be undone by + * a matching cgroup_kn_unlock() invocation. If @drain_offline is %true, the + * cgroup is drained of offlining csses before return, and an interrupted drain + * fails with -ERESTARTSYS. * * Any cgroup kernfs method implementation which requires locking the * associated cgroup should use this helper. It avoids nesting cgroup @@ -1697,6 +1685,7 @@ void cgroup_kn_unlock(struct kernfs_node *kn) struct cgroup *cgroup_kn_lock_live(struct kernfs_node *kn, bool drain_offline) { struct cgroup *cgrp; + int ret; if (kernfs_type(kn) == KERNFS_DIR) cgrp = kn->priv; @@ -1710,19 +1699,25 @@ struct cgroup *cgroup_kn_lock_live(struct kernfs_node *kn, bool drain_offline) * break the active_ref protection. */ if (!cgroup_tryget(cgrp)) - return NULL; + return ERR_PTR(-ENODEV); kernfs_break_active_protection(kn); - if (drain_offline) - cgroup_lock_and_drain_offline(cgrp); - else + if (drain_offline) { + ret = cgroup_lock_and_drain_offline(cgrp); + if (unlikely(ret)) { + kernfs_unbreak_active_protection(kn); + cgroup_put(cgrp); + return ERR_PTR(ret); + } + } else { cgroup_lock(); + } if (!cgroup_is_dead(cgrp)) return cgrp; cgroup_kn_unlock(kn); - return NULL; + return ERR_PTR(-ENODEV); } static void cgroup_rm_file(struct cgroup *cgrp, const struct cftype *cft) @@ -2131,12 +2126,24 @@ void init_cgroup_root(struct cgroup_fs_context *ctx) { struct cgroup_root *root = ctx->root; struct cgroup *cgrp = &root->cgrp; + struct cgroup_subsys *ss; + int ssid; INIT_LIST_HEAD_RCU(&root->root_list); atomic_set(&root->nr_cgrps, 1); cgrp->root = root; init_cgroup_housekeeping(cgrp); + /* + * A root cgroup's effective css is always the root css in + * init_css_set.subsys[], whichever hierarchy the subsystem is bound + * to, so rebind_subsystems() doesn't need to update e_css[]. For + * cgrp_dfl_root this runs before the root csses exist, and + * online_css() sets the entries when they come online. + */ + for_each_subsys(ss, ssid) + RCU_INIT_POINTER(cgrp->e_css[ssid], init_css_set.subsys[ssid]); + /* DYNMODS must be modified through cgroup_favor_dynmods() */ root->flags = ctx->flags & ~CGRP_ROOT_FAVOR_DYNMODS; if (ctx->release_agent) @@ -3320,16 +3327,20 @@ static int cgroup_update_dfl_csses(struct cgroup *cgrp) * @cgrp: root of the target subtree * * Because css offlining is asynchronous, userland may try to re-enable a - * controller while the previous css is still around. This function grabs - * cgroup_mutex and drains the previous css instances of @cgrp's subtree. + * controller while the previous css is still around. This function grabs + * cgroup_mutex and waits until no css in @cgrp's subtree is dying. A dying css + * offlines only after every task that still pins it has finished exiting, which + * can take arbitrarily long, so the wait is interruptible. + * + * Returns 0 with cgroup_mutex held once the subtree is drained, or -ERESTARTSYS + * without it if interrupted by a signal. */ -void cgroup_lock_and_drain_offline(struct cgroup *cgrp) - __acquires(&cgroup_mutex) +int cgroup_lock_and_drain_offline(struct cgroup *cgrp) { struct cgroup *dsct; struct cgroup_subsys_state *d_css; struct cgroup_subsys *ss; - int ssid; + int ssid, ret; restart: cgroup_lock(); @@ -3343,17 +3354,20 @@ void cgroup_lock_and_drain_offline(struct cgroup *cgrp) continue; cgroup_get_live(dsct); - prepare_to_wait(&dsct->offline_waitq, &wait, - TASK_UNINTERRUPTIBLE); - + ret = prepare_to_wait_event(&dsct->offline_waitq, &wait, + TASK_INTERRUPTIBLE); cgroup_unlock(); - schedule(); + if (!ret) + schedule(); finish_wait(&dsct->offline_waitq, &wait); - cgroup_put(dsct); + if (unlikely(ret)) + return ret; goto restart; } } + + return 0; } /** @@ -3650,8 +3664,8 @@ static ssize_t cgroup_subtree_control_write(struct kernfs_open_file *of, } cgrp = cgroup_kn_lock_live(of->kn, true); - if (!cgrp) - return -ENODEV; + if (IS_ERR(cgrp)) + return PTR_ERR(cgrp); for_each_subsys(ss, ssid) { if (enable & (1 << ssid)) { @@ -3790,8 +3804,8 @@ static ssize_t cgroup_type_write(struct kernfs_open_file *of, char *buf, /* drain dying csses before we re-apply (threaded) subtree control */ cgrp = cgroup_kn_lock_live(of->kn, true); - if (!cgrp) - return -ENOENT; + if (IS_ERR(cgrp)) + return PTR_ERR(cgrp); /* threaded can only be enabled */ ret = cgroup_enable_threaded(cgrp); @@ -3833,8 +3847,8 @@ static ssize_t cgroup_max_descendants_write(struct kernfs_open_file *of, return -ERANGE; cgrp = cgroup_kn_lock_live(of->kn, false); - if (!cgrp) - return -ENOENT; + if (IS_ERR(cgrp)) + return PTR_ERR(cgrp); WRITE_ONCE(cgrp->max_descendants, descendants); @@ -3876,8 +3890,8 @@ static ssize_t cgroup_max_depth_write(struct kernfs_open_file *of, return -ERANGE; cgrp = cgroup_kn_lock_live(of->kn, false); - if (!cgrp) - return -ENOENT; + if (IS_ERR(cgrp)) + return PTR_ERR(cgrp); WRITE_ONCE(cgrp->max_depth, depth); @@ -4075,8 +4089,8 @@ static ssize_t pressure_write(struct kernfs_open_file *of, char *buf, ssize_t ret = 0; cgrp = cgroup_kn_lock_live(of->kn, false); - if (!cgrp) - return -ENODEV; + if (IS_ERR(cgrp)) + return PTR_ERR(cgrp); ctx = of->priv; if (!ctx) { @@ -4192,8 +4206,8 @@ static ssize_t cgroup_pressure_write(struct kernfs_open_file *of, return -ERANGE; cgrp = cgroup_kn_lock_live(of->kn, false); - if (!cgrp) - return -ENOENT; + if (IS_ERR(cgrp)) + return PTR_ERR(cgrp); psi = cgroup_psi(cgrp); if (psi->enabled != enable) { @@ -4268,8 +4282,8 @@ static ssize_t cgroup_freeze_write(struct kernfs_open_file *of, return -ERANGE; cgrp = cgroup_kn_lock_live(of->kn, false); - if (!cgrp) - return -ENOENT; + if (IS_ERR(cgrp)) + return PTR_ERR(cgrp); cgroup_freeze(cgrp, freeze); @@ -4330,8 +4344,8 @@ static ssize_t cgroup_kill_write(struct kernfs_open_file *of, char *buf, return -ERANGE; cgrp = cgroup_kn_lock_live(of->kn, false); - if (!cgrp) - return -ENOENT; + if (IS_ERR(cgrp)) + return PTR_ERR(cgrp); /* * Killing is a process directed operation, i.e. the whole thread-group @@ -5488,8 +5502,8 @@ static ssize_t __cgroup_procs_write(struct kernfs_open_file *of, char *buf, enum cgroup_attach_lock_mode lock_mode; dst_cgrp = cgroup_kn_lock_live(of->kn, false); - if (!dst_cgrp) - return -ENODEV; + if (IS_ERR(dst_cgrp)) + return PTR_ERR(dst_cgrp); task = cgroup_procs_write_start(buf, threadgroup, &lock_mode); ret = PTR_ERR_OR_ZERO(task); @@ -5859,6 +5873,22 @@ static void init_and_link_css(struct cgroup_subsys_state *css, BUG_ON(cgroup_css(cgrp, ss)); } +static void cgroup_update_e_css(struct cgroup *cgrp, struct cgroup_subsys *ss) +{ + struct cgroup_subsys_state *d_css; + + lockdep_assert_held(&cgroup_mutex); + + css_for_each_descendant_pre(d_css, &cgrp->self) { + struct cgroup *dsct = d_css->cgroup; + struct cgroup_subsys_state *css = cgroup_css(dsct, ss); + + if (!css) + css = cgroup_e_css(cgroup_parent(dsct), ss); + rcu_assign_pointer(dsct->e_css[ss->id], css); + } +} + /* invoke ->css_online() on a new CSS and mark it online if successful */ static int online_css(struct cgroup_subsys_state *css) { @@ -5872,6 +5902,7 @@ static int online_css(struct cgroup_subsys_state *css) if (!ret) { css->flags |= CSS_ONLINE; rcu_assign_pointer(css->cgroup->subsys[ss->id], css); + cgroup_update_e_css(css->cgroup, ss); atomic_inc(&css->online_cnt); if (css->parent) { @@ -5898,6 +5929,7 @@ static void offline_css(struct cgroup_subsys_state *css) css->flags &= ~CSS_ONLINE; RCU_INIT_POINTER(css->cgroup->subsys[ss->id], NULL); + cgroup_update_e_css(css->cgroup, ss); wake_up_all(&css->cgroup->offline_waitq); } @@ -5969,6 +6001,7 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name, { struct cgroup_root *root = parent->root; struct cgroup *cgrp, *tcgrp; + struct cgroup_subsys *ss; struct kernfs_node *kn; int i, level = parent->level + 1; int ret; @@ -6013,6 +6046,9 @@ static struct cgroup *cgroup_create(struct cgroup *parent, const char *name, for (tcgrp = cgrp; tcgrp; tcgrp = cgroup_parent(tcgrp)) cgrp->ancestors[tcgrp->level] = tcgrp; + for_each_subsys(ss, i) + RCU_INIT_POINTER(cgrp->e_css[i], cgroup_e_css(parent, ss)); + /* * New cgroup inherits effective freeze counter, and * if the parent has to be frozen, the child has too. @@ -6123,8 +6159,8 @@ int cgroup_mkdir(struct kernfs_node *parent_kn, const char *name, umode_t mode) return -EINVAL; parent = cgroup_kn_lock_live(parent_kn, false); - if (!parent) - return -ENODEV; + if (IS_ERR(parent)) + return PTR_ERR(parent); if (!cgroup_check_hierarchy_limits(parent)) { ret = -EAGAIN; @@ -6400,7 +6436,7 @@ int cgroup_rmdir(struct kernfs_node *kn) int ret = 0; cgrp = cgroup_kn_lock_live(kn, false); - if (!cgrp) + if (IS_ERR(cgrp)) return 0; ret = cgroup_destroy_locked(cgrp); @@ -7197,15 +7233,19 @@ static void do_cgroup_task_dead(struct task_struct *tsk) * the cgroup and task_struct can be pinned indefinitely. Bounce through lazy * irq_work to allow batching while ensuring timely completion. */ -static DEFINE_PER_CPU(struct llist_head, cgrp_dead_tasks); -static DEFINE_PER_CPU(struct irq_work, cgrp_dead_tasks_iwork); +struct cgroup_dead { + struct irq_work iwork; + struct llist_head tasks; +}; +static DEFINE_PER_CPU(struct cgroup_dead, cgroup_dead); static void cgrp_dead_tasks_iwork_fn(struct irq_work *iwork) { + struct cgroup_dead *cgrp_dead = container_of(iwork, struct cgroup_dead, iwork); struct llist_node *lnode; struct task_struct *task, *next; - lnode = llist_del_all(this_cpu_ptr(&cgrp_dead_tasks)); + lnode = llist_del_all(&cgrp_dead->tasks); llist_for_each_entry_safe(task, next, lnode, cg_dead_lnode) { do_cgroup_task_dead(task); put_task_struct(task); @@ -7217,17 +7257,20 @@ static void __init cgroup_rt_init(void) int cpu; for_each_possible_cpu(cpu) { - init_llist_head(per_cpu_ptr(&cgrp_dead_tasks, cpu)); - per_cpu(cgrp_dead_tasks_iwork, cpu) = - IRQ_WORK_INIT_LAZY(cgrp_dead_tasks_iwork_fn); + struct cgroup_dead *cgrp_dead = per_cpu_ptr(&cgroup_dead, cpu); + + init_llist_head(&cgrp_dead->tasks); + cgrp_dead->iwork = IRQ_WORK_INIT_LAZY(cgrp_dead_tasks_iwork_fn); } } void cgroup_task_dead(struct task_struct *task) { + struct cgroup_dead *cgrp_dead = this_cpu_ptr(&cgroup_dead); + get_task_struct(task); - llist_add(&task->cg_dead_lnode, this_cpu_ptr(&cgrp_dead_tasks)); - irq_work_queue(this_cpu_ptr(&cgrp_dead_tasks_iwork)); + llist_add(&task->cg_dead_lnode, &cgrp_dead->tasks); + irq_work_queue(&cgrp_dead->iwork); } #else /* CONFIG_PREEMPT_RT */ static void __init cgroup_rt_init(void) {}
diff --git a/kernel/cgroup/cpuset-internal.h b/kernel/cgroup/cpuset-internal.h index e7d0106..5da9c91 100644 --- a/kernel/cgroup/cpuset-internal.h +++ b/kernel/cgroup/cpuset-internal.h
@@ -304,7 +304,9 @@ void cpuset_callback_lock_irq(void); void cpuset_callback_unlock_irq(void); void cpuset_update_tasks_cpumask(struct cpuset *cs, struct cpumask *new_cpus); void cpuset_update_tasks_nodemask(struct cpuset *cs); -int cpuset_update_flag(cpuset_flagbits_t bit, struct cpuset *cs, int turning_on); +struct cpuset *dup_or_alloc_cpuset(struct cpuset *cs); +void free_cpuset(struct cpuset *cs); +int validate_change(struct cpuset *cur, struct cpuset *trial); ssize_t cpuset_write_resmask(struct kernfs_open_file *of, char *buf, size_t nbytes, loff_t off); int cpuset_common_seq_show(struct seq_file *sf, void *v); @@ -318,7 +320,6 @@ void cpuset_full_unlock(void); extern struct cftype cpuset1_files[]; void cpuset1_update_task_spread_flags(struct cpuset *cs, struct task_struct *tsk); -void cpuset1_update_tasks_flags(struct cpuset *cs); void cpuset1_hotplug_update_tasks(struct cpuset *cs, struct cpumask *new_cpus, nodemask_t *new_mems, bool cpus_updated, bool mems_updated); @@ -328,11 +329,11 @@ void cpuset1_init(struct cpuset *cs); void cpuset1_online_css(struct cgroup_subsys_state *css); int cpuset1_generate_sched_domains(cpumask_var_t **domains, struct sched_domain_attr **attributes); +void cpuset1_offline_css(struct cpuset *cs); #else static inline void cpuset1_update_task_spread_flags(struct cpuset *cs, struct task_struct *tsk) {} -static inline void cpuset1_update_tasks_flags(struct cpuset *cs) {} static inline void cpuset1_hotplug_update_tasks(struct cpuset *cs, struct cpumask *new_cpus, nodemask_t *new_mems, bool cpus_updated, bool mems_updated) {} @@ -344,6 +345,7 @@ static inline void cpuset1_init(struct cpuset *cs) {} static inline void cpuset1_online_css(struct cgroup_subsys_state *css) {} static inline int cpuset1_generate_sched_domains(cpumask_var_t **domains, struct sched_domain_attr **attributes) { return 0; }; +static inline void cpuset1_offline_css(struct cpuset *cs) {} #endif /* CONFIG_CPUSETS_V1 */
diff --git a/kernel/cgroup/cpuset-v1.c b/kernel/cgroup/cpuset-v1.c index 562ad35..7c7f288 100644 --- a/kernel/cgroup/cpuset-v1.c +++ b/kernel/cgroup/cpuset-v1.c
@@ -229,7 +229,7 @@ void cpuset1_update_task_spread_flags(struct cpuset *cs, * function is called with cpuset_mutex held, cpuset membership stays * stable. */ -void cpuset1_update_tasks_flags(struct cpuset *cs) +static void cpuset1_update_tasks_flags(struct cpuset *cs) { struct css_task_iter it; struct task_struct *task; @@ -473,6 +473,51 @@ static u64 cpuset_read_u64(struct cgroup_subsys_state *css, struct cftype *cft) return 0; } +/* + * cpuset_update_flag - read a 0 or a 1 in a file and update associated flag + * bit: the bit to update (see cpuset_flagbits_t) + * cs: the cpuset to update + * turning_on: whether the flag is being set or cleared + * + * Call with cpuset_mutex held. + */ +static int cpuset_update_flag(cpuset_flagbits_t bit, struct cpuset *cs, + int turning_on) +{ + struct cpuset *trialcs; + int balance_flag_changed; + int spread_page_changed; + int err; + + trialcs = dup_or_alloc_cpuset(cs); + if (!trialcs) + return -ENOMEM; + + assign_bit(bit, &trialcs->flags, turning_on); + + err = validate_change(cs, trialcs); + if (err < 0) + goto out; + + balance_flag_changed = (is_sched_load_balance(cs) != + is_sched_load_balance(trialcs)); + + spread_page_changed = is_spread_page(cs) != is_spread_page(trialcs); + + cpuset_callback_lock_irq(); + cs->flags = trialcs->flags; + cpuset_callback_unlock_irq(); + + if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed) + rebuild_sched_domains_locked(); + + if (spread_page_changed) + cpuset1_update_tasks_flags(cs); +out: + free_cpuset(trialcs); + return err; +} + static int cpuset_write_u64(struct cgroup_subsys_state *css, struct cftype *cft, u64 val) { @@ -581,6 +626,18 @@ void cpuset1_online_css(struct cgroup_subsys_state *css) cpuset_callback_unlock_irq(); } +/* + * Legacy-hierarchy handling when a cpuset is taken offline: if it had + * sched_load_balance enabled, turn it off so the scheduler domains are + * rebuilt. A no-op on the default hierarchy. + */ +void cpuset1_offline_css(struct cpuset *cs) +{ + if (!cgroup_subsys_on_dfl(cpuset_cgrp_subsys) && + is_sched_load_balance(cs)) + cpuset_update_flag(CS_SCHED_LOAD_BALANCE, cs, 0); +} + static void update_domain_attr(struct sched_domain_attr *dattr, struct cpuset *c) {
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c index 8b220e9..0ebba2d 100644 --- a/kernel/cgroup/cpuset.c +++ b/kernel/cgroup/cpuset.c
@@ -168,7 +168,6 @@ static cpumask_var_t isolated_hk_cpus; /* T */ * It can be set in * - update_partition_sd_lb() * - update_cpumasks_hier() - * - cpuset_update_flag() * - cpuset_hotplug_update_tasks() * - cpuset_handle_hotplug() * @@ -629,7 +628,7 @@ static inline void free_tmpmasks(struct tmpmasks *tmp) * * Return: Pointer to newly allocated cpuset on success, NULL on failure */ -static struct cpuset *dup_or_alloc_cpuset(struct cpuset *cs) +struct cpuset *dup_or_alloc_cpuset(struct cpuset *cs) { struct cpuset *trial; @@ -670,7 +669,7 @@ static struct cpuset *dup_or_alloc_cpuset(struct cpuset *cs) * free_cpuset - free the cpuset * @cs: the cpuset to be freed */ -static inline void free_cpuset(struct cpuset *cs) +void free_cpuset(struct cpuset *cs) { free_cpumask_var(cs->cpus_allowed); free_cpumask_var(cs->effective_cpus); @@ -764,7 +763,7 @@ static inline bool mems_excl_conflict(struct cpuset *cs1, struct cpuset *cs2) * Return 0 if valid, -errno if not. */ -static int validate_change(struct cpuset *cur, struct cpuset *trial) +int validate_change(struct cpuset *cur, struct cpuset *trial) { struct cgroup_subsys_state *css; struct cpuset *c, *par; @@ -792,8 +791,8 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial) * For v1, effective_cpus == cpus_allowed & user_xcpus() returns * cpus_allowed. * - * For v2, is_cpu_exclusive() & is_sched_load_balance() are true only - * for non-isolated partition root. At this point, the target + * For v2, is_partition_valid(cur) & is_sched_load_balance() are true + * only for non-isolated partition root. At this point, the target * effective_cpus isn't computed yet. user_xcpus() is the best * approximation. * @@ -802,7 +801,8 @@ static int validate_change(struct cpuset *cur, struct cpuset *trial) * becomes an issue. */ ret = -EBUSY; - if (is_cpu_exclusive(cur) && is_sched_load_balance(cur) && + if ((is_partition_valid(cur) || (!cpuset_v2() && is_cpu_exclusive(cur))) && + is_sched_load_balance(cur) && !cpuset_cpumask_can_shrink(cur->effective_cpus, user_xcpus(trial))) goto out; @@ -1195,25 +1195,6 @@ static void update_sibling_cpumasks(struct cpuset *parent, struct cpuset *cs, struct tmpmasks *tmp); /* - * Update partition exclusive flag - * - * Return: 0 if successful, an error code otherwise - */ -static int update_partition_exclusive_flag(struct cpuset *cs, int new_prs) -{ - bool exclusive = (new_prs > PRS_MEMBER); - - if (exclusive && !is_cpu_exclusive(cs)) { - if (cpuset_update_flag(CS_CPU_EXCLUSIVE, cs, 1)) - return PERR_NOTEXCL; - } else if (!exclusive && is_cpu_exclusive(cs)) { - /* Turning off CS_CPU_EXCLUSIVE will not return error */ - cpuset_update_flag(CS_CPU_EXCLUSIVE, cs, 0); - } - return 0; -} - -/* * Update partition load balance flag and/or rebuild sched domain * * Changing load balance flag will automatically call @@ -1237,10 +1218,7 @@ static void update_partition_sd_lb(struct cpuset *cs, int old_prs) } if (new_lb != !!is_sched_load_balance(cs)) { rebuild_domains = true; - if (new_lb) - set_bit(CS_SCHED_LOAD_BALANCE, &cs->flags); - else - clear_bit(CS_SCHED_LOAD_BALANCE, &cs->flags); + assign_bit(CS_SCHED_LOAD_BALANCE, &cs->flags, new_lb); } if (rebuild_domains) @@ -1271,11 +1249,9 @@ static void reset_partition_data(struct cpuset *cs) lockdep_assert_held(&callback_lock); - if (cpumask_empty(cs->exclusive_cpus)) { + if (cpumask_empty(cs->exclusive_cpus)) cpumask_clear(cs->effective_xcpus); - if (is_cpu_exclusive(cs)) - clear_bit(CS_CPU_EXCLUSIVE, &cs->flags); - } + if (!cpumask_and(cs->effective_cpus, parent->effective_cpus, cs->cpus_allowed)) cpumask_copy(cs->effective_cpus, parent->effective_cpus); } @@ -2053,19 +2029,6 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd, return 0; /* - * Transitioning between invalid to valid or vice versa may require - * changing CS_CPU_EXCLUSIVE. In the case of partcmd_update, - * validate_change() has already been successfully called and - * CPU lists in cs haven't been updated yet. So defer it to later. - */ - if ((old_prs != new_prs) && (cmd != partcmd_update)) { - int err = update_partition_exclusive_flag(cs, new_prs); - - if (err) - return err; - } - - /* * Change the parent's effective_cpus & effective_xcpus (top cpuset * only). * @@ -2087,9 +2050,6 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd, spin_unlock_irq(&callback_lock); - if ((old_prs != new_prs) && (cmd == partcmd_update)) - update_partition_exclusive_flag(cs, new_prs); - if (adding || deleting) { cpuset_update_tasks_cpumask(parent, tmp->addmask); update_sibling_cpumasks(parent, cs, tmp); @@ -2330,10 +2290,8 @@ static void update_cpumasks_hier(struct cpuset *cs, struct tmpmasks *tmp, */ if (cpuset_v2() && !is_partition_valid(cp) && (is_sched_load_balance(parent) != is_sched_load_balance(cp))) { - if (is_sched_load_balance(parent)) - set_bit(CS_SCHED_LOAD_BALANCE, &cp->flags); - else - clear_bit(CS_SCHED_LOAD_BALANCE, &cp->flags); + assign_bit(CS_SCHED_LOAD_BALANCE, &cp->flags, + is_sched_load_balance(parent)); } /* @@ -2891,59 +2849,6 @@ bool current_cpuset_is_being_rebound(void) return ret; } -/* - * cpuset_update_flag - read a 0 or a 1 in a file and update associated flag - * bit: the bit to update (see cpuset_flagbits_t) - * cs: the cpuset to update - * turning_on: whether the flag is being set or cleared - * - * Call with cpuset_mutex held. - */ - -int cpuset_update_flag(cpuset_flagbits_t bit, struct cpuset *cs, - int turning_on) -{ - struct cpuset *trialcs; - int balance_flag_changed; - int spread_page_changed; - int err; - - trialcs = dup_or_alloc_cpuset(cs); - if (!trialcs) - return -ENOMEM; - - if (turning_on) - set_bit(bit, &trialcs->flags); - else - clear_bit(bit, &trialcs->flags); - - err = validate_change(cs, trialcs); - if (err < 0) - goto out; - - balance_flag_changed = (is_sched_load_balance(cs) != - is_sched_load_balance(trialcs)); - - spread_page_changed = is_spread_page(cs) != is_spread_page(trialcs); - - spin_lock_irq(&callback_lock); - cs->flags = trialcs->flags; - spin_unlock_irq(&callback_lock); - - if (!cpumask_empty(trialcs->cpus_allowed) && balance_flag_changed) { - if (cpuset_v2()) - cpuset_force_rebuild(); - else - rebuild_sched_domains_locked(); - } - - if (spread_page_changed) - cpuset1_update_tasks_flags(cs); -out: - free_cpuset(trialcs); - return err; -} - /** * update_prstate - update partition_root_state * @cs: the cpuset to update @@ -2971,10 +2876,6 @@ static int update_prstate(struct cpuset *cs, int new_prs) if (alloc_tmpmasks(&tmpmask)) return -ENOMEM; - err = update_partition_exclusive_flag(cs, new_prs); - if (err) - goto out; - if (!old_prs) { /* * cpus_allowed and exclusive_cpus cannot be both empty. @@ -3038,13 +2939,10 @@ static int update_prstate(struct cpuset *cs, int new_prs) } out: /* - * Make partition invalid & disable CS_CPU_EXCLUSIVE if an error - * happens. + * Make partition invalid if an error happens. */ - if (err) { + if (err) new_prs = -new_prs; - update_partition_exclusive_flag(cs, new_prs); - } spin_lock_irq(&callback_lock); cs->partition_root_state = new_prs; @@ -3066,8 +2964,6 @@ static int update_prstate(struct cpuset *cs, int new_prs) update_partition_sd_lb(cs, old_prs); notify_partition_change(cs, old_prs); - if (force_sd_rebuild) - rebuild_sched_domains_locked(); free_tmpmasks(&tmpmask); return 0; } @@ -3706,21 +3602,12 @@ static int cpuset_css_online(struct cgroup_subsys_state *css) return 0; } -/* - * If the cpuset being removed has its flag 'sched_load_balance' - * enabled, then simulate turning sched_load_balance off, which - * will call rebuild_sched_domains_locked(). That is not needed - * in the default hierarchy where only changes in partition - * will cause repartitioning. - */ static void cpuset_css_offline(struct cgroup_subsys_state *css) { struct cpuset *cs = css_cs(css); cpuset_full_lock(); - if (!cpuset_v2() && is_sched_load_balance(cs)) - cpuset_update_flag(CS_SCHED_LOAD_BALANCE, cs, 0); - + cpuset1_offline_css(cs); cpuset_dec(); cpuset_full_unlock(); } @@ -4336,7 +4223,7 @@ int cpuset_num_cpus(struct cgroup *cgrp) int nr = num_online_cpus(); struct cpuset *cs; - if (is_in_v2_mode()) { + if (cpuset_v2()) { guard(rcu)(); cs = css_cs(cgroup_e_css(cgrp, &cpuset_cgrp_subsys)); if (cs)
diff --git a/kernel/cgroup/debug.c b/kernel/cgroup/debug.c index 883347b..aba243b 100644 --- a/kernel/cgroup/debug.c +++ b/kernel/cgroup/debug.c
@@ -45,13 +45,13 @@ static int current_css_set_read(struct seq_file *seq, void *v) struct cgroup_subsys_state *css; int i, refcnt; - if (!cgroup_kn_lock_live(of->kn, false)) + if (IS_ERR(cgroup_kn_lock_live(of->kn, false))) return -ENODEV; spin_lock_irq(&css_set_lock); cset = task_css_set(current); refcnt = refcount_read(&cset->refcount); - seq_printf(seq, "css_set %pK %d", cset, refcnt); + seq_printf(seq, "css_set %p %d", cset, refcnt); if (refcnt > cset->nr_tasks) seq_printf(seq, " +%d", refcnt - cset->nr_tasks); seq_puts(seq, "\n"); @@ -125,10 +125,10 @@ static int cgroup_css_links_read(struct seq_file *seq, void *v) * Print out the proc_cset and threaded_cset relationship * and highlight difference between refcount and task_count. */ - seq_printf(seq, "css_set %pK", cset); + seq_printf(seq, "css_set %p", cset); if (rcu_dereference_protected(cset->dom_cset, 1) != cset) { threaded_csets++; - seq_printf(seq, "=>%pK", cset->dom_cset); + seq_printf(seq, "=>%p", cset->dom_cset); } if (!list_empty(&cset->threaded_csets)) { struct css_set *tcset; @@ -137,7 +137,7 @@ static int cgroup_css_links_read(struct seq_file *seq, void *v) list_for_each_entry(tcset, &cset->threaded_csets, threaded_csets_node) { seq_puts(seq, idx ? "," : "<="); - seq_printf(seq, "%pK", tcset); + seq_printf(seq, "%p", tcset); idx++; } } else { @@ -206,8 +206,8 @@ static int cgroup_subsys_states_read(struct seq_file *seq, void *v) int i; cgrp = cgroup_kn_lock_live(of->kn, false); - if (!cgrp) - return -ENODEV; + if (IS_ERR(cgrp)) + return PTR_ERR(cgrp); for_each_subsys(ss, i) { css = rcu_dereference_check(cgrp->subsys[ss->id], true); @@ -254,8 +254,8 @@ static int cgroup_masks_read(struct seq_file *seq, void *v) struct cgroup *cgrp; cgrp = cgroup_kn_lock_live(of->kn, false); - if (!cgrp) - return -ENODEV; + if (IS_ERR(cgrp)) + return PTR_ERR(cgrp); cgroup_masks_read_one(seq, "subtree_control", cgrp->subtree_control); cgroup_masks_read_one(seq, "subtree_ss_mask", cgrp->subtree_ss_mask);
diff --git a/kernel/cgroup/dmem.c b/kernel/cgroup/dmem.c index 4683f3d..10e148d 100644 --- a/kernel/cgroup/dmem.c +++ b/kernel/cgroup/dmem.c
@@ -706,8 +706,8 @@ EXPORT_SYMBOL_GPL(dmem_cgroup_uncharge); * * When this function fails with -EAGAIN and @ret_limit_pool is non-null, it * will be set to the pool for which the limit is hit. This can be used for - * eviction as argument to dmem_cgroup_evict_valuable(). This reference must be freed - * with @dmem_cgroup_pool_state_put(). + * eviction as argument to dmem_cgroup_state_evict_valuable(). This reference + * must be freed with @dmem_cgroup_pool_state_put(). * * Return: 0 on success, -EAGAIN on hitting a limit, or a negative errno on failure. */
diff --git a/kernel/cgroup/freezer.c b/kernel/cgroup/freezer.c index 6c18854..35112d6 100644 --- a/kernel/cgroup/freezer.c +++ b/kernel/cgroup/freezer.c
@@ -20,10 +20,7 @@ static bool cgroup_update_frozen_flag(struct cgroup *cgrp, bool frozen) if (test_bit(CGRP_FROZEN, &cgrp->flags) == frozen) return false; - if (frozen) - set_bit(CGRP_FROZEN, &cgrp->flags); - else - clear_bit(CGRP_FROZEN, &cgrp->flags); + assign_bit(CGRP_FROZEN, &cgrp->flags, frozen); cgroup_file_notify(&cgrp->events_file); TRACE_CGROUP_PATH(notify_frozen, cgrp, frozen);
diff --git a/kernel/cgroup/namespace.c b/kernel/cgroup/namespace.c index ea4ee13..7666033 100644 --- a/kernel/cgroup/namespace.c +++ b/kernel/cgroup/namespace.c
@@ -53,8 +53,6 @@ struct cgroup_namespace *copy_cgroup_ns(u64 flags, struct ucounts *ucounts; struct css_set *cset; - BUG_ON(!old_ns); - if (!(flags & CLONE_NEWCGROUP)) { get_cgroup_ns(old_ns); return old_ns;
diff --git a/kernel/notifier.c b/kernel/notifier.c index 2f9fe7c..55fbd2b 100644 --- a/kernel/notifier.c +++ b/kernel/notifier.c
@@ -1,4 +1,5 @@ // SPDX-License-Identifier: GPL-2.0-only +#include <linux/device/devres.h> #include <linux/kdebug.h> #include <linux/kprobes.h> #include <linux/export.h> @@ -197,6 +198,58 @@ int atomic_notifier_chain_unregister(struct atomic_notifier_head *nh, } EXPORT_SYMBOL_GPL(atomic_notifier_chain_unregister); +struct atomic_notifier_chain_devres { + struct atomic_notifier_head *nh; + struct notifier_block *nb; +}; + +static void devm_atomic_notifier_chain_unregister(struct device *dev, void *res) +{ + struct atomic_notifier_chain_devres *dr = res; + + atomic_notifier_chain_unregister(dr->nh, dr->nb); +} + +/** + * devm_atomic_notifier_chain_register - Device-managed atomic notifier registration + * @dev: Device to tie the notifier lifetime to + * @nh: Pointer to head of the atomic notifier chain + * @nb: New entry in notifier chain + * + * Adds a notifier to an atomic notifier chain and registers a cleanup + * action to automatically unregister it when @dev is unbound. + * + * Must be called in process context. + * + * Return: + * 0 on success, negative errno on error. + */ +int devm_atomic_notifier_chain_register(struct device *dev, + struct atomic_notifier_head *nh, + struct notifier_block *nb) +{ + struct atomic_notifier_chain_devres *dr; + int ret; + + dr = devres_alloc(devm_atomic_notifier_chain_unregister, + sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + ret = atomic_notifier_chain_register(nh, nb); + if (ret) { + devres_free(dr); + return ret; + } + + dr->nh = nh; + dr->nb = nb; + devres_add(dev, dr); + + return 0; +} +EXPORT_SYMBOL_GPL(devm_atomic_notifier_chain_register); + /** * atomic_notifier_call_chain - Call functions in an atomic notifier chain * @nh: Pointer to head of the atomic notifier chain @@ -349,6 +402,58 @@ int blocking_notifier_call_chain_robust(struct blocking_notifier_head *nh, } EXPORT_SYMBOL_GPL(blocking_notifier_call_chain_robust); +struct blocking_notifier_chain_devres { + struct blocking_notifier_head *nh; + struct notifier_block *nb; +}; + +static void devm_blocking_notifier_chain_unregister(struct device *dev, + void *res) +{ + struct blocking_notifier_chain_devres *dr = res; + + blocking_notifier_chain_unregister(dr->nh, dr->nb); +} + +/** + * devm_blocking_notifier_chain_register - Device-managed blocking notifier registration + * @dev: Device to tie the notifier lifetime to + * @nh: Pointer to head of the blocking notifier chain + * @nb: New entry in notifier chain + * + * Adds a notifier to a blocking notifier chain and registers a cleanup + * action to automatically unregister it when @dev is unbound. + * Must be called in process context. + * + * Return: + * 0 on success, negative errno on error. + */ +int devm_blocking_notifier_chain_register(struct device *dev, + struct blocking_notifier_head *nh, + struct notifier_block *nb) +{ + struct blocking_notifier_chain_devres *dr; + int ret; + + dr = devres_alloc(devm_blocking_notifier_chain_unregister, + sizeof(*dr), GFP_KERNEL); + if (!dr) + return -ENOMEM; + + ret = blocking_notifier_chain_register(nh, nb); + if (ret) { + devres_free(dr); + return ret; + } + + dr->nh = nh; + dr->nb = nb; + devres_add(dev, dr); + + return 0; +} +EXPORT_SYMBOL_GPL(devm_blocking_notifier_chain_register); + /** * blocking_notifier_call_chain - Call functions in a blocking notifier chain * @nh: Pointer to head of the blocking notifier chain
diff --git a/kernel/padata.c b/kernel/padata.c index 0d3ea1b..5a113c6 100644 --- a/kernel/padata.c +++ b/kernel/padata.c
@@ -534,7 +534,7 @@ static void padata_init_reorder_list(struct parallel_data *pd) } } -/* Allocate and initialize the internal cpumask dependend resources. */ +/* Allocate and initialize the internal cpumask dependent resources. */ static struct parallel_data *padata_alloc_pd(struct padata_shell *ps, int offlining_cpu) {
diff --git a/kernel/power/qos.c b/kernel/power/qos.c index 1944dbe..c241da5 100644 --- a/kernel/power/qos.c +++ b/kernel/power/qos.c
@@ -159,7 +159,7 @@ static void pm_qos_flags_remove_req(struct pm_qos_flags *pqf, list_for_each_entry(req, &pqf->list, node) val |= req->flags; - pqf->effective_flags = val; + WRITE_ONCE(pqf->effective_flags, val); } /** @@ -193,7 +193,7 @@ bool pm_qos_update_flags(struct pm_qos_flags *pqf, req->flags = val; INIT_LIST_HEAD(&req->node); list_add_tail(&req->node, &pqf->list); - pqf->effective_flags |= val; + WRITE_ONCE(pqf->effective_flags, pqf->effective_flags | val); break; default: /* no action */
diff --git a/kernel/sched/ext/cid.c b/kernel/sched/ext/cid.c index 4b08866..a5330b7 100644 --- a/kernel/sched/ext/cid.c +++ b/kernel/sched/ext/cid.c
@@ -31,6 +31,7 @@ static struct scx_cid_tables *scx_cid_tables; /* used only during alloc/free */ #define SCX_CID_TOPO_NEG (struct scx_cid_topo) { \ .core_cid = -1, .core_idx = -1, .llc_cid = -1, .llc_idx = -1, \ .node_cid = -1, .node_idx = -1, .shard_cid = -1, .shard_idx = -1, \ + .cluster_cid = -1, .cluster_idx = -1, \ } /* @@ -182,12 +183,14 @@ s32 scx_cid_init(struct scx_sched *sch) cpumask_var_t to_walk __free(free_cpumask_var) = CPUMASK_VAR_NULL; cpumask_var_t node_scratch __free(free_cpumask_var) = CPUMASK_VAR_NULL; cpumask_var_t llc_scratch __free(free_cpumask_var) = CPUMASK_VAR_NULL; + cpumask_var_t cluster_scratch __free(free_cpumask_var) = CPUMASK_VAR_NULL; cpumask_var_t core_scratch __free(free_cpumask_var) = CPUMASK_VAR_NULL; cpumask_var_t llc_fallback __free(free_cpumask_var) = CPUMASK_VAR_NULL; cpumask_var_t online_no_topo __free(free_cpumask_var) = CPUMASK_VAR_NULL; struct scx_cid_tables *tbls; u32 next_cid = 0; s32 next_node_idx = 0, next_llc_idx = 0, next_core_idx = 0; + s32 next_cluster_idx = 0; s32 next_shard_idx = 0; u32 shard_size, max_cids; u32 notopo_in_shard; @@ -215,6 +218,7 @@ s32 scx_cid_init(struct scx_sched *sch) if (!zalloc_cpumask_var(&to_walk, GFP_KERNEL) || !zalloc_cpumask_var(&node_scratch, GFP_KERNEL) || !zalloc_cpumask_var(&llc_scratch, GFP_KERNEL) || + !zalloc_cpumask_var(&cluster_scratch, GFP_KERNEL) || !zalloc_cpumask_var(&core_scratch, GFP_KERNEL) || !zalloc_cpumask_var(&llc_fallback, GFP_KERNEL) || !zalloc_cpumask_var(&online_no_topo, GFP_KERNEL)) @@ -256,6 +260,7 @@ s32 scx_cid_init(struct scx_sched *sch) u32 cores_per_shard, nr_large; u32 shard_local = 0, cores_in_shard = 0, cids_in_shard = 0; s32 shard_cid, shard_idx; + s32 cluster_cid = -1, cluster_idx = -1; /* llc_scratch = node_scratch & this llc */ cpumask_and(llc_scratch, node_scratch, llc_mask); @@ -268,15 +273,32 @@ s32 scx_cid_init(struct scx_sched *sch) tbls->shard_node[shard_idx] = nid; while (!cpumask_empty(llc_scratch)) { - s32 lcpu = cpumask_first(llc_scratch); - const struct cpumask *sib = topology_sibling_cpumask(lcpu); - s32 core_cid = next_cid; - s32 core_idx = next_core_idx++; - s32 ccpu; + const struct cpumask *sib; + s32 core_cid, core_idx, lcpu, ccpu; u32 max_cores, cids_in_core; - /* core_scratch = llc_scratch & this core */ - cpumask_and(core_scratch, llc_scratch, sib); + /* + * Take the cores of one cluster before moving + * on, so that a cluster is a contiguous cid + * range like the core, LLC and node levels. + */ + if (cpumask_empty(cluster_scratch)) { + s32 xcpu = cpumask_first(llc_scratch); + + cpumask_or(cluster_scratch, topology_cluster_cpumask(xcpu), + topology_sibling_cpumask(xcpu)); + cpumask_and(cluster_scratch, cluster_scratch, llc_scratch); + cluster_cid = next_cid; + cluster_idx = next_cluster_idx++; + } + + lcpu = cpumask_first(cluster_scratch); + sib = topology_sibling_cpumask(lcpu); + core_cid = next_cid; + core_idx = next_core_idx++; + + /* core_scratch = cluster_scratch & this core */ + cpumask_and(core_scratch, cluster_scratch, sib); if (WARN_ON_ONCE(!cpumask_test_cpu(lcpu, core_scratch))) return -EINVAL; @@ -316,8 +338,11 @@ s32 scx_cid_init(struct scx_sched *sch) .node_idx = node_idx, .shard_cid = shard_cid, .shard_idx = shard_idx, + .cluster_cid = cluster_cid, + .cluster_idx = cluster_idx, }; + cpumask_clear_cpu(ccpu, cluster_scratch); cpumask_clear_cpu(ccpu, llc_scratch); cpumask_clear_cpu(ccpu, node_scratch); cpumask_clear_cpu(ccpu, to_walk); @@ -461,8 +486,8 @@ __bpf_kfunc_start_defs(); * starts must be strictly increasing with the first entry 0 and all values < * num_possible_cpus(). The last shard extends to num_possible_cpus() and no * shard may span more than SCX_CID_SHARD_MAX_CPUS cids. Topo info - * (core/LLC/node) is cleared and the shard layout is set from the input. On - * invalid input, abort the scheduler. + * (core/cluster/LLC/node) is cleared and the shard layout is set from the + * input. On invalid input, abort the scheduler. */ __bpf_kfunc void scx_bpf_cid_override(const s32 *cpu_to_cid__arena, u32 cpu_to_cid_cnt, const s32 *shard_start__arena, u32 shard_start_cnt, @@ -641,6 +666,29 @@ __bpf_kfunc s32 scx_bpf_cid_to_cpu(s32 cid, const struct bpf_prog_aux *aux) } /** + * scx_bpf_cid_node - Return the NUMA node the given @cid belongs to + * @cid: cid to look up + * @aux: implicit BPF argument to access bpf_prog_aux hidden from BPF progs + * + * Return NUMA_NO_NODE if @cid is invalid or there is no scheduler. Unlike + * scx_bpf_cpu_node(), this kfunc is available only with CID support, so BPF + * schedulers can use its presence to detect NUMA-aware CID lookups. + */ +__bpf_kfunc s32 scx_bpf_cid_node(s32 cid, const struct bpf_prog_aux *aux) +{ + struct scx_sched *sch; + s32 cpu; + + guard(rcu)(); + + sch = scx_prog_sched(aux); + if (unlikely(!sch)) + return NUMA_NO_NODE; + cpu = scx_cid_to_cpu(sch, cid); + return cpu < 0 ? NUMA_NO_NODE : cpu_to_node(cpu); +} + +/** * scx_bpf_cpu_to_cid - Return the cid for @cpu * @cpu: cpu to look up * @aux: implicit BPF argument to access bpf_prog_aux hidden from BPF progs @@ -958,6 +1006,7 @@ static const struct btf_kfunc_id_set scx_kfunc_set_init_cids = { BTF_KFUNCS_START(scx_kfunc_ids_cid) BTF_ID_FLAGS(func, scx_bpf_cid_to_cpu, KF_IMPLICIT_ARGS) +BTF_ID_FLAGS(func, scx_bpf_cid_node, KF_IMPLICIT_ARGS) BTF_ID_FLAGS(func, scx_bpf_cpu_to_cid, KF_IMPLICIT_ARGS) BTF_ID_FLAGS(func, scx_bpf_cid_topo, KF_IMPLICIT_ARGS) BTF_KFUNCS_END(scx_kfunc_ids_cid)
diff --git a/kernel/sched/ext/cid.h b/kernel/sched/ext/cid.h index 2fe2311..709afbf 100644 --- a/kernel/sched/ext/cid.h +++ b/kernel/sched/ext/cid.h
@@ -13,11 +13,12 @@ * kernel type sized for the maximum NR_CPUS (4k), with verbose helper sequences * for every op. * - * cids give every cpu a dense, topology-ordered id. CPUs sharing a core, LLC or - * NUMA node get contiguous cid ranges, so a topology unit becomes a (start, - * length) slice of cid space. Communication can pass a slice instead of a - * cpumask, and BPF code can process, for example, a u64 word's worth of cids at - * a time. + * cids give every cpu a dense, topology-ordered id. CPUs in each core, + * cluster, LLC or NUMA node get contiguous cid ranges, so a topology unit + * becomes a (start, length) slice of cid space. A core without a wider cluster + * level forms a cluster of its own. Communication can pass a slice + * instead of a cpumask, and BPF code can process, for example, a u64 word's + * worth of cids at a time. * * The mapping is built once at root scheduler enable time by walking the * topology of online cpus only. Going by online cpus is out of necessity:
diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c index 2b62397..9bae826 100644 --- a/kernel/sched/ext/ext.c +++ b/kernel/sched/ext/ext.c
@@ -24,9 +24,41 @@ DEFINE_RAW_SPINLOCK(scx_sched_lock); -bool scx_allow_proxy_exec(const struct task_struct *p) +/* + * Block a retained proxy donor, telling put_prev_task_scx() that the donor is + * about to be dequeued and must not be reenqueued. + */ +static void scx_block_proxy_donor(struct rq *rq, struct task_struct *p) { - return true; + rq->scx.flags |= SCX_RQ_PROXY_BLOCKING; + sched_proxy_block_task(rq, p); + rq->scx.flags &= ~SCX_RQ_PROXY_BLOCKING; +} + +bool __scx_allow_proxy_exec(const struct task_struct *p) +{ + struct scx_sched *sch; + + if (p->sched_class != &ext_sched_class) + return true; + + sch = scx_task_sched(p); + return !sch || (sch->ops.flags & SCX_OPS_ENQ_BLOCKED); +} + +/* + * End retained proxy execution before changing @p's BPF scheduler ownership. + * Called with @p's pi and rq locks held immediately before + * sched_change_begin(). The caller must pass DEQUEUE_NOCLOCK so the rq clock + * is updated only once. + */ +void scx_prepare_task_sched_change(struct task_struct *p) +{ + lockdep_assert_held(&p->pi_lock); + lockdep_assert_rq_held(task_rq(p)); + + update_rq_clock(task_rq(p)); + scx_block_proxy_donor(task_rq(p), p); } /* @@ -46,10 +78,21 @@ struct scx_sched __rcu *scx_root; LIST_HEAD(scx_sched_all); #ifdef CONFIG_EXT_SUB_SCHED +static __always_inline int scx_sched_cmpfn(struct rhashtable_compare_arg *arg, + const void *ptr) +{ + const struct scx_sched *sch = ptr; + + BUILD_BUG_ON(sizeof_field(struct scx_sched, ops.sub_cgroup_id) != sizeof(u64)); + + return sch->ops.sub_cgroup_id != *(const u64 *)arg->key; +} + const struct rhashtable_params scx_sched_hash_params = { .key_len = sizeof_field(struct scx_sched, ops.sub_cgroup_id), .key_offset = offsetof(struct scx_sched, ops.sub_cgroup_id), .head_offset = offsetof(struct scx_sched, hash_node), + .obj_cmpfn = scx_sched_cmpfn, .insecure_elasticity = true, /* inserted under scx_sched_lock */ }; @@ -57,10 +100,20 @@ struct rhashtable scx_sched_hash; #endif /* see SCX_OPS_TID_TO_TASK */ +static __always_inline int scx_tid_cmpfn(struct rhashtable_compare_arg *arg, const void *ptr) +{ + const struct sched_ext_entity *scx = ptr; + + BUILD_BUG_ON(sizeof_field(struct sched_ext_entity, tid) != sizeof(u64)); + + return scx->tid != *(const u64 *)arg->key; +} + static const struct rhashtable_params scx_tid_hash_params = { .key_len = sizeof_field(struct sched_ext_entity, tid), .key_offset = offsetof(struct sched_ext_entity, tid), .head_offset = offsetof(struct sched_ext_entity, tid_hash_node), + .obj_cmpfn = scx_tid_cmpfn, .insecure_elasticity = true, /* inserted/removed under scx_tasks_lock */ }; static struct rhashtable scx_tid_hash; @@ -194,10 +247,20 @@ static DEFINE_PER_CPU(struct scx_tid_alloc, scx_tid_alloc); */ static DEFINE_PER_CPU(struct task_struct *, direct_dispatch_task); +static __always_inline int dsq_cmpfn(struct rhashtable_compare_arg *arg, const void *ptr) +{ + const struct scx_dispatch_q *dsq = ptr; + + BUILD_BUG_ON(sizeof_field(struct scx_dispatch_q, id) != sizeof(u64)); + + return dsq->id != *(const u64 *)arg->key; +} + static const struct rhashtable_params dsq_hash_params = { .key_len = sizeof_field(struct scx_dispatch_q, id), .key_offset = offsetof(struct scx_dispatch_q, id), .head_offset = offsetof(struct scx_dispatch_q, hash_node), + .obj_cmpfn = dsq_cmpfn, }; static LLIST_HEAD(dsqs_to_free); @@ -327,7 +390,6 @@ static const struct sched_class *scx_setscheduler_class(struct task_struct *p) static struct scx_dispatch_q *bypass_enq_target_dsq(struct scx_sched *sch, s32 cpu) { -#ifdef CONFIG_EXT_SUB_SCHED /* * If @sch is a sub-sched which is bypassing, its tasks should go into * the bypass DSQs of the nearest ancestor which is not bypassing. The @@ -339,11 +401,7 @@ static struct scx_dispatch_q *bypass_enq_target_dsq(struct scx_sched *sch, s32 c * are re-enqueued after scx_bypassing() is turned on, guaranteeing that * all tasks are transferred to the right DSQs. */ - while (scx_parent(sch) && scx_bypassing(sch, cpu)) - sch = scx_parent(sch); -#endif /* CONFIG_EXT_SUB_SCHED */ - - return scx_bypass_dsq(sch, cpu); + return scx_bypass_dsq(scx_exec_sched(sch, cpu), cpu); } /** @@ -379,28 +437,28 @@ static bool rq_is_open(struct rq *rq, u64 enq_flags) */ /* - * If we're in the dispatch path holding rq lock, $curr may or may not + * If we're in the dispatch path holding rq lock, $donor may or may not * be ready depending on whether the on-going dispatch decides to extend - * $curr's slice. We say yes here and resolve it at the end of dispatch. + * $donor's slice. We say yes here and resolve it at the end of dispatch. * See dispatch_one(). */ if (rq->scx.flags & SCX_RQ_IN_DISPATCH) return true; /* - * %SCX_ENQ_PREEMPT clears $curr's slice if on SCX and kicks dispatch, + * The preemption flags clear $donor's slice if on SCX and kick dispatch, * so allow it to avoid spuriously triggering reenq on a combined * PREEMPT|IMMED insertion. */ - if (enq_flags & SCX_ENQ_PREEMPT) { - struct task_struct *curr = rq->curr; + if (enq_flags & (SCX_ENQ_PREEMPT | SCX_ENQ_PREEMPT_LAZY)) { + struct task_struct *donor = rq->donor; /* * A protected slice refuses the preemption and the cpu stays * occupied. See rq_owned_post_enq(). */ - return curr->sched_class != &ext_sched_class || - likely(!(curr->scx.flags & SCX_TASK_PROTECTED)); + return donor->sched_class != &ext_sched_class || + likely(!(donor->scx.flags & SCX_TASK_PROTECTED)); } /* @@ -497,11 +555,13 @@ enum scx_dsq_iter_flags { /* iterate in the reverse dispatch order */ SCX_DSQ_ITER_REV = 1U << 16, + __SCX_DSQ_ITER_HAS_REENQ = 1U << 29, __SCX_DSQ_ITER_HAS_SLICE = 1U << 30, __SCX_DSQ_ITER_HAS_VTIME = 1U << 31, __SCX_DSQ_ITER_USER_FLAGS = SCX_DSQ_ITER_REV, __SCX_DSQ_ITER_ALL_FLAGS = __SCX_DSQ_ITER_USER_FLAGS | + __SCX_DSQ_ITER_HAS_REENQ | __SCX_DSQ_ITER_HAS_SLICE | __SCX_DSQ_ITER_HAS_VTIME, }; @@ -1092,8 +1152,63 @@ static void schedule_deferred_locked(struct rq *rq) schedule_deferred(rq); } +#ifdef CONFIG_NO_HZ_FULL +static void scx_proxy_tick_bal_cb(struct rq *rq) +{ + sched_update_tick_dependency(rq); +} + +static void scx_proxy_update_tick(struct rq *rq, struct task_struct *next) +{ + bool proxy = next != rq->donor; + bool was_proxy = rq->scx.flags & SCX_RQ_PROXY_TICK; + + if (likely(proxy == was_proxy)) + return; + + if (proxy) { + /* Keep proxy execution tick-driven for now. */ + rq->scx.flags |= SCX_RQ_PROXY_TICK; + tick_nohz_dep_set_cpu(cpu_of(rq), TICK_DEP_BIT_SCHED); + } else { + rq->scx.flags &= ~SCX_RQ_PROXY_TICK; + /* + * The selected donor is already visible, but rq->curr still + * identifies the outgoing execution context. Reevaluate after + * context_switch() updates rq->curr so sched_can_stop_tick() sees + * the complete selection. + */ + queue_balance_callback(rq, &rq->scx.proxy_tick_bal_cb, + scx_proxy_tick_bal_cb); + } +} +#endif + +/* + * Complete sched_ext bookkeeping after proxy resolution and retry tasks which + * couldn't be reenqueued by an earlier reject DSQ drain. + */ void scx_proxy_reenqueue_retry(struct rq *rq, struct task_struct *next) { + lockdep_assert_rq_held(rq); + +#ifdef CONFIG_NO_HZ_FULL + if (scx_enabled() && tick_nohz_full_cpu(cpu_of(rq))) + scx_proxy_update_tick(rq, next); +#endif + + /* + * A higher priority class may wake up while @rq is transiently idle + * for proxy resolution. wakeup_preempt_scx() isn't invoked in that + * case, so reenqueue IMMED donors parked on the local DSQ here. + */ + if (rq->scx.nr_immed && sched_class_above(rq->next_class, &ext_sched_class)) + scx_schedule_reenq_local(rq, 0); + + if (rq->scx.flags & SCX_RQ_PROXY_RETRY) { + rq->scx.flags &= ~SCX_RQ_PROXY_RETRY; + schedule_deferred_locked(rq); + } } void schedule_dsq_reenq(struct scx_sched *sch, struct scx_dispatch_q *dsq, @@ -1112,6 +1227,18 @@ void schedule_dsq_reenq(struct scx_sched *sch, struct scx_dispatch_q *dsq, rq = container_of(dsq, struct rq, scx.local_dsq); /* + * An inactive cpu's local DSQ holds only tasks that are bound + * to it or are being moved off, so a reenq of it is pointless. + * Once balance push is installed, queue_balance_callback() also + * drops the callback that would run a reenq requested from + * dispatch, and irq_work_queue_on() can't reach an offline cpu. + * The reenq's node would then stay on this rq's list after + * @sch's pcpu is freed. + */ + if (unlikely(!cpu_active(cpu_of(rq)))) + return; + + /* * A sub-sched lacking baseline access on the target cid has no * business triggering IPIs. The lockless test is fine: slipping * through right after a revoke is harmless and a wrong denial @@ -1144,7 +1271,7 @@ void schedule_dsq_reenq(struct scx_sched *sch, struct scx_dispatch_q *dsq, } else if (!(dsq->id & SCX_DSQ_FLAG_BUILTIN)) { rq = this_rq(); - struct scx_dsq_pcpu *dsq_pcpu = per_cpu_ptr(dsq->pcpu, cpu_of(rq)); + struct scx_dsq_pcpu *dsq_pcpu = per_cpu_ptr(dsq->pcpu_user, cpu_of(rq)); struct scx_deferred_reenq_user *dru = &dsq_pcpu->deferred_reenq_user; /* @@ -1167,7 +1294,9 @@ void schedule_dsq_reenq(struct scx_sched *sch, struct scx_dispatch_q *dsq, WRITE_ONCE(dru->flags, dru->flags | reenq_flags); } } else { - scx_error(sch, "DSQ 0x%llx not allowed for reenq", dsq->id); + /* destroyed since the caller resolved it, nothing to reenq */ + if (READ_ONCE(dsq->id) != SCX_DSQ_INVALID) + scx_error(sch, "DSQ 0x%llx not allowed for reenq", dsq->id); return; } @@ -1411,20 +1540,27 @@ static void apply_slice_vtime(struct task_struct *p, u64 slice, u64 vtime, u64 e static void update_curr_scx(struct rq *rq) { - struct task_struct *curr = rq->curr; + struct task_struct *donor; s64 delta_exec; + /* + * update_curr_scx() is selected through rq->donor->sched_class, not + * rq->curr->sched_class, so @donor is always an EXT task here. If an EXT + * owner executes for a FAIR donor, FAIR's update_curr() runs instead. + */ + donor = rq->donor; + /* apply even on 0 delta_exec, callers may still act on the slice */ - apply_task_slice_oob(rq, curr); + apply_task_slice_oob(rq, donor); delta_exec = update_curr_common(rq); if (unlikely(delta_exec <= 0)) return; - if (curr->scx.slice != SCX_SLICE_INF) - curr->scx.slice -= min_t(u64, curr->scx.slice, delta_exec); + if (donor->scx.slice != SCX_SLICE_INF) + donor->scx.slice -= min_t(u64, donor->scx.slice, delta_exec); - if (unlikely(curr == scx_rescuee(rq))) + if (unlikely(donor == scx_rescuee(rq))) scx_rescue_charge(rq, delta_exec); dl_server_update(&rq->ext_server, delta_exec); @@ -1530,6 +1666,26 @@ static bool task_leave_custody(struct task_struct *p) return true; } +/* + * A task with an infinite slice may be running with its tick stopped. Lazy + * rescheduling doesn't send an IPI, so restore the tick dependency to guarantee + * that the lazy request is promoted by a real scheduler tick. Set the lazy + * request first so that the dependency update's IPI can also serve it on return + * to user space. + */ +static void scx_resched_curr_lazy(struct rq *rq) +{ + resched_curr_lazy(rq); + + if (rq->scx.flags & SCX_RQ_CAN_STOP_TICK) { + rq->scx.flags &= ~SCX_RQ_CAN_STOP_TICK; + if (rq->clock_update_flags < RQCF_UPDATED) + update_rq_clock(rq); + update_other_load_avgs(rq); + sched_update_tick_dependency(rq); + } +} + static void rq_owned_post_enq(struct scx_sched *sch, struct rq *rq, struct scx_dispatch_q *dsq, struct task_struct *p, u64 enq_flags) @@ -1538,8 +1694,10 @@ static void rq_owned_post_enq(struct scx_sched *sch, struct rq *rq, SCX_CALL_OP_TASK(sch, dequeue, rq, p, 0); /* - * Only local inserts get the wakeup treatment below. Rejects kick the - * deferred reenq and rescue parks are paced by the rescue timer. + * Only local inserts get the wakeup treatment below. Rejects kick a + * deferred reenq and rescue parks are paced by the rescue timer. Proxy + * rejects which aren't ready when drained request a later retry from + * scx_proxy_reenqueue_retry(). */ if (unlikely(dsq->id != SCX_DSQ_LOCAL)) { if (dsq->id == SCX_DSQ_REJECT) @@ -1593,12 +1751,16 @@ static void rq_owned_post_enq(struct scx_sched *sch, struct rq *rq, if (rq->scx.flags & SCX_RQ_IN_DISPATCH) return; - if ((enq_flags & SCX_ENQ_PREEMPT) && p != rq->curr && - rq->curr->sched_class == &ext_sched_class) { - if (likely(scx_set_task_slice(rq->curr, 0))) - resched_curr(rq); - else + if ((enq_flags & (SCX_ENQ_PREEMPT | SCX_ENQ_PREEMPT_LAZY)) && + p != rq->donor && rq->donor->sched_class == &ext_sched_class) { + if (likely(scx_set_task_slice(rq->donor, 0))) { + if (enq_flags & SCX_ENQ_PREEMPT) + resched_curr(rq); + else + scx_resched_curr_lazy(rq); + } else { __scx_add_event(sch, SCX_EV_SLICE_DENIED, 1); + } } } @@ -1606,12 +1768,10 @@ static void scx_dispatch_enqueue(struct scx_sched *sch, struct rq *rq, struct scx_dispatch_q *dsq, struct task_struct *p, u64 slice, u64 vtime, u64 enq_flags) { - bool is_rq_owned = false; + bool is_rq_owned = dsq_is_rq_owned(dsq); - if (dsq->id == SCX_DSQ_LOCAL) { + if (dsq->id == SCX_DSQ_LOCAL) dsq = scx_resolve_local_dsq(sch, rq, p, &enq_flags); - is_rq_owned = true; - } WARN_ON_ONCE(p->scx.dsq || !list_empty(&p->scx.dsq_list.node)); WARN_ON_ONCE((p->scx.dsq_flags & SCX_TASK_DSQ_ON_PRIQ) || @@ -1688,7 +1848,7 @@ static void scx_dispatch_enqueue(struct scx_sched *sch, struct rq *rq, scx_error(sch, "DSQ ID 0x%016llx already had PRIQ-enqueued tasks", dsq->id); - if (enq_flags & (SCX_ENQ_HEAD | SCX_ENQ_PREEMPT)) { + if (enq_flags & (SCX_ENQ_HEAD | SCX_ENQ_PREEMPT | SCX_ENQ_PREEMPT_LAZY)) { /* new task inserted at head - use fastpath */ if (dsq_insert_head(dsq, p) && !(dsq->id & SCX_DSQ_FLAG_BUILTIN)) rcu_assign_pointer(dsq->first_task, p); @@ -1762,6 +1922,7 @@ void scx_task_unlink_from_dsq(struct task_struct *p, struct scx_dispatch_q *dsq) RB_CLEAR_NODE(&p->scx.dsq_priq); p->scx.dsq_flags &= ~SCX_TASK_DSQ_ON_PRIQ; } + p->scx.dsq_flags &= ~SCX_TASK_DSQ_REENQ; list_del_init(&p->scx.dsq_list.node); dsq_dec_nr(dsq, p); @@ -1790,10 +1951,10 @@ void scx_dispatch_dequeue(struct rq *rq, struct task_struct *p) list_del_init(&p->scx.dsq_list.node); /* - * When dispatching directly from the BPF scheduler to a local - * DSQ, the task isn't associated with any DSQ but - * @p->scx.holding_cpu may be set under the protection of - * %SCX_OPSS_DISPATCHING. + * When dispatch_to_local_dsq() or remote consumption moves a + * task to a local DSQ, the task isn't associated with any DSQ + * but @p->scx.holding_cpu may be set. Clearing holding_cpu + * tells dispatch_to_local_dsq() that it lost to a dequeue. */ if (p->scx.holding_cpu >= 0) p->scx.holding_cpu = -1; @@ -1813,10 +1974,10 @@ void scx_dispatch_dequeue(struct rq *rq, struct task_struct *p) scx_task_unlink_from_dsq(p, dsq); } else { /* - * We're racing against dispatch_to_local_dsq() which already - * removed @p from @dsq and set @p->scx.holding_cpu. Clear the - * holding_cpu which tells dispatch_to_local_dsq() that it lost - * the race. + * We're racing against unlink_dsq_and_switch_rq_lock(), + * which already removed @p from @dsq and set + * @p->scx.holding_cpu. Clear holding_cpu to tell + * unlink_dsq_and_switch_rq_lock() that it lost the race. */ WARN_ON_ONCE(!list_empty(&p->scx.dsq_list.node)); p->scx.holding_cpu = -1; @@ -1999,6 +2160,12 @@ bool scx_rq_online(struct rq *rq) void scx_do_enqueue_task(struct rq *rq, struct task_struct *p, u64 enq_flags, int sticky_cpu) { + enum { + ENQ_ACTION_NONE, + ENQ_ACTION_DIRECT, + ENQ_ACTION_LOCAL_NOREFILL, + ENQ_ACTION_ENQUEUE, + } action = ENQ_ACTION_NONE; struct scx_sched *sch = scx_task_sched(p); struct task_struct **ddsp_taskp; struct scx_dispatch_q *dsq; @@ -2032,7 +2199,7 @@ void scx_do_enqueue_task(struct rq *rq, struct task_struct *p, u64 enq_flags, __scx_exit(sch, SCX_EXIT_ERROR_REENQ, 0, cpu_of(rq), "%s[%d] reenqueued %u times without running", p->comm, p->pid, p->scx.reenq_cnt); - return; + goto out; } } @@ -2052,19 +2219,28 @@ void scx_do_enqueue_task(struct rq *rq, struct task_struct *p, u64 enq_flags, if (p->scx.ddsp_dsq_id != SCX_DSQ_INVALID) goto direct; - /* see %SCX_OPS_ENQ_EXITING */ - if (!(sch->ops.flags & SCX_OPS_ENQ_EXITING) && - unlikely(p->flags & PF_EXITING)) { - __scx_add_event(sch, SCX_EV_ENQ_SKIP_EXITING, 1); - enq_flags |= SCX_ENQ_RESCUE; /* avoid looping on cap rejection */ - goto local; - } + /* + * A full wakeup enqueue happens before is_blocked is cleared. Don't + * report it as another blocked-donor admission. + */ + if ((sch->ops.flags & SCX_OPS_ENQ_BLOCKED) && p->is_blocked && + !(enq_flags & SCX_ENQ_WAKEUP)) { + enq_flags |= SCX_ENQ_BLOCKED; + } else { + /* see %SCX_OPS_ENQ_EXITING */ + if (unlikely(p->flags & PF_EXITING) && + !(sch->ops.flags & SCX_OPS_ENQ_EXITING)) { + __scx_add_event(sch, SCX_EV_ENQ_SKIP_EXITING, 1); + enq_flags |= SCX_ENQ_RESCUE; /* avoid looping on cap rejection */ + goto local; + } - /* see %SCX_OPS_ENQ_MIGRATION_DISABLED */ - if (!(sch->ops.flags & SCX_OPS_ENQ_MIGRATION_DISABLED) && - is_migration_disabled(p)) { - __scx_add_event(sch, SCX_EV_ENQ_SKIP_MIGRATION_DISABLED, 1); - goto local; + /* see %SCX_OPS_ENQ_MIGRATION_DISABLED */ + if (!(sch->ops.flags & SCX_OPS_ENQ_MIGRATION_DISABLED) && + is_migration_disabled(p)) { + __scx_add_event(sch, SCX_EV_ENQ_SKIP_MIGRATION_DISABLED, 1); + goto local; + } } if (unlikely(!SCX_HAS_OP(sch, enqueue))) @@ -2103,14 +2279,14 @@ void scx_do_enqueue_task(struct rq *rq, struct task_struct *p, u64 enq_flags, * dequeue may be waiting. The store_release matches their load_acquire. */ atomic_long_set_release(&p->scx.ops_state, SCX_OPSS_QUEUED | qseq); - return; + goto out; direct: - direct_dispatch(sch, p, enq_flags); - return; + action = ENQ_ACTION_DIRECT; + goto out; local_norefill: - scx_dispatch_enqueue(sch, rq, &rq->scx.local_dsq, p, 0, 0, enq_flags); - return; + action = ENQ_ACTION_LOCAL_NOREFILL; + goto out; local: dsq = &rq->scx.local_dsq; goto enqueue; @@ -2122,9 +2298,27 @@ void scx_do_enqueue_task(struct rq *rq, struct task_struct *p, u64 enq_flags, goto enqueue; enqueue: - refill_task_slice_dfl(sch, p); - clear_direct_dispatch(p); - scx_dispatch_enqueue(sch, rq, dsq, p, 0, 0, enq_flags); + action = ENQ_ACTION_ENQUEUE; +out: + /* The reason is input to ops.enqueue(), not to the resulting placement. */ + p->scx.flags &= ~SCX_TASK_REENQ_REASON_MASK; + + switch (action) { + case ENQ_ACTION_DIRECT: + direct_dispatch(sch, p, enq_flags); + break; + case ENQ_ACTION_LOCAL_NOREFILL: + scx_dispatch_enqueue(sch, rq, &rq->scx.local_dsq, p, 0, 0, + enq_flags); + break; + case ENQ_ACTION_ENQUEUE: + refill_task_slice_dfl(sch, p); + clear_direct_dispatch(p); + scx_dispatch_enqueue(sch, rq, dsq, p, 0, 0, enq_flags); + break; + case ENQ_ACTION_NONE: + break; + } } static bool task_runnable(const struct task_struct *p) @@ -2187,13 +2381,14 @@ static void enqueue_task_scx(struct rq *rq, struct task_struct *p, int core_enq_ rq->scx.flags |= SCX_RQ_IN_WAKEUP; /* - * Restoring a running task will be immediately followed by - * set_next_task_scx() which expects the task to not be on the BPF + * Restoring the current scheduling context will be immediately followed + * by set_next_task_scx() which expects the task to not be on the BPF * scheduler as tasks can only start running through local DSQs. Force * direct-dispatch into the local DSQ by setting the sticky_cpu. Mark * IGNORE_CAPS to force entry into the local DSQ. */ - if (unlikely(enq_flags & ENQUEUE_RESTORE) && task_current(rq, p)) { + if (unlikely(enq_flags & ENQUEUE_RESTORE) && + task_current_donor(rq, p)) { sticky_cpu = cpu_of(rq); enq_flags |= SCX_ENQ_IGNORE_CAPS; } @@ -2321,10 +2516,10 @@ static bool dequeue_task_scx(struct rq *rq, struct task_struct *p, int core_deq_ ops_dequeue(rq, p, deq_flags); /* - * A currently running task which is going off @rq first gets dequeued - * and then stops running. As we want running <-> stopping transitions - * to be contained within runnable <-> quiescent transitions, trigger - * ->stopping() early here instead of in put_prev_task_scx(). + * A current scheduling context which is going off @rq first gets + * dequeued and then stops running. As we want running <-> stopping + * transitions to be contained within runnable <-> quiescent transitions, + * trigger ->stopping() early here instead of in put_prev_task_scx(). * * @p may go through multiple stopping <-> running transitions between * here and put_prev_task_scx() if task attribute changes occur while @@ -2332,11 +2527,13 @@ static bool dequeue_task_scx(struct rq *rq, struct task_struct *p, int core_deq_ * information meaningful to the BPF scheduler and can be suppressed by * skipping the callbacks if the task is !QUEUED. */ - if (task_current(rq, p) && - (SCX_HAS_OP(sch, stopping) || unlikely(p == scx_rescuee(rq)))) { - update_curr_scx(rq); - if (SCX_HAS_OP(sch, stopping)) - SCX_CALL_OP_TASK(sch, stopping, rq, p, false); + if (task_current_donor(rq, p) && (p->scx.flags & SCX_TASK_RUN_TRACKED)) { + if (SCX_HAS_OP(sch, stopping) || unlikely(p == scx_rescuee(rq))) { + update_curr_scx(rq); + if (SCX_HAS_OP(sch, stopping)) + SCX_CALL_OP_TASK(sch, stopping, rq, p, false); + } + p->scx.flags &= ~SCX_TASK_RUN_TRACKED; } if (SCX_HAS_OP(sch, quiescent) && !task_on_rq_migrating(p)) @@ -2352,9 +2549,10 @@ static bool dequeue_task_scx(struct rq *rq, struct task_struct *p, int core_deq_ sub_nr_running(rq, 1); scx_dispatch_dequeue(rq, p); + p->scx.flags &= ~SCX_TASK_REENQ_REASON_MASK; /* see scx_task_slice_ended() for the save/restore exception */ - if (!((deq_flags & DEQUEUE_SAVE) && task_current(rq, p))) + if (!((deq_flags & DEQUEUE_SAVE) && task_current_donor(rq, p))) scx_task_slice_ended(rq, p); clear_direct_dispatch(p); @@ -2394,10 +2592,23 @@ static void wakeup_preempt_scx(struct rq *rq, struct task_struct *p, int wake_fl /* * Preemption between SCX tasks is implemented by resetting the victim * task's slice to 0 and triggering reschedule on the target CPU. - * Nothing to do. + * + * A retained proxy donor can wake through ttwu_runnable() without another + * ops.enqueue(). WF_TTWU_RQ identifies this path. Request rescheduling so + * that ops.dispatch() can reconsider the task after ttwu_runnable() clears + * is_blocked. A full wakeup activation has already enqueued the task and + * doesn't need the additional reschedule. */ - if (p->sched_class == &ext_sched_class) + if (p->sched_class == &ext_sched_class) { + if (sched_proxy_exec() && (wake_flags & WF_TTWU_RQ) && + p->is_blocked) { + struct scx_sched *sch = scx_task_sched(p); + + if (sch && (sch->ops.flags & SCX_OPS_ENQ_BLOCKED)) + resched_curr(rq); + } return; + } /* * Getting preempted by a higher-priority class. Reenqueue IMMED tasks. @@ -2425,7 +2636,7 @@ void scx_move_local_task_to_local_dsq(struct scx_sched *sch, struct task_struct dst_dsq = scx_resolve_local_dsq(sch, dst_rq, p, &enq_flags); - if (enq_flags & (SCX_ENQ_HEAD | SCX_ENQ_PREEMPT)) + if (enq_flags & (SCX_ENQ_HEAD | SCX_ENQ_PREEMPT | SCX_ENQ_PREEMPT_LAZY)) dsq_insert_head(dst_dsq, p); else list_add_tail(&p->scx.dsq_list.node, &dst_dsq->list); @@ -2495,8 +2706,10 @@ static void move_remote_task_to_local_dsq(struct scx_sched *sch, * - The BPF scheduler is bypassed while the rq is offline and we can always say * no to the BPF scheduler initiated migrations while offline. * - * The caller must ensure that @p and @rq are on different CPUs. - * If enforce == true, caller must hold @p's rq lock. + * The caller must ensure that @p and @rq are on different CPUs. If @enforce is + * true, report violations attributable to BPF-directed migrations. The caller + * must hold @p's rq lock to avoid reporting a transient race as a scheduler + * error. */ static bool task_can_run_on_remote_rq(struct scx_sched *sch, struct task_struct *p, struct rq *rq, @@ -2504,17 +2717,27 @@ static bool task_can_run_on_remote_rq(struct scx_sched *sch, { s32 cpu = cpu_of(rq); - /* - * To prevent races with @p still running on its old CPU while switching - * out, make sure we're holding @p's rq lock so as not to risk - * erroneously killing the BPF scheduler. - */ if (enforce) lockdep_assert_rq_held(task_rq(p)); WARN_ON_ONCE(task_cpu(p) == cpu); /* + * proxy_set_task_cpu() preserves wake_cpu when moving a donor's scheduling + * context to its lock owner's rq. For example, if BPF places donor D on + * CPU0 while its lock owner runs on CPU1, proxy execution moves D to CPU1 + * but leaves D->wake_cpu pointing to CPU0. If D is later put on a shared + * DSQ, CPU0 could otherwise consume it and move it back, only for proxy + * execution to return it to CPU1 again. + * + * When task_cpu() == wake_cpu, the donor has not been proxy-migrated and + * BPF may still choose its placement. An actively donating task is + * rejected separately by task_proxy_running_or_donating(). + */ + if (sched_proxy_exec() && p->is_blocked && task_cpu(p) != p->wake_cpu) + return false; + + /* * If @p has migration disabled, @p->cpus_ptr is updated to contain only * the pinned CPU in migrate_disable_switch() while @p is being switched * out. However, put_prev_task_scx() is called before @p->cpus_ptr is @@ -2555,6 +2778,64 @@ static bool task_can_run_on_remote_rq(struct scx_sched *sch, return true; } +/* + * Proxy execution can change @p's execution and migration-disabled state + * without touching its DSQ entry or clearing holding_cpu. Check those states + * with @p's rq locked. Without proxy execution, the holding_cpu handshake is + * sufficient and this must not affect the existing migration path. + * + * A BPF-directed transfer to a remote local DSQ performs a normal task + * migration and thus cannot move a migration-disabled task. In contrast, + * proxy_migrate_task() moves only a blocked donor's scheduling context towards + * the mutex owner and preserves its execution home in wake_cpu. The latter is + * therefore allowed even when the donor is migration-disabled. + */ +static bool task_proxy_running_or_donating(struct task_struct *p) +{ + struct rq *src_rq = task_rq(p); + + lockdep_assert_rq_held(src_rq); + + if (!sched_proxy_exec()) + return false; + + /* @p may be rq->curr under another task's scheduling context. */ + if (task_on_cpu(src_rq, p)) + return true; + + /* Don't move an active scheduling context off its source rq. */ + if (task_current_donor(src_rq, p)) + return true; + + return false; +} + +static bool task_proxy_unsafe_to_move(struct task_struct *p) +{ + if (!sched_proxy_exec()) + return false; + + return task_proxy_running_or_donating(p) || is_migration_disabled(p); +} + +/* + * Park a task whose remote transfer raced with proxy execution. Reenqueueing + * from the source rq makes the task's owning scheduler choose its placement + * again and preserves sub-scheduler containment. + */ +static void scx_proxy_reject_task(struct scx_sched *sch, struct rq *rq, + struct task_struct *p, u64 enq_flags) +{ + lockdep_assert_rq_held(rq); + WARN_ON_ONCE(p->scx.flags & SCX_TASK_REENQ_REASON_MASK); + + p->scx.holding_cpu = -1; + p->scx.flags |= SCX_TASK_REENQ_PROXY; + scx_divert_strip_flags(p, &enq_flags); + + scx_dispatch_enqueue(sch, rq, &rq->scx.reject_dsq, p, 0, 0, enq_flags); +} + /** * unlink_dsq_and_switch_rq_lock() - Unlink task and switch to its rq lock * @p: target task @@ -2583,7 +2864,7 @@ static bool task_can_run_on_remote_rq(struct scx_sched *sch, * points to this CPU. See scx_dispatch_dequeue() for the counterpart. * * On return, @dsq is unlocked and @src_rq is locked. Returns %true if @p is - * still valid. %false if lost to dequeue. + * still valid and detached from @dsq. %false if lost to dequeue. */ static bool unlink_dsq_and_switch_rq_lock(struct task_struct *p, struct scx_dispatch_q *dsq, @@ -2604,6 +2885,13 @@ static bool unlink_dsq_and_switch_rq_lock(struct task_struct *p, /* task_rq couldn't have changed if we're still the holding cpu */ if (likely(p->scx.holding_cpu == cpu) && !WARN_ON_ONCE(src_rq != task_rq(p))) { + /* + * Keep ->dsq set until we own @src_rq so that a racing dequeue + * can find @dsq and clear holding_cpu. Once ownership is + * confirmed, clear it under @src_rq so that deactivate_task() + * takes the !dsq path instead of retaking @dsq->lock. + */ + p->scx.dsq = NULL; scx_wait_dispatching(p); return true; } @@ -2616,6 +2904,19 @@ static bool consume_remote_task(struct scx_sched *sch, struct rq *this_rq, struct scx_dispatch_q *dsq, struct rq *src_rq) { if (unlink_dsq_and_switch_rq_lock(p, dsq, this_rq, src_rq)) { + /* + * Proxy execution may have changed @p's running or + * migration-disabled state while switching rq locks without + * clearing holding_cpu. Park it on the source rq and let its + * owning scheduler choose its placement again. + */ + if (unlikely(task_proxy_unsafe_to_move(p))) { + p->scx.dsq = NULL; + scx_proxy_reject_task(sch, src_rq, p, enq_flags | SCX_ENQ_CLEAR_OPSS); + switch_rq_lock(src_rq, this_rq); + return false; + } + move_remote_task_to_local_dsq(sch, p, enq_flags, src_rq, this_rq); return true; } else { @@ -2655,6 +2956,19 @@ static struct rq *move_task_between_dsqs(struct scx_sched *sch, if (dst_dsq->id == SCX_DSQ_LOCAL) { dst_rq = container_of(dst_dsq, struct rq, scx.local_dsq); + /* + * Unlike the rq-lock handoff paths, @src_rq has been locked + * throughout this operation. Only active proxy state can race the + * move here; let the enforcing check below diagnose an ordinary + * migration-disabled task. + */ + if (src_rq != dst_rq && + unlikely(task_proxy_running_or_donating(p))) { + dispatch_dequeue_locked(p, src_dsq); + raw_spin_unlock(&src_dsq->lock); + scx_proxy_reject_task(sch, src_rq, p, enq_flags); + return src_rq; + } if (src_rq != dst_rq && unlikely(!task_can_run_on_remote_rq(sch, p, dst_rq, true))) { dst_dsq = find_global_dsq(sch, task_cpu(p)); @@ -2677,6 +2991,7 @@ static struct rq *move_task_between_dsqs(struct scx_sched *sch, raw_spin_unlock(&src_dsq->lock); scx_move_local_task_to_local_dsq(sch, p, enq_flags, dst_rq); } else { + dispatch_dequeue_locked(p, src_dsq); raw_spin_unlock(&src_dsq->lock); move_remote_task_to_local_dsq(sch, p, enq_flags, src_rq, dst_rq); } @@ -2811,6 +3126,7 @@ static void dispatch_to_local_dsq(struct scx_sched *sch, struct rq *rq, if (likely(p->scx.holding_cpu == raw_smp_processor_id()) && !WARN_ON_ONCE(src_rq != task_rq(p))) { bool fallback = false; + /* * If @p is staying on the same rq, there's no need to go * through the full deactivate/activate cycle. Optimize by @@ -2820,6 +3136,9 @@ static void dispatch_to_local_dsq(struct scx_sched *sch, struct rq *rq, p->scx.holding_cpu = -1; scx_dispatch_enqueue(sch, dst_rq, &dst_rq->scx.local_dsq, p, slice, vtime, enq_flags | SCX_ENQ_APPLY_SLICE); + } else if (unlikely(task_proxy_unsafe_to_move(p))) { + fallback = true; + scx_proxy_reject_task(sch, src_rq, p, enq_flags); } else if (unlikely(!task_can_run_on_remote_rq(sch, p, dst_rq, true))) { p->scx.holding_cpu = -1; fallback = true; @@ -2835,7 +3154,8 @@ static void dispatch_to_local_dsq(struct scx_sched *sch, struct rq *rq, } /* if the destination CPU is idle, wake it up */ - if (!fallback && sched_class_above(p->sched_class, dst_rq->curr->sched_class)) + if (!fallback && sched_class_above(p->sched_class, + dst_rq->donor->sched_class)) resched_curr(dst_rq); } @@ -3053,10 +3373,36 @@ static enum scx_dsp_verdict dispatch_one(struct rq *rq, struct task_struct *prev return verdict; } -static void set_next_task_scx(struct rq *rq, struct task_struct *p, enum snt_e type) +static void scx_start_task_running(struct rq *rq, struct task_struct *p) { struct scx_sched *sch = scx_task_sched(p); + if (p->scx.flags & SCX_TASK_RUN_TRACKED) + return; + + scx_cid_sched_update(rq, sch); + + if (SCX_HAS_OP(sch, running)) + SCX_CALL_OP_TASK(sch, running, rq, p); + + p->scx.flags |= SCX_TASK_RUN_TRACKED; +} + +static void set_next_task_scx(struct rq *rq, struct task_struct *p, enum snt_e type) +{ + bool first = type == SNT_PICK; + bool can_stop_tick; + + /* + * A blocked pick is provisional until proxy resolution completes, see + * put_prev_task_scx(). A retry can repick the same donor, so + * SNT_REPICK must set it again. + */ + rq->scx.flags &= ~SCX_RQ_PROXY_PENDING; + if (sched_proxy_exec() && p->is_blocked && + (type == SNT_PICK || type == SNT_REPICK)) + rq->scx.flags |= SCX_RQ_PROXY_PENDING; + if (type == SNT_REPICK) return; @@ -3067,18 +3413,31 @@ static void set_next_task_scx(struct rq *rq, struct task_struct *p, enum snt_e t */ ops_dequeue(rq, p, SCX_DEQ_CORE_SCHED_EXEC); scx_dispatch_dequeue(rq, p); + p->scx.flags &= ~SCX_TASK_REENQ_REASON_MASK; } p->se.exec_start = rq_clock_task(rq); - /* see dequeue_task_scx() on why we skip when !QUEUED */ - if (SCX_HAS_OP(sch, running) && (p->scx.flags & SCX_TASK_QUEUED)) - SCX_CALL_OP_TASK(sch, running, rq, p); + /* + * See dequeue_task_scx() for why we skip when !QUEUED. + * + * During a normal switch (@first), a blocked task is only a provisional + * donor. Proxy resolution may fail or migrate the donor to another CPU, + * so defer ops.running() until scx_proxy_donor_start() confirms that + * resolution succeeded. + * + * !@first denotes restoration after a SAVE/RESTORE cycle. The matching + * dequeue already issued ops.stopping(), so restart the session here + * regardless of the donor state. + */ + if ((p->scx.flags & SCX_TASK_QUEUED) && !(p->is_blocked && first)) + scx_start_task_running(rq, p); clr_task_runnable(p, true); /* apply any pending out-of-band slice request before the tick decision */ apply_task_slice_oob(rq, p); + can_stop_tick = p->scx.slice == SCX_SLICE_INF && !p->is_blocked; /* * @p is getting newly scheduled or got kicked after someone updated its @@ -3089,7 +3448,7 @@ static void set_next_task_scx(struct rq *rq, struct task_struct *p, enum snt_e t * nohz. In the future, we might want to add a mechanism to update * load_avgs periodically on tick-stopped CPUs. */ - if (p->scx.slice == SCX_SLICE_INF) { + if (can_stop_tick) { if (!(rq->scx.flags & SCX_RQ_CAN_STOP_TICK)) { /* * Bypass mode always assigns finite slices, so @p @@ -3110,7 +3469,8 @@ static void set_next_task_scx(struct rq *rq, struct task_struct *p, enum snt_e t /* * @rq still references the outgoing scheduling context. A finite - * slice is sufficient by itself to require the tick. + * slice or a blocked proxy donor is sufficient by itself to require + * the tick. */ if (tick_nohz_full_cpu(cpu_of(rq))) tick_nohz_dep_set_cpu(cpu_of(rq), TICK_DEP_BIT_SCHED); @@ -3119,6 +3479,13 @@ static void set_next_task_scx(struct rq *rq, struct task_struct *p, enum snt_e t void scx_proxy_donor_start(struct rq *rq) { + struct task_struct *donor = rq->donor; + + lockdep_assert_rq_held(rq); + rq->scx.flags &= ~SCX_RQ_PROXY_PENDING; + + if (donor->sched_class == &ext_sched_class && (donor->scx.flags & SCX_TASK_QUEUED)) + scx_start_task_running(rq, donor); } static enum scx_cpu_preempt_reason @@ -3176,8 +3543,13 @@ static void put_prev_task_scx(struct rq *rq, struct task_struct *p, struct task_struct *next) { struct scx_sched *sch = scx_task_sched(p); + bool proxy_put = p->is_blocked && next == rq->idle && + (rq->scx.flags & SCX_RQ_PROXY_PENDING); + bool proxy_block = rq->scx.flags & SCX_RQ_PROXY_BLOCKING; bool rescue_keep = false; + rq->scx.flags &= ~SCX_RQ_PROXY_PENDING; + /* see kick_sync_wait_bal_cb() */ smp_store_release(&rq->scx.kick_sync, rq->scx.kick_sync + 1); @@ -3194,29 +3566,51 @@ static void put_prev_task_scx(struct rq *rq, struct task_struct *p, scx_task_slice_ended(rq, p); } - /* see dequeue_task_scx() on why we skip when !QUEUED */ - if (SCX_HAS_OP(sch, stopping) && (p->scx.flags & SCX_TASK_QUEUED)) - SCX_CALL_OP_TASK(sch, stopping, rq, p, true); + /* + * Preserve the running session when proxy execution refreshes the same + * donor around an execution-context switch on this rq. + */ + if (next != p && (p->scx.flags & SCX_TASK_QUEUED) && + (p->scx.flags & SCX_TASK_RUN_TRACKED)) { + if (SCX_HAS_OP(sch, stopping)) + SCX_CALL_OP_TASK(sch, stopping, rq, p, !proxy_block); + + p->scx.flags &= ~SCX_TASK_RUN_TRACKED; + } if (p->scx.flags & SCX_TASK_QUEUED) { + if (proxy_block) + goto switch_class; + set_task_runnable(rq, p); /* + * If the donor is the same and only the mutex owner changes, + * avoid triggering another ops.enqueue(): the BPF scheduler has + * already admitted the donor, so it can continue running. + */ + if (p->is_blocked && next == p) + goto switch_class; + + /* * If @p has slice left and is being put, @p is getting * preempted by a higher priority scheduler class or core-sched * forcing a different task. Leave it at the head of the local * DSQ unless it was an IMMED task. IMMED tasks should not * linger on a busy CPU, reenqueue them to the BPF scheduler. * + * The exception is an IMMED donor put by proxy_resched_idle(): + * the CPU isn't busy, proxy resolution is only retrying through + * idle, so keep the donor where it can be picked again. + * * An open rescue must keep @p on the local DSQ even if the * scheduler zeroed the slice in ops.stopping() above. */ if ((p->scx.slice || unlikely(p == scx_rescuee(rq))) && !scx_bypassing(sch, cpu_of(rq))) { - if (p->scx.flags & SCX_TASK_IMMED) { + if ((p->scx.flags & SCX_TASK_IMMED) && !proxy_put) { p->scx.flags |= SCX_TASK_REENQ_PREEMPTED; scx_do_enqueue_task(rq, p, SCX_ENQ_REENQ, -1); - p->scx.flags &= ~SCX_TASK_REENQ_REASON_MASK; } else { u64 enq_flags = 0; @@ -3231,6 +3625,9 @@ static void put_prev_task_scx(struct rq *rq, struct task_struct *p, enq_flags |= SCX_ENQ_HEAD; } else { enq_flags |= SCX_ENQ_HEAD; + /* only require SCX_CAP_ENQ_IMMED, see scx_caps_for_enq() */ + if (proxy_put && (p->scx.flags & SCX_TASK_IMMED)) + enq_flags |= SCX_ENQ_IMMED; } scx_dispatch_enqueue(sch, rq, &rq->scx.local_dsq, p, 0, 0, @@ -3243,13 +3640,15 @@ static void put_prev_task_scx(struct rq *rq, struct task_struct *p, * If @p is runnable but we're about to enter a lower * sched_class, %SCX_OPS_ENQ_LAST must be set. Tell * ops.enqueue() that @p is the only one available for this cpu. - * This doesn't apply if the baseline access on the CPU is lost. + * This doesn't apply if the baseline access on the CPU is lost or + * proxy resolution temporarily switches to idle. * * Under core scheduling, a pick dispatches only when nothing is * locally runnable and can legitimately go idle with @p still * runnable (see do_pick_task_scx()). */ - if (next && sched_class_above(&ext_sched_class, next->sched_class) && + if (!proxy_put && next && + sched_class_above(&ext_sched_class, next->sched_class) && scx_task_can_stay_on_cpu(rq, p)) { WARN_ON_ONCE(!sched_core_enabled(rq) && !(sch->ops.flags & SCX_OPS_ENQ_LAST)); @@ -3270,8 +3669,10 @@ static void put_prev_task_scx(struct rq *rq, struct task_struct *p, } switch_class: - if (next && next->sched_class != &ext_sched_class) + if (next && next->sched_class != &ext_sched_class) { + scx_cid_sched_update(rq, NULL); switch_class(rq, next); + } } static void kick_sync_wait_bal_cb(struct rq *rq) @@ -3339,7 +3740,8 @@ static struct task_struct *first_local_task(struct rq *rq) } /* - * Run dispatch and queue the follow-up work for a pick. + * Run dispatch for a pick. The follow-up work is queued by do_pick_task_scx() + * once the pick is final. */ static enum scx_dsp_verdict dispatch_pick(struct rq *rq, struct rq_flags *rf, struct task_struct *prev) @@ -3349,18 +3751,6 @@ static enum scx_dsp_verdict dispatch_pick(struct rq *rq, struct rq_flags *rf, rq_unpin_lock(rq, rf); verdict = dispatch_one(rq, prev); rq_repin_lock(rq, rf); - maybe_queue_balance_callback(rq); - - /* - * Defer to a balance callback which can drop rq lock and enable IRQs. - * Waiting directly in the pick path would deadlock against CPUs sending - * us IPIs (e.g. TLB flushes) while we wait for them. - */ - if (unlikely(rq->scx.kick_sync_pending)) { - rq->scx.kick_sync_pending = false; - queue_balance_callback(rq, &rq->scx.kick_sync_bal_cb, - kick_sync_wait_bal_cb); - } return verdict; } @@ -3387,23 +3777,20 @@ static enum scx_dsp_verdict dispatch_core_pick(struct rq *rq, struct rq_flags *r verdict = dispatch_one(rq, prev); - if (cpu_of(rq) == smp_processor_id()) { - maybe_queue_balance_callback(rq); - - /* see dispatch_pick() */ - if (unlikely(rq->scx.kick_sync_pending)) { - rq->scx.kick_sync_pending = false; - queue_balance_callback(rq, &rq->scx.kick_sync_bal_cb, - kick_sync_wait_bal_cb); - } - } else if (unlikely(rq->scx.flags & SCX_RQ_BAL_CB_PENDING)) { - /* - * Balance callbacks must run in the context that queued them, - * so they can't be queued on another CPU's rq. Run the deferred - * work directly instead. - */ + /* + * A pick that returns a task isn't final under core scheduling: the + * selection goes on to pick the siblings, and their dispatch can + * release the rq lock, which can't happen with balance callbacks + * queued. Don't queue the deferred work as a balance callback, for this + * CPU or a sibling, and run it from irq_work instead. + * + * do_pick_task_scx() leaves %SCX_RQ_BAL_CB_PENDING alone under core + * scheduling, so that the early return above leaves it to the dispatch + * in flight, which handles it here. + */ + if (unlikely(rq->scx.flags & SCX_RQ_BAL_CB_PENDING)) { rq->scx.flags &= ~SCX_RQ_BAL_CB_PENDING; - run_deferred(rq); + schedule_deferred(rq); } rq_repin_lock(rq, rf); @@ -3425,22 +3812,33 @@ static enum scx_dsp_verdict dispatch_core_pick(struct rq *rq, struct rq_flags *r static struct task_struct * do_pick_task_scx(struct rq *rq, struct rq_flags *rf, bool force_scx) { - struct task_struct *prev = rq->curr; + struct task_struct *prev = rq->donor; + bool core_sched = sched_core_enabled(rq); enum scx_dsp_verdict verdict; struct task_struct *p; + /* A retry can abandon a provisional blocked-donor pick. */ + rq->scx.flags &= ~SCX_RQ_PROXY_PENDING; + /* see kick_sync_wait_bal_cb() */ smp_store_release(&rq->scx.kick_sync, rq->scx.kick_sync + 1); rq_modified_begin(rq, &ext_sched_class); - if (sched_core_enabled(rq)) + /* + * Core scheduling can get enabled while dispatch_pick() has the rq lock + * released. Stick to @core_sched, so that the follow-up work below + * matches the dispatch that ran. + */ + if (core_sched) verdict = dispatch_core_pick(rq, rf, prev); else verdict = dispatch_pick(rq, rf, prev); - if (verdict == SCX_DSP_RETRY) - return RETRY_TASK; + if (verdict == SCX_DSP_RETRY) { + p = RETRY_TASK; + goto out; + } /* * If any higher-priority sched class enqueued a runnable task on this @@ -3450,8 +3848,10 @@ do_pick_task_scx(struct rq *rq, struct rq_flags *rf, bool force_scx) * If @force_scx is true, always try to pick a SCHED_EXT task, * regardless of any higher-priority sched classes activity. */ - if (!force_scx && rq_modified_above(rq, &ext_sched_class)) - return RETRY_TASK; + if (!force_scx && rq_modified_above(rq, &ext_sched_class)) { + p = RETRY_TASK; + goto out; + } /* * If we're keeping @prev, replenish slice if necessary and keep running @@ -3467,7 +3867,7 @@ do_pick_task_scx(struct rq *rq, struct rq_flags *rf, bool force_scx) } else { p = first_local_task(rq); if (!p) - return NULL; + goto out; if (unlikely(!p->scx.slice) && scx_task_can_stay_on_cpu(rq, p)) { struct scx_sched *sch = scx_task_sched(p); @@ -3482,6 +3882,40 @@ do_pick_task_scx(struct rq *rq, struct rq_flags *rf, bool force_scx) } } +out: + if (cpu_of(rq) != smp_processor_id()) + return p; + + /* + * Balance callbacks must be consumed before the rq lock is released, so + * queue them only when the pick is final. On RETRY_TASK, or after a + * NULL pick from the dl_server, the core continues picking and can + * release the rq lock (e.g., prev_balance() or another dispatch). In + * that case, run the deferred work from irq_work, which doesn't depend + * on the current rq lock section, and leave the kick sync wait pending + * for the next pick. + */ + if (p != RETRY_TASK && (p || !force_scx)) { + /* under core scheduling, see dispatch_core_pick() */ + if (!core_sched) + maybe_queue_balance_callback(rq); + + /* + * Defer to a balance callback which can drop rq lock and enable + * IRQs. Waiting directly in the pick path would deadlock against + * CPUs sending us IPIs (e.g., TLB flushes) while we wait for + * them. + */ + if (unlikely(rq->scx.kick_sync_pending)) { + rq->scx.kick_sync_pending = false; + queue_balance_callback(rq, &rq->scx.kick_sync_bal_cb, + kick_sync_wait_bal_cb); + } + } else if (!core_sched && (rq->scx.flags & SCX_RQ_BAL_CB_PENDING)) { + rq->scx.flags &= ~SCX_RQ_BAL_CB_PENDING; + schedule_deferred(rq); + } + return p; } @@ -3889,9 +4323,9 @@ void scx_tick(struct rq *rq) update_other_load_avgs(rq); } -static void task_tick_scx(struct rq *rq, struct task_struct *curr, int queued) +static void task_tick_scx(struct rq *rq, struct task_struct *donor, int queued) { - struct scx_sched *sch = scx_task_sched(curr); + struct scx_sched *sch = scx_task_sched(donor); update_curr_scx(rq); @@ -3900,12 +4334,18 @@ static void task_tick_scx(struct rq *rq, struct task_struct *curr, int queued) * management. */ if (scx_bypassing(sch, cpu_of(rq))) - scx_set_task_slice(curr, 0); + scx_set_task_slice(donor, 0); else if (SCX_HAS_OP(sch, tick)) - SCX_CALL_OP_TASK(sch, tick, rq, curr); + SCX_CALL_OP_TASK(sch, tick, rq, donor); - if (!curr->scx.slice) - resched_curr(rq); + if (!donor->scx.slice) { + /* the slice can't be trusted while bypassing */ + if (READ_ONCE(donor->scx.lazy_resched) && + !scx_bypassing(sch, cpu_of(rq))) + scx_resched_curr_lazy(rq); + else + resched_curr(rq); + } } #ifdef CONFIG_EXT_GROUP_SCHED @@ -4021,6 +4461,7 @@ static void __scx_enable_task(struct scx_sched *sch, struct task_struct *p) weight = sched_prio_to_weight[p->static_prio - MAX_RT_PRIO]; p->scx.weight = sched_weight_to_cgroup(weight); + p->scx.lazy_resched = sch->ops.flags & SCX_OPS_LAZY_RESCHED; if (SCX_HAS_OP(sch, enable)) { if (scx_is_cid_type()) { @@ -4394,6 +4835,13 @@ static void switching_to_scx(struct rq *rq, struct task_struct *p) static void switched_from_scx(struct rq *rq, struct task_struct *p) { + /* + * A class change of the running task: sched_change_begin() put @p with + * no successor, which leaves rq->scx.sched set. + */ + if (task_current_donor(rq, p)) + scx_cid_sched_update(rq, NULL); + if (task_dead_and_done(p)) return; @@ -4416,7 +4864,7 @@ int scx_check_setscheduler(struct task_struct *p, int policy) { lockdep_assert_rq_held(task_rq(p)); - /* if disallow, reject transitioning into SCX */ + /* If disallow, reject transitioning into SCX. */ if (scx_enabled() && READ_ONCE(p->scx.disallow) && p->policy != policy && policy == SCHED_EXT) return -EACCES; @@ -4424,6 +4872,20 @@ int scx_check_setscheduler(struct task_struct *p, int policy) return 0; } +/* + * Don't carry a donor retained by another class into sched_ext. The caller + * has updated the rq clock and invokes this immediately before + * sched_change_begin() records the task's queued state. + */ +void scx_prepare_setscheduler(struct task_struct *p, int policy) +{ + lockdep_assert_held(&p->pi_lock); + lockdep_assert_rq_held(task_rq(p)); + + if (scx_enabled() && p->policy != policy && policy == SCHED_EXT) + scx_block_proxy_donor(task_rq(p), p); +} + static void process_ddsp_deferred_locals(struct rq *rq) { struct task_struct *p; @@ -4565,8 +5027,7 @@ static u32 reenq_local(struct scx_sched *sch, struct rq *rq, u64 reenq_flags) scx_wait_dispatching(p); scx_dispatch_dequeue(rq, p); - if (WARN_ON_ONCE(p->scx.flags & SCX_TASK_REENQ_REASON_MASK)) - p->scx.flags &= ~SCX_TASK_REENQ_REASON_MASK; + WARN_ON_ONCE(p->scx.flags & SCX_TASK_REENQ_REASON_MASK); p->scx.flags |= reason; list_add_tail(&p->scx.dsq_list.node, &tasks); @@ -4577,21 +5038,20 @@ static u32 reenq_local(struct scx_sched *sch, struct rq *rq, u64 reenq_flags) scx_do_enqueue_task(rq, p, SCX_ENQ_REENQ, -1); - p->scx.flags &= ~SCX_TASK_REENQ_REASON_MASK; nr_enqueued++; } /* - * The revoke that scheduled this scan may have raced the pick: curr + * The revoke that scheduled this scan may have raced the pick: donor * may be a now-capless task, either one that kept running or one * promoted off the local DSQ between the ecaps sync and this scan. * Zero the slice to evict it. The enqueue gate blocks new capless * inserts, so no later pick can slip through after the scan. */ if ((reenq_flags & SCX_REENQ_CAP_REVOKE) && - rq->curr->sched_class == &ext_sched_class && - scx_task_reenq_on_cap_revoke(rq, rq->curr)) { - scx_set_task_slice(rq->curr, 0); + rq->donor->sched_class == &ext_sched_class && + scx_task_reenq_on_cap_revoke(rq, rq->donor)) { + scx_set_task_slice(rq->donor, 0); resched_curr(rq); } @@ -4640,7 +5100,9 @@ static void process_deferred_reenq_locals(struct rq *rq) static bool user_task_should_reenq(struct task_struct *p, u64 reenq_flags, u32 *reason) { *reason = SCX_TASK_REENQ_KFUNC; - return reenq_flags & SCX_REENQ_ANY; + if (reenq_flags & SCX_REENQ_ANY) + return true; + return (reenq_flags & SCX_REENQ_MARKED) && (p->scx.dsq_flags & SCX_TASK_DSQ_REENQ); } static void reenq_user(struct rq *rq, struct scx_dispatch_q *dsq, u64 reenq_flags) @@ -4649,7 +5111,7 @@ static void reenq_user(struct rq *rq, struct scx_dispatch_q *dsq, u64 reenq_flag struct scx_sched *sch = dsq->sched; struct scx_dsq_list_node cursor = INIT_DSQ_LIST_CURSOR(cursor, dsq, 0); struct task_struct *p; - s32 nr_enqueued = 0; + s32 nr_visited = 0; lockdep_assert_rq_held(rq); @@ -4659,6 +5121,21 @@ static void reenq_user(struct rq *rq, struct scx_dispatch_q *dsq, u64 reenq_flag struct rq *task_rq; u32 reason; + /* + * Count skipped tasks too so that a long walk doesn't hold the + * locks throughout. The cursor keeps the position. + */ + if (!(++nr_visited % SCX_TASK_ITER_BATCH)) { + raw_spin_unlock(&dsq->lock); + if (locked_rq) { + scx_rq_lock_drop(locked_rq); + raw_spin_rq_unlock(locked_rq); + locked_rq = NULL; + } + cpu_relax(); + raw_spin_lock(&dsq->lock); + } + p = nldsq_cursor_next_task(&cursor, dsq); if (!p) break; @@ -4690,21 +5167,11 @@ static void reenq_user(struct rq *rq, struct scx_dispatch_q *dsq, u64 reenq_flag dispatch_dequeue_locked(p, dsq); raw_spin_unlock(&dsq->lock); - if (WARN_ON_ONCE(p->scx.flags & SCX_TASK_REENQ_REASON_MASK)) - p->scx.flags &= ~SCX_TASK_REENQ_REASON_MASK; + WARN_ON_ONCE(p->scx.flags & SCX_TASK_REENQ_REASON_MASK); p->scx.flags |= reason; scx_do_enqueue_task(task_rq, p, SCX_ENQ_REENQ, -1); - p->scx.flags &= ~SCX_TASK_REENQ_REASON_MASK; - - if (!(++nr_enqueued % SCX_TASK_ITER_BATCH)) { - scx_rq_lock_drop(locked_rq); - raw_spin_rq_unlock(locked_rq); - locked_rq = NULL; - cpu_relax(); - } - raw_spin_lock(&dsq->lock); } @@ -4759,6 +5226,60 @@ static void process_deferred_reenq_users(struct rq *rq) } } +/* + * Drain ready tasks from @rq->scx.reject_dsq and reenqueue them so that their + * owning BPF schedulers choose placement again. Proxy-active tasks remain + * parked and rearm the retry notification for a later proxy resolution. + * + * A task can be re-rejected repeatedly. Reenqueues are bounded per task by + * SCX_REENQ_MAX_REPEAT in scx_do_enqueue_task(), which ejects the owning + * scheduler. + */ +static void scx_reenq_reject(struct rq *rq) +{ + LIST_HEAD(tasks); + struct task_struct *p, *n; + + lockdep_assert_rq_held(rq); + + if (list_empty(&rq->scx.reject_dsq.list)) + return; + + /* + * Move ready tasks to a private list so a task re-rejected by + * scx_do_enqueue_task() below isn't revisited this round. + */ + list_for_each_entry_safe(p, n, &rq->scx.reject_dsq.list, scx.dsq_list.node) { + u32 reason = p->scx.flags & SCX_TASK_REENQ_REASON_MASK; + + WARN_ON_ONCE(!reason); + + if (sched_proxy_exec() && reason == SCX_TASK_REENQ_PROXY) { + /* Affinity machinery will dequeue and reactivate @p. */ + if (p->migration_pending) + continue; + + if (task_on_cpu(rq, p) || task_current_donor(rq, p)) { + rq->scx.flags |= SCX_RQ_PROXY_RETRY; + continue; + } + } else { + WARN_ON_ONCE(p->migration_pending); + } + + scx_wait_dispatching(p); + scx_dispatch_dequeue(rq, p); + + list_add_tail(&p->scx.dsq_list.node, &tasks); + } + + list_for_each_entry_safe(p, n, &tasks, scx.dsq_list.node) { + list_del_init(&p->scx.dsq_list.node); + + scx_do_enqueue_task(rq, p, SCX_ENQ_REENQ, -1); + } +} + static void run_deferred(struct rq *rq) { process_ddsp_deferred_locals(rq); @@ -4775,14 +5296,18 @@ static void run_deferred(struct rq *rq) #ifdef CONFIG_NO_HZ_FULL bool scx_can_stop_tick(struct rq *rq) { - struct task_struct *p = rq->curr; + struct task_struct *p = rq->donor; struct scx_sched *sch = scx_task_sched(p); + /* Proxy execution is conservatively tick-driven for now. */ + if (rq->scx.flags & SCX_RQ_PROXY_TICK) + return false; + if (p->sched_class != &ext_sched_class) return true; /* - * @rq->curr may still reference an outgoing EXT task after it has been + * @rq->donor may still reference an outgoing EXT task after it has been * dequeued. If no EXT tasks are accounted on @rq, ignore its stale * slice state. If another task is dispatched from a DSQ, * set_next_task_scx() will update the dependency for the incoming task. @@ -4803,7 +5328,8 @@ bool scx_can_stop_tick(struct rq *rq) /* * @rq can dispatch from different DSQs, so we can't tell whether it * needs the tick or not by looking at nr_running. Allow stopping ticks - * iff the BPF scheduler indicated so. See set_next_task_scx(). + * iff set_next_task_scx() determined that the selected scheduling context + * can run tickless. */ return rq->scx.flags & SCX_RQ_CAN_STOP_TICK; } @@ -4818,7 +5344,7 @@ void scx_tg_init(struct task_group *tg) tg->scx.weight = CGROUP_WEIGHT_DFL; tg->scx.bw_period_us = default_bw_period_us(); tg->scx.bw_quota_us = RUNTIME_INF; - tg->scx.idle = false; + tg->scx.sched_idle = false; } /** @@ -4901,7 +5427,7 @@ int scx_tg_online(struct task_group *tg) .bw_period_us = tg->scx.bw_period_us, .bw_quota_us = tg->scx.bw_quota_us, .bw_burst_us = tg->scx.bw_burst_us, - .sched_idle = tg->scx.idle }; + .sched_idle = tg->scx.sched_idle }; ret = SCX_CALL_OP_RET(sch, cgroup_init, NULL, tg->css.cgroup, &args); @@ -5068,11 +5594,11 @@ void scx_group_set_idle(struct task_group *tg, bool idle) sch = scx_tg_knob_sched(tg); if (scx_cgroup_enabled && sch && SCX_HAS_OP(sch, cgroup_set_idle) && - tg->scx.idle != idle) + tg->scx.sched_idle != idle) SCX_CALL_OP(sch, cgroup_set_idle, NULL, tg_cgrp(tg), idle); /* Update the task group's idle state */ - tg->scx.idle = idle; + tg->scx.sched_idle = idle; percpu_up_read(&scx_cgroup_ops_rwsem); } @@ -5186,12 +5712,16 @@ s32 scx_init_dsq(struct scx_dispatch_q *dsq, u64 dsq_id, struct scx_sched *sch) dsq->id = dsq_id; dsq->sched = sch; - dsq->pcpu = alloc_percpu(struct scx_dsq_pcpu); - if (!dsq->pcpu) + /* per-DSQ deferred reenq state is only needed for user DSQs */ + if (dsq_id & SCX_DSQ_FLAG_BUILTIN) + return 0; + + dsq->pcpu_user = alloc_percpu(struct scx_dsq_pcpu); + if (!dsq->pcpu_user) return -ENOMEM; for_each_possible_cpu(cpu) { - struct scx_dsq_pcpu *pcpu = per_cpu_ptr(dsq->pcpu, cpu); + struct scx_dsq_pcpu *pcpu = per_cpu_ptr(dsq->pcpu_user, cpu); pcpu->dsq = dsq; INIT_LIST_HEAD(&pcpu->deferred_reenq_user.node); @@ -5204,8 +5734,11 @@ static void exit_dsq(struct scx_dispatch_q *dsq) { s32 cpu; + if (!dsq->pcpu_user) + return; + for_each_possible_cpu(cpu) { - struct scx_dsq_pcpu *pcpu = per_cpu_ptr(dsq->pcpu, cpu); + struct scx_dsq_pcpu *pcpu = per_cpu_ptr(dsq->pcpu_user, cpu); struct scx_deferred_reenq_user *dru = &pcpu->deferred_reenq_user; struct rq *rq = cpu_rq(cpu); @@ -5219,7 +5752,7 @@ static void exit_dsq(struct scx_dispatch_q *dsq) } } - free_percpu(dsq->pcpu); + free_percpu(dsq->pcpu_user); } static void free_dsq_rcufn(struct rcu_head *rcu) @@ -5246,7 +5779,7 @@ static void free_dsq_irq_workfn(struct irq_work *irq_work) * and queues nothing. */ for_each_possible_cpu(cpu) { - struct scx_dsq_pcpu *pcpu = per_cpu_ptr(dsq->pcpu, cpu); + struct scx_dsq_pcpu *pcpu = per_cpu_ptr(dsq->pcpu_user, cpu); struct rq *rq = cpu_rq(cpu); guard(raw_spinlock_irqsave)(&rq->scx.deferred_reenq_lock); @@ -5341,7 +5874,7 @@ static int scx_cgroup_init(struct scx_sched *sch) .bw_period_us = tg->scx.bw_period_us, .bw_quota_us = tg->scx.bw_quota_us, .bw_burst_us = tg->scx.bw_burst_us, - .sched_idle = tg->scx.idle, + .sched_idle = tg->scx.sched_idle, }; ret = SCX_CALL_OP_RET(sch, cgroup_init, NULL, css->cgroup, &args); @@ -5535,6 +6068,7 @@ static void scx_sched_free_rcu_work(struct work_struct *work) free_cpumask_var(pcpu->cpus_to_kick); free_cpumask_var(pcpu->cpus_to_kick_if_idle); free_cpumask_var(pcpu->cpus_to_preempt); + free_cpumask_var(pcpu->cpus_to_preempt_lazy); free_cpumask_var(pcpu->cpus_to_wait); exit_dsq(scx_bypass_dsq(sch, cpu)); @@ -6013,7 +6547,7 @@ static void bypass_lb_node(struct scx_sched *sch, int node) /* * We don't want CPUs to have more than $nr_donor_target tasks and - * balancing to fill donee CPUs upto $nr_target. Once targets are + * balancing to fill donee CPUs up to $nr_target. Once targets are * calculated, find the donee CPUs. */ nr_target = DIV_ROUND_UP(nr_tasks, nr_cpus); @@ -6323,6 +6857,24 @@ void scx_bypass(struct scx_sched *sch, bool bypass) } /* + * Bypass trumps protection. Cycling the queued tasks below + * clears theirs. The current donor isn't on the runnable list, + * so strip its protection here. + * + * When bypass lifts, the current donor keeps running on its + * slice without a cap check. Evict it if it can't stay on the + * cpu. + */ + p = rq->donor; + if (p->sched_class == &ext_sched_class && + scx_is_descendant(scx_task_sched(p), sch)) { + if (bypass) + scx_task_slice_ended(rq, p); + else if (!scx_task_can_stay_on_cpu(rq, p)) + scx_set_task_slice(p, 0); + } + + /* * The use of list_for_each_entry_safe_reverse() is required * because each task is going to be removed from and added back * to the runnable_list during iteration. Because they're added @@ -6334,13 +6886,6 @@ void scx_bypass(struct scx_sched *sch, bool bypass) if (!scx_is_descendant(scx_task_sched(p), sch)) continue; - /* - * Bypass trumps protection. Cycling clears for queued - * tasks but current task needs explicit stripping. - */ - if (bypass && task_current(rq, p)) - scx_task_slice_ended(rq, p); - /* cycling deq/enq is enough, see the function comment */ scoped_guard (sched_change, p, DEQUEUE_SAVE | DEQUEUE_MOVE) { /* nothing */ ; @@ -6672,6 +7217,8 @@ static void scx_root_disable(struct scx_sched *sch) } } + scx_ops_cid_sched_updated_disable(sch); + /* no task is on scx, turn off all the switches and flush in-progress calls */ static_branch_disable(&__scx_enabled); static_branch_disable(&__scx_is_cid_type); @@ -7050,6 +7597,8 @@ static void scx_dump_cpu(struct scx_sched *sch, struct seq_buf *s, scx_rescue_dump(&ns, rq); scx_dump_line(&ns, " curr=%s[%d] class=%ps", rq->curr->comm, rq->curr->pid, rq->curr->sched_class); + scx_dump_line(&ns, " donor=%s[%d] class=%ps", + rq->donor->comm, rq->donor->pid, rq->donor->sched_class); if (!cpumask_empty(pcpu->cpus_to_kick)) scx_dump_line(&ns, " cpus_to_kick : %*pb", cpumask_pr_args(pcpu->cpus_to_kick)); @@ -7059,6 +7608,9 @@ static void scx_dump_cpu(struct scx_sched *sch, struct seq_buf *s, if (!cpumask_empty(pcpu->cpus_to_preempt)) scx_dump_line(&ns, " cpus_to_preempt: %*pb", cpumask_pr_args(pcpu->cpus_to_preempt)); + if (!cpumask_empty(pcpu->cpus_to_preempt_lazy)) + scx_dump_line(&ns, " preempt_lazy : %*pb", + cpumask_pr_args(pcpu->cpus_to_preempt_lazy)); if (!cpumask_empty(pcpu->cpus_to_wait)) scx_dump_line(&ns, " cpus_to_wait : %*pb", cpumask_pr_args(pcpu->cpus_to_wait)); @@ -7093,6 +7645,10 @@ static void scx_dump_cpu(struct scx_sched *sch, struct seq_buf *s, if (rq->curr->sched_class == &ext_sched_class && (dump_all_tasks || scx_task_on_sched(sch, rq->curr))) scx_dump_task(sch, s, dctx, rq, rq->curr, '*'); + if (rq->donor != rq->curr && + rq->donor->sched_class == &ext_sched_class && + (dump_all_tasks || scx_task_on_sched(sch, rq->donor))) + scx_dump_task(sch, s, dctx, rq, rq->donor, ' '); list_for_each_entry(p, &rq->scx.runnable_list, scx.runnable_node) if (dump_all_tasks || scx_task_on_sched(sch, p)) @@ -7376,6 +7932,7 @@ struct scx_sched *scx_alloc_and_add_sched(struct scx_enable_cmd *cmd, if (!zalloc_cpumask_var_node(&pcpu->cpus_to_kick, GFP_KERNEL, node) || !zalloc_cpumask_var_node(&pcpu->cpus_to_kick_if_idle, GFP_KERNEL, node) || !zalloc_cpumask_var_node(&pcpu->cpus_to_preempt, GFP_KERNEL, node) || + !zalloc_cpumask_var_node(&pcpu->cpus_to_preempt_lazy, GFP_KERNEL, node) || !zalloc_cpumask_var_node(&pcpu->cpus_to_wait, GFP_KERNEL, node)) { ret = -ENOMEM; goto err_free_pcpu; @@ -7511,6 +8068,7 @@ struct scx_sched *scx_alloc_and_add_sched(struct scx_enable_cmd *cmd, free_cpumask_var(pcpu->cpus_to_kick); free_cpumask_var(pcpu->cpus_to_kick_if_idle); free_cpumask_var(pcpu->cpus_to_preempt); + free_cpumask_var(pcpu->cpus_to_preempt_lazy); free_cpumask_var(pcpu->cpus_to_wait); } for_each_possible_cpu(cpu) { @@ -7601,6 +8159,11 @@ int scx_validate_ops(struct scx_sched *sch, const struct sched_ext_ops *ops) return -EINVAL; } + if ((ops->flags & SCX_OPS_ENQ_BLOCKED) && !ops->enqueue) { + scx_error(sch, "SCX_OPS_ENQ_BLOCKED requires ops.enqueue() to be implemented"); + return -EINVAL; + } + /* * SCX_OPS_TID_TO_TASK is enabled by the root scheduler. A sub-sched * may set it to declare a dependency; reject if the root hasn't @@ -7864,6 +8427,8 @@ static void scx_root_enable_workfn(struct kthread_work *work) if (((void (**)(void))ops)[i]) set_bit(i, sch->has_op); + scx_ops_cid_sched_updated_enable(sch); + if (sch->ops.cpu_acquire || sch->ops.cpu_release) sch->ops.flags |= SCX_OPS_HAS_CPU_PREEMPT; @@ -7990,6 +8555,10 @@ static void scx_root_enable_workfn(struct kthread_work *work) if (old_class != new_class) queue_flags |= DEQUEUE_CLASS; + if (new_class == &ext_sched_class) { + scx_prepare_task_sched_change(p); + queue_flags |= DEQUEUE_NOCLOCK; + } scoped_guard (sched_change, p, queue_flags) { scx_set_task_slice(p, READ_ONCE(sch->slice_dfl)); @@ -8510,6 +9079,8 @@ static void sched_ext_ops_cid__set_cmask(struct task_struct *p, const struct scx static void sched_ext_ops_cid__enable(struct task_struct *p, struct scx_enable_args *args) {} static void sched_ext_ops__sub_caps_updated(const struct scx_cmask *cmask__arena, u64 caps) {} static void sched_ext_ops__sub_ecaps_updated(s32 cid, u64 before, u64 after) {} +static void sched_ext_ops__sub_cid_sched_updated(s32 cid, u64 sched) {} +static void sched_ext_ops__sub_child_ecaps_updated(u64 cgroup_id, s32 cid, u64 before, u64 after) {} static struct sched_ext_ops_cid __bpf_ops_sched_ext_ops_cid = { .select_cid = sched_ext_ops__select_cpu, @@ -8544,6 +9115,8 @@ static struct sched_ext_ops_cid __bpf_ops_sched_ext_ops_cid = { .sub_detach = sched_ext_ops__sub_detach, .sub_caps_updated = sched_ext_ops__sub_caps_updated, .sub_ecaps_updated = sched_ext_ops__sub_ecaps_updated, + .sub_cid_sched_updated = sched_ext_ops__sub_cid_sched_updated, + .sub_child_ecaps_updated = sched_ext_ops__sub_child_ecaps_updated, .cid_online = sched_ext_ops__cpu_online, .cid_offline = sched_ext_ops__cpu_offline, .init_cids = sched_ext_ops__init_cids, @@ -8638,13 +9211,23 @@ static bool kick_one_cpu(s32 cpu, struct scx_sched_pcpu *pcpu, struct rq *this_r { struct rq *rq = cpu_rq(cpu); struct scx_rq *this_scx = &this_rq->scx; + struct rq_flags rf; const struct sched_class *cur_class; bool should_wait = false; bool kickable; - unsigned long flags; + bool preempt, preempt_lazy, wait, immediate; - raw_spin_rq_lock_irqsave(rq, flags); - cur_class = rq->curr->sched_class; + rq_lock_irqsave(rq, &rf); + cur_class = rq->donor->sched_class; + preempt = cpumask_test_cpu(cpu, pcpu->cpus_to_preempt); + preempt_lazy = cpumask_test_cpu(cpu, pcpu->cpus_to_preempt_lazy); + wait = cpumask_test_cpu(cpu, pcpu->cpus_to_wait); + /* + * Immediate preemption, waiting and a plain kick take precedence over + * lazy preemption. The lazy request still clears the slice, so all + * accumulated requests are served. + */ + immediate = preempt || wait || cpumask_test_cpu(cpu, pcpu->cpus_to_kick); /* * During CPU hotplug, a CPU may depend on kicking itself to make @@ -8658,19 +9241,23 @@ static bool kick_one_cpu(s32 cpu, struct scx_sched_pcpu *pcpu, struct rq *this_r !sched_class_above(cur_class, &ext_sched_class); if (kickable && !scx_missing_caps(pcpu->sch, cpu, SCX_CAP_BASE)) { - if (cpumask_test_cpu(cpu, pcpu->cpus_to_preempt)) { + if (preempt || preempt_lazy) { if (cur_class == &ext_sched_class) { u64 caps = scx_caps_for_preempt(pcpu->sch, rq, 0); - if (unlikely(scx_missing_caps(pcpu->sch, cpu, caps))) + if (unlikely(scx_missing_caps(pcpu->sch, cpu, caps))) { __scx_add_event(pcpu->sch, SCX_EV_SUB_PREEMPT_DENIED, 1); - else if (unlikely(!scx_set_task_slice(rq->curr, 0))) + /* degrade to a plain, immediate kick */ + immediate = true; + } else if (unlikely(!scx_set_task_slice(rq->donor, 0))) { __scx_add_event(pcpu->sch, SCX_EV_SLICE_DENIED, 1); + } } cpumask_clear_cpu(cpu, pcpu->cpus_to_preempt); + cpumask_clear_cpu(cpu, pcpu->cpus_to_preempt_lazy); } - if (cpumask_test_cpu(cpu, pcpu->cpus_to_wait)) { + if (wait) { if (cur_class == &ext_sched_class) { cpumask_set_cpu(cpu, this_scx->cpus_to_sync); ksyncs[cpu] = rq->scx.kick_sync; @@ -8679,17 +9266,21 @@ static bool kick_one_cpu(s32 cpu, struct scx_sched_pcpu *pcpu, struct rq *this_r cpumask_clear_cpu(cpu, pcpu->cpus_to_wait); } - resched_curr(rq); + if (immediate) + resched_curr(rq); + else + scx_resched_curr_lazy(rq); } else { /* a kickable cpu was skipped solely for the missing caps */ if (kickable) __scx_add_event(pcpu->sch, SCX_EV_SUB_KICK_DENIED, 1); cpumask_clear_cpu(cpu, pcpu->cpus_to_preempt); + cpumask_clear_cpu(cpu, pcpu->cpus_to_preempt_lazy); cpumask_clear_cpu(cpu, pcpu->cpus_to_wait); } scx_rq_lock_drop(rq); - raw_spin_rq_unlock_irqrestore(rq, flags); + rq_unlock_irqrestore(rq, &rf); return should_wait; } @@ -8739,7 +9330,7 @@ static void kick_cpus_irq_workfn(struct irq_work *irq_work) list_for_each_entry_safe(pcpu, tmp, &this_scx->sched_pcpus_to_kick, to_kick_node) { list_del_init(&pcpu->to_kick_node); - for_each_cpu(cpu, pcpu->cpus_to_kick) { + for_each_cpu_or(cpu, pcpu->cpus_to_kick, pcpu->cpus_to_preempt_lazy) { should_wait |= kick_one_cpu(cpu, pcpu, this_rq, ksyncs); cpumask_clear_cpu(cpu, pcpu->cpus_to_kick); cpumask_clear_cpu(cpu, pcpu->cpus_to_kick_if_idle); @@ -8870,8 +9461,8 @@ void __init init_sched_ext_class(void) /* local_dsq's sch will be set during scx_root_enable() */ BUG_ON(scx_init_dsq(&rq->scx.local_dsq, SCX_DSQ_LOCAL, NULL)); -#ifdef CONFIG_EXT_SUB_SCHED BUG_ON(scx_init_dsq(&rq->scx.reject_dsq, SCX_DSQ_REJECT, NULL)); +#ifdef CONFIG_EXT_SUB_SCHED scx_rescue_init(rq); #endif @@ -9004,7 +9595,7 @@ __bpf_kfunc_start_defs(); * task is inserted. * * When called from ops.dispatch(), there are no restrictions on @p or @dsq_id - * and this function can be called upto ops.dispatch_max_batch times to insert + * and this function can be called up to ops.dispatch_max_batch times to insert * multiple tasks. scx_bpf_dispatch_nr_slots() returns the number of the * remaining slots. scx_bpf_dsq_move_to_local() flushes the batch and resets the * counter. @@ -9089,7 +9680,9 @@ struct scx_bpf_dsq_insert_vtime_args { * * @args->vtime ordering is according to time_before64() which considers * wrapping. A numerically larger vtime may indicate an earlier position in the - * ordering and vice-versa. + * ordering and vice-versa. vtime is a rolling cursor and values used for + * ordering within a given DSQ should stay less than 2^63 apart for + * time_before64() ordering to remain well-defined. * * A DSQ can only be used as a FIFO or priority queue at any given time and this * function must not be called on a DSQ which already has one or more FIFO tasks @@ -9167,6 +9760,40 @@ static const struct btf_kfunc_id_set scx_kfunc_set_enqueue_dispatch = { .filter = scx_kfunc_context_filter, }; +/* + * Lock @rq from a kfunc called either from ops.dispatch(), which holds the + * dispatched rq's lock, or from a context holding no rq lock. Under core + * scheduling, dispatch can run for a sibling rq, so the locked rq is not + * necessarily this CPU's. Return the rq locked on entry, NULL if none. + */ +static struct rq *kf_switch_rq_lock(struct rq *rq, unsigned long *flags) +{ + struct rq *entry_rq; + + local_irq_save(*flags); + + entry_rq = scx_locked_rq(); + if (entry_rq) { + if (entry_rq != rq) + switch_rq_lock(entry_rq, rq); + } else { + raw_spin_rq_lock(rq); + } + return entry_rq; +} + +/* undo kf_switch_rq_lock(), @rq is the rq locked now */ +static void kf_restore_rq_lock(struct rq *rq, struct rq *entry_rq, unsigned long flags) +{ + if (entry_rq) { + if (entry_rq != rq) + switch_rq_lock(rq, entry_rq); + } else { + scx_rq_lock_drop(rq); + raw_spin_rq_unlock_irqrestore(rq, flags); + } +} + static bool scx_dsq_move(struct bpf_iter_scx_dsq_kern *kit, struct task_struct *p, u64 dsq_id, u64 enq_flags, bool priq) @@ -9201,27 +9828,8 @@ static bool scx_dsq_move(struct bpf_iter_scx_dsq_kern *kit, if (unlikely(READ_ONCE(sch->aborting))) return false; - /* - * Can be called from either ops.dispatch() holding the dispatched rq's - * lock or any context where no rq lock is held. If latter, lock @p's - * task_rq which we'll likely need anyway. - */ src_rq = task_rq(p); - - local_irq_save(flags); - - /* - * Under core scheduling, dispatch can run for a sibling rq, so the - * locked rq is not necessarily this CPU's. - */ - locked_rq = scx_locked_rq(); - - if (locked_rq) { - if (locked_rq != src_rq) - switch_rq_lock(locked_rq, src_rq); - } else { - raw_spin_rq_lock(src_rq); - } + locked_rq = kf_switch_rq_lock(src_rq, &flags); p_rq = src_rq; raw_spin_lock(&src_dsq->lock); @@ -9260,13 +9868,7 @@ static bool scx_dsq_move(struct bpf_iter_scx_dsq_kern *kit, p_rq = move_task_between_dsqs(sch, p, enq_flags, src_dsq, dst_dsq); dispatched = true; out: - if (locked_rq) { - if (locked_rq != p_rq) - switch_rq_lock(p_rq, locked_rq); - } else { - scx_rq_lock_drop(p_rq); - raw_spin_rq_unlock_irqrestore(p_rq, flags); - } + kf_restore_rq_lock(p_rq, locked_rq, flags); kit->cursor.flags &= ~(__SCX_DSQ_ITER_HAS_SLICE | __SCX_DSQ_ITER_HAS_VTIME); @@ -9500,6 +10102,8 @@ BTF_ID_FLAGS(func, scx_bpf_dsq_move_set_slice, KF_RCU) BTF_ID_FLAGS(func, scx_bpf_dsq_move_set_vtime, KF_RCU) BTF_ID_FLAGS(func, scx_bpf_dsq_move, KF_RCU) BTF_ID_FLAGS(func, scx_bpf_dsq_move_vtime, KF_RCU) +/* also in scx_kfunc_ids_unlocked, same contexts as scx_bpf_dsq_move() */ +BTF_ID_FLAGS(func, scx_bpf_dsq_reenq_task, KF_RCU) #ifdef CONFIG_EXT_SUB_SCHED BTF_ID_FLAGS(func, scx_bpf_sub_dispatch, KF_IMPLICIT_ARGS) #endif @@ -9615,6 +10219,7 @@ BTF_ID_FLAGS(func, scx_bpf_dsq_move_set_slice, KF_RCU) BTF_ID_FLAGS(func, scx_bpf_dsq_move_set_vtime, KF_RCU) BTF_ID_FLAGS(func, scx_bpf_dsq_move, KF_RCU) BTF_ID_FLAGS(func, scx_bpf_dsq_move_vtime, KF_RCU) +BTF_ID_FLAGS(func, scx_bpf_dsq_reenq_task, KF_RCU) /* also in scx_kfunc_ids_select_cpu: also callable from ops.select_cpu()/ops.enqueue() */ BTF_ID_FLAGS(func, __scx_bpf_select_cpu_and, KF_IMPLICIT_ARGS | KF_RCU) BTF_ID_FLAGS(func, scx_bpf_select_cpu_and, KF_RCU) @@ -9659,8 +10264,10 @@ __bpf_kfunc bool scx_bpf_task_set_slice(struct task_struct *p, u64 slice, return false; /* - * Directly write only when we hold the lock of the rq @p is queued or - * running on. See the write rules above. + * Directly write only when we hold the lock of the rq @p is queued on or + * provides the current scheduling context for. Under proxy execution, + * rq->donor owns and consumes the slice while rq->curr executes on its + * behalf. See the slice write rules above. * * While @p is queued on a user DSQ or in the BPF scheduler, * synchronization is the scheduler's responsibility. This write can @@ -9674,7 +10281,7 @@ __bpf_kfunc bool scx_bpf_task_set_slice(struct task_struct *p, u64 slice, locked_rq = scx_locked_rq(); if (!locked_rq || (READ_ONCE(p->scx.runnable_cpu) != cpu_of(locked_rq) && - !task_current(locked_rq, p))) { + !task_current_donor(locked_rq, p))) { set_task_slice_oob(sch, p, slice); return true; } @@ -9715,18 +10322,56 @@ __bpf_kfunc bool scx_bpf_task_set_dsq_vtime(struct task_struct *p, u64 vtime, return true; } +/** + * scx_bpf_task_set_lazy_resched - Set task's tick reschedule mode + * @p: task of interest + * @lazy: whether slice expiry should request lazy rescheduling + * @aux: implicit BPF argument to access bpf_prog_aux hidden from BPF progs + * + * Choose whether depletion of @p's slice at the scheduler tick requests lazy or + * immediate rescheduling. This is a persistent per-task policy and does not + * itself clear @p's slice or request rescheduling, unlike the + * %SCX_ENQ_PREEMPT_LAZY and %SCX_KICK_PREEMPT_LAZY one-shot operations. + * + * With lazy rescheduling enabled, a task interrupted in user space still + * reschedules before returning to user space. A task interrupted in the kernel + * may continue until its next return to user space or the next scheduler tick, + * which promotes the request. If lazy preemption is disabled at runtime, the + * request behaves like an immediate reschedule. + * + * @p must be on the calling scheduler. + * + * Return %true on success, %false if @p is not on the calling scheduler. + */ +__bpf_kfunc bool scx_bpf_task_set_lazy_resched(struct task_struct *p, bool lazy, + const struct bpf_prog_aux *aux) +{ + struct scx_sched *sch; + + /* + * clang's register locations for @lazy make pahole 1.32 drop this kfunc + * from BTF. Keep @lazy in memory so its location names no register. + */ + barrier_data(&lazy); + guard(rcu)(); + sch = scx_prog_sched(aux); + if (unlikely(!sch || !scx_task_on_sched(sch, p))) + return false; + + WRITE_ONCE(p->scx.lazy_resched, lazy); + return true; +} + void scx_kick_cpu(struct scx_sched *sch, s32 cpu, u64 flags) { struct scx_sched_pcpu *pcpu; struct rq *this_rq; unsigned long irq_flags; - /* - * The per-cpu kick list is guarded only by local_irq_save(), which does - * not mask NMIs, so kicking from NMI could corrupt it and is unsupported. - */ - if (unlikely(in_nmi())) { - scx_error(sch, "scx_bpf_kick_cpu() called from NMI"); + if (!scx_kf_allowed_ctx(sch)) + return; + if (unlikely(flags & ~SCX_KICK_ALL_FLAGS)) { + scx_error(sch, "invalid kick flags 0x%llx", flags); return; } @@ -9754,7 +10399,8 @@ void scx_kick_cpu(struct scx_sched *sch, s32 cpu, u64 flags) if (flags & SCX_KICK_IDLE) { struct rq *target_rq = cpu_rq(cpu); - if (unlikely(flags & (SCX_KICK_PREEMPT | SCX_KICK_WAIT))) + if (unlikely(flags & (SCX_KICK_PREEMPT | SCX_KICK_PREEMPT_LAZY | + SCX_KICK_WAIT))) scx_error(sch, "PREEMPT/WAIT cannot be used with SCX_KICK_IDLE"); if (raw_spin_rq_trylock(target_rq)) { @@ -9768,12 +10414,17 @@ void scx_kick_cpu(struct scx_sched *sch, s32 cpu, u64 flags) } cpumask_set_cpu(cpu, pcpu->cpus_to_kick_if_idle); } else { - cpumask_set_cpu(cpu, pcpu->cpus_to_kick); - + /* + * Accumulate requests and resolve their precedence at delivery. + */ if (flags & SCX_KICK_PREEMPT) cpumask_set_cpu(cpu, pcpu->cpus_to_preempt); + if (flags & SCX_KICK_PREEMPT_LAZY) + cpumask_set_cpu(cpu, pcpu->cpus_to_preempt_lazy); if (flags & SCX_KICK_WAIT) cpumask_set_cpu(cpu, pcpu->cpus_to_wait); + if (!(flags & SCX_KICK_PREEMPT_LAZY)) + cpumask_set_cpu(cpu, pcpu->cpus_to_kick); } if (list_empty(&pcpu->to_kick_node)) @@ -9813,8 +10464,9 @@ __bpf_kfunc void scx_bpf_kick_cpu(s32 cpu, u64 flags, const struct bpf_prog_aux * cid-addressed equivalent of scx_bpf_kick_cpu(). An invalid @cid aborts the * scheduler via scx_cid_to_cpu(). Caps are enforced on the delivery path: a * kick is dropped if the caller lacks baseline access on @cid, and a - * %SCX_KICK_PREEMPT degrades to a plain reschedule if the caller lacks - * %SCX_CAP_PREEMPT for a task outside its subtree. + * %SCX_KICK_PREEMPT or %SCX_KICK_PREEMPT_LAZY request degrades to a plain + * reschedule if the caller lacks %SCX_CAP_PREEMPT for a task outside its + * subtree. */ __bpf_kfunc void scx_bpf_kick_cid(s32 cid, u64 flags, const struct bpf_prog_aux *aux) { @@ -9896,8 +10548,13 @@ __bpf_kfunc void scx_bpf_destroy_dsq(u64 dsq_id, const struct bpf_prog_aux *aux) guard(rcu)(); sch = scx_prog_sched(aux); - if (sch) - destroy_dsq(sch, dsq_id); + if (unlikely(!sch)) + return; + + if (!scx_kf_allowed_ctx(sch)) + return; + + destroy_dsq(sch, dsq_id); } /** @@ -9934,6 +10591,9 @@ __bpf_kfunc int bpf_iter_scx_dsq_new(struct bpf_iter_scx_dsq *it, u64 dsq_id, if (unlikely(!sch)) return -ENODEV; + if (!scx_kf_allowed_ctx(sch)) + return -EDEADLK; + if (flags & ~__SCX_DSQ_ITER_USER_FLAGS) return -EINVAL; @@ -9968,7 +10628,8 @@ __bpf_kfunc struct task_struct *bpf_iter_scx_dsq_next(struct bpf_iter_scx_dsq *i * bpf_iter_scx_dsq_destroy - Destroy a DSQ iterator * @it: iterator to destroy * - * Undo bpf_iter_scx_dsq_new(). + * Undo bpf_iter_scx_dsq_new(). If the iteration marked tasks with + * scx_bpf_dsq_reenq_task(), schedule their re-enqueue. */ __bpf_kfunc void bpf_iter_scx_dsq_destroy(struct bpf_iter_scx_dsq *it) { @@ -9984,6 +10645,13 @@ __bpf_kfunc void bpf_iter_scx_dsq_destroy(struct bpf_iter_scx_dsq *it) list_del_init(&kit->cursor.node); raw_spin_unlock_irqrestore(&kit->dsq->lock, flags); } + + if (kit->cursor.flags & __SCX_DSQ_ITER_HAS_REENQ) { + guard(preempt)(); + schedule_dsq_reenq(kit->dsq->sched, kit->dsq, SCX_REENQ_MARKED, + scx_locked_rq()); + } + kit->dsq = NULL; } @@ -10036,7 +10704,8 @@ __bpf_kfunc struct task_struct *scx_bpf_dsq_peek(u64 dsq_id, * - Local DSQs (%SCX_DSQ_LOCAL or %SCX_DSQ_LOCAL_ON | $cpu) * - User DSQs * - * Re-enqueues are performed asynchronously. Can be called from anywhere. + * Re-enqueues are performed asynchronously. Can be called from anywhere. A + * re-enqueue of an inactive cpu's local DSQ is ignored. * * %SCX_DSQ_LOCAL resolves to the local DSQ of the rq the current scheduler * operation is locked to - e.g. the rq being dispatched for in ops.dispatch() - @@ -10060,6 +10729,9 @@ __bpf_kfunc void scx_bpf_dsq_reenq(u64 dsq_id, u64 reenq_flags, return; } + if (!scx_kf_allowed_ctx(sch)) + return; + /* not specifying any filter bits is the same as %SCX_REENQ_ANY */ if (!(reenq_flags & __SCX_REENQ_FILTER_MASK)) reenq_flags |= SCX_REENQ_ANY; @@ -10069,6 +10741,64 @@ __bpf_kfunc void scx_bpf_dsq_reenq(u64 dsq_id, u64 reenq_flags, } /** + * scx_bpf_dsq_reenq_task - Re-enqueue a task from a DSQ iteration + * @it__iter: DSQ iterator in progress + * @p: task to re-enqueue + * + * Mark @p, which is on the DSQ iterated by @it__iter and was queued before the + * iteration started, for re-enqueue. When the iteration ends, the DSQ's marked + * tasks go through ops.enqueue() with %SCX_ENQ_REENQ in DSQ order and the other + * tasks on the DSQ keep their positions. A marked task that leaves the DSQ in + * the meantime is not re-enqueued. The mark belongs to @p, so a re-enqueue + * scheduled by another iteration of the DSQ may re-enqueue @p before this + * iteration ends. @p must be on the DSQ's scheduler. + * + * Re-enqueues are performed asynchronously. Can be called from ops.dispatch() + * or any BPF context which doesn't hold a rq lock (e.g. BPF timers or SYSCALL + * programs). + * + * Return %true if @p was marked, %false if @p left the DSQ or was queued after + * the iteration started, @p is on another scheduler, or the iterator holds no + * DSQ. + */ +__bpf_kfunc bool scx_bpf_dsq_reenq_task(struct bpf_iter_scx_dsq *it__iter, + struct task_struct *p) +{ + struct bpf_iter_scx_dsq_kern *kit = (void *)it__iter; + struct scx_dispatch_q *dsq = kit->dsq; + struct rq *src_rq, *entry_rq; + unsigned long flags; + bool marked = false; + + /* NULL after a failed bpf_iter_scx_dsq_new(), see scx_dsq_move() */ + if (unlikely(!dsq)) + return false; + + /* the cursor check needs @p's rq locked */ + src_rq = task_rq(p); + entry_rq = kf_switch_rq_lock(src_rq, &flags); + + scoped_guard (raw_spinlock, &dsq->lock) { + if (nldsq_cursor_lost_task(&kit->cursor, src_rq, dsq, p)) + break; + + if (unlikely(!scx_task_on_sched(dsq->sched, p))) { + scx_error(dsq->sched, "scx_bpf_dsq_reenq_task() on %s[%d] but the task belongs to a different scheduler", + p->comm, p->pid); + break; + } + + p->scx.dsq_flags |= SCX_TASK_DSQ_REENQ; + /* the walk is scheduled once, by bpf_iter_scx_dsq_destroy() */ + kit->cursor.flags |= __SCX_DSQ_ITER_HAS_REENQ; + marked = true; + } + + kf_restore_rq_lock(src_rq, entry_rq, flags); + return marked; +} + +/** * scx_bpf_reenqueue_local___v2 - Re-enqueue tasks on a local DSQ * @aux: implicit BPF argument to access bpf_prog_aux hidden from BPF progs * @@ -10447,6 +11177,9 @@ __bpf_kfunc void scx_bpf_cpuperf_set(s32 cpu, u32 perf, const struct bpf_prog_au if (unlikely(!sch)) return; + if (!scx_kf_allowed_ctx(sch)) + return; + scx_cpuperf_set(sch, cpu, perf); } @@ -10472,6 +11205,10 @@ __bpf_kfunc s32 scx_bpf_cidperf_set(s32 cid, u32 perf, sch = scx_prog_sched(aux); if (unlikely(!sch)) return -ENODEV; + + if (!scx_kf_allowed_ctx(sch)) + return -EDEADLK; + cpu = scx_cid_to_cpu(sch, cid); if (cpu < 0) return cpu; @@ -10604,12 +11341,17 @@ __bpf_kfunc void scx_bpf_put_cpumask(const struct cpumask *cpumask) } /** - * scx_bpf_task_running - Is task currently running? + * scx_bpf_task_running - Is task the current scheduling context? * @p: task of interest + * + * Under proxy execution, this reports the donor rather than the task whose + * code is physically executing. The physical execution context is intentionally + * not exposed to the BPF scheduler, which continues to observe the donor as the + * running scheduling context. */ __bpf_kfunc bool scx_bpf_task_running(const struct task_struct *p) { - return task_rq(p)->curr == p; + return rcu_access_pointer(task_rq(p)->donor) == p; } /** @@ -10670,10 +11412,15 @@ __bpf_kfunc struct rq *scx_bpf_locked_rq(const struct bpf_prog_aux *aux) } /** - * scx_bpf_cpu_curr - Return remote CPU's curr task + * scx_bpf_cpu_curr - Return remote CPU's current scheduling context * @cpu: CPU of interest * @aux: implicit BPF argument to access bpf_prog_aux hidden from BPF progs * + * Under proxy execution, this returns the donor, which supplies the scheduling + * policy and runtime budget, rather than the task whose code is physically + * executing. The physical execution context is intentionally not exposed to + * the BPF scheduler. + * * Callers must hold RCU read lock (KF_RCU). */ __bpf_kfunc struct task_struct *scx_bpf_cpu_curr(s32 cpu, const struct bpf_prog_aux *aux) @@ -10689,7 +11436,7 @@ __bpf_kfunc struct task_struct *scx_bpf_cpu_curr(s32 cpu, const struct bpf_prog_ if (!scx_cpu_valid(sch, cpu, NULL)) return NULL; - return rcu_dereference(cpu_rq(cpu)->curr); + return rcu_dereference(cpu_rq(cpu)->donor); } /** @@ -10713,7 +11460,7 @@ __bpf_kfunc struct task_struct *scx_bpf_cid_curr(s32 cid, const struct bpf_prog_ cpu = scx_cid_to_cpu(sch, cid); if (cpu < 0) return NULL; - return rcu_dereference(cpu_rq(cpu)->curr); + return rcu_dereference(cpu_rq(cpu)->donor); } /** @@ -10887,6 +11634,23 @@ __bpf_kfunc struct cgroup *scx_bpf_task_cgroup(struct task_struct *p, cgroup_get(cgrp); return cgrp; } + +/** + * scx_bpf_cgroup_nr_cpus - Return the number of CPUs in a cgroup's cpuset + * @cgrp: cgroup of interest + * + * Return the number of CPUs in @cgrp's effective cpuset, which is inherited + * from the nearest ancestor with the cpuset controller enabled. This matches + * the count used by fair's group share calculation and lets hierarchical BPF + * schedulers bound a group's weight by the CPUs it can actually run on. + * + * The value is a snapshot and may change at any time through cpuset updates or + * CPU hotplug. Schedulers should re-read it when recomputing group state. + */ +__bpf_kfunc u32 scx_bpf_cgroup_nr_cpus(struct cgroup *cgrp) +{ + return cpuset_num_cpus(cgrp); +} #endif /* CONFIG_CGROUP_SCHED */ __bpf_kfunc_end_defs(); @@ -10894,6 +11658,7 @@ __bpf_kfunc_end_defs(); BTF_KFUNCS_START(scx_kfunc_ids_any) BTF_ID_FLAGS(func, scx_bpf_task_set_slice, KF_IMPLICIT_ARGS | KF_RCU); BTF_ID_FLAGS(func, scx_bpf_task_set_dsq_vtime, KF_IMPLICIT_ARGS | KF_RCU); +BTF_ID_FLAGS(func, scx_bpf_task_set_lazy_resched, KF_IMPLICIT_ARGS | KF_RCU); BTF_ID_FLAGS(func, scx_bpf_kick_cpu, KF_IMPLICIT_ARGS) BTF_ID_FLAGS(func, scx_bpf_kick_cid, KF_IMPLICIT_ARGS) BTF_ID_FLAGS(func, scx_bpf_dsq_nr_queued, KF_IMPLICIT_ARGS) @@ -10933,6 +11698,7 @@ BTF_ID_FLAGS(func, scx_bpf_now) BTF_ID_FLAGS(func, scx_bpf_events, KF_IMPLICIT_ARGS) #ifdef CONFIG_CGROUP_SCHED BTF_ID_FLAGS(func, scx_bpf_task_cgroup, KF_IMPLICIT_ARGS | KF_RCU | KF_ACQUIRE) +BTF_ID_FLAGS(func, scx_bpf_cgroup_nr_cpus, KF_RCU) #endif BTF_ID_FLAGS(func, scx_bpf_sub_grant, KF_IMPLICIT_ARGS) BTF_ID_FLAGS(func, scx_bpf_sub_revoke, KF_IMPLICIT_ARGS) @@ -11026,6 +11792,7 @@ static const u32 scx_kf_allow_flags[] = { [SCX_OP_IDX(sub_attach)] = SCX_KF_ALLOW_UNLOCKED, [SCX_OP_IDX(sub_detach)] = SCX_KF_ALLOW_UNLOCKED, [SCX_OP_IDX(sub_ecaps_updated)] = SCX_KF_ALLOW_ENQUEUE | SCX_KF_ALLOW_DISPATCH, + [SCX_OP_IDX(sub_child_ecaps_updated)] = SCX_KF_ALLOW_ENQUEUE | SCX_KF_ALLOW_DISPATCH, [SCX_OP_IDX(cpu_online)] = SCX_KF_ALLOW_UNLOCKED, [SCX_OP_IDX(cpu_offline)] = SCX_KF_ALLOW_UNLOCKED, [SCX_OP_IDX(init_cids)] = SCX_KF_ALLOW_UNLOCKED | SCX_KF_ALLOW_INIT_CIDS, @@ -11169,6 +11936,8 @@ static int __init scx_init(void) CID_OFFSET_MATCH(sub_detach, sub_detach); CID_OFFSET_MATCH(sub_caps_updated, sub_caps_updated); CID_OFFSET_MATCH(sub_ecaps_updated, sub_ecaps_updated); + CID_OFFSET_MATCH(sub_cid_sched_updated, sub_cid_sched_updated); + CID_OFFSET_MATCH(sub_child_ecaps_updated, sub_child_ecaps_updated); CID_OFFSET_MATCH(init_cids, init_cids); CID_OFFSET_MATCH(init, init); CID_OFFSET_MATCH(exit, exit);
diff --git a/kernel/sched/ext/ext.h b/kernel/sched/ext/ext.h index 3cfbfeb..d32bc01 100644 --- a/kernel/sched/ext/ext.h +++ b/kernel/sched/ext/ext.h
@@ -18,12 +18,28 @@ bool scx_can_stop_tick(struct rq *rq); void scx_rq_activate(struct rq *rq); void scx_rq_deactivate(struct rq *rq); int scx_check_setscheduler(struct task_struct *p, int policy); +void scx_prepare_setscheduler(struct task_struct *p, int policy); bool task_should_scx(int policy); bool scx_allow_ttwu_queue(const struct task_struct *p); -bool scx_allow_proxy_exec(const struct task_struct *p); +bool __scx_allow_proxy_exec(const struct task_struct *p); void scx_proxy_donor_start(struct rq *rq); void scx_proxy_reenqueue_retry(struct rq *rq, struct task_struct *next); void init_sched_ext_class(void); +void __scx_update_idle(struct rq *rq, bool idle, bool do_notify); + +static inline bool scx_allow_proxy_exec(const struct task_struct *p) +{ + if (scx_enabled()) + return __scx_allow_proxy_exec(p); + + return true; +} + +static inline void scx_update_idle(struct rq *rq, bool idle, bool do_notify) +{ + if (scx_enabled()) + __scx_update_idle(rq, idle, do_notify); +} static inline u32 scx_cpuperf_target(s32 cpu) { @@ -55,6 +71,7 @@ static inline bool scx_can_stop_tick(struct rq *rq) { return true; } static inline void scx_rq_activate(struct rq *rq) {} static inline void scx_rq_deactivate(struct rq *rq) {} static inline int scx_check_setscheduler(struct task_struct *p, int policy) { return 0; } +static inline void scx_prepare_setscheduler(struct task_struct *p, int policy) {} static inline bool task_on_scx(const struct task_struct *p) { return false; } static inline bool scx_allow_ttwu_queue(const struct task_struct *p) { return true; } static inline bool scx_allow_proxy_exec(const struct task_struct *p) { return true; } @@ -62,21 +79,10 @@ static inline void scx_proxy_donor_start(struct rq *rq) {} static inline void scx_proxy_reenqueue_retry(struct rq *rq, struct task_struct *next) {} static inline void init_sched_ext_class(void) {} +static inline void scx_update_idle(struct rq *rq, bool idle, bool do_notify) {} #endif /* CONFIG_SCHED_CLASS_EXT */ -#ifdef CONFIG_SCHED_CLASS_EXT -void __scx_update_idle(struct rq *rq, bool idle, bool do_notify); - -static inline void scx_update_idle(struct rq *rq, bool idle, bool do_notify) -{ - if (scx_enabled()) - __scx_update_idle(rq, idle, do_notify); -} -#else -static inline void scx_update_idle(struct rq *rq, bool idle, bool do_notify) {} -#endif - #ifdef CONFIG_CGROUP_SCHED #ifdef CONFIG_EXT_GROUP_SCHED void scx_tg_init(struct task_group *tg);
diff --git a/kernel/sched/ext/idle.c b/kernel/sched/ext/idle.c index 28ed9e3..922fbc3 100644 --- a/kernel/sched/ext/idle.c +++ b/kernel/sched/ext/idle.c
@@ -153,7 +153,18 @@ static s32 pick_idle_cpu_from_online_nodes(const struct cpumask *cpus_allowed, i nodemask_t *unvisited; s32 cpu = -EBUSY; - preempt_disable(); + /* + * @per_cpu_unvisited is per-CPU scratch and the idle kfuncs can be + * called from IRQ-enabled contexts, so mask IRQs to keep a nested + * invocation from clobbering the mask an outer invocation is still + * iterating. + * + * NMI nesting is not handled: there is no legitimate reason to call + * pick_idle from NMI and doing so poses no crash risk, so such a + * caller is on its own. + */ + guard(irqsave)(); + unvisited = this_cpu_ptr(&per_cpu_unvisited); /* @@ -183,7 +194,6 @@ static s32 pick_idle_cpu_from_online_nodes(const struct cpumask *cpus_allowed, i if (cpu >= 0) break; } - preempt_enable(); return cpu; }
diff --git a/kernel/sched/ext/internal.h b/kernel/sched/ext/internal.h index 352547a..29e69a8 100644 --- a/kernel/sched/ext/internal.h +++ b/kernel/sched/ext/internal.h
@@ -215,6 +215,34 @@ enum scx_ops_flags { */ SCX_OPS_TID_TO_TASK = 1LLU << 8, + /* + * If set, tasks default to requesting lazy rescheduling when their + * slice runs out at the tick, the way fair.c expires a slice from + * update_curr(). The default is copied to p->scx.lazy_resched + * immediately before ops.enable(), after which + * scx_bpf_task_set_lazy_resched() may override it per task. + * + * A task in user space still reschedules on the way back from the tick; + * a task in the kernel runs on to its next return to user space or to + * the next tick, which promotes the request. When lazy preemption is + * disabled at runtime, the request behaves like an immediate + * reschedule. Rescheduling while bypassing stays immediate. + */ + SCX_OPS_LAZY_RESCHED = 1LLU << 9, + + /* + * If set, mutex-blocked tasks remain runnable as proxy donors and are + * passed to ops.enqueue() with %SCX_ENQ_BLOCKED. The BPF scheduler controls + * when donors are dispatched and whether they should preempt other work. + * + * If clear, mutex-blocked tasks are removed from the runqueue normally + * and cannot donate their scheduling context through proxy execution. + * + * For blocked donors, this flag takes precedence over + * %SCX_OPS_ENQ_EXITING and %SCX_OPS_ENQ_MIGRATION_DISABLED. + */ + SCX_OPS_ENQ_BLOCKED = 1LLU << 10, + SCX_OPS_ALL_FLAGS = SCX_OPS_KEEP_BUILTIN_IDLE | SCX_OPS_ENQ_LAST | SCX_OPS_ENQ_EXITING | @@ -223,7 +251,9 @@ enum scx_ops_flags { SCX_OPS_SWITCH_PARTIAL | SCX_OPS_BUILTIN_IDLE_PER_NODE | SCX_OPS_ALWAYS_ENQ_IMMED | - SCX_OPS_TID_TO_TASK, + SCX_OPS_TID_TO_TASK | + SCX_OPS_LAZY_RESCHED | + SCX_OPS_ENQ_BLOCKED, /* high 8 bits are internal, don't include in SCX_OPS_ALL_FLAGS */ __SCX_OPS_INTERNAL_MASK = 0xffLLU << 56, @@ -336,6 +366,18 @@ struct scx_sub_detach_args { char *cgroup_path; }; +/* + * What a sched sees running on a cid, as reported by + * ops.sub_cid_sched_updated(): NONE when the cid is idle or runs a task outside + * the sched's subtree, SELF for the sched itself, or a direct child by its + * cgroup id. The sentinels lie outside the cgroup id space, whose low 32 bits + * are an idr value of at most INT_MAX. + */ +enum scx_cid_sched_consts { + SCX_CID_SCHED_NONE = (u64)-2, + SCX_CID_SCHED_SELF = (u64)-1, +}; + /** * struct sched_ext_ops - Operation table for BPF scheduler implementation * @@ -477,6 +519,12 @@ struct sched_ext_ops { * Therefore, always use scx_bpf_task_cpu(@p) to determine the * target CPU the task is going to use. * + * Under proxy execution, the BPF scheduler continues to observe the + * donor as the current scheduling context. A blocked donor enters a + * ->running()/->stopping() session while its scheduling context drives + * the lock owner. The lock owner executing on its behalf is intentionally + * not reported through these callbacks. + * * See ->runnable() for explanation on the task state notifiers. */ void (*running)(struct task_struct *p); @@ -828,6 +876,11 @@ struct sched_ext_ops { /** * @sub_detach: Detach a sub-scheduler * @args: argument container, see the struct definition + * + * The sub-scheduler holds no caps by this point and can no longer + * affect any cid. Its caps went away without a + * sub_child_ecaps_updated() report, so whatever was delegated to it, + * e.g. cpuperf targets, is the parent's to restore here. */ void (*sub_detach)(struct scx_sub_detach_args *args); @@ -864,6 +917,41 @@ struct sched_ext_ops { */ void (*sub_ecaps_updated)(s32 cid, u64 before, u64 after); + /** + * @sub_cid_sched_updated: The sched running on a cid changed + * @cid: cid whose running sched changed + * @sched: what this sched now sees running there + * + * Invoked when the sched owning the task running on @cid changes. + * @sched is %SCX_CID_SCHED_NONE when no task of this sched's subtree + * runs there, %SCX_CID_SCHED_SELF for its own task, or the cgroup id of + * the direct child whose subtree the task belongs to. Changes inside a + * child's subtree, whether across tasks or nested sub-scheds, are not + * reported. Every sched for which @sched changes is notified. + * + * Runs with the rq lock held on the context switch path. + */ + void (*sub_cid_sched_updated)(s32 cid, u64 sched); + + /** + * @sub_child_ecaps_updated: A child's effective caps on a cid changed + * @cgroup_id: cgroup id of the direct child + * @cid: the cid whose effective caps changed + * @before: the child's effective caps as of the last delivery + * @after: the child's effective caps now + * + * Invoked right after the child's sub_ecaps_updated(), once a grant or + * revoke is in effect on the cpu. From here on the parent can act on a + * cap the child lost, e.g. reset the cpuperf target or schedule on the + * cid. A detaching child's caps go away without a report, see + * sub_detach(). A cpu going offline drops caps without a report. + * + * Runs in dispatch context with rq lock held, and can perform all + * operations allowed in ops.dispatch() including inserting/moving + * tasks. + */ + void (*sub_child_ecaps_updated)(u64 cgroup_id, s32 cid, u64 before, u64 after); + /* * All online ops must come before ops.cpu_online(). */ @@ -911,6 +999,9 @@ struct sched_ext_ops { * ops.exit() is also called on ops.init() failure, which is a bit * unusual. This is to allow rich reporting through @info on how * ops.init() failed. + * + * A sub-scheduler holds no caps by the time ops.exit() runs. Its + * cap-gated kfuncs are denied. */ void (*exit)(struct scx_exit_info *info); @@ -1118,6 +1209,8 @@ struct sched_ext_ops_cid { void (*sub_detach)(struct scx_sub_detach_args *args); void (*sub_caps_updated)(const struct scx_cmask *cmask__arena, u64 caps); void (*sub_ecaps_updated)(s32 cid, u64 before, u64 after); + void (*sub_cid_sched_updated)(s32 cid, u64 sched); + void (*sub_child_ecaps_updated)(u64 cgroup_id, s32 cid, u64 before, u64 after); void (*cid_online)(s32 cid); void (*cid_offline)(s32 cid); s32 (*init_cids)(void); @@ -1359,6 +1452,7 @@ struct scx_sched_pcpu { cpumask_var_t cpus_to_kick; cpumask_var_t cpus_to_kick_if_idle; cpumask_var_t cpus_to_preempt; + cpumask_var_t cpus_to_preempt_lazy; cpumask_var_t cpus_to_wait; struct list_head to_kick_node; @@ -1380,7 +1474,10 @@ struct scx_sched_pcpu { struct llist_node ecaps_to_sync_node; /* owed a forced update_idle() re-notify on this cpu */ bool idle_renotify; - /* effective caps as of the last sub_ecaps_updated() delivery */ + /* + * ecaps as of the last sub_ecaps_updated() and + * sub_child_ecaps_updated() delivery. See __scx_process_sync_ecaps(). + */ u64 reported_ecaps; /* @@ -1439,15 +1536,16 @@ struct scx_sched_pnode { * the allocation pattern. * * ENQ_IMMED insert an IMMED task onto the cid's local DSQ - * - kick the cid's cpu (except SCX_KICK_PREEMPT) + * - kick the cid's cpu (except SCX_KICK_PREEMPT and + * SCX_KICK_PREEMPT_LAZY) * * ENQ insert any task onto the cid's local DSQ (implies ENQ_IMMED) * * PREEMPT preempt any task running on the cid regardless of the owning * sched (implies ENQ). Preempting a task in the sched's own subtree * doesn't require any cap. - * - SCX_ENQ_PREEMPT inserts - * - SCX_KICK_PREEMPT kicks + * - SCX_ENQ_PREEMPT and SCX_ENQ_PREEMPT_LAZY insert + * - SCX_KICK_PREEMPT and SCX_KICK_PREEMPT_LAZY kick * * PERF control the cid's cpu power/perf management state, currently the * cpufreq target set through scx_bpf_cidperf_set(). Hardware @@ -1733,10 +1831,19 @@ enum scx_enq_flags { SCX_ENQ_PREEMPT = 1LLU << 32, /* + * Like %SCX_ENQ_PREEMPT, but request lazy rescheduling. The current + * task's slice is still cleared immediately so that the next scheduling + * boundary observes the new ordering. %SCX_ENQ_PREEMPT takes precedence + * if both are specified. Implies %SCX_ENQ_HEAD, which is all it means + * on a non-local DSQ, as with %SCX_ENQ_PREEMPT. + */ + SCX_ENQ_PREEMPT_LAZY = 1LLU << 35, + + /* * Only allowed on local DSQs. Guarantees that the task either gets * on the CPU immediately and stays on it, or gets reenqueued back - * to the BPF scheduler. It will never linger on a local DSQ or be - * silently put back after preemption. + * to the BPF scheduler. A blocked proxy donor may be put back on the + * local DSQ temporarily while proxy execution resolves its mutex owner. * * The protection persists until the next fresh enqueue - it * survives SAVE/RESTORE cycles, slice extensions and preemption. @@ -1780,6 +1887,18 @@ enum scx_enq_flags { */ SCX_ENQ_LAST = 1LLU << 41, + /* + * The task is blocked on a mutex and is being kept runnable as a proxy + * donor. Only passed to ops.enqueue() when %SCX_OPS_ENQ_BLOCKED is set. + * + * Blocking on the mutex does not enqueue the task by itself. A donor put + * with slice left stays at the head of the local DSQ, except when an + * IMMED donor is preempted or cannot stay local. It is passed to + * ops.enqueue() when its slice runs out, the IMMED placement cannot be + * kept, or proxy execution moves it to the owner's CPU. + */ + SCX_ENQ_BLOCKED = 1LLU << 42, + /* high 8 bits are internal */ __SCX_ENQ_INTERNAL_MASK = 0xffLLU << 56, @@ -1792,6 +1911,15 @@ enum scx_enq_flags { SCX_ENQ_SLICE_DFL = 1LLU << 62, /* carried slice is a default refill */ }; +/* Strip priority and carried slice state when diverting from a local DSQ. */ +static inline void scx_divert_strip_flags(struct task_struct *p, u64 *enq_flags) +{ + *enq_flags &= ~(SCX_ENQ_IMMED | SCX_ENQ_PREEMPT | + SCX_ENQ_PREEMPT_LAZY | SCX_ENQ_HEAD | + SCX_ENQ_APPLY_SLICE | SCX_ENQ_SLICE_DFL); + p->scx.flags &= ~SCX_TASK_IMMED; +} + enum scx_deq_flags { /* expose select DEQUEUE_* flags as enums */ SCX_DEQ_SLEEP = DEQUEUE_SLEEP, @@ -1818,6 +1946,8 @@ enum scx_reenq_flags { /* internal: kernel-issued on cap revoke, not accepted from BPF */ SCX_REENQ_CAP_REVOKE = 1LLU << 1, + /* internal: tasks marked by scx_bpf_dsq_reenq_task() */ + SCX_REENQ_MARKED = 1LLU << 2, __SCX_REENQ_FILTER_MASK = 0xffffLLU, @@ -1859,6 +1989,15 @@ enum scx_kick_flags { * is not on SCX. */ SCX_KICK_WAIT = 1LLU << 2, + + /* + * Like %SCX_KICK_PREEMPT, but request lazy rescheduling. If combined + * with %SCX_KICK_PREEMPT or %SCX_KICK_WAIT, rescheduling is immediate. + */ + SCX_KICK_PREEMPT_LAZY = 1LLU << 3, + + SCX_KICK_ALL_FLAGS = SCX_KICK_IDLE | SCX_KICK_PREEMPT | + SCX_KICK_WAIT | SCX_KICK_PREEMPT_LAZY, }; enum scx_tg_flags { @@ -2107,6 +2246,7 @@ struct task_struct *scx_task_iter_next_locked(struct scx_task_iter *iter); bool scx_set_task_slice(struct task_struct *p, u64 slice); void scx_task_slice_ended(struct rq *rq, struct task_struct *p); void scx_task_unlink_from_dsq(struct task_struct *p, struct scx_dispatch_q *dsq); +void scx_prepare_task_sched_change(struct task_struct *p); void scx_dispatch_dequeue(struct rq *rq, struct task_struct *p); void scx_do_enqueue_task(struct rq *rq, struct task_struct *p, u64 enq_flags, int sticky_cpu); @@ -2168,6 +2308,22 @@ extern struct scx_sched *scx_enabling_sub_sched; #define scx_error(sch, fmt, args...) \ scx_exit((sch), SCX_EXIT_ERROR, 0, fmt, ##args) +/* + * Tracing progs can call kfuncs from NMI. Kfuncs that take scheduler locks or + * touch the kick lists, which are only protected by irq masking, can't run + * there, so abort the scheduler instead. scx_error() is NMI-safe. + */ +static __always_inline bool __scx_kf_allowed_ctx(struct scx_sched *sch, const char *who) +{ + if (unlikely(in_nmi())) { + scx_error(sch, "%s called from NMI", who); + return false; + } + return true; +} + +#define scx_kf_allowed_ctx(sch) __scx_kf_allowed_ctx((sch), __func__) + /** * scx_root_protected_live - Root sched for paths that only run while live * @@ -2258,6 +2414,15 @@ static inline void scx_schedule_reenq_local(struct rq *rq, u64 reenq_flags) */ static inline struct rq *scx_locked_rq(void) { + /* + * Tracing progs can call kfuncs from NMI. scx_locked_rq_state tracks + * the rq locked by the interrupted context, so a non-NULL read from + * NMI would falsely claim its lock. Return NULL from NMI so that + * callers take their unlocked paths. + */ + if (unlikely(in_nmi())) + return NULL; + return __this_cpu_read(scx_locked_rq_state); } @@ -2539,4 +2704,21 @@ static inline struct scx_sched *scx_parent(struct scx_sched *sch) { return NULL; #endif /* CONFIG_EXT_SUB_SCHED */ +/** + * scx_exec_sched - Find the sched running @sch's tasks on @cpu + * @sch: sched owning the tasks + * @cpu: cpu of interest + * + * A bypassing sched's tasks are run by its nearest ancestor that isn't + * bypassing. Return @sch if it isn't bypassing on @cpu, otherwise that + * ancestor, or the root if every ancestor is bypassing. Hold @cpu's rq lock for + * a stable answer. + */ +static inline struct scx_sched *scx_exec_sched(struct scx_sched *sch, s32 cpu) +{ + while (scx_parent(sch) && scx_bypassing(sch, cpu)) + sch = scx_parent(sch); + return sch; +} + #endif /* _KERNEL_SCHED_EXT_INTERNAL_H */
diff --git a/kernel/sched/ext/sub.c b/kernel/sched/ext/sub.c index 212de1c..eb1270f 100644 --- a/kernel/sched/ext/sub.c +++ b/kernel/sched/ext/sub.c
@@ -28,6 +28,13 @@ */ DEFINE_STATIC_KEY_FALSE(__scx_has_subs); +/* + * On while a loaded sched implements ops.sub_cid_sched_updated(), see + * scx_ops_cid_sched_updated_enable(). + */ +static DEFINE_STATIC_KEY_FALSE(__scx_ops_cid_sched_updated_enabled); +static s32 scx_nr_ops_cid_sched_updated; /* such scheds, under scx_enable_mutex */ + /* latched at root enable before any rescue runs */ static s32 scx_rescue_bw_1024; static s64 scx_rescue_quantum_ns; @@ -92,6 +99,161 @@ struct scx_sched *scx_next_descendant_pre(struct scx_sched *pos, struct scx_sche return scx_skip_subtree_pre(pos, root); } +/** + * scx_cid_sched_id_from - Resolve what @from sees when @sch runs on a cid + * @sch: sched whose task runs there, %NULL for none + * @from: sched asking + * + * Return %SCX_CID_SCHED_NONE when @sch is %NULL or outside @from's subtree, + * %SCX_CID_SCHED_SELF for @from itself, or else the cgroup id of the direct + * child of @from on the way down to @sch. + */ +static u64 scx_cid_sched_id_from(struct scx_sched *sch, struct scx_sched *from) +{ + if (!sch || !scx_is_descendant(sch, from)) + return SCX_CID_SCHED_NONE; + if (sch == from) + return SCX_CID_SCHED_SELF; + return sch->ancestors[from->level + 1]->ops.sub_cgroup_id; +} + +/* notify @from of what it now sees running on @rq's cid */ +static void scx_cid_notify_sched_updated(struct rq *rq, struct scx_sched *sch, + struct scx_sched *from) +{ + if (SCX_HAS_OP(from, sub_cid_sched_updated)) + SCX_CALL_OP(from, sub_cid_sched_updated, rq, __scx_cpu_to_cid(cpu_of(rq)), + scx_cid_sched_id_from(sch, from)); +} + +/** + * scx_cid_sched_update - Update rq->scx.sched and notify the scheds affected + * @rq: rq whose running session opens or closes + * @sch: sched starting a session, %NULL to close the open one + * + * Every sched whose scx_cid_sched_id_from() value changes is notified of the + * new one. Above the deepest common ancestor of the two scheds, both map to the + * same child, so the walk stops there. With root R, children A and B, and A's + * child A1, a switch from an A1 task to a B task reports: + * + * R R: A -> B + * / \ + * A B A: A1 -> NONE B: NONE -> SELF + * | + * A1 A1: SELF -> NONE + * + * When the task on one side is not an ext task, there is no common ancestor and + * only the other side is walked. + */ +void scx_cid_sched_update(struct rq *rq, struct scx_sched *sch) +{ + struct scx_sched *prev = rq->scx.sched; + s32 level, common = -1; + + lockdep_assert_rq_held(rq); + + if (!static_branch_unlikely(&__scx_ops_cid_sched_updated_enabled) || prev == sch) + return; + + rq->scx.sched = sch; + + if (prev && sch) { + for (level = min(prev->level, sch->level); level >= 0; level--) + if (prev->ancestors[level] == sch->ancestors[level]) + break; + common = level; + scx_cid_notify_sched_updated(rq, sch, prev->ancestors[common]); + } + if (prev) + for (level = common + 1; level <= prev->level; level++) + scx_cid_notify_sched_updated(rq, sch, prev->ancestors[level]); + if (sch) + for (level = common + 1; level <= sch->level; level++) + scx_cid_notify_sched_updated(rq, sch, sch->ancestors[level]); +} + +/** + * scx_ops_cid_sched_updated_enable - Maintain rq->scx.sched if @sch has the op + * @sch: sched being enabled, its has_op filled in + * + * rq->scx.sched is maintained only while a loaded sched implements + * ops.sub_cid_sched_updated(), so that everyone else pays one static branch per + * session open or close. The first such sched turns the key on and then + * initializes every rq from the task running there, in that order so that no + * session change in between goes unrecorded. While the key is off every + * rq->scx.sched is NULL, see scx_ops_cid_sched_updated_disable(). + */ +void scx_ops_cid_sched_updated_enable(struct scx_sched *sch) +{ + s32 cpu; + + lockdep_assert_held(&scx_enable_mutex); + + if (!SCX_HAS_OP(sch, sub_cid_sched_updated) || scx_nr_ops_cid_sched_updated++) + return; + + static_branch_enable(&__scx_ops_cid_sched_updated_enabled); + + for_each_possible_cpu(cpu) { + struct rq *rq = cpu_rq(cpu); + struct task_struct *p; + + guard(rq_lock_irqsave)(rq); + p = rq->donor; + if (p->sched_class == &ext_sched_class && + (p->scx.flags & SCX_TASK_RUN_TRACKED)) + rq->scx.sched = scx_task_sched(p); + } +} + +/** + * scx_ops_cid_sched_updated_disable - Stop maintaining rq->scx.sched for @sch + * @sch: sched being disabled, its tasks all gone + * + * Close the session on every rq that still points at @sch, before ops.exit(), + * so that no sched is notified of @sch once it is gone. The last sched with the + * op turns the key off first and clears every rq, so while the key is off every + * rq->scx.sched is NULL. A sched whose enable failed before its has_op fill was + * never counted, so has_op gates the decrement. + */ +void scx_ops_cid_sched_updated_disable(struct scx_sched *sch) +{ + bool last; + s32 cpu; + + lockdep_assert_held(&scx_enable_mutex); + + last = SCX_HAS_OP(sch, sub_cid_sched_updated) && !--scx_nr_ops_cid_sched_updated; + if (last) + static_branch_disable(&__scx_ops_cid_sched_updated_enabled); + + /* + * Re-homing restarts a running task's session under its new sched. A + * task that blocked while its cpu's dispatch had the rq lock dropped is + * put and set next again without a restart, so rq->scx.sched keeps @sch + * until the pick completes: + * + * cpu 0, __schedule() cpu 1, scx_sub_disable(@sch) + * T of @sch blocks, stops running + * dispatch drops the rq lock + * re-home T, nothing to restart + * this sweep + * pick N, N's session opens + * + * Closing the session here reports NONE to @sch and its ancestors now + * and lets the pick report N's sched from NONE instead of from @sch. + */ + for_each_possible_cpu(cpu) { + struct rq *rq = cpu_rq(cpu); + + guard(rq_lock_irqsave)(rq); + if (rq->scx.sched == sch) + scx_cid_sched_update(rq, NULL); + if (last) + rq->scx.sched = NULL; + } +} + static struct scx_sched *scx_find_sub_sched(u64 cgroup_id) { return rhashtable_lookup(&scx_sched_hash, &cgroup_id, @@ -285,7 +447,8 @@ void scx_rescue_charge(struct rq *rq, s64 delta_exec) rq->scx.rescue.budget -= delta_exec; /* per-cpu usage average feeds the overload victim pick */ - pcpu = per_cpu_ptr(scx_task_sched(rq->curr)->pcpu, cpu_of(rq)); + pcpu = per_cpu_ptr(scx_task_sched(rq->scx.rescue.curr)->pcpu, + cpu_of(rq)); pcpu->rescue_avg = scx_rescue_decay_avg(pcpu) + delta_exec; if (!scx_rescue_slice_remaining(rq)) @@ -557,7 +720,7 @@ static void scx_rescue_timerfn(struct timer_list *timer) scx_rescue_admit(rq, p, slice); scx_move_local_task_to_local_dsq(scx_task_sched(p), p, SCX_ENQ_IGNORE_CAPS, rq); - if (sched_class_above(&ext_sched_class, rq->curr->sched_class)) + if (sched_class_above(&ext_sched_class, rq->donor->sched_class)) resched_curr(rq); } else if (p->scx.dsq && rq->scx.rescue.budget > 2 * scx_rescue_quantum_ns) { /* @@ -671,7 +834,7 @@ void scx_rescue_init(struct rq *rq) } /** - * scx_resolve_local_dsq - Pick the local, rescue or reject DSQ for an insert + * __scx_resolve_local_dsq - Pick the local, rescue or reject DSQ for an insert * @sch: enqueuing sub-sched * @rq: rq whose local DSQ @p targets * @p: task being inserted @@ -682,20 +845,18 @@ void scx_rescue_init(struct rq *rq) * rescue is enabled, or @rq's reject DSQ after recording the reenq reason on * @p. * - * %SCX_ENQ_IMMED, %SCX_ENQ_PREEMPT and %SCX_ENQ_HEAD are cleared when diverting - * to rescue or reject. %SCX_ENQ_PREEMPT is also cleared on a fallback - * migration-disabled admission. + * %SCX_ENQ_IMMED, %SCX_ENQ_PREEMPT, %SCX_ENQ_PREEMPT_LAZY and %SCX_ENQ_HEAD are + * cleared when diverting to rescue or reject. %SCX_ENQ_PREEMPT and + * %SCX_ENQ_PREEMPT_LAZY are also cleared on a fallback migration-disabled + * admission. * * Bypass doesn't need special-casing as a bypassing sched's tasks are enqueued * to and run by its nearest non-bypassing ancestor. If root is bypassing, it * always holds all caps. */ -struct scx_dispatch_q *scx_resolve_local_dsq(struct scx_sched *sch, struct rq *rq, - struct task_struct *p, u64 *enq_flags) +struct scx_dispatch_q *__scx_resolve_local_dsq(struct scx_sched *sch, struct rq *rq, + struct task_struct *p, u64 *enq_flags) { - if (!scx_has_subs()) - return &rq->scx.local_dsq; - s32 cid = __scx_cpu_to_cid(cpu_of(rq)); struct scx_sched *asch = rq->scx.remote_activate_sch ?: sch; u64 needed = scx_caps_for_enq(*enq_flags); @@ -705,7 +866,7 @@ struct scx_dispatch_q *scx_resolve_local_dsq(struct scx_sched *sch, struct rq *r * On a remote activation the scheduling sched (@asch) differs from * @p's owner (@sch). Check caps against the scheduling sched. */ - if (*enq_flags & SCX_ENQ_PREEMPT) + if (*enq_flags & (SCX_ENQ_PREEMPT | SCX_ENQ_PREEMPT_LAZY)) needed |= scx_caps_for_preempt(asch, rq, *enq_flags); missing = scx_missing_caps(asch, cpu_of(rq), needed); @@ -722,7 +883,7 @@ struct scx_dispatch_q *scx_resolve_local_dsq(struct scx_sched *sch, struct rq *r if (unlikely(!scx_rq_online(rq) || is_migration_disabled(p) || p->migration_pending)) { __scx_add_event(sch, SCX_EV_SUB_FORCED_ADMIT, 1); - *enq_flags &= ~SCX_ENQ_PREEMPT; + *enq_flags &= ~(SCX_ENQ_PREEMPT | SCX_ENQ_PREEMPT_LAZY); return &rq->scx.local_dsq; } @@ -731,9 +892,7 @@ struct scx_dispatch_q *scx_resolve_local_dsq(struct scx_sched *sch, struct rq *r * or HEAD - a diversion has no priority and IMMED is not allowed on * non-local DSQs. Strip the enq and task flags along with the slice. */ - *enq_flags &= ~(SCX_ENQ_IMMED | SCX_ENQ_PREEMPT | SCX_ENQ_HEAD | - SCX_ENQ_APPLY_SLICE | SCX_ENQ_SLICE_DFL); - p->scx.flags &= ~SCX_TASK_IMMED; + scx_divert_strip_flags(p, enq_flags); /* the enqueuer opted for rescue instead of rejection and reenqueue */ if ((*enq_flags & SCX_ENQ_RESCUE) && likely(scx_rescue_bw_1024)) { @@ -748,6 +907,8 @@ struct scx_dispatch_q *scx_resolve_local_dsq(struct scx_sched *sch, struct rq *r p->scx.reenq_reason_caps = missing; p->scx.reenq_reason_cid = cid; + WARN_ON_ONCE(p->scx.flags & SCX_TASK_REENQ_REASON_MASK); + p->scx.flags |= SCX_TASK_REENQ_CAP; return &rq->scx.reject_dsq; } @@ -755,67 +916,24 @@ struct scx_dispatch_q *scx_resolve_local_dsq(struct scx_sched *sch, struct rq *r /* @p lost the caps needed to stay on @rq's local DSQ? Record reason if so. */ bool scx_task_reenq_on_cap_revoke(struct rq *rq, struct task_struct *p) { + s32 cpu = cpu_of(rq); u64 missing; /* migration-disabled tasks and the rescuee are admitted capless */ if (is_migration_disabled(p) || p == scx_rescuee(rq)) return false; - missing = scx_missing_caps(scx_task_sched(p), cpu_of(rq), scx_caps_for_task(p)); + /* check caps against the sched running a bypassed task */ + missing = scx_missing_caps(scx_exec_sched(scx_task_sched(p), cpu), cpu, + scx_caps_for_task(p)); if (likely(!missing)) return false; p->scx.reenq_reason_caps = missing; - p->scx.reenq_reason_cid = __scx_cpu_to_cid(cpu_of(rq)); + p->scx.reenq_reason_cid = __scx_cpu_to_cid(cpu); return true; } -/* - * Drain @rq->scx.reject_dsq, reenqueueing each task so the BPF re-decides - * from p->scx.reenq_reason_*. - * - * A task can be re-rejected repeatedly. The reenqueue is bounded per task in - * scx_do_enqueue_task(), which ejects the owning sub past SCX_REENQ_MAX_REPEAT. - * Rejection can't happen for root. - */ -void scx_reenq_reject(struct rq *rq) -{ - LIST_HEAD(tasks); - struct task_struct *p, *n; - - lockdep_assert_rq_held(rq); - - if (!scx_has_subs() || list_empty(&rq->scx.reject_dsq.list)) - return; - - /* - * Move to a private list so a task re-rejected by the - * scx_do_enqueue_task() below isn't revisited this round. - */ - list_for_each_entry_safe(p, n, &rq->scx.reject_dsq.list, scx.dsq_list.node) { - /* migration_pending tasks should have bypassed to local DSQ */ - if (WARN_ON_ONCE(p->migration_pending)) - continue; - - scx_wait_dispatching(p); - scx_dispatch_dequeue(rq, p); - - if (WARN_ON_ONCE(p->scx.flags & SCX_TASK_REENQ_REASON_MASK)) - p->scx.flags &= ~SCX_TASK_REENQ_REASON_MASK; - p->scx.flags |= SCX_TASK_REENQ_CAP; - - list_add_tail(&p->scx.dsq_list.node, &tasks); - } - - list_for_each_entry_safe(p, n, &tasks, scx.dsq_list.node) { - list_del_init(&p->scx.dsq_list.node); - - scx_do_enqueue_task(rq, p, SCX_ENQ_REENQ, -1); - - p->scx.flags &= ~SCX_TASK_REENQ_REASON_MASK; - } -} - /* record a caps change, see struct scx_caps_updated */ static void caps_updated_record(struct scx_pshard *ps, const struct scx_cmask *cids, u64 caps, struct list_head *to_deliver) @@ -921,7 +1039,7 @@ static void queue_sync_ecaps(struct scx_sched *sch, s32 cid) struct scx_sched_pcpu *pcpu = per_cpu_ptr(sch->pcpu, cpu); /* - * Pairs with smp_mb() in scx_process_sync_ecaps(). Either the check + * Pairs with smp_mb() in __scx_process_sync_ecaps(). Either the check * below sees the node off the list and queues it, or the in-flight sync * sees the caps[] update made before this call. */ @@ -946,7 +1064,7 @@ static void discard_queued_syncs(struct rq *rq) } /** - * scx_process_sync_ecaps - Sync this cpu's ecaps to pshard->caps[] + * __scx_process_sync_ecaps - Sync this cpu's ecaps to pshard->caps[] * @rq: the cid's cpu rq * @prev: @rq's previous task from the in-progress dispatch * @@ -958,16 +1076,14 @@ static void discard_queued_syncs(struct rq *rq) * learns the cid's idle state. Such a gain arms the per-rq * %SCX_RQ_SUB_IDLE_RENOTIFY gate so the next idle pick delivers it. */ -void scx_process_sync_ecaps(struct rq *rq, struct task_struct *prev) +void __scx_process_sync_ecaps(struct rq *rq, struct task_struct *prev) { s32 cpu = cpu_of(rq); s32 cid, shard; struct llist_node *batch, *pos, *tmp; u64 lost_all = 0; - lockdep_assert_rq_held(rq); - - if (!scx_has_subs() || likely(llist_empty(&rq->scx.ecaps_to_sync))) + if (likely(llist_empty(&rq->scx.ecaps_to_sync))) return; /* @@ -1008,27 +1124,43 @@ void scx_process_sync_ecaps(struct rq *rq, struct task_struct *prev) lost_all |= lost; /* - * Tell the sched its effective caps on this cid changed. The - * invocation is equivalent to the dispatch path and may drop - * and re-acquire the rq lock temporarily while the rest of - * @batch is held privately, see scx_discard_ecaps_to_sync(). - * The dispatch kfuncs resolve their context on the executing - * cpu, which under core scheduling can differ from @rq's cpu, - * so the context is set up there. The rq recorded in it keeps - * the dispatches targeting @rq. + * Tell the sched and its parent that the sched's effective caps + * on this cid changed. The invocations are equivalent to the + * dispatch path and may drop and re-acquire the rq lock + * temporarily while the rest of @batch is held privately, see + * scx_discard_ecaps_to_sync(). The dispatch kfuncs resolve + * their context on the executing cpu, which under core + * scheduling can differ from @rq's cpu, so the context is set + * up there. The rq recorded in it keeps the dispatches + * targeting @rq. + * + * Bypass propagates down the hierarchy, so a sched that isn't + * bypassing has no bypassing parent. The child's bypass state + * gates both deliveries. Both report the same before value, so + * one reported_ecaps covers them. */ - if (ecaps != pcpu->reported_ecaps && - SCX_HAS_OP(pcpu->sch, sub_ecaps_updated) && - !scx_bypassing(pcpu->sch, cpu)) { - struct scx_dsp_ctx *dspc = &this_cpu_ptr(pcpu->sch->pcpu)->dsp_ctx; + if (ecaps != pcpu->reported_ecaps && !scx_bypassing(pcpu->sch, cpu)) { + struct scx_sched *parent = scx_parent(pcpu->sch); + struct scx_dsp_ctx *dspc; - dspc->rq = rq; /* stash @prev so nested dispatches can access it */ rq->scx.sub_dispatch_prev = prev; - SCX_CALL_OP(pcpu->sch, sub_ecaps_updated, rq, scx_cpu_arg(cpu), - pcpu->reported_ecaps, ecaps); + if (SCX_HAS_OP(pcpu->sch, sub_ecaps_updated)) { + dspc = &this_cpu_ptr(pcpu->sch->pcpu)->dsp_ctx; + dspc->rq = rq; + SCX_CALL_OP(pcpu->sch, sub_ecaps_updated, rq, + scx_cpu_arg(cpu), pcpu->reported_ecaps, ecaps); + scx_flush_dispatch_buf(pcpu->sch, rq); + } + if (SCX_HAS_OP(parent, sub_child_ecaps_updated)) { + dspc = &this_cpu_ptr(parent->pcpu)->dsp_ctx; + dspc->rq = rq; + SCX_CALL_OP(parent, sub_child_ecaps_updated, rq, + pcpu->sch->ops.sub_cgroup_id, scx_cpu_arg(cpu), + pcpu->reported_ecaps, ecaps); + scx_flush_dispatch_buf(parent, rq); + } rq->scx.sub_dispatch_prev = NULL; - scx_flush_dispatch_buf(pcpu->sch, rq); pcpu->reported_ecaps = ecaps; } @@ -1154,6 +1286,34 @@ void scx_offline_ecaps(struct rq *rq) } /* + * Clear every cap @sch holds. The pshard caps go first as they are the source a + * pending sync recomputes ecaps from. ecaps are then zeroed directly for the + * cap checks. + */ +static void clear_all_caps(struct scx_sched *sch) +{ + s32 si, cpu; + u32 cap_bit; + + /* enable may have failed before scx_alloc_pshards() */ + if (!sch->pshard) + return; + + for (si = 0; si < sch->nr_pshards; si++) { + struct scx_pshard *ps = sch->pshard[si]; + + guard(raw_spinlock_irqsave)(&ps->lock); + for (cap_bit = 0; cap_bit < __SCX_NR_CAPS; cap_bit++) + scx_cmask_clear(&ps->caps[cap_bit].cmask); + } + + for_each_possible_cpu(cpu) { + guard(rq_lock_irqsave)(cpu_rq(cpu)); + WRITE_ONCE(per_cpu_ptr(sch->pcpu, cpu)->ecaps, 0); + } +} + +/* * @pcpu's sched was unhashed before the grace period, so nothing re-queues its * sync node. Remove the node from @rq's pending list so the pcpu can be freed. */ @@ -1252,7 +1412,9 @@ static void scx_rehome_task(struct scx_sched *to, struct task_struct *p) lockdep_assert_held(&p->pi_lock); lockdep_assert_rq_held(task_rq(p)); - scoped_guard (sched_change, p, DEQUEUE_SAVE | DEQUEUE_MOVE) { + scx_prepare_task_sched_change(p); + scoped_guard (sched_change, p, + DEQUEUE_SAVE | DEQUEUE_MOVE | DEQUEUE_NOCLOCK) { scx_disable_and_exit_task(scx_task_sched(p), p); scx_set_task_state(p, SCX_TASK_INIT_BEGIN); scx_set_task_state(p, SCX_TASK_INIT); @@ -1282,7 +1444,9 @@ static void scx_punt_task(struct scx_sched *to, struct task_struct *p) lockdep_assert_rq_held(task_rq(p)); WARN_ON_ONCE(!READ_ONCE(to->bypass_depth)); - scoped_guard (sched_change, p, DEQUEUE_SAVE | DEQUEUE_MOVE) { + scx_prepare_task_sched_change(p); + scoped_guard (sched_change, p, + DEQUEUE_SAVE | DEQUEUE_MOVE | DEQUEUE_NOCLOCK) { scx_disable_and_exit_task(scx_task_sched(p), p); scx_set_task_sched(p, to); } @@ -1358,7 +1522,7 @@ static s32 scx_cgroup_claim_subtree(struct scx_sched *sch) .bw_period_us = tg->scx.bw_period_us, .bw_quota_us = tg->scx.bw_quota_us, .bw_burst_us = tg->scx.bw_burst_us, - .sched_idle = tg->scx.idle, + .sched_idle = tg->scx.sched_idle, }; if (tg->scx.sched != parent || @@ -1462,7 +1626,7 @@ static void scx_cgroup_return_subtree(struct scx_sched *sch) .bw_period_us = tg->scx.bw_period_us, .bw_quota_us = tg->scx.bw_quota_us, .bw_burst_us = tg->scx.bw_burst_us, - .sched_idle = tg->scx.idle, + .sched_idle = tg->scx.sched_idle, }; /* the first pass must have transferred everything */ @@ -1616,6 +1780,8 @@ void scx_sub_disable(struct scx_sched *sch) scx_cgroup_unlock(); percpu_up_write(&scx_fork_rwsem); + scx_ops_cid_sched_updated_disable(sch); + /* * All tasks are moved off of @sch but there may still be on-going * operations (e.g. ops.select_cpu()). Drain them by flushing RCU. Use @@ -1628,6 +1794,12 @@ void scx_sub_disable(struct scx_sched *sch) scx_unlink_sched(sch); + /* + * The parent restores what it delegated in ops.sub_detach(). @sch must + * hold no caps by then. + */ + clear_all_caps(sch); + mutex_unlock(&scx_enable_mutex); /* @@ -1787,6 +1959,15 @@ void scx_sub_enable_workfn(struct kthread_work *work) if (ret) goto err_disable; + /* + * Bypass before @sch is linked and grants can reach it. The parent's + * delivery advances reported_ecaps, so a sync consumed before @sch's + * ops are registered would reach the parent and never be replayed to + * @sch. While bypassed, the syncs are consumed without a delivery and + * replayed to both at unbypass. + */ + scx_bypass(sch, true); + ret = scx_link_sched(sch); if (ret) goto err_disable; @@ -1832,12 +2013,12 @@ void scx_sub_enable_workfn(struct kthread_work *work) } sch->sub_attached = true; - scx_bypass(sch, true); - for (i = SCX_OPI_BEGIN; i < SCX_OPI_END; i++) if (((void (**)(void))ops)[i]) set_bit(i, sch->has_op); + scx_ops_cid_sched_updated_enable(sch); + percpu_down_write(&scx_fork_rwsem); scx_cgroup_lock(); @@ -1940,7 +2121,9 @@ void scx_sub_enable_workfn(struct kthread_work *work) if (!(p->scx.flags & SCX_TASK_SUB_INIT)) continue; - scoped_guard (sched_change, p, DEQUEUE_SAVE | DEQUEUE_MOVE) { + scx_prepare_task_sched_change(p); + scoped_guard (sched_change, p, + DEQUEUE_SAVE | DEQUEUE_MOVE | DEQUEUE_NOCLOCK) { /* * $p must be either READY or ENABLED. If ENABLED, * __scx_disabled_and_exit_task() first disables and @@ -2266,6 +2449,9 @@ static s32 sub_cap_preamble(u64 cgroup_id, u64 caps, const struct bpf_prog_aux * if (unlikely(!parent)) return -ENODEV; + if (!scx_kf_allowed_ctx(parent)) + return -EDEADLK; + if (!scx_is_cid_type()) { scx_error(parent, "sub-cap kfuncs require a cid-form scheduler"); return -EOPNOTSUPP; @@ -2306,8 +2492,8 @@ static s32 sub_cap_preamble(u64 cgroup_id, u64 caps, const struct bpf_prog_aux * * All-or-nothing keeps the caller-visible result binary per cid, so the denied * mask is one mask to interpret rather than a per-cap matrix. * - * Return 0 on full success, -EPERM if any cid was refused, or a negative - * errno on other failures. + * Return 0 on full success, -EPERM if any cid was refused, -ENODEV if the child + * is gone or being disabled, or a negative errno on other failures. */ __bpf_kfunc s32 scx_bpf_sub_grant(u64 cgroup_id, u64 caps, const struct scx_cmask *cmask__arena, @@ -2361,6 +2547,12 @@ __bpf_kfunc s32 scx_bpf_sub_grant(u64 cgroup_id, u64 caps, scoped_guard (raw_spinlock, &pps->lock) { guard(raw_spinlock_nested)(&cps->lock); + /* the child is being disabled, see clear_all_caps() */ + if (unlikely(READ_ONCE(child->aborting))) { + ret = -ENODEV; + goto out; + } + /* * Narrow granted_cids to cids the parent holds every * requested cap on. All-or-nothing per cid. @@ -2413,9 +2605,10 @@ __bpf_kfunc s32 scx_bpf_sub_grant(u64 cgroup_id, u64 caps, } } + ret = any_denied ? -EPERM : 0; +out: caps_updated_deliver(&to_deliver); - - return any_denied ? -EPERM : 0; + return ret; } /**
diff --git a/kernel/sched/ext/sub.h b/kernel/sched/ext/sub.h index f7bcdfd..b76d7504 100644 --- a/kernel/sched/ext/sub.h +++ b/kernel/sched/ext/sub.h
@@ -16,6 +16,9 @@ struct scx_sched *scx_skip_subtree_pre(struct scx_sched *pos, struct scx_sched *root); struct scx_sched *scx_next_descendant_pre(struct scx_sched *pos, struct scx_sched *root); +void scx_cid_sched_update(struct rq *rq, struct scx_sched *sch); +void scx_ops_cid_sched_updated_enable(struct scx_sched *sch); +void scx_ops_cid_sched_updated_disable(struct scx_sched *sch); void scx_set_task_sched(struct task_struct *p, struct scx_sched *sch); struct cgroup *sch_cgroup(struct scx_sched *sch); void set_cgroup_sched(struct cgroup *cgrp, struct scx_sched *sch); @@ -28,16 +31,15 @@ bool scx_bpf_sub_dispatch(u64 cgroup_id, const struct bpf_prog_aux *aux); void scx_free_pshards(struct scx_sched *sch); s32 scx_alloc_pshards(struct scx_sched *sch); void scx_init_root_caps(struct scx_sched *sch); -void scx_process_sync_ecaps(struct rq *rq, struct task_struct *prev); +void __scx_process_sync_ecaps(struct rq *rq, struct task_struct *prev); void scx_unbypass_replay_ecaps(struct rq *rq, struct scx_sched *sch); void scx_online_ecaps(struct rq *rq); void scx_offline_ecaps(struct rq *rq); void scx_discard_ecaps_to_sync(s32 cpu, struct scx_sched_pcpu *pcpu); void scx_discard_stale_ecaps_syncs(void); -struct scx_dispatch_q *scx_resolve_local_dsq(struct scx_sched *sch, struct rq *rq, - struct task_struct *p, u64 *enq_flags); +struct scx_dispatch_q *__scx_resolve_local_dsq(struct scx_sched *sch, struct rq *rq, + struct task_struct *p, u64 *enq_flags); bool scx_task_reenq_on_cap_revoke(struct rq *rq, struct task_struct *p); -void scx_reenq_reject(struct rq *rq); void scx_rescue_charge(struct rq *rq, s64 delta_exec); void scx_rescue_end(struct rq *rq); bool scx_rescue_keep(struct rq *rq, struct task_struct *p); @@ -72,10 +74,32 @@ static inline void scx_dec_has_subs(struct scx_sched *sch) static_branch_dec(&__scx_has_subs); } +/* hot-path hooks, gated inline so that a root-only system skips the calls */ +static inline void scx_process_sync_ecaps(struct rq *rq, struct task_struct *prev) +{ + lockdep_assert_rq_held(rq); + + if (scx_has_subs()) + __scx_process_sync_ecaps(rq, prev); +} + +static inline struct scx_dispatch_q *scx_resolve_local_dsq(struct scx_sched *sch, + struct rq *rq, + struct task_struct *p, + u64 *enq_flags) +{ + if (!scx_has_subs()) + return &rq->scx.local_dsq; + return __scx_resolve_local_dsq(sch, rq, p, enq_flags); +} + #else /* CONFIG_EXT_SUB_SCHED */ static inline struct scx_sched *scx_next_descendant_pre(struct scx_sched *pos, struct scx_sched *root) { return pos ? NULL : root; } static inline struct scx_sched *scx_skip_subtree_pre(struct scx_sched *pos, struct scx_sched *root) { return NULL; } +static inline void scx_cid_sched_update(struct rq *rq, struct scx_sched *sch) {} +static inline void scx_ops_cid_sched_updated_enable(struct scx_sched *sch) {} +static inline void scx_ops_cid_sched_updated_disable(struct scx_sched *sch) {} static inline void scx_set_task_sched(struct task_struct *p, struct scx_sched *sch) {} static inline struct cgroup *sch_cgroup(struct scx_sched *sch) { return NULL; } static inline const char *sch_cgrp_path(struct scx_sched *sch) { return "/"; } @@ -93,7 +117,6 @@ static inline void scx_discard_ecaps_to_sync(s32 cpu, struct scx_sched_pcpu *pcp static inline void scx_discard_stale_ecaps_syncs(void) {} static inline struct scx_dispatch_q *scx_resolve_local_dsq(struct scx_sched *sch, struct rq *rq, struct task_struct *p, u64 *enq_flags) { return &rq->scx.local_dsq; } static inline bool scx_task_reenq_on_cap_revoke(struct rq *rq, struct task_struct *p) { return false; } -static inline void scx_reenq_reject(struct rq *rq) {} static inline void scx_rescue_charge(struct rq *rq, s64 delta_exec) {} static inline void scx_rescue_end(struct rq *rq) {} static inline bool scx_rescue_keep(struct rq *rq, struct task_struct *p) { return false; } @@ -169,17 +192,18 @@ static inline u64 scx_caps_for_task(struct task_struct *p) return SCX_CAP_ENQ; } -/* the cap @sch needs to preempt @rq's current task, 0 if none */ -static inline u64 scx_caps_for_preempt(struct scx_sched *sch, struct rq *rq, u64 enq_flags) +/* the cap @sch needs to preempt @rq's current scheduling context, 0 if none */ +static inline u64 scx_caps_for_preempt(struct scx_sched *sch, struct rq *rq, + u64 enq_flags) { - struct task_struct *curr = rq->curr; + struct task_struct *donor = rq->donor; /* a kernel-forced placement preempts regardless of caps */ if (unlikely(enq_flags & SCX_ENQ_IGNORE_CAPS)) return 0; /* a non-ext task can't be preempted by ext, own-subtree needs no cap */ - if (curr->sched_class != &ext_sched_class || - scx_is_descendant(scx_task_sched(curr), sch)) + if (donor->sched_class != &ext_sched_class || + scx_is_descendant(scx_task_sched(donor), sch)) return 0; return SCX_CAP_PREEMPT; } @@ -199,6 +223,8 @@ static inline u64 scx_caps_implied(u64 cap) /* may @p keep running on @rq's cpu? requires baseline cpu access */ static inline bool scx_task_can_stay_on_cpu(struct rq *rq, struct task_struct *p) { + s32 cpu = cpu_of(rq); + if (!scx_has_subs()) return true; @@ -206,7 +232,9 @@ static inline bool scx_task_can_stay_on_cpu(struct rq *rq, struct task_struct *p if (unlikely(is_migration_disabled(p))) return true; - return likely(!scx_missing_caps(scx_task_sched(p), cpu_of(rq), SCX_CAP_BASE)); + /* check caps against the sched running a bypassed task */ + return likely(!scx_missing_caps(scx_exec_sched(scx_task_sched(p), cpu), cpu, + SCX_CAP_BASE)); } /* the task admitted for rescue on @rq, NULL if none */
diff --git a/kernel/sched/ext/types.h b/kernel/sched/ext/types.h index 139176c..38514d6 100644 --- a/kernel/sched/ext/types.h +++ b/kernel/sched/ext/types.h
@@ -59,17 +59,31 @@ enum scx_consts { }; /* - * Per-cid topology info. For each topology level (core, LLC, node) and shard, - * records the first cid in the unit and its global index. Global indices are - * consecutive integers assigned in cid-walk order, so e.g. core_idx ranges over - * [0, nr_cores_at_init) with no gaps. No-topo cids have core/LLC/node fields - * set to -1 but always have valid shard assignments. + * Per-cid topology info. For each topology level (core, cluster, LLC, node) and + * shard, records the first cid in the unit and its global index. Global indices + * are consecutive integers assigned in cid-walk order, so e.g. core_idx ranges + * over [0, nr_cores_at_init) with no gaps. No-topo cids have core/cluster/LLC/ + * node fields set to -1 but always have valid shard assignments. + * + * A cluster is the cache-sharing level between the core and the LLC. Where + * this level is absent, each core forms a cluster of its own. Where the cache + * level spans the LLC, the whole LLC forms one cluster. Each cluster has a + * unique cluster_cid and a dense cluster_idx, and its cids form a contiguous + * range. + * + * Every cid therefore has a cluster, so cluster_cid alone does not say whether + * the machine has the level: the first cluster of an LLC starts at the LLC's + * own base cid and a core-wide one at the core's. * * Shards are contiguous CID ranges used as scalable locking/work domains for * sub-scheduler operations. By default each LLC becomes one shard, split into * smaller shards if the LLC exceeds the target size. No-topo cids are packed * into their own max-sized shards. * + * Shards are cut on core boundaries only, so a shard doesn't need to contain a + * whole cluster: a cluster may straddle two shards. Only core, cluster, LLC + * and node are nested, in that order. + * * New fields are appended, never inserted: scx_bpf_cid_topo() copies this * struct out sized by the program's own layout, and an older program's copy * must stay a prefix of the kernel's. @@ -82,6 +96,8 @@ enum scx_consts { * @node_idx: global index of that node, in [0, nr_nodes_at_init) * @shard_cid: first cid of this cid's shard * @shard_idx: global index of that shard, in [0, scx_nr_cid_shards) + * @cluster_cid: first cid of this cid's cluster + * @cluster_idx: global index of that cluster, in [0, nr_clusters_at_init) */ struct scx_cid_topo { s32 core_cid; @@ -92,6 +108,8 @@ struct scx_cid_topo { s32 node_idx; s32 shard_cid; s32 shard_idx; + s32 cluster_cid; + s32 cluster_idx; }; enum scx_cid_consts {
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index 499a564..87c5335 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h
@@ -791,6 +791,10 @@ enum scx_rq_flags { SCX_RQ_BAL_CB_PENDING = 1 << 6, /* must queue a cb after dispatching */ SCX_RQ_SUB_IDLE_RENOTIFY = 1 << 7, /* sub-scheds are owed update_idle() */ SCX_RQ_ROOT_IDLE_RENOTIFY = 1 << 8, /* the root is owed update_idle() */ + SCX_RQ_PROXY_RETRY = 1 << 9, /* proxy-rejected tasks need retry */ + SCX_RQ_PROXY_TICK = 1 << 10, /* proxy execution requires the tick */ + SCX_RQ_PROXY_PENDING = 1 << 11, /* blocked donor awaits proxy resolution */ + SCX_RQ_PROXY_BLOCKING = 1 << 12, /* donor is being removed for sched change */ SCX_RQ_IN_WAKEUP = 1 << 16, SCX_RQ_IN_DISPATCH = 1 << 17, @@ -810,8 +814,8 @@ struct scx_rq_rescue { struct scx_rq { struct scx_dispatch_q local_dsq; + struct scx_dispatch_q reject_dsq; /* staging for rejected tasks */ #ifdef CONFIG_EXT_SUB_SCHED - struct scx_dispatch_q reject_dsq; /* staging for cap-rejected tasks */ struct scx_rq_rescue rescue; #endif struct list_head runnable_list; /* runnable tasks on this rq */ @@ -830,6 +834,8 @@ struct scx_rq { #endif u64 clock; /* current per-rq clock -- see scx_bpf_now() */ #ifdef CONFIG_EXT_SUB_SCHED + /* sched of the open running session, see scx_cid_sched_update() */ + struct scx_sched *sched; struct llist_head ecaps_to_sync; /* pending ecaps syncs */ struct task_struct *sub_dispatch_prev; #endif @@ -844,6 +850,9 @@ struct scx_rq { struct list_head deferred_reenq_users; /* user DSQs requesting reenq */ struct balance_callback deferred_bal_cb; struct balance_callback kick_sync_bal_cb; +#ifdef CONFIG_NO_HZ_FULL + struct balance_callback proxy_tick_bal_cb; +#endif struct irq_work deferred_irq_work; struct irq_work kick_cpus_irq_work; };
diff --git a/kernel/sched/syscalls.c b/kernel/sched/syscalls.c index b215b0e..45a127d 100644 --- a/kernel/sched/syscalls.c +++ b/kernel/sched/syscalls.c
@@ -678,6 +678,8 @@ int __sched_setscheduler(struct task_struct *p, if (prev_class != next_class) queue_flags |= DEQUEUE_CLASS; + scx_prepare_setscheduler(p, policy); + scoped_guard (sched_change, p, queue_flags) { if (!(attr->sched_flags & SCHED_FLAG_KEEP_PARAMS)) {
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index c1cb328..f2e8071 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c
@@ -56,6 +56,7 @@ #include <linux/kvm_para.h> #include <linux/delay.h> #include <linux/irq_work.h> +#include <linux/math64.h> #include "workqueue_internal.h" @@ -161,6 +162,9 @@ struct llc_shard_layout { * LN: pool->lock and wq_node_nr_active->lock protected for writes. Either for * reads. * + * FN: wq_flush_pnode->lock protected. list_empty(&pwq->flush_node) can also be + * tested with only pool->lock held. + * * K: Only modified by worker while holding pool->lock. Can be safely read by * self, while holding pool->lock or from IRQ context if %current is the * kworker. @@ -208,7 +212,7 @@ struct worker_pool { * but w/ pool->lock held. The readers grab pool->lock and are * guaranteed to see if the counter reached zero. */ - int nr_running; + int __data_racy nr_running; struct list_head worklist; /* L: list of pending works */ @@ -274,8 +278,10 @@ struct pool_workqueue { int work_color; /* L: current color */ int flush_color; /* L: flushing color */ int refcnt; /* L: reference count */ + int total_in_flight; /* L: sum of nr_in_flight[] */ int nr_in_flight[WORK_NR_COLORS]; /* L: nr of in_flight works */ + struct list_head flush_node; /* FN: node on wq_flush_pnode->pwqs */ bool plugged; /* L: execution suspended */ /* @@ -345,6 +351,21 @@ struct wq_node_nr_active { }; /* + * Per-node list of pwqs active since the last flush so that flushes visit only + * those. One per possible node plus the NUMA_NO_NODE fallback at nr_node_ids, + * each allocated on its node. A pwq is added when a work item is queued to it + * while off the list and removed by a flush which finds it with nothing in + * flight. ->work_color mirrors wq->work_color. Reading it and adding the pwq in + * one ->lock section keeps queueing coherent against flushing: a work item is + * either stamped with the new color or its pwq is visible to the flusher. + */ +struct wq_flush_pnode { + raw_spinlock_t lock; /* nests inside pool locks */ + int work_color; /* FN: mirrors wq->work_color */ + struct list_head pwqs; /* FN: pwqs active since last flush */ +}; + +/* * The externally visible workqueue. It relays the issued work items to * the appropriate worker_pool through its pool_workqueues. */ @@ -359,6 +380,7 @@ struct workqueue_struct { struct wq_flusher *first_flusher; /* WQ: first flusher */ struct list_head flusher_queue; /* WQ: flush waiters */ struct list_head flusher_overflow; /* WQ: flush overflow list */ + struct wq_flush_pnode **flush_pnodes; /* I: per-node flush membership */ struct list_head maydays; /* MD: pwqs requesting rescue */ struct worker *rescuer; /* MD: rescue worker */ @@ -367,6 +389,7 @@ struct workqueue_struct { /* See alloc_workqueue() function comment for info on min/max_active */ int max_active; /* WO: max active works */ + int percpu_max_active; /* WO: max active works per cpu */ int min_active; /* WO: min active works */ int saved_max_active; /* WQ: saved max_active */ int saved_min_active; /* WQ: saved min_active */ @@ -510,12 +533,6 @@ static DEFINE_IDR(worker_pool_idr); /* PR: idr of all pools */ /* PL: hash of all unbound pools keyed by pool->attrs */ static DEFINE_HASHTABLE(unbound_pool_hash, UNBOUND_POOL_HASH_ORDER); -/* I: attributes used when instantiating standard unbound pools on demand */ -static struct workqueue_attrs *unbound_std_wq_attrs[NR_STD_WORKER_POOLS]; - -/* I: attributes used when instantiating ordered pools on demand */ -static struct workqueue_attrs *ordered_wq_attrs[NR_STD_WORKER_POOLS]; - /* * I: kthread_worker to release pwq's. pwq release needs to be bounced to a * process context while holding a pool lock. Bounce to a dedicated kthread @@ -619,6 +636,26 @@ static void show_one_worker_pool(struct worker_pool *pool); list_for_each_entry_rcu((pwq), &(wq)->pwqs, pwqs_node, \ lockdep_is_held(&(wq->mutex))) +/* + * Per-node arrays in this file carry an extra slot at nr_node_ids serving + * NUMA_NO_NODE. Return the slot after all nodes. + */ +static int next_node_with_fallback(int node) +{ + if (node >= nr_node_ids) + return nr_node_ids + 1; + + node = next_node(node, node_possible_map); + if (node >= nr_node_ids) + return nr_node_ids; + return node; +} + +#define for_each_node_with_fallback(node) \ + for ((node) = first_node(node_possible_map); \ + (node) <= nr_node_ids; \ + (node) = next_node_with_fallback(node)) + #ifdef CONFIG_DEBUG_OBJECTS_WORK static const struct debug_obj_descr work_debug_descr; @@ -739,7 +776,7 @@ static int worker_pool_assign_id(struct worker_pool *pool) } static struct pool_workqueue __rcu ** -unbound_pwq_slot(struct workqueue_struct *wq, int cpu) +pwq_slot(struct workqueue_struct *wq, int cpu) { if (cpu >= 0) return per_cpu_ptr(wq->cpu_pwq, cpu); @@ -748,9 +785,9 @@ unbound_pwq_slot(struct workqueue_struct *wq, int cpu) } /* @cpu < 0 for dfl_pwq */ -static struct pool_workqueue *unbound_pwq(struct workqueue_struct *wq, int cpu) +static struct pool_workqueue *installed_pwq(struct workqueue_struct *wq, int cpu) { - return rcu_dereference_check(*unbound_pwq_slot(wq, cpu), + return rcu_dereference_check(*pwq_slot(wq, cpu), lockdep_is_held(&wq_pool_mutex) || lockdep_is_held(&wq->mutex)); } @@ -765,7 +802,7 @@ static struct pool_workqueue *unbound_pwq(struct workqueue_struct *wq, int cpu) */ static struct cpumask *unbound_effective_cpumask(struct workqueue_struct *wq) { - return unbound_pwq(wq, -1)->pool->attrs->__pod_cpumask; + return installed_pwq(wq, -1)->pool->attrs->__pod_cpumask; } static unsigned int work_color_to_flags(int color) @@ -1532,6 +1569,7 @@ void wq_worker_tick(struct task_struct *task) struct worker *worker = kthread_data(task); struct pool_workqueue *pwq = worker->current_pwq; struct worker_pool *pool = worker->pool; + u64 delta; if (!pwq) return; @@ -1572,6 +1610,11 @@ void wq_worker_tick(struct task_struct *task) pwq->stats[PWQ_STAT_CM_WAKEUP]++; raw_spin_unlock(&pool->lock); + + delta = READ_ONCE(worker->task->se.sum_exec_runtime) - worker->current_at; + trace_workqueue_cpu_intensive(pwq, worker->current_work, + worker->current_func, + div_u64(delta, NSEC_PER_USEC)); } /** @@ -1635,6 +1678,22 @@ static struct wq_node_nr_active *wq_node_nr_active(struct workqueue_struct *wq, } /** + * wq_flush_pnode - Determine wq_flush_pnode to use + * @wq: workqueue of interest + * @node: NUMA node, can be %NUMA_NO_NODE + * + * Return @wq's wq_flush_pnode for @node, the nr_node_ids fallback if @node is + * %NUMA_NO_NODE. + */ +static struct wq_flush_pnode *wq_flush_pnode(struct workqueue_struct *wq, int node) +{ + if (node == NUMA_NO_NODE) + node = nr_node_ids; + + return wq->flush_pnodes[node]; +} + +/** * wq_update_node_max_active - Update per-node max_actives to use * @wq: workqueue to update * @off_cpu: CPU that's going down, -1 if a CPU is not going down @@ -1712,6 +1771,14 @@ static void put_pwq(struct pool_workqueue *pwq) lockdep_assert_held(&pwq->pool->lock); if (likely(--pwq->refcnt)) return; + + /* + * pwq_release_worker is only created in workqueue_init(). Getting + * here before that means an early workqueue allocation failed, which + * is fatal anyway. + */ + BUG_ON(!pwq_release_worker); + /* * @pwq can't be released under pool->lock, bounce to a dedicated * kthread_worker to avoid A-A deadlocks. @@ -1788,10 +1855,10 @@ static bool pwq_tryinc_nr_active(struct pool_workqueue *pwq, bool fill) /* * A concurrency-managed per-cpu pool accounts nr_active per pwq, so - * pwq->nr_active against wq->max_active is sufficient. + * pwq->nr_active against wq->percpu_max_active is sufficient. */ if (is_percpu_pool(pool)) { - obtained = pwq->nr_active < READ_ONCE(wq->max_active); + obtained = pwq->nr_active < READ_ONCE(wq->percpu_max_active); goto out; } @@ -2060,6 +2127,22 @@ static void pwq_dec_nr_active(struct pool_workqueue *pwq) } /** + * pwq_inc_nr_in_flight - increment pwq's nr_in_flight + * @pwq: pwq of interest + * @work_color: color of the work item being queued + * + * A work item or a barrier with @work_color is being queued to @pwq. + * + * CONTEXT: + * raw_spin_lock_irq(pool->lock). + */ +static void pwq_inc_nr_in_flight(struct pool_workqueue *pwq, int work_color) +{ + pwq->nr_in_flight[work_color]++; + pwq->total_in_flight++; +} + +/** * pwq_dec_nr_in_flight - decrement pwq's nr_in_flight * @pwq: pwq of interest * @work_data: work_data of work which left the queue @@ -2083,6 +2166,7 @@ static void pwq_dec_nr_in_flight(struct pool_workqueue *pwq, unsigned long work_ pwq_dec_nr_active(pwq); pwq->nr_in_flight[color]--; + pwq->total_in_flight--; /* is flush in progress and are we at the flushing tip? */ if (likely(pwq->flush_color != color)) @@ -2432,7 +2516,21 @@ static void __queue_work(int cpu, struct workqueue_struct *wq, if (WARN_ON(!list_empty(&work->entry))) goto out; - pwq->nr_in_flight[pwq->work_color]++; + /* + * Add @pwq to its wq_flush_pnode list if off it. Syncing ->work_color + * in the same fpn->lock section is what keeps a concurrent flush from + * missing @work, see wq_flush_pnode. + */ + if (unlikely(list_empty(&pwq->flush_node))) { + struct wq_flush_pnode *fpn = wq_flush_pnode(wq, pool->node); + + raw_spin_lock(&fpn->lock); + pwq->work_color = fpn->work_color; + list_add_tail(&pwq->flush_node, &fpn->pwqs); + raw_spin_unlock(&fpn->lock); + } + + pwq_inc_nr_in_flight(pwq, pwq->work_color); work_flags = work_color_to_flags(pwq->work_color); /* @@ -3117,6 +3215,7 @@ static void send_mayday(struct pool_workqueue *pwq) list_add_tail(&pwq->mayday_node, &wq->maydays); wake_up_process(wq->rescuer->task); pwq->stats[PWQ_STAT_MAYDAY]++; + trace_workqueue_mayday(pwq); } } @@ -3623,6 +3722,7 @@ static bool assign_rescuer_work(struct pool_workqueue *pwq, struct worker *rescu list_for_each_entry_safe_from(work, n, &pool->worklist, entry) { if (get_work_pwq(work) == pwq && assign_work(work, rescuer, &n)) { pwq->stats[PWQ_STAT_RESCUED]++; + trace_workqueue_rescued(pwq, work, work->func); /* put the cursor for next search */ list_move_tail(&cursor->entry, &n->entry); return true; @@ -3758,6 +3858,9 @@ static void bh_worker(struct worker *worker) struct worker_pool *pool = worker->pool; int nr_restarts = BH_WORKER_RESTARTS; unsigned long end = jiffies + BH_WORKER_JIFFIES; + bool budget_exhausted = false; + bool timeout = false; + int restarts = 0; worker_lock_callback(pool); raw_spin_lock_irq(&pool->lock); @@ -3780,8 +3883,23 @@ static void bh_worker(struct worker *worker) if (assign_work(work, worker, NULL)) process_scheduled_works(worker); - } while (keep_working(pool) && - --nr_restarts && time_before(jiffies, end)); + + if (!keep_working(pool)) + break; + + if (!--nr_restarts) { + budget_exhausted = true; + break; + } + + if (!time_before(jiffies, end)) { + budget_exhausted = true; + timeout = true; + break; + } + + restarts++; + } while (1); worker_set_flags(worker, WORKER_PREP); done: @@ -3789,6 +3907,10 @@ static void bh_worker(struct worker *worker) kick_pool(pool); raw_spin_unlock_irq(&pool->lock); worker_unlock_callback(pool); + + if (budget_exhausted) + trace_workqueue_bh_budget_yield(pool, restarts, timeout, + pool->attrs->nice == HIGHPRI_NICE_LEVEL); } /* @@ -4008,7 +4130,15 @@ static void insert_wq_barrier(struct pool_workqueue *pwq, __set_bit(WORK_STRUCT_LINKED_BIT, bits); } - pwq->nr_in_flight[work_color]++; + /* + * Flushes must wait for barriers too as a barrier pins @pwq and a + * worker until it runs and destroy_workqueue()'s drain relies on that. + * @target being in flight keeps @pwq on its wq_flush_pnode list, so no + * need to add it here. + */ + WARN_ON_ONCE(list_empty(&pwq->flush_node)); + + pwq_inc_nr_in_flight(pwq, work_color); work_flags |= work_color_to_flags(work_color); insert_work(pwq, &barr->work, head, work_flags); @@ -4020,23 +4150,23 @@ static void insert_wq_barrier(struct pool_workqueue *pwq, * @flush_color: new flush color, < 0 for no-op * @work_color: new work color, < 0 for no-op * - * Prepare pwqs for workqueue flushing. + * Prepare pwqs for workqueue flushing. Only the pwqs on @wq's wq_flush_pnode + * lists, which have been active since the last flush, are visited. * - * If @flush_color is non-negative, flush_color on all pwqs should be - * -1. If no pwq has in-flight commands at the specified color, all - * pwq->flush_color's stay at -1 and %false is returned. If any pwq - * has in flight commands, its pwq->flush_color is set to - * @flush_color, @wq->nr_pwqs_to_flush is updated accordingly, pwq - * wakeup logic is armed and %true is returned. + * If @flush_color >= 0, flush_color on all visited pwqs should be -1. If no + * visited pwq has in-flight work items at the specified color, all + * pwq->flush_color's stay at -1 and return %false. If any visited pwq has + * in-flight work items, set its pwq->flush_color to @flush_color, update + * @wq->nr_pwqs_to_flush accordingly, arm pwq wakeup logic and return %true. * - * The caller should have initialized @wq->first_flusher prior to - * calling this function with non-negative @flush_color. If - * @flush_color is negative, no flush color update is done and %false - * is returned. + * The caller should have initialized @wq->first_flusher prior to calling this + * function with non-negative @flush_color. If @flush_color < 0, no flush color + * update is done and %false is returned. * - * If @work_color is non-negative, all pwqs should have the same - * work_color which is previous to @work_color and all will be - * advanced to @work_color. + * If @work_color >= 0, all visited pwqs and every wq_flush_pnode's work color + * mirror are advanced to @work_color. The mirrors of nodes with no active pwqs + * must be advanced too as a pwq added to a list later stamps the color it reads + * from the mirror. * * CONTEXT: * mutex_lock(wq->mutex). @@ -4048,50 +4178,81 @@ static void insert_wq_barrier(struct pool_workqueue *pwq, static bool flush_workqueue_prep_pwqs(struct workqueue_struct *wq, int flush_color, int work_color) { + struct pool_workqueue *pwq, *next; bool wait = false; - struct pool_workqueue *pwq; - struct worker_pool *current_pool = NULL; + int node; if (flush_color >= 0) { WARN_ON_ONCE(atomic_read(&wq->nr_pwqs_to_flush)); atomic_set(&wq->nr_pwqs_to_flush, 1); } - /* - * For unbound workqueue, pwqs will map to only a few pools. - * Most of the time, pwqs within the same pool will be linked - * sequentially to wq->pwqs by cpu index. So in the majority - * of pwq iters, the pool is the same, only doing lock/unlock - * if the pool has changed. This can largely reduce expensive - * lock operations. - */ - for_each_pwq(pwq, wq) { - if (current_pool != pwq->pool) { - if (likely(current_pool)) - raw_spin_unlock_irq(¤t_pool->lock); - current_pool = pwq->pool; - raw_spin_lock_irq(¤t_pool->lock); - } + for_each_node_with_fallback(node) { + struct wq_flush_pnode *fpn = wq->flush_pnodes[node]; + struct worker_pool *current_pool = NULL; + LIST_HEAD(to_visit); + LIST_HEAD(to_keep); - if (flush_color >= 0) { - WARN_ON_ONCE(pwq->flush_color != -1); - - if (pwq->nr_in_flight[flush_color]) { - pwq->flush_color = flush_color; - atomic_inc(&wq->nr_pwqs_to_flush); - wait = true; - } - } - + /* + * Advance the node's color mirror and take its active pwqs. + * Work items queued to off-list pwqs afterwards carry the new + * color and don't need visiting. + */ + raw_spin_lock_irq(&fpn->lock); if (work_color >= 0) { - WARN_ON_ONCE(work_color != work_next_color(pwq->work_color)); - pwq->work_color = work_color; + WARN_ON_ONCE(work_color != work_next_color(fpn->work_color)); + fpn->work_color = work_color; + } + list_splice_init(&fpn->pwqs, &to_visit); + raw_spin_unlock_irq(&fpn->lock); + + /* + * Unbound workqueues map multiple pwqs to one pool. Only cycle + * pool->lock when the pool changes. + */ + list_for_each_entry_safe(pwq, next, &to_visit, flush_node) { + if (current_pool != pwq->pool) { + if (likely(current_pool)) + raw_spin_unlock_irq(¤t_pool->lock); + current_pool = pwq->pool; + raw_spin_lock_irq(¤t_pool->lock); + } + + if (flush_color >= 0) { + WARN_ON_ONCE(pwq->flush_color != -1); + + if (pwq->nr_in_flight[flush_color]) { + pwq->flush_color = flush_color; + atomic_inc(&wq->nr_pwqs_to_flush); + wait = true; + } + } + + if (work_color >= 0) { + WARN_ON_ONCE(work_color != work_next_color(pwq->work_color)); + pwq->work_color = work_color; + } + + /* + * A cascade can arm a color retired several advances + * ago, so keep a pwq listed while any color has work + * items in flight. + */ + if (pwq->total_in_flight) + list_move_tail(&pwq->flush_node, &to_keep); + else + list_del_init(&pwq->flush_node); } - } + if (current_pool) + raw_spin_unlock_irq(¤t_pool->lock); - if (current_pool) - raw_spin_unlock_irq(¤t_pool->lock); + if (!list_empty(&to_keep)) { + raw_spin_lock_irq(&fpn->lock); + list_splice_tail(&to_keep, &fpn->pwqs); + raw_spin_unlock_irq(&fpn->lock); + } + } if (flush_color >= 0 && atomic_dec_and_test(&wq->nr_pwqs_to_flush)) complete(&wq->first_flusher->done); @@ -5049,13 +5210,10 @@ static void free_node_nr_active(struct wq_node_nr_active **nna_ar) { int node; - for_each_node(node) { + for_each_node_with_fallback(node) { kfree(nna_ar[node]); nna_ar[node] = NULL; } - - kfree(nna_ar[nr_node_ids]); - nna_ar[nr_node_ids] = NULL; } static void init_node_nr_active(struct wq_node_nr_active *nna) @@ -5075,21 +5233,15 @@ static int alloc_node_nr_active(struct wq_node_nr_active **nna_ar) struct wq_node_nr_active *nna; int node; - for_each_node(node) { - nna = kzalloc_node(sizeof(*nna), GFP_KERNEL, node); + for_each_node_with_fallback(node) { + nna = kzalloc_node(sizeof(*nna), GFP_KERNEL, + node < nr_node_ids ? node : NUMA_NO_NODE); if (!nna) goto err_free; init_node_nr_active(nna); nna_ar[node] = nna; } - /* [nr_node_ids] is used as the fallback */ - nna = kzalloc_node(sizeof(*nna), GFP_KERNEL, NUMA_NO_NODE); - if (!nna) - goto err_free; - init_node_nr_active(nna); - nna_ar[nr_node_ids] = nna; - return 0; err_free: @@ -5097,6 +5249,47 @@ static int alloc_node_nr_active(struct wq_node_nr_active **nna_ar) return -ENOMEM; } +static void free_flush_pnodes(struct workqueue_struct *wq) +{ + int node; + + if (!wq->flush_pnodes) + return; + + for_each_node_with_fallback(node) + kfree(wq->flush_pnodes[node]); + kfree(wq->flush_pnodes); + wq->flush_pnodes = NULL; +} + +static int alloc_flush_pnodes(struct workqueue_struct *wq) +{ + struct wq_flush_pnode *fpn; + int node; + + wq->flush_pnodes = kcalloc(nr_node_ids + 1, sizeof(*wq->flush_pnodes), GFP_KERNEL); + if (!wq->flush_pnodes) + return -ENOMEM; + + for_each_node_with_fallback(node) { + fpn = kzalloc_node(sizeof(*fpn), GFP_KERNEL, + node < nr_node_ids ? node : NUMA_NO_NODE); + if (!fpn) + goto err_free; + + raw_spin_lock_init(&fpn->lock); + fpn->work_color = wq->work_color; + INIT_LIST_HEAD(&fpn->pwqs); + wq->flush_pnodes[node] = fpn; + } + + return 0; + +err_free: + free_flush_pnodes(wq); + return -ENOMEM; +} + static void rcu_free_wq(struct rcu_head *rcu) { struct workqueue_struct *wq = @@ -5105,6 +5298,7 @@ static void rcu_free_wq(struct rcu_head *rcu) if (wq->flags & WQ_UNBOUND) free_node_nr_active(wq->node_nr_active); + free_flush_pnodes(wq); wq_free_lockdep(wq); free_percpu(wq->cpu_pwq); free_workqueue_attrs(wq->attrs); @@ -5286,6 +5480,19 @@ static void pwq_release_workfn(struct kthread_work *work) is_last = list_empty(&wq->pwqs); /* + * An idle pwq can linger on its wq_flush_pnode list until the + * next flush. wq->mutex excludes flushers, which never drop it + * with pwqs on their private lists. + */ + if (!list_empty(&pwq->flush_node)) { + struct wq_flush_pnode *fpn = wq_flush_pnode(wq, pool->node); + + raw_spin_lock_irq(&fpn->lock); + list_del_init(&pwq->flush_node); + raw_spin_unlock_irq(&fpn->lock); + } + + /* * For ordered workqueue with a plugged dfl_pwq, restart it now. */ if (!is_last && (wq->flags & __WQ_ORDERED)) @@ -5335,6 +5542,7 @@ static void init_pwq(struct pool_workqueue *pwq, struct workqueue_struct *wq, pwq->refcnt = 1; INIT_LIST_HEAD(&pwq->inactive_works); INIT_LIST_HEAD(&pwq->pending_node); + INIT_LIST_HEAD(&pwq->flush_node); INIT_LIST_HEAD(&pwq->pwqs_node); INIT_LIST_HEAD(&pwq->mayday_node); kthread_init_work(&pwq->release_work, pwq_release_workfn); @@ -5385,22 +5593,34 @@ static struct worker_pool *get_percpu_pool(struct workqueue_struct *wq, int cpu) return &per_cpu_ptr(pools, cpu)[highpri]; } -/* obtain a pool matching @attr and create a pwq associating the pool and @wq */ +/* + * Obtain the pool backing @wq on @cpu and create a pwq associating the two. + * A WQ_PERCPU workqueue is backed by the static per-cpu pool of @cpu, + * everything else by a pool matching @attrs. @cpu < 0 is always unbound. + */ static struct pool_workqueue *alloc_pwq(struct workqueue_struct *wq, - const struct workqueue_attrs *attrs) + const struct workqueue_attrs *attrs, + int cpu) { struct worker_pool *pool; struct pool_workqueue *pwq; lockdep_assert_held(&wq_pool_mutex); - pool = get_unbound_pool(attrs); - if (!pool) - return NULL; + WARN_ON_ONCE((wq->flags & WQ_PERCPU) && cpu < 0); + + if (cpu >= 0 && (wq->flags & WQ_PERCPU)) { + pool = get_percpu_pool(wq, cpu); + } else { + pool = get_unbound_pool(attrs); + if (!pool) + return NULL; + } pwq = kmem_cache_alloc_node(pwq_cache, GFP_KERNEL, pool->node); if (!pwq) { - put_unbound_pool(pool); + if (!is_percpu_pool(pool)) + put_unbound_pool(pool); return NULL; } @@ -5408,6 +5628,13 @@ static struct pool_workqueue *alloc_pwq(struct workqueue_struct *wq, return pwq; } +/* create a pwq backed by an unbound pool matching @attrs */ +static struct pool_workqueue *alloc_unbound_pwq(struct workqueue_struct *wq, + const struct workqueue_attrs *attrs) +{ + return alloc_pwq(wq, attrs, -1); +} + /** * wq_calc_pod_cpumask - calculate a wq_attrs' cpumask for a pod * @attrs: the wq_attrs of the default pwq of the target workqueue @@ -5437,10 +5664,10 @@ static void wq_calc_pod_cpumask(struct workqueue_attrs *attrs, int cpu) } /* install @pwq into @wq and return the old pwq, @cpu < 0 for dfl_pwq */ -static struct pool_workqueue *install_unbound_pwq(struct workqueue_struct *wq, - int cpu, struct pool_workqueue *pwq) +static struct pool_workqueue *install_pwq(struct workqueue_struct *wq, + int cpu, struct pool_workqueue *pwq) { - struct pool_workqueue __rcu **slot = unbound_pwq_slot(wq, cpu); + struct pool_workqueue __rcu **slot = pwq_slot(wq, cpu); struct pool_workqueue *old_pwq; lockdep_assert_held(&wq_pool_mutex); @@ -5503,15 +5730,18 @@ apply_wqattrs_prepare(struct workqueue_struct *wq, /* * If something goes wrong during CPU up/down, we'll fall back to - * the default pwq covering whole @attrs->cpumask. Always create - * it even if we don't use it immediately. + * the default pwq covering whole @attrs->cpumask. Create it even + * if we don't use it immediately. A percpu workqueue has a pwq on + * every possible CPU and never falls back, so it has no default. */ copy_workqueue_attrs(new_attrs, attrs); wqattrs_actualize_cpumask(new_attrs, unbound_cpumask); cpumask_copy(new_attrs->__pod_cpumask, new_attrs->cpumask); - ctx->dfl_pwq = alloc_pwq(wq, new_attrs); - if (!ctx->dfl_pwq) - goto out_free; + if (!(wq->flags & WQ_PERCPU)) { + ctx->dfl_pwq = alloc_unbound_pwq(wq, new_attrs); + if (!ctx->dfl_pwq) + goto out_free; + } for_each_possible_cpu(cpu) { if (new_attrs->ordered) { @@ -5519,7 +5749,7 @@ apply_wqattrs_prepare(struct workqueue_struct *wq, ctx->pwq_tbl[cpu] = ctx->dfl_pwq; } else { wq_calc_pod_cpumask(new_attrs, cpu); - ctx->pwq_tbl[cpu] = alloc_pwq(wq, new_attrs); + ctx->pwq_tbl[cpu] = alloc_pwq(wq, new_attrs, cpu); if (!ctx->pwq_tbl[cpu]) goto out_free; } @@ -5561,9 +5791,10 @@ static void apply_wqattrs_commit(struct apply_wqattrs_ctx *ctx) /* save the previous pwqs and install the new ones */ for_each_possible_cpu(cpu) - ctx->pwq_tbl[cpu] = install_unbound_pwq(ctx->wq, cpu, - ctx->pwq_tbl[cpu]); - ctx->dfl_pwq = install_unbound_pwq(ctx->wq, -1, ctx->dfl_pwq); + ctx->pwq_tbl[cpu] = install_pwq(ctx->wq, cpu, + ctx->pwq_tbl[cpu]); + if (ctx->dfl_pwq) + ctx->dfl_pwq = install_pwq(ctx->wq, -1, ctx->dfl_pwq); /* update node_nr_active->max, which only unbound workqueues have */ if (ctx->wq->flags & WQ_UNBOUND) @@ -5577,10 +5808,6 @@ static int apply_workqueue_attrs_locked(struct workqueue_struct *wq, { struct apply_wqattrs_ctx *ctx; - /* only unbound workqueues can change attributes */ - if (WARN_ON(!(wq->flags & WQ_UNBOUND))) - return -EINVAL; - ctx = apply_wqattrs_prepare(wq, attrs, wq_unbound_cpumask); if (IS_ERR(ctx)) return PTR_ERR(ctx); @@ -5612,6 +5839,10 @@ int apply_workqueue_attrs(struct workqueue_struct *wq, { int ret; + /* only unbound workqueues can change attributes */ + if (WARN_ON(!(wq->flags & WQ_UNBOUND))) + return -EINVAL; + mutex_lock(&wq_pool_mutex); ret = apply_workqueue_attrs_locked(wq, attrs); mutex_unlock(&wq_pool_mutex); @@ -5660,11 +5891,11 @@ static void unbound_wq_update_pwq(struct workqueue_struct *wq, int cpu) /* nothing to do if the target cpumask matches the current pwq */ wq_calc_pod_cpumask(target_attrs, cpu); - if (wqattrs_equal(target_attrs, unbound_pwq(wq, cpu)->pool->attrs)) + if (wqattrs_equal(target_attrs, installed_pwq(wq, cpu)->pool->attrs)) return; /* create a new pwq */ - pwq = alloc_pwq(wq, target_attrs); + pwq = alloc_unbound_pwq(wq, target_attrs); if (!pwq) { pr_warn("workqueue: allocation failed while updating CPU pod affinity of \"%s\"\n", wq->name); @@ -5673,49 +5904,43 @@ static void unbound_wq_update_pwq(struct workqueue_struct *wq, int cpu) /* Install the new pwq. */ mutex_lock(&wq->mutex); - old_pwq = install_unbound_pwq(wq, cpu, pwq); + old_pwq = install_pwq(wq, cpu, pwq); goto out_unlock; use_dfl_pwq: mutex_lock(&wq->mutex); - pwq = unbound_pwq(wq, -1); + pwq = installed_pwq(wq, -1); raw_spin_lock_irq(&pwq->pool->lock); get_pwq(pwq); raw_spin_unlock_irq(&pwq->pool->lock); - old_pwq = install_unbound_pwq(wq, cpu, pwq); + old_pwq = install_pwq(wq, cpu, pwq); out_unlock: mutex_unlock(&wq->mutex); put_pwq_unlocked(old_pwq); } -static int alloc_and_link_percpu_pwqs(struct workqueue_struct *wq) +/* the attrs @wq asked for, as spelled by its flags */ +static struct workqueue_attrs *alloc_wq_std_attrs(struct workqueue_struct *wq) { - struct pool_workqueue *pwq; - int cpu; + struct workqueue_attrs *attrs; - for_each_possible_cpu(cpu) { - struct worker_pool *pool = get_percpu_pool(wq, cpu); + attrs = alloc_workqueue_attrs(); + if (!attrs) + return NULL; - pwq = kmem_cache_alloc_node(pwq_cache, GFP_KERNEL, pool->node); - if (!pwq) - return -ENOMEM; + if (wq->flags & WQ_HIGHPRI) + attrs->nice = HIGHPRI_NICE_LEVEL; - init_pwq(pwq, wq, pool); + if (wq->flags & __WQ_ORDERED) + attrs->ordered = true; - mutex_lock(&wq->mutex); - link_pwq(pwq); - mutex_unlock(&wq->mutex); - - rcu_assign_pointer(*per_cpu_ptr(wq->cpu_pwq, cpu), pwq); - } - - return 0; + return attrs; } static int alloc_and_link_pwqs(struct workqueue_struct *wq) { - bool highpri = wq->flags & WQ_HIGHPRI; - int cpu, ret; + struct workqueue_attrs *attrs; + int ret; lockdep_assert_held(&wq_pool_mutex); @@ -5723,47 +5948,29 @@ static int alloc_and_link_pwqs(struct workqueue_struct *wq) if (!wq->cpu_pwq) goto enomem; - if (!(wq->flags & WQ_UNBOUND)) { - ret = alloc_and_link_percpu_pwqs(wq); - } else if (wq->flags & __WQ_ORDERED) { - struct pool_workqueue *dfl_pwq; + attrs = alloc_wq_std_attrs(wq); + if (!attrs) + goto enomem; - ret = apply_workqueue_attrs_locked(wq, ordered_wq_attrs[highpri]); - /* there should only be single pwq for ordering guarantee */ - dfl_pwq = rcu_access_pointer(wq->dfl_pwq); - WARN(!ret && (wq->pwqs.next != &dfl_pwq->pwqs_node || - wq->pwqs.prev != &dfl_pwq->pwqs_node), - "ordering guarantee broken for workqueue %s\n", wq->name); - } else { - ret = apply_workqueue_attrs_locked(wq, unbound_std_wq_attrs[highpri]); - } - + ret = apply_workqueue_attrs_locked(wq, attrs); + free_workqueue_attrs(attrs); if (ret) goto enomem; + + if (wq->flags & __WQ_ORDERED) { + struct pool_workqueue *dfl_pwq = rcu_access_pointer(wq->dfl_pwq); + + /* there should only be single pwq for ordering guarantee */ + WARN(wq->pwqs.next != &dfl_pwq->pwqs_node || + wq->pwqs.prev != &dfl_pwq->pwqs_node, + "ordering guarantee broken for workqueue %s\n", wq->name); + } + return 0; enomem: - if (wq->cpu_pwq) { - for_each_possible_cpu(cpu) { - struct pool_workqueue __rcu **slot; - struct pool_workqueue *pwq; - - slot = per_cpu_ptr(wq->cpu_pwq, cpu); - pwq = rcu_access_pointer(*slot); - if (pwq) { - /* - * Unlink pwq from wq->pwqs since link_pwq() - * may have already added it. wq->mutex is not - * needed as the wq has not been published yet. - */ - if (!list_empty(&pwq->pwqs_node)) - list_del_rcu(&pwq->pwqs_node); - kmem_cache_free(pwq_cache, pwq); - } - } - free_percpu(wq->cpu_pwq); - wq->cpu_pwq = NULL; - } + free_percpu(wq->cpu_pwq); + wq->cpu_pwq = NULL; return -ENOMEM; } @@ -5828,9 +6035,9 @@ static int init_rescuer(struct workqueue_struct *wq) * wq_adjust_max_active - update a wq's max_active to the current setting * @wq: target workqueue * - * If @wq isn't freezing, set @wq->max_active to the saved_max_active and - * activate inactive work items accordingly. If @wq is freezing, clear - * @wq->max_active to zero. + * If @wq isn't freezing, set the limit that applies to @wq's backing to the + * saved_max_active and activate inactive work items accordingly. If @wq is + * freezing, clear it to zero. */ static void wq_adjust_max_active(struct workqueue_struct *wq) { @@ -5847,20 +6054,25 @@ static void wq_adjust_max_active(struct workqueue_struct *wq) new_min = wq->saved_min_active; } - if (wq->max_active == new_max && wq->min_active == new_min) - return; - /* - * Update @wq->max/min_active and then kick inactive work items if more - * active work items are allowed. This doesn't break work item ordering + * Update the limit and then kick inactive work items if more active + * work items are allowed. This doesn't break work item ordering * because new work items are always queued behind existing inactive * work items if there are any. */ - WRITE_ONCE(wq->max_active, new_max); - WRITE_ONCE(wq->min_active, new_min); + if (wq->flags & WQ_UNBOUND) { + if (wq->max_active == new_max && wq->min_active == new_min) + return; - if (wq->flags & WQ_UNBOUND) + WRITE_ONCE(wq->max_active, new_max); + WRITE_ONCE(wq->min_active, new_min); wq_update_node_max_active(wq, -1); + } else { + if (wq->percpu_max_active == new_max) + return; + + WRITE_ONCE(wq->percpu_max_active, new_max); + } if (new_max == 0) return; @@ -5957,10 +6169,14 @@ static struct workqueue_struct *__alloc_workqueue(const char *fmt, /* init wq */ wq->flags = flags; - wq->max_active = max_active; - wq->min_active = min(max_active, WQ_DFL_MIN_ACTIVE); - wq->saved_max_active = wq->max_active; - wq->saved_min_active = wq->min_active; + if (flags & WQ_UNBOUND) { + wq->max_active = max_active; + wq->min_active = min(max_active, WQ_DFL_MIN_ACTIVE); + wq->saved_min_active = wq->min_active; + } else { + wq->percpu_max_active = max_active; + } + wq->saved_max_active = max_active; mutex_init(&wq->mutex); atomic_set(&wq->nr_pwqs_to_flush, 0); INIT_LIST_HEAD(&wq->pwqs); @@ -5970,6 +6186,9 @@ static struct workqueue_struct *__alloc_workqueue(const char *fmt, INIT_LIST_HEAD(&wq->list); + if (alloc_flush_pnodes(wq) < 0) + goto err_free_wq; + if (flags & WQ_UNBOUND) { if (alloc_node_nr_active(wq->node_nr_active) < 0) goto err_free_wq; @@ -6007,12 +6226,13 @@ static struct workqueue_struct *__alloc_workqueue(const char *fmt, * flushing the pwq_release_worker ensures that the pwq_release_workfn() * completes before calling kfree(wq). */ - if (wq->flags & WQ_UNBOUND) { + if (pwq_release_worker) kthread_flush_worker(pwq_release_worker); + if (wq->flags & WQ_UNBOUND) free_node_nr_active(wq->node_nr_active); - } err_free_wq: free_workqueue_attrs(wq->attrs); + free_flush_pnodes(wq); kfree(wq); return NULL; err_unlock_destroy: @@ -6104,11 +6324,8 @@ EXPORT_SYMBOL_GPL(alloc_workqueue_lockdep_map); static bool pwq_busy(struct pool_workqueue *pwq) { - int i; - - for (i = 0; i < WORK_NR_COLORS; i++) - if (pwq->nr_in_flight[i]) - return true; + if (pwq->total_in_flight) + return true; if ((pwq != rcu_access_pointer(pwq->wq->dfl_pwq)) && (pwq->refcnt > 1)) return true; @@ -6199,12 +6416,12 @@ void destroy_workqueue(struct workqueue_struct *wq) rcu_read_lock(); for_each_possible_cpu(cpu) { - put_pwq_unlocked(unbound_pwq(wq, cpu)); - RCU_INIT_POINTER(*unbound_pwq_slot(wq, cpu), NULL); + put_pwq_unlocked(installed_pwq(wq, cpu)); + RCU_INIT_POINTER(*pwq_slot(wq, cpu), NULL); } - put_pwq_unlocked(unbound_pwq(wq, -1)); - RCU_INIT_POINTER(*unbound_pwq_slot(wq, -1), NULL); + put_pwq_unlocked(installed_pwq(wq, -1)); + RCU_INIT_POINTER(*pwq_slot(wq, -1), NULL); rcu_read_unlock(); } @@ -8203,24 +8420,6 @@ void __init workqueue_init_early(void) init_cpu_worker_pool(pool, cpu, std_nice[i++]); } - /* create default unbound and ordered wq attrs */ - for (i = 0; i < NR_STD_WORKER_POOLS; i++) { - struct workqueue_attrs *attrs; - - BUG_ON(!(attrs = alloc_workqueue_attrs())); - attrs->nice = std_nice[i]; - unbound_std_wq_attrs[i] = attrs; - - /* - * An ordered wq should have only one pwq as ordering is - * guaranteed by max_active which is enforced by pwqs. - */ - BUG_ON(!(attrs = alloc_workqueue_attrs())); - attrs->nice = std_nice[i]; - attrs->ordered = true; - ordered_wq_attrs[i] = attrs; - } - system_wq = alloc_workqueue("events", WQ_PERCPU | __WQ_DEPRECATED, 0); system_percpu_wq = alloc_workqueue("events", WQ_PERCPU, 0); system_highpri_wq = alloc_workqueue("events_highpri", @@ -8264,7 +8463,7 @@ static void __init wq_cpu_intensive_thresh_init(void) * lot slower CPUs including microcontrollers where the threshold is way * too low. * - * Let's scale up the threshold upto 1 second if BogoMips is below 4000. + * Let's scale up the threshold up to 1 second if BogoMips is below 4000. * This is by no means accurate but it doesn't have to be. The mechanism * is still useful even when the threshold is fully scaled up. Also, as * the reports would usually be applicable to everyone, some machines
diff --git a/lib/842/842_decompress.c b/lib/842/842_decompress.c index 582085e..45a9815 100644 --- a/lib/842/842_decompress.c +++ b/lib/842/842_decompress.c
@@ -165,6 +165,9 @@ static int __do_index(struct sw842_param *p, u8 size, u8 bits, u64 fsize) u64 index, offset, total = round_down(p->out - p->ostart, 8); int ret; + if (size > p->olen) + return -ENOSPC; + ret = next_bits(p, &index, bits); if (ret) return ret; @@ -306,7 +309,7 @@ int sw842_decompress(const u8 *in, unsigned int ilen, if (ret) return ret; - if (p.out == out) /* no previous bytes */ + if (p.out - p.ostart < 8) /* no complete previous block */ return -EINVAL; /* copy rep + 1 */ @@ -344,6 +347,8 @@ int sw842_decompress(const u8 *in, unsigned int ilen, if (!bytes || bytes > SHORT_DATA_BITS_MAX) return -EINVAL; + if (bytes > p.olen) + return -ENOSPC; while (bytes-- > 0) { ret = next_bits(&p, &tmp, 8);
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index f1b0982..004188a 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug
@@ -649,7 +649,7 @@ config MAGIC_SYSRQ bool "Magic SysRq key" - depends on !UML + depends on !UML || MCONSOLE help If you say Y here, you will have some control over the system even if the system crashes for example during kernel debugging (e.g., you @@ -657,9 +657,11 @@ immediately or dump some status information). This is accomplished by pressing various keys while holding SysRq (Alt+PrintScreen). It also works on a serial console (on PC hardware at least), if you - send a BREAK and then within 5 seconds a command keypress. The - keys are documented in <file:Documentation/admin-guide/sysrq.rst>. - Don't say Y unless you really know what this hack does. + send a BREAK and then within 5 seconds a command keypress. On UML, + this is accomplished by sending a "sysrq" command with mconsole, + followed by the letter for the requested command. The keys are + documented in <file:Documentation/admin-guide/sysrq.rst>. Don't say + Y unless you really know what this hack does. config MAGIC_SYSRQ_DEFAULT_ENABLE hex "Enable magic SysRq key functions by default" @@ -2237,6 +2239,21 @@ if RUNTIME_TESTING_MENU +config 842_DECOMPRESS_KUNIT_TEST + tristate "KUnit tests for the 842 decompressor" if !KUNIT_ALL_TESTS + depends on KUNIT + depends on 842_DECOMPRESS + default KUNIT_ALL_TESTS + help + Enable stream-validation and boundary tests for the software 842 + decompressor. The tests exercise indexed copies, short data and + repeat operations at valid and invalid output or history boundaries. + + For more information on KUnit and unit tests in general, refer to + Documentation/dev-tools/kunit/. + + If unsure, say N. + config TEST_DHRY tristate "Dhrystone benchmark test" help
diff --git a/lib/cache_maint.c b/lib/cache_maint.c index 9256a9f..132d281 100644 --- a/lib/cache_maint.c +++ b/lib/cache_maint.c
@@ -59,12 +59,12 @@ static int cache_inval_done_one(struct cache_coherency_ops_inst *cci) static int cache_invalidate_memregion(phys_addr_t addr, size_t size) { - int ret; struct cache_coherency_ops_inst *cci; struct cc_inval_params params = { .addr = addr, .size = size, }; + int ret = -ENXIO; guard(rwsem_read)(&cache_ops_instance_list_lock); list_for_each_entry(cci, &cache_ops_instance_list, node) { @@ -78,7 +78,7 @@ static int cache_invalidate_memregion(phys_addr_t addr, size_t size) return ret; } - return 0; + return ret; } struct cache_coherency_ops_inst *
diff --git a/lib/kunit/Kconfig b/lib/kunit/Kconfig index 94ff8e4..cbda618 100644 --- a/lib/kunit/Kconfig +++ b/lib/kunit/Kconfig
@@ -133,7 +133,7 @@ config KUNIT_UML_PCI bool "KUnit UML PCI Support" - depends on UML + depends on UML && MMU select UML_PCI help Enables the PCI subsystem on UML for use by KUnit tests.
diff --git a/lib/kunit/executor.c b/lib/kunit/executor.c index b0f8a41..c798a02 100644 --- a/lib/kunit/executor.c +++ b/lib/kunit/executor.c
@@ -371,7 +371,7 @@ static void kunit_handle_shutdown(void) } -int kunit_run_all_tests(void) +void kunit_run_all_tests(void) { struct kunit_suite_set suite_set = {NULL, NULL}; struct kunit_suite_set filtered_suite_set = {NULL, NULL}; @@ -382,7 +382,7 @@ int kunit_run_all_tests(void) __kunit_suites_start, __kunit_suites_end, }; size_t init_num_suites = init_suite_set.end - init_suite_set.start; - int err = 0; + int err; if (init_num_suites > 0) { suite_set = kunit_merge_suite_sets(init_suite_set, normal_suite_set); @@ -432,7 +432,6 @@ int kunit_run_all_tests(void) out: kunit_handle_shutdown(); - return err; } #if IS_BUILTIN(CONFIG_KUNIT_TEST)
diff --git a/lib/rhashtable.c b/lib/rhashtable.c index 6362896..500c45c 100644 --- a/lib/rhashtable.c +++ b/lib/rhashtable.c
@@ -191,7 +191,6 @@ static struct bucket_table *bucket_table_alloc(struct rhashtable *ht, struct bucket_table *tbl = NULL; size_t size; int i; - static struct lock_class_key __key; tbl = alloc_hooks_tag(ht->alloc_tag, kvmalloc_node_align_noprof(struct_size(tbl, buckets, nbuckets), @@ -207,7 +206,9 @@ static struct bucket_table *bucket_table_alloc(struct rhashtable *ht, if (tbl == NULL) return NULL; - lockdep_init_map(&tbl->dep_map, "rhashtable_bucket", &__key, 0); +#ifdef CONFIG_LOCKDEP + lockdep_init_map(&tbl->dep_map, "rhashtable_bucket", ht->lockdep_key, 0); +#endif tbl->size = size; @@ -548,7 +549,7 @@ static void *rhashtable_lookup_one(struct rhashtable *ht, if (!key || (ht->p.obj_cmpfn ? ht->p.obj_cmpfn(&arg, rht_obj(ht, head)) : - rhashtable_compare(&arg, rht_obj(ht, head)))) { + rhashtable_compare(&arg, rht_obj(ht, head), ht->p))) { pprev = &head->next; continue; } @@ -710,7 +711,8 @@ static struct rhash_head *__rhashtable_next_in_table( rht_for_each_rcu(he, tbl, b) { bool match = params.obj_cmpfn ? !params.obj_cmpfn(&arg, rht_obj(ht, he)) - : !rhashtable_compare(&arg, rht_obj(ht, he)); + : !rhashtable_compare(&arg, rht_obj(ht, he), + params); if (found) { if (match) continue; @@ -1120,51 +1122,9 @@ static u32 rhashtable_jhash2(const void *key, u32 length, u32 seed) return jhash2(key, length, seed); } -/** - * rhashtable_init - initialize a new hash table - * @ht: hash table to be initialized - * @params: configuration parameters - * - * Initializes a new hash table based on the provided configuration - * parameters. A table can be configured either with a variable or - * fixed length key: - * - * Configuration Example 1: Fixed length keys - * struct test_obj { - * int key; - * void * my_member; - * struct rhash_head node; - * }; - * - * struct rhashtable_params params = { - * .head_offset = offsetof(struct test_obj, node), - * .key_offset = offsetof(struct test_obj, key), - * .key_len = sizeof(int), - * .hashfn = jhash, - * }; - * - * Configuration Example 2: Variable length keys - * struct test_obj { - * [...] - * struct rhash_head node; - * }; - * - * u32 my_hash_fn(const void *data, u32 len, u32 seed) - * { - * struct test_obj *obj = data; - * - * return [... hash ...]; - * } - * - * struct rhashtable_params params = { - * .head_offset = offsetof(struct test_obj, node), - * .hashfn = jhash, - * .obj_hashfn = my_hash_fn, - * }; - */ int __rhashtable_init_noprof(struct rhashtable *ht, - const struct rhashtable_params *params, - struct lock_class_key *key) + const struct rhashtable_params *params, + struct rhashtable_lockdep_keys *keys) { struct bucket_table *tbl; size_t size; @@ -1174,8 +1134,12 @@ int __rhashtable_init_noprof(struct rhashtable *ht, return -EINVAL; memset(ht, 0, sizeof(*ht)); - mutex_init_with_key(&ht->mutex, key); + mutex_init_with_key(&ht->mutex, &keys->mutex_key); spin_lock_init(&ht->lock); + lockdep_set_class(&ht->lock, &keys->lock_key); +#ifdef CONFIG_LOCKDEP + ht->lockdep_key = &keys->bucket_key; +#endif memcpy(&ht->p, params, sizeof(*params)); alloc_tag_record(ht->alloc_tag); @@ -1228,22 +1192,13 @@ int __rhashtable_init_noprof(struct rhashtable *ht, } EXPORT_SYMBOL_GPL(__rhashtable_init_noprof); -/** - * rhltable_init - initialize a new hash list table - * @hlt: hash list table to be initialized - * @params: configuration parameters - * - * Initializes a new hash list table. - * - * See documentation for rhashtable_init. - */ int __rhltable_init_noprof(struct rhltable *hlt, const struct rhashtable_params *params, - struct lock_class_key *key) + struct rhashtable_lockdep_keys *keys) { int err; - err = __rhashtable_init_noprof(&hlt->ht, params, key); + err = __rhashtable_init_noprof(&hlt->ht, params, keys); hlt->ht.rhlist = true; return err; }
diff --git a/lib/tests/842_decompress_kunit.c b/lib/tests/842_decompress_kunit.c new file mode 100644 index 0000000..11202ba --- /dev/null +++ b/lib/tests/842_decompress_kunit.c
@@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <kunit/test.h> +#include <linux/sw842.h> + +#define SW842_GUARD_SIZE 8 +#define SW842_MAX_OUTPUT 16 +#define SW842_GUARD_BYTE 0x42 +#define SW842_OUTPUT_POISON 0x5a + +/* ZEROS, I8(0), END, CRC32. */ +static const u8 sw842_index_exact_fit[] = { + 0xe6, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00, +}; + +/* D8(eight zero bytes), I8(0), END, CRC32. */ +static const u8 sw842_index_output_overflow[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x06, 0x40, 0x3c, 0x00, 0x00, 0x00, 0x00, +}; + +/* ZEROS, SHORT_DATA(01 02 03 04 05), END, CRC32. */ +static const u8 sw842_short_data_exact_fit[] = { + 0xe7, 0x68, 0x08, 0x10, 0x18, 0x20, + 0x2f, 0xa9, 0x67, 0xfc, 0x07, 0xc0, +}; + +/* ZEROS, SHORT_DATA(five zero bytes), END, CRC32. */ +static const u8 sw842_short_data_output_overflow[] = { + 0xe7, 0x48, 0x07, 0x80, 0x00, 0x00, 0x00, 0x00, +}; + +/* ZEROS, REPEAT(one block), END, CRC32. */ +static const u8 sw842_repeat_exact_history[] = { + 0xe6, 0xc0, 0xf0, 0x00, 0x00, 0x00, 0x00, +}; + +/* + * SHORT_DATA(seven zero bytes), REPEAT(one block), END, CRC32. + * CRC32 includes SW842_GUARD_BYTE copied from before output into byte 7. + */ +static const u8 sw842_repeat_without_full_history[] = { + 0xef, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xd8, 0x1e, 0x09, 0xa3, 0x1d, 0xd6, +}; + +static const u8 sw842_zero_output[SW842_MAX_OUTPUT]; +static const u8 sw842_short_data_output[] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x03, 0x04, 0x05, +}; + +struct sw842_decompress_test_case { + const char *name; + const u8 *compressed; + unsigned int compressed_len; + const u8 *expected_output; + unsigned int output_capacity; + int expected_ret; +}; + +#define SW842_DECOMPRESS_CASE(_name, _compressed, _compressed_len, _expected, \ + _capacity, _ret) \ + { \ + .name = _name, \ + .compressed = _compressed, \ + .compressed_len = _compressed_len, \ + .expected_output = _expected, \ + .output_capacity = _capacity, \ + .expected_ret = _ret, \ + } + +static const struct sw842_decompress_test_case sw842_decompress_cases[] = { + SW842_DECOMPRESS_CASE("index_exact_fit", sw842_index_exact_fit, + ARRAY_SIZE(sw842_index_exact_fit), + sw842_zero_output, 16, 0), + SW842_DECOMPRESS_CASE("index_output_overflow", + sw842_index_output_overflow, + ARRAY_SIZE(sw842_index_output_overflow), + sw842_zero_output, 8, -ENOSPC), + SW842_DECOMPRESS_CASE("short_data_exact_fit", + sw842_short_data_exact_fit, + ARRAY_SIZE(sw842_short_data_exact_fit), + sw842_short_data_output, + sizeof(sw842_short_data_output), 0), + SW842_DECOMPRESS_CASE("short_data_output_overflow", + sw842_short_data_output_overflow, + ARRAY_SIZE(sw842_short_data_output_overflow), + sw842_zero_output, 8, -ENOSPC), + SW842_DECOMPRESS_CASE("repeat_exact_history", + sw842_repeat_exact_history, + ARRAY_SIZE(sw842_repeat_exact_history), + sw842_zero_output, 16, 0), + SW842_DECOMPRESS_CASE("repeat_without_full_history", + sw842_repeat_without_full_history, + ARRAY_SIZE(sw842_repeat_without_full_history), + sw842_zero_output, 15, -EINVAL), +}; + +KUNIT_ARRAY_PARAM_DESC(sw842_decompress, sw842_decompress_cases, name); + +static void sw842_decompress_test(struct kunit *test) +{ + const struct sw842_decompress_test_case *test_case = test->param_value; + u8 storage[SW842_GUARD_SIZE + SW842_MAX_OUTPUT + SW842_GUARD_SIZE]; + u8 expected_guard[SW842_GUARD_SIZE]; + u8 *output = storage + SW842_GUARD_SIZE; + unsigned int output_len = test_case->output_capacity; + int ret; + + KUNIT_ASSERT_LE(test, test_case->output_capacity, SW842_MAX_OUTPUT); + memset(storage, SW842_GUARD_BYTE, sizeof(storage)); + memset(expected_guard, SW842_GUARD_BYTE, sizeof(expected_guard)); + memset(output, SW842_OUTPUT_POISON, test_case->output_capacity); + + ret = sw842_decompress(test_case->compressed, + test_case->compressed_len, output, &output_len); + + KUNIT_EXPECT_EQ(test, ret, test_case->expected_ret); + /* Every successful case is an exact-fit boundary test. */ + KUNIT_EXPECT_EQ(test, output_len, + test_case->expected_ret ? 0U : test_case->output_capacity); + if (!test_case->expected_ret) + KUNIT_EXPECT_MEMEQ(test, output, test_case->expected_output, + test_case->output_capacity); + KUNIT_EXPECT_MEMEQ(test, storage, expected_guard, SW842_GUARD_SIZE); + KUNIT_EXPECT_MEMEQ(test, output + test_case->output_capacity, + expected_guard, SW842_GUARD_SIZE); +} + +static struct kunit_case sw842_decompress_test_cases[] = { + KUNIT_CASE_PARAM(sw842_decompress_test, sw842_decompress_gen_params), + {} +}; + +static struct kunit_suite sw842_decompress_test_suite = { + .name = "842-decompress", + .test_cases = sw842_decompress_test_cases, +}; + +kunit_test_suite(sw842_decompress_test_suite); + +MODULE_DESCRIPTION("Software 842 decompressor KUnit tests"); +MODULE_LICENSE("GPL");
diff --git a/lib/tests/Makefile b/lib/tests/Makefile index 1a3d39d..5f6cf65 100644 --- a/lib/tests/Makefile +++ b/lib/tests/Makefile
@@ -4,6 +4,7 @@ # KUnit tests CFLAGS_bitfield_kunit.o := $(DISABLE_STRUCTLEAK_PLUGIN) +obj-$(CONFIG_842_DECOMPRESS_KUNIT_TEST) += 842_decompress_kunit.o obj-$(CONFIG_BASE64_KUNIT) += base64_kunit.o obj-$(CONFIG_BITOPS_KUNIT) += bitops_kunit.o obj-$(CONFIG_BITFIELD_KUNIT) += bitfield_kunit.o
diff --git a/rust/kernel/mem.rs b/rust/kernel/mem.rs index f811c94..cd00289 100644 --- a/rust/kernel/mem.rs +++ b/rust/kernel/mem.rs
@@ -2,9 +2,10 @@ //! Basic utilities for dealing with memory, values, and types. +use crate::prelude::*; + // TODO: `Alignment` should be moved here as well, Rust moved it upstream in 1.96. pub use crate::ptr::Alignment; -use crate::prelude::*; /// Trait indicating that [`Align<N>`] is a valid alignment. pub trait ValidAlign {
diff --git a/samples/Kconfig b/samples/Kconfig index a75e8e78..00eed83 100644 --- a/samples/Kconfig +++ b/samples/Kconfig
@@ -166,8 +166,17 @@ bool "Landlock example" depends on CC_CAN_LINK && HEADERS_INSTALL help - Build a simple Landlock sandbox manager able to start a process - restricted by a user-defined filesystem access control policy. + Build a Landlock sandbox manager able to start a process restricted + by user-defined filesystem, network, scope, namespace, and capability + policies. + + The optional libcap development headers and library enable capability + names. Without them, the sample still builds, accepts capability + numbers, and warns when capability settings are used. + +config SAMPLE_LANDLOCK_LIBCAP + def_bool $(cc_can_link_user,-include sys/capability.h -lcap) + depends on SAMPLE_LANDLOCK config SAMPLE_PIDFD bool "pidfd sample"
diff --git a/samples/landlock/Makefile b/samples/landlock/Makefile index 5d601e5..db5d327 100644 --- a/samples/landlock/Makefile +++ b/samples/landlock/Makefile
@@ -4,6 +4,11 @@ userccflags += -I usr/include +ifeq ($(CONFIG_SAMPLE_LANDLOCK_LIBCAP),y) +userccflags += -DUSE_LIBCAP +userldlibs += -lcap +endif + .PHONY: all clean all:
diff --git a/samples/landlock/sandboxer.c b/samples/landlock/sandboxer.c index 0305832..1362f08 100644 --- a/samples/landlock/sandboxer.c +++ b/samples/landlock/sandboxer.c
@@ -12,8 +12,11 @@ #include <arpa/inet.h> #include <errno.h> #include <fcntl.h> +#include <limits.h> #include <linux/landlock.h> +#include <linux/sched.h> #include <linux/socket.h> +#include <stdbool.h> #include <stddef.h> #include <stdio.h> #include <stdlib.h> @@ -22,7 +25,10 @@ #include <sys/stat.h> #include <sys/syscall.h> #include <unistd.h> -#include <stdbool.h> + +#ifdef USE_LIBCAP +#include <sys/capability.h> +#endif #if defined(__GLIBC__) #include <linux/prctl.h> @@ -62,6 +68,10 @@ static inline int landlock_restrict_self(const int ruleset_fd, #define ENV_TCP_BIND_NAME "LL_TCP_BIND" #define ENV_TCP_CONNECT_NAME "LL_TCP_CONNECT" #define ENV_NET_QUIET_NAME "LL_NET_QUIET" +#define ENV_NS_NAME "LL_NS" +#define ENV_NS_QUIET_NAME "LL_NS_QUIET" +#define ENV_CAP_NAME "LL_CAP" +#define ENV_CAP_QUIET_NAME "LL_CAP_QUIET" #define ENV_SCOPED_NAME "LL_SCOPED" #define ENV_QUIET_ACCESS_NAME "LL_QUIET_ACCESS" #define ENV_FORCE_LOG_NAME "LL_FORCE_LOG" @@ -69,6 +79,18 @@ static inline int landlock_restrict_self(const int ruleset_fd, #define ENV_UDP_CONNECT_SEND_NAME "LL_UDP_CONNECT_SEND" #define ENV_DELIMITER ":" +#ifdef USE_LIBCAP +#define CAP_VALUE_DESCRIPTION "names or numbers" +#define CAP_VALUE_EXAMPLES "cap_net_bind_service, cap_sys_admin, 18" +#define CAP_VALUE_EXAMPLE "cap_sys_admin" +#else +#define CAP_VALUE_DESCRIPTION "numbers" +#define CAP_VALUE_EXAMPLES "10, 18, 21" +#define CAP_VALUE_EXAMPLE "21" +#endif + +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + static int str2num(const char *numstr, __u64 *num_dst) { char *endptr = NULL; @@ -232,6 +254,185 @@ static int populate_ruleset_net(const char *const env_var, const int ruleset_fd, return ret; } +static __u64 str2ns(const char *const name) +{ + static const struct { + const char *name; + __u64 value; + } ns_map[] = { + /* clang-format off */ + { "cgroup", CLONE_NEWCGROUP }, + { "ipc", CLONE_NEWIPC }, + { "mnt", CLONE_NEWNS }, + { "net", CLONE_NEWNET }, + { "pid", CLONE_NEWPID }, + { "time", CLONE_NEWTIME }, + { "user", CLONE_NEWUSER }, + { "uts", CLONE_NEWUTS }, + /* clang-format on */ + }; + size_t i; + + for (i = 0; i < ARRAY_SIZE(ns_map); i++) { + if (strcmp(name, ns_map[i].name) == 0) + return ns_map[i].value; + } + return 0; +} + +/* + * Parses a colon-delimited list of namespace type names into a bitmask. + * Returns 0 on success (mask 0 when the variable is unset or empty), or 1 on a + * parse error. + */ +static int parse_ns_list(const char *const env_var, __u64 *const mask) +{ + int ret = 1; + char *env_ns_name, *env_ns_name_next, *strns; + + *mask = 0; + env_ns_name = getenv(env_var); + if (!env_ns_name) + return 0; + env_ns_name = strdup(env_ns_name); + unsetenv(env_var); + + env_ns_name_next = env_ns_name; + while ((strns = strsep(&env_ns_name_next, ENV_DELIMITER))) { + __u64 ns_type; + + if (strcmp(strns, "") == 0) + continue; + + ns_type = str2ns(strns); + if (!ns_type) { + fprintf(stderr, "Unknown namespace type \"%s\"\n", + strns); + goto out_free_name; + } + *mask |= ns_type; + } + ret = 0; + +out_free_name: + free(env_ns_name); + return ret; +} + +static int populate_ruleset_ns(const char *const allowed_env, + const char *const quiet_env, + const int ruleset_fd) +{ + struct landlock_namespace_attr ns_attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + }; + + if (parse_ns_list(allowed_env, &ns_attr.allowed_namespace_types)) + return 1; + if (parse_ns_list(quiet_env, &ns_attr.quiet_namespace_types)) + return 1; + + if (!ns_attr.allowed_namespace_types && !ns_attr.quiet_namespace_types) + return 0; + + if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, &ns_attr, + 0)) { + fprintf(stderr, + "Failed to update the ruleset with namespace types: %s\n", + strerror(errno)); + return 1; + } + return 0; +} + +static int str2cap(const char *const strcap, __u64 *const cap) +{ +#ifdef USE_LIBCAP + cap_value_t value; +#endif + + if (!str2num(strcap, cap)) + return 0; + +#ifdef USE_LIBCAP + if (cap_from_name(strcap, &value)) + return 1; + *cap = value; + return 0; +#else + return 1; +#endif +} + +/* + * Parses a colon-delimited list of capability values into a bitmask. Returns 0 + * on success (mask 0 when the variable is unset or empty), or 1 on a parse + * error. + */ +static int parse_cap_list(const char *const env_var, __u64 *const mask) +{ + int ret = 1; + char *env_cap_name, *env_cap_name_next, *strcap; + + *mask = 0; + env_cap_name = getenv(env_var); + if (!env_cap_name) + return 0; + env_cap_name = strdup(env_cap_name); + unsetenv(env_var); + + env_cap_name_next = env_cap_name; + while ((strcap = strsep(&env_cap_name_next, ENV_DELIMITER))) { + __u64 cap; + + if (strcmp(strcap, "") == 0) + continue; + + if (str2cap(strcap, &cap)) { + fprintf(stderr, "Failed to parse capability \"%s\"\n", + strcap); + goto out_free_name; + } + if (cap >= sizeof(*mask) * CHAR_BIT) { + fprintf(stderr, "Capability \"%s\" is out of range\n", + strcap); + goto out_free_name; + } + *mask |= 1ULL << cap; + } + ret = 0; + +out_free_name: + free(env_cap_name); + return ret; +} + +static int populate_ruleset_cap(const char *const allowed_env, + const char *const quiet_env, + const int ruleset_fd) +{ + struct landlock_capability_attr cap_attr = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + }; + + if (parse_cap_list(allowed_env, &cap_attr.allowed_capabilities)) + return 1; + if (parse_cap_list(quiet_env, &cap_attr.quiet_capabilities)) + return 1; + + if (!cap_attr.allowed_capabilities && !cap_attr.quiet_capabilities) + return 0; + + if (landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, &cap_attr, + 0)) { + fprintf(stderr, + "Failed to update the ruleset with capabilities: %s\n", + strerror(errno)); + return 1; + } + return 0; +} + /* Returns true on error, false otherwise. */ static bool check_ruleset_scope(const char *const env_var, struct landlock_ruleset_attr *ruleset_attr) @@ -369,7 +570,7 @@ static int add_quiet_access(const char *const env_var, return 0; } -#define LANDLOCK_ABI_LAST 11 +#define LANDLOCK_ABI_LAST 12 #define XSTR(s) #s #define STR(s) XSTR(s) @@ -397,6 +598,23 @@ static const char help[] = "* " ENV_UDP_CONNECT_SEND_NAME ": remote UDP ports allowed to connect " "or send to (client: use as destination port / server: receive only from it)\n" "(caution: sending requires being able to bind to a local source port)\n" + "* " ENV_NS_NAME ": namespace types allowed to use\n" + " (cgroup, ipc, mnt, net, pid, time, user, uts)\n" + "* " ENV_NS_QUIET_NAME + ": namespace types whose denial should not be audit logged\n" + " (same value format as " ENV_NS_NAME + "; quieting an allowed member is inert,\n" + " as an allowed member is never denied; setting it alone still\n" + " restricts namespace use, denying every type)\n" + "* " ENV_CAP_NAME ": capabilities allowed to use, as " + CAP_VALUE_DESCRIPTION "\n" + " (e.g. " CAP_VALUE_EXAMPLES ")\n" + "* " ENV_CAP_QUIET_NAME + ": capabilities whose denial should not be audit logged\n" + " (same value format as " ENV_CAP_NAME + "; quieting an allowed member is inert,\n" + " as an allowed member is never denied; setting it alone still\n" + " restricts capability use, denying every capability)\n" "* " ENV_SCOPED_NAME ": actions denied on the outside of the landlock domain\n" " - \"a\" to restrict opening abstract unix sockets\n" " - \"s\" to restrict sending signals\n" @@ -423,6 +641,8 @@ static const char help[] = ENV_TCP_BIND_NAME "=\"9418\" " ENV_TCP_CONNECT_NAME "=\"80:443\" " ENV_UDP_CONNECT_SEND_NAME "=\"53\" " + ENV_NS_NAME "=\"user:uts:net\" " + ENV_CAP_NAME "=\"" CAP_VALUE_EXAMPLE "\" " ENV_SCOPED_NAME "=\"a:s\" " "%1$s bash -i\n" "\n" @@ -451,6 +671,8 @@ int main(const int argc, char *const argv[], char *const *const envp) .quiet_access_fs = 0, .quiet_access_net = 0, .quiet_scoped = 0, + .handled_permissions = LANDLOCK_PERMISSION_NAMESPACE_USE | + LANDLOCK_PERMISSION_CAPABILITY_USE, }; bool quiet_supported = true; int supported_restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON | @@ -552,7 +774,12 @@ int main(const int argc, char *const argv[], char *const *const envp) supported_restrict_flags &= ~LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS; set_restrict_flags &= ~LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS; - + __attribute__((fallthrough)); + case 11: + /* Removes LANDLOCK_PERMISSION_* for ABI < 12 */ + ruleset_attr.handled_permissions &= + ~(LANDLOCK_PERMISSION_NAMESPACE_USE | + LANDLOCK_PERMISSION_CAPABILITY_USE); /* Must be printed for any ABI < LANDLOCK_ABI_LAST. */ fprintf(stderr, "Hint: You should update the running kernel " @@ -597,6 +824,32 @@ int main(const int argc, char *const argv[], char *const *const envp) ~LANDLOCK_ACCESS_NET_CONNECT_SEND_UDP; } + /* Removes namespace handling if not set by a user. */ + if (!getenv(ENV_NS_NAME) && !getenv(ENV_NS_QUIET_NAME)) + ruleset_attr.handled_permissions &= + ~LANDLOCK_PERMISSION_NAMESPACE_USE; + if (!(ruleset_attr.handled_permissions & + LANDLOCK_PERMISSION_NAMESPACE_USE)) { + unsetenv(ENV_NS_NAME); + unsetenv(ENV_NS_QUIET_NAME); + } + +#ifndef USE_LIBCAP + if (getenv(ENV_CAP_NAME) || getenv(ENV_CAP_QUIET_NAME)) + fprintf(stderr, + "Warning: Built without libcap; use capability numbers, not names.\n"); +#endif + + /* Removes capability handling if not set by a user. */ + if (!getenv(ENV_CAP_NAME) && !getenv(ENV_CAP_QUIET_NAME)) + ruleset_attr.handled_permissions &= + ~LANDLOCK_PERMISSION_CAPABILITY_USE; + if (!(ruleset_attr.handled_permissions & + LANDLOCK_PERMISSION_CAPABILITY_USE)) { + unsetenv(ENV_CAP_NAME); + unsetenv(ENV_CAP_QUIET_NAME); + } + if (check_ruleset_scope(ENV_SCOPED_NAME, &ruleset_attr)) return 1; @@ -680,6 +933,16 @@ int main(const int argc, char *const argv[], char *const *const envp) } } + if ((ruleset_attr.handled_permissions & + LANDLOCK_PERMISSION_NAMESPACE_USE) && + populate_ruleset_ns(ENV_NS_NAME, ENV_NS_QUIET_NAME, ruleset_fd)) + goto err_close_ruleset; + + if ((ruleset_attr.handled_permissions & + LANDLOCK_PERMISSION_CAPABILITY_USE) && + populate_ruleset_cap(ENV_CAP_NAME, ENV_CAP_QUIET_NAME, ruleset_fd)) + goto err_close_ruleset; + if (!(set_restrict_flags & LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS) && prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { perror("Failed to restrict privileges");
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index 1492e9f..92596bf 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c
@@ -1,5 +1,6 @@ // SPDX-License-Identifier: GPL-2.0 #define COMPILE_OFFSETS +#include <linux/device-id/scmi.h> #include <linux/kbuild.h> #include <linux/mod_devicetable.h> @@ -144,6 +145,10 @@ int main(void) DEVID(rpmsg_device_id); DEVID_FIELD(rpmsg_device_id, name); + DEVID(scmi_device_id); + DEVID_FIELD(scmi_device_id, protocol_id); + DEVID_FIELD(scmi_device_id, name); + DEVID(i2c_device_id); DEVID_FIELD(i2c_device_id, name);
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 980d7da..61a831c 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c
@@ -121,6 +121,7 @@ typedef struct { /* Big exception to the "don't include kernel headers into userspace, which * even potentially has different endianness and word sizes, since * we handle those differences explicitly below */ +#include "../../include/linux/device-id/scmi.h" #include "../../include/linux/mod_devicetable.h" struct devtable { @@ -852,6 +853,16 @@ static void do_rpmsg_entry(struct module *mod, void *symval) module_alias_printf(mod, false, RPMSG_DEVICE_MODALIAS_FMT, *name); } +/* Looks like: scmi:NN:S */ +static void do_scmi_entry(struct module *mod, void *symval) +{ + DEF_FIELD(symval, scmi_device_id, protocol_id); + DEF_FIELD_ADDR(symval, scmi_device_id, name); + + module_alias_printf(mod, false, SCMI_MODULE_PREFIX "%02x:%s", + protocol_id, *name); +} + /* Looks like: i2c:S */ static void do_i2c_entry(struct module *mod, void *symval) { @@ -1498,6 +1509,7 @@ static const struct devtable devtable[] = { {"virtio", SIZE_virtio_device_id, do_virtio_entry}, {"vmbus", SIZE_hv_vmbus_device_id, do_vmbus_entry}, {"rpmsg", SIZE_rpmsg_device_id, do_rpmsg_entry}, + {"scmi", SIZE_scmi_device_id, do_scmi_entry}, {"i2c", SIZE_i2c_device_id, do_i2c_entry}, {"i3c", SIZE_i3c_device_id, do_i3c_entry}, {"slim", SIZE_slim_device_id, do_slim_entry},
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c index 9bfea85..ac83288 100644 --- a/security/integrity/evm/evm_main.c +++ b/security/integrity/evm/evm_main.c
@@ -563,7 +563,7 @@ static int evm_protect_xattr(const struct mnt_idmap *idmap, dentry->d_inode, dentry->d_name.name, "update_metadata", integrity_status_msg[evm_status], - -EPERM, 0); + -EPERM, 0, -EPERM); } out: /* Exception if the HMAC is not going to be calculated. */ @@ -588,7 +588,7 @@ static int evm_protect_xattr(const struct mnt_idmap *idmap, integrity_audit_msg(AUDIT_INTEGRITY_METADATA, d_backing_inode(dentry), dentry->d_name.name, "appraise_metadata", integrity_status_msg[evm_status], - -EPERM, 0); + -EPERM, 0, -EPERM); return evm_status == INTEGRITY_PASS ? 0 : -EPERM; } @@ -729,7 +729,7 @@ static int evm_inode_set_acl(const struct mnt_idmap *idmap, struct dentry *dentr integrity_audit_msg(AUDIT_INTEGRITY_METADATA, d_backing_inode(dentry), dentry->d_name.name, "appraise_metadata", integrity_status_msg[evm_status], - -EPERM, 0); + -EPERM, 0, -EPERM); return -EPERM; } @@ -992,7 +992,8 @@ static int evm_inode_setattr(const struct mnt_idmap *idmap, struct dentry *dentr integrity_audit_msg(AUDIT_INTEGRITY_METADATA, d_backing_inode(dentry), dentry->d_name.name, "appraise_metadata", - integrity_status_msg[evm_status], -EPERM, 0); + integrity_status_msg[evm_status], -EPERM, 0, + -EPERM); return -EPERM; }
diff --git a/security/integrity/ima/ima_api.c b/security/integrity/ima/ima_api.c index 3c5a23b..45701f0 100644 --- a/security/integrity/ima/ima_api.c +++ b/security/integrity/ima/ima_api.c
@@ -116,7 +116,7 @@ int ima_store_template(struct ima_template_entry *entry, if (result < 0) { integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, template_name, op, - audit_cause, result, 0); + audit_cause, result, 0, result); return result; } } @@ -159,7 +159,7 @@ void ima_add_violation(struct file *file, const unsigned char *filename, ima_free_template_entry(entry); err_out: integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, - op, cause, result, 0); + op, cause, result, 0, result); } /** @@ -330,7 +330,7 @@ int ima_collect_measurement(struct ima_iint_cache *iint, struct file *file, integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, filename.name.name, "collect_data", - audit_cause, result, 0); + audit_cause, result, 0, result); release_dentry_name_snapshot(&filename); } @@ -383,7 +383,7 @@ void ima_store_measurement(struct ima_iint_cache *iint, struct file *file, result = ima_alloc_init_template(&event_data, &entry, template_desc); if (result < 0) { integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, - op, audit_cause, result, 0); + op, audit_cause, result, 0, result); return; }
diff --git a/security/integrity/ima/ima_appraise.c b/security/integrity/ima/ima_appraise.c index 63b0cb9..134174d 100644 --- a/security/integrity/ima/ima_appraise.c +++ b/security/integrity/ima/ima_appraise.c
@@ -564,7 +564,7 @@ int ima_appraise_measurement(enum ima_hooks func, struct ima_iint_cache *iint, status = INTEGRITY_FAIL; cause = "unverifiable-signature"; integrity_audit_msg(audit_msgno, inode, filename, - op, cause, rc, 0); + op, cause, rc, 0, rc < 0 ? rc : 0); } else if (status != INTEGRITY_PASS) { /* Fix mode, but don't replace file signatures. */ if ((ima_appraise & IMA_APPRAISE_FIX) && !try_modsig && @@ -589,7 +589,7 @@ int ima_appraise_measurement(enum ima_hooks func, struct ima_iint_cache *iint, } integrity_audit_msg(audit_msgno, inode, filename, - op, cause, rc, 0); + op, cause, rc, 0, rc < 0 ? rc : 0); } else { ima_cache_flags(iint, func); } @@ -752,7 +752,7 @@ static int validate_hash_algo(struct dentry *dentry, path = NULL; integrity_audit_msg(AUDIT_INTEGRITY_DATA, d_inode(dentry), path, - "set_data", errmsg, -EACCES, 0); + "set_data", errmsg, -EACCES, 0, -EACCES); kfree(pathbuf);
diff --git a/security/integrity/ima/ima_fs.c b/security/integrity/ima/ima_fs.c index 2a0bca5..3b8174a 100644 --- a/security/integrity/ima/ima_fs.c +++ b/security/integrity/ima/ima_fs.c
@@ -592,11 +592,11 @@ static ssize_t ima_write_policy(struct file *file, const char __user *buf, if (data[0] == '/') { result = ima_read_policy(data); } else if (ima_appraise & IMA_APPRAISE_POLICY) { + result = -EACCES; pr_err("signed policy file (specified as an absolute pathname) required\n"); integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, "policy_update", "signed policy required", - 1, 0); - result = -EACCES; + result, 0, result); } else { ima_measure_raw_policy(data, datalen); result = ima_parse_add_rule(data); @@ -745,7 +745,8 @@ static int ima_release_policy(struct inode *inode, struct file *file) pr_info("policy update %s\n", cause); integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, - "policy_update", cause, !valid_policy, 0); + "policy_update", cause, !valid_policy, 0, + !valid_policy ? -EINVAL : 0); if (!valid_policy) { ima_delete_rules();
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c index d53f4d8..7a76e26 100644 --- a/security/integrity/ima/ima_init.c +++ b/security/integrity/ima/ima_init.c
@@ -103,7 +103,7 @@ static int __init ima_add_boot_aggregate(void) return 0; err_out: integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, filename, op, - audit_cause, result, 0); + audit_cause, result, 0, result); return result; }
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c index 7ac38a9..fed80da 100644 --- a/security/integrity/ima/ima_main.c +++ b/security/integrity/ima/ima_main.c
@@ -119,7 +119,7 @@ static int mmap_violation_check(enum ima_hooks func, struct file *file, *pathname = ima_d_path(&file->f_path, pathbuf, filename); integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, *pathname, - "mmap_file", "mmapped_writers", rc, 0); + "mmap_file", "mmapped_writers", rc, 0, rc); } return rc; } @@ -466,7 +466,7 @@ static int process_measurement(struct file *file, const struct cred *cred, integrity_audit_msg(AUDIT_INTEGRITY_DATA, file_inode(file), pathname, "collect_data", - "denied-hash-algorithm", rc, 0); + "denied-hash-algorithm", rc, 0, rc); } out_locked: if ((mask & MAY_WRITE) && test_bit(IMA_DIGSIG, &iint->atomic_flags) && @@ -579,7 +579,8 @@ static int ima_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot, file = vma->vm_file; pathname = ima_d_path(&file->f_path, &pathbuf, filename); integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, pathname, - "collect_data", "failed-mprotect", result, 0); + "collect_data", "failed-mprotect", result, 0, + result); if (pathbuf) __putname(pathbuf); @@ -1195,9 +1196,9 @@ int process_buffer_measurement(const struct mnt_idmap *idmap, out: if (ret < 0) - integrity_audit_message(AUDIT_INTEGRITY_PCR, NULL, eventname, - func_measure_str(func), - audit_cause, ret, 0, ret); + integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, eventname, + func_measure_str(func), + audit_cause, ret, 0, ret); return ret; }
diff --git a/security/integrity/ima/ima_policy.c b/security/integrity/ima/ima_policy.c index b34d962..2dc1d93 100644 --- a/security/integrity/ima/ima_policy.c +++ b/security/integrity/ima/ima_policy.c
@@ -1992,7 +1992,8 @@ ssize_t ima_parse_add_rule(char *rule) entry = kzalloc_obj(*entry); if (!entry) { integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, - NULL, op, "-ENOMEM", -ENOMEM, audit_info); + NULL, op, "-ENOMEM", -ENOMEM, audit_info, + -ENOMEM); return -ENOMEM; } @@ -2003,7 +2004,7 @@ ssize_t ima_parse_add_rule(char *rule) ima_free_rule(entry); integrity_audit_msg(AUDIT_INTEGRITY_STATUS, NULL, NULL, op, "invalid-policy", result, - audit_info); + audit_info, result); return result; } @@ -2421,7 +2422,7 @@ void ima_measure_loaded_policy(void) rule = kmalloc(rule_len, GFP_KERNEL); if (!rule) { integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, event_name, - op, "ENOMEM", result, 0); + op, "ENOMEM", result, 0, result); return; } @@ -2440,7 +2441,7 @@ void ima_measure_loaded_policy(void) result = -E2BIG; integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, event_name, op, "rule_length", - result, 0); + result, 0, result); rcu_read_unlock(); goto free_rule; } @@ -2454,7 +2455,7 @@ void ima_measure_loaded_policy(void) file.buf = kmalloc(file_len, GFP_KERNEL); if (!file.buf) { integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, event_name, - op, "ENOMEM", result, 0); + op, "ENOMEM", result, 0, result); goto free_rule; }
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c index 0f1b7e4..67782c0 100644 --- a/security/integrity/ima/ima_queue.c +++ b/security/integrity/ima/ima_queue.c
@@ -291,7 +291,7 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation, out: mutex_unlock(&ima_extend_list_mutex); integrity_audit_msg(AUDIT_INTEGRITY_PCR, inode, filename, - op, audit_cause, result, audit_info); + op, audit_cause, result, audit_info, result); return result; }
diff --git a/security/integrity/ima/ima_queue_keys.c b/security/integrity/ima/ima_queue_keys.c index b5ed33c..8adc886 100644 --- a/security/integrity/ima/ima_queue_keys.c +++ b/security/integrity/ima/ima_queue_keys.c
@@ -90,10 +90,10 @@ static struct ima_key_entry *ima_alloc_key_entry(struct key *keyring, out: if (rc) { - integrity_audit_message(AUDIT_INTEGRITY_PCR, NULL, - keyring->description, - func_measure_str(KEY_CHECK), - audit_cause, rc, 0, rc); + integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, + keyring->description, + func_measure_str(KEY_CHECK), + audit_cause, rc, 0, rc); ima_free_key_entry(entry); entry = NULL; }
diff --git a/security/integrity/ima/ima_template.c b/security/integrity/ima/ima_template.c index 7034573..1615407 100644 --- a/security/integrity/ima/ima_template.c +++ b/security/integrity/ima/ima_template.c
@@ -450,6 +450,11 @@ int ima_restore_measurement_list(loff_t size, void *buf) return -EINVAL; } + if (khdr->buffer_size > size) { + pr_err("attempting to restore a corrupted measurement list"); + return -EINVAL; + } + bitmap_zero(hdr_mask, HDR__LAST); bitmap_set(hdr_mask, HDR_PCR, 1); bitmap_set(hdr_mask, HDR_DIGEST, 1); @@ -524,6 +529,13 @@ int ima_restore_measurement_list(loff_t size, void *buf) ret = -EINVAL; break; } + } else { + /* + * If the template hash found in the kexec buffer is all + * zeros, record it as a violation. Note that this can + * be a false positive. + */ + atomic_long_inc(&ima_num_violations); } entry->pcr = !ima_canonical_fmt ? *(u32 *)(hdr[HDR_PCR].data) :
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c index 8a89236..9bd80ca 100644 --- a/security/integrity/ima/ima_template_lib.c +++ b/security/integrity/ima/ima_template_lib.c
@@ -392,7 +392,7 @@ int ima_eventdigest_init(struct ima_event_data *event_data, if (result) { integrity_audit_msg(AUDIT_INTEGRITY_DATA, inode, event_data->filename, "collect_data", - "failed", result, 0); + "failed", result, 0, result); return result; } cur_digest = hash_hdr->digest;
diff --git a/security/integrity/integrity.h b/security/integrity/integrity.h index 0c581c0..52c5ec8 100644 --- a/security/integrity/integrity.h +++ b/security/integrity/integrity.h
@@ -218,12 +218,8 @@ static inline void evm_load_x509(void) /* declarations */ void integrity_audit_msg(int audit_msgno, struct inode *inode, const unsigned char *fname, const char *op, - const char *cause, int result, int info); - -void integrity_audit_message(int audit_msgno, struct inode *inode, - const unsigned char *fname, const char *op, - const char *cause, int result, int info, - int errno); + const char *cause, int result, int info, + int errno); static inline struct audit_buffer * integrity_audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type) @@ -235,15 +231,7 @@ integrity_audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, int type) static inline void integrity_audit_msg(int audit_msgno, struct inode *inode, const unsigned char *fname, const char *op, const char *cause, - int result, int info) -{ -} - -static inline void integrity_audit_message(int audit_msgno, - struct inode *inode, - const unsigned char *fname, - const char *op, const char *cause, - int result, int info, int errno) + int result, int info, int errno) { }
diff --git a/security/integrity/integrity_audit.c b/security/integrity/integrity_audit.c index d8d9e5f..22106aa 100644 --- a/security/integrity/integrity_audit.c +++ b/security/integrity/integrity_audit.c
@@ -27,16 +27,8 @@ __setup("integrity_audit=", integrity_audit_setup); void integrity_audit_msg(int audit_msgno, struct inode *inode, const unsigned char *fname, const char *op, - const char *cause, int result, int audit_info) -{ - integrity_audit_message(audit_msgno, inode, fname, op, cause, - result, audit_info, 0); -} - -void integrity_audit_message(int audit_msgno, struct inode *inode, - const unsigned char *fname, const char *op, - const char *cause, int result, int audit_info, - int errno) + const char *cause, int result, int audit_info, + int errno) { struct audit_buffer *ab; char name[TASK_COMM_LEN];
diff --git a/security/ipe/audit.c b/security/ipe/audit.c index 93fb59f..b6f8fb5 100644 --- a/security/ipe/audit.c +++ b/security/ipe/audit.c
@@ -34,34 +34,34 @@ "new_policy_digest=" IPE_AUDIT_HASH_ALG ":" static const char *const audit_op_names[__IPE_OP_MAX + 1] = { - "EXECUTE", - "FIRMWARE", - "KMODULE", - "KEXEC_IMAGE", - "KEXEC_INITRAMFS", - "POLICY", - "X509_CERT", - "UNKNOWN", + [IPE_OP_EXEC] = "EXECUTE", + [IPE_OP_FIRMWARE] = "FIRMWARE", + [IPE_OP_KERNEL_MODULE] = "KMODULE", + [IPE_OP_KEXEC_IMAGE] = "KEXEC_IMAGE", + [IPE_OP_KEXEC_INITRAMFS] = "KEXEC_INITRAMFS", + [IPE_OP_POLICY] = "POLICY", + [IPE_OP_X509] = "X509_CERT", + [IPE_OP_INVALID] = "UNKNOWN", }; static const char *const audit_hook_names[__IPE_HOOK_MAX] = { - "BPRM_CHECK", - "BPRM_CREDS_FOR_EXEC", - "MMAP", - "MPROTECT", - "KERNEL_READ", - "KERNEL_LOAD", + [IPE_HOOK_BPRM_CHECK] = "BPRM_CHECK", + [IPE_HOOK_BPRM_CREDS_FOR_EXEC] = "BPRM_CREDS_FOR_EXEC", + [IPE_HOOK_MMAP] = "MMAP", + [IPE_HOOK_MPROTECT] = "MPROTECT", + [IPE_HOOK_KERNEL_READ] = "KERNEL_READ", + [IPE_HOOK_KERNEL_LOAD] = "KERNEL_LOAD", }; static const char *const audit_prop_names[__IPE_PROP_MAX] = { - "boot_verified=FALSE", - "boot_verified=TRUE", - "dmverity_roothash=", - "dmverity_signature=FALSE", - "dmverity_signature=TRUE", - "fsverity_digest=", - "fsverity_signature=FALSE", - "fsverity_signature=TRUE", + [IPE_PROP_BOOT_VERIFIED_FALSE] = "boot_verified=FALSE", + [IPE_PROP_BOOT_VERIFIED_TRUE] = "boot_verified=TRUE", + [IPE_PROP_DMV_ROOTHASH] = "dmverity_roothash=", + [IPE_PROP_DMV_SIG_FALSE] = "dmverity_signature=FALSE", + [IPE_PROP_DMV_SIG_TRUE] = "dmverity_signature=TRUE", + [IPE_PROP_FSV_DIGEST] = "fsverity_digest=", + [IPE_PROP_FSV_SIG_FALSE] = "fsverity_signature=FALSE", + [IPE_PROP_FSV_SIG_TRUE] = "fsverity_signature=TRUE", }; /** @@ -262,18 +262,10 @@ void ipe_audit_policy_load(const struct ipe_policy *const p) */ void ipe_audit_enforce(bool new_enforce, bool old_enforce) { - struct audit_buffer *ab; - - ab = audit_log_start(audit_context(), GFP_KERNEL, AUDIT_MAC_STATUS); - if (!ab) - return; - audit_log(audit_context(), GFP_KERNEL, AUDIT_MAC_STATUS, "enforcing=%d old_enforcing=%d auid=%u ses=%u" " enabled=1 old-enabled=1 lsm=ipe res=1", new_enforce, old_enforce, from_kuid(&init_user_ns, audit_get_loginuid(current)), audit_get_sessionid(current)); - - audit_log_end(ab); }
diff --git a/security/ipe/policy.c b/security/ipe/policy.c index 827867b..e542329 100644 --- a/security/ipe/policy.c +++ b/security/ipe/policy.c
@@ -52,7 +52,7 @@ void ipe_free_policy(struct ipe_policy *p) ipe_del_policyfs_node(p); ipe_free_parsed_policy(p->parsed); /* - * p->text is allocated only when p->pkcs7 is not NULL + * p->text is allocated only when p->pkcs7 is NULL * otherwise it points to the plaintext data inside the pkcs7 */ if (!p->pkcs7)
diff --git a/security/ipe/policy_parser.c b/security/ipe/policy_parser.c index 6fa5beb..309a615 100644 --- a/security/ipe/policy_parser.c +++ b/security/ipe/policy_parser.c
@@ -128,6 +128,8 @@ static const match_table_t header_tokens = { {__IPE_HEADER_MAX, NULL} }; +static_assert(ARRAY_SIZE(header_tokens) == __IPE_HEADER_MAX + 1); + /** * parse_header() - Parse policy header information. * @line: Supplies header line to be parsed. @@ -201,7 +203,7 @@ static int parse_header(char *line, struct ipe_parsed_policy *p) * * %false - The token is not "DEFAULT" * * %true - The token is "DEFAULT" */ -static bool token_default(char *token) +static bool token_default(const char *token) { return !strcmp(token, "DEFAULT"); } @@ -240,6 +242,8 @@ static const match_table_t operation_tokens = { {IPE_OP_INVALID, NULL} }; +static_assert(ARRAY_SIZE(operation_tokens) == __IPE_OP_MAX + 1); + /** * parse_operation() - Parse the operation type given a token string. * @t: Supplies the token string to be parsed. @@ -259,6 +263,8 @@ static const match_table_t action_tokens = { {IPE_ACTION_INVALID, NULL} }; +static_assert(ARRAY_SIZE(action_tokens) == __IPE_ACTION_MAX + 1); + /** * parse_action() - Parse the action type given a token string. * @t: Supplies the token string to be parsed. @@ -284,6 +290,8 @@ static const match_table_t property_tokens = { {IPE_PROP_INVALID, NULL} }; +static_assert(ARRAY_SIZE(property_tokens) == __IPE_PROP_MAX + 1); + /** * parse_property() - Parse a rule property given a token string. * @t: Supplies the token string to be parsed.
diff --git a/security/keys/key.c b/security/keys/key.c index a438c45..6ebb869 100644 --- a/security/keys/key.c +++ b/security/keys/key.c
@@ -588,11 +588,18 @@ int key_reject_and_link(struct key *key, ret = -EBUSY; if (keyring) { - if (keyring->restrict_link) - return -EPERM; - link_ret = __key_link_lock(keyring, &key->index_key); if (link_ret == 0) { + /* + * Check the restriction under the keyring semaphore. + * keyring_restrict() installs it while holding the + * semaphore, so testing it beforehand races with a + * concurrent restriction install. + */ + if (keyring->restrict_link) { + __key_link_end(keyring, &key->index_key, edit); + return -EPERM; + } link_ret = __key_link_begin(keyring, &key->index_key, &edit); if (link_ret < 0) __key_link_end(keyring, &key->index_key, edit);
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c index d14ace8..36ffba0 100644 --- a/security/keys/keyctl.c +++ b/security/keys/keyctl.c
@@ -677,12 +677,14 @@ long keyctl_describe_key(key_serial_t keyid, /* calculate how much information we're going to return */ ret = -ENOMEM; + down_read(&key->sem); infobuf = kasprintf(GFP_KERNEL, "%s;%d;%d;%08x;", key->type->name, from_kuid_munged(current_user_ns(), key->uid), from_kgid_munged(current_user_ns(), key->gid), key->perm); + up_read(&key->sem); if (!infobuf) goto error2; infolen = strlen(infobuf); @@ -806,8 +808,12 @@ static long __keyctl_read_key(struct key *key, char *buffer, size_t buflen) down_read(&key->sem); ret = key_validate(key); - if (ret == 0) - ret = key->type->read(key, buffer, buflen); + if (ret == 0) { + if (key->type->read) + ret = key->type->read(key, buffer, buflen); + else + ret = -EOPNOTSUPP; + } up_read(&key->sem); return ret; } @@ -861,11 +867,6 @@ long keyctl_read_key(key_serial_t keyid, char __user *buffer, size_t buflen) /* the key is probably readable - now try to read it */ can_read_key: - if (!key->type->read) { - ret = -EOPNOTSUPP; - goto key_put_out; - } - if (!buffer || !buflen) { /* Get the key length from the read method */ ret = __keyctl_read_key(key, NULL, 0);
diff --git a/security/keys/keyring.c b/security/keys/keyring.c index 15bf4af..7143f30 100644 --- a/security/keys/keyring.c +++ b/security/keys/keyring.c
@@ -14,6 +14,9 @@ #include <linux/err.h> #include <linux/user_namespace.h> #include <linux/nsproxy.h> +#include <linux/once.h> +#include <linux/random.h> +#include <linux/siphash.h> #include <keys/keyring-type.h> #include <keys/user-type.h> #include <linux/assoc_array_priv.h> @@ -147,49 +150,46 @@ static int keyring_instantiate(struct key *keyring, } /* - * Multiply 64-bits by 32-bits to 96-bits and fold back to 64-bit. Ideally we'd - * fold the carry back too, but that requires inline asm. + * Give key types and domains address-independent identities. Zero means that + * an ID has not yet been allocated. As with inode sequence numbers used by + * futexes, this relies on the 64-bit counter not wrapping in a machine's + * lifetime. */ -static u64 mult_64x32_and_fold(u64 x, u32 y) +static u64 key_index_id(atomic64_t *id) { - u64 hi = (u64)(u32)(x >> 32) * y; - u64 lo = (u64)(u32)(x) * y; - return lo + ((u64)(u32)hi << 32) + (u32)(hi >> 32); + static atomic64_t next_id; + u64 old, new; + + old = atomic64_read(id); + if (likely(old)) + return old; + + do { + new = atomic64_inc_return(&next_id); + } while (WARN_ON_ONCE(!new)); + + old = 0; + if (!atomic64_try_cmpxchg_relaxed(id, &old, new)) + return old; + return new; } /* - * Hash a key type and description. + * Hash a key type, domain and description. KEYCTL_READ exposes the tree's + * traversal order, so no part of the index may contain kernel addresses. */ static void hash_key_type_and_desc(struct keyring_index_key *index_key) { const unsigned level_shift = ASSOC_ARRAY_LEVEL_STEP; const unsigned long fan_mask = ASSOC_ARRAY_FAN_MASK; - const char *description = index_key->description; - unsigned long hash, type; - u32 piece; + static siphash_key_t hash_key __read_mostly; + unsigned long hash; u64 acc; - int n, desc_len = index_key->desc_len; - type = (unsigned long)index_key->type; - acc = mult_64x32_and_fold(type, desc_len + 13); - acc = mult_64x32_and_fold(acc, 9207); - piece = (unsigned long)index_key->domain_tag; - acc = mult_64x32_and_fold(acc, piece); - acc = mult_64x32_and_fold(acc, 9207); - - for (;;) { - n = desc_len; - if (n <= 0) - break; - if (n > 4) - n = 4; - piece = 0; - memcpy(&piece, description, n); - description += n; - desc_len -= n; - acc = mult_64x32_and_fold(acc, piece); - acc = mult_64x32_and_fold(acc, 9207); - } + get_random_once(&hash_key, sizeof(hash_key)); + acc = siphash(index_key->description, index_key->desc_len, &hash_key); + acc = siphash_3u64(index_key->type_id, index_key->domain_id, acc, + &hash_key); /* Fold the hash down to 32 bits if need be. */ hash = acc; @@ -209,7 +209,7 @@ static void hash_key_type_and_desc(struct keyring_index_key *index_key) /* * Finalise an index key to include a part of the description actually in the - * index key, to set the domain tag and to calculate the hash. + * index key, to set the domain tag and index IDs, and to calculate the hash. */ void key_set_index_key(struct keyring_index_key *index_key) { @@ -225,6 +225,14 @@ void key_set_index_key(struct keyring_index_key *index_key) index_key->domain_tag = &default_domain_tag; } + /* Preserve the IDs when copying an existing key's index. In + * particular, its type may already have been unregistered. + */ + if (!index_key->type_id) + index_key->type_id = key_index_id(&index_key->type->index_id); + if (!index_key->domain_id) + index_key->domain_id = key_index_id(&index_key->domain_tag->index_id); + hash_key_type_and_desc(index_key); } @@ -263,15 +271,19 @@ void key_remove_domain(struct key_tag *domain_tag) /* * Build the next index key chunk. * + * The hash and inline description are followed by the 64-bit type and domain + * IDs, low word first, and then by the rest of the description. * We return it one word-sized chunk at a time. */ static unsigned long keyring_get_key_chunk(const void *data, int level) { + const unsigned int id_chunks = sizeof(u64) / sizeof(unsigned long); const struct keyring_index_key *index_key = data; + int desc_len = index_key->desc_len; unsigned long chunk = 0; - const u8 *d; - int desc_len = index_key->desc_len, n = sizeof(chunk); + int n = sizeof(chunk); unsigned int offset; + const u8 *d; level /= ASSOC_ARRAY_KEY_CHUNK_SIZE; switch (level) { @@ -279,27 +291,30 @@ static unsigned long keyring_get_key_chunk(const void *data, int level) return index_key->hash; case 1: return index_key->x; - case 2: - return (unsigned long)index_key->type; - case 3: - return (unsigned long)index_key->domain_tag; - default: - level -= 4; - offset = sizeof(index_key->desc) + level * sizeof(long); - if (desc_len <= offset) - return 0; - - d = index_key->description + offset; - desc_len -= offset; - if (desc_len > n) - desc_len = n; - d += desc_len; - do { - chunk <<= 8; - chunk |= *--d; - } while (--desc_len > 0); - return chunk; } + + level -= 2; + if (level < id_chunks) + return index_key->type_id >> (level * ASSOC_ARRAY_KEY_CHUNK_SIZE); + level -= id_chunks; + if (level < id_chunks) + return index_key->domain_id >> (level * ASSOC_ARRAY_KEY_CHUNK_SIZE); + level -= id_chunks; + + offset = sizeof(index_key->desc) + level * sizeof(long); + if (desc_len <= offset) + return 0; + + d = index_key->description + offset; + desc_len -= offset; + if (desc_len > n) + desc_len = n; + d += desc_len; + do { + chunk <<= 8; + chunk |= *--d; + } while (--desc_len > 0); + return chunk; } static unsigned long keyring_get_object_key_chunk(const void *object, int level) @@ -331,6 +346,7 @@ static int keyring_diff_objects(const void *object, const void *data) const struct keyring_index_key *b = data; unsigned long seg_a, seg_b; int level, i; + u64 diff; level = 0; seg_a = a->hash; @@ -339,28 +355,22 @@ static int keyring_diff_objects(const void *object, const void *data) goto differ; level += ASSOC_ARRAY_KEY_CHUNK_SIZE / 8; - /* The number of bits contributed by the hash is controlled by a - * constant in the assoc_array headers. Everything else thereafter we - * can deal with as being machine word-size dependent. - */ + /* The inline description contributes one machine-word-sized chunk. */ seg_a = a->x; seg_b = b->x; if ((seg_a ^ seg_b) != 0) goto differ; level += sizeof(unsigned long); - /* The next bit may not work on big endian */ - seg_a = (unsigned long)a->type; - seg_b = (unsigned long)b->type; - if ((seg_a ^ seg_b) != 0) - goto differ; - level += sizeof(unsigned long); + diff = a->type_id ^ b->type_id; + if (diff) + return level * 8 + __ffs64(diff); + level += sizeof(u64); - seg_a = (unsigned long)a->domain_tag; - seg_b = (unsigned long)b->domain_tag; - if ((seg_a ^ seg_b) != 0) - goto differ; - level += sizeof(unsigned long); + diff = a->domain_id ^ b->domain_id; + if (diff) + return level * 8 + __ffs64(diff); + level += sizeof(u64); i = sizeof(a->desc); if (a->desc_len <= i) @@ -1158,7 +1168,7 @@ struct key *find_keyring_by_name(const char *name, bool uid_keyring) * grants Search permission and that hasn't been revoked */ list_for_each_entry(keyring, &ns->keyring_name_list, name_link) { - if (!kuid_has_mapping(ns, keyring->user->uid)) + if (!kuid_has_mapping(ns, keyring->uid)) continue; if (test_bit(KEY_FLAG_REVOKED, &keyring->flags))
diff --git a/security/keys/proc.c b/security/keys/proc.c index 4f4e2c1..aea06a7 100644 --- a/security/keys/proc.c +++ b/security/keys/proc.c
@@ -68,7 +68,7 @@ static struct rb_node *key_serial_next(struct seq_file *p, struct rb_node *n) n = rb_next(n); while (n) { struct key *key = rb_entry(n, struct key, serial_node); - if (kuid_has_mapping(user_ns, key->user->uid)) + if (kuid_has_mapping(user_ns, key->uid)) break; n = rb_next(n); } @@ -100,7 +100,7 @@ static struct key *find_ge_key(struct seq_file *p, key_serial_t id) return NULL; for (;;) { - if (kuid_has_mapping(user_ns, minkey->user->uid)) + if (kuid_has_mapping(user_ns, minkey->uid)) return minkey; n = rb_next(&minkey->serial_node); if (!n)
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c index a63c46b..1a51a36 100644 --- a/security/keys/process_keys.c +++ b/security/keys/process_keys.c
@@ -528,7 +528,7 @@ key_ref_t search_cred_keyrings_rcu(struct keyring_search_context *ctx) /* * Search the process keyrings attached to the supplied cred for the first - * matching key in the manner of search_my_process_keyrings(), but also search + * matching key in the manner of search_cred_keyrings_rcu(), but also search * the keys attached to the assumed authorisation key using its credentials if * one is available. * @@ -556,9 +556,8 @@ key_ref_t search_process_keyrings_rcu(struct keyring_search_context *ctx) ) { const struct cred *cred = ctx->cred; - if (key_validate(cred->request_key_auth) == 0) { - rka = ctx->cred->request_key_auth->payload.data[0]; - + rka = dereference_key_rcu(cred->request_key_auth); + if (rka && key_validate(cred->request_key_auth) == 0) { //// was search_process_keyrings() [ie. recursive] ctx->cred = rka->cred; key_ref = search_cred_keyrings_rcu(ctx);
diff --git a/security/keys/trusted-keys/trusted_tpm1.c b/security/keys/trusted-keys/trusted_tpm1.c index e5a904b..3b7af11 100644 --- a/security/keys/trusted-keys/trusted_tpm1.c +++ b/security/keys/trusted-keys/trusted_tpm1.c
@@ -48,15 +48,17 @@ enum { #ifdef CONFIG_TRUSTED_KEYS_DEBUG static inline void dump_options(struct trusted_key_options *o) { + struct trusted_key_tpm *private = o->private; + if (!trusted_debug) return; pr_debug("sealing key type %d\n", o->keytype); - pr_debug("sealing key handle %0X\n", o->keyhandle); - pr_debug("pcrlock %d\n", o->pcrlock); - pr_debug("pcrinfo %d\n", o->pcrinfo_len); + pr_debug("sealing key handle %0X\n", private->keyhandle); + pr_debug("pcrlock %d\n", private->pcrlock); + pr_debug("pcrinfo %d\n", private->pcrinfo_len); print_hex_dump_debug("pcrinfo ", DUMP_PREFIX_NONE, - 16, 1, o->pcrinfo, o->pcrinfo_len, 0); + 16, 1, private->pcrinfo, private->pcrinfo_len, 0); } static inline void dump_sess(struct osapsess *s) @@ -626,6 +628,7 @@ static int tpm_unseal(struct tpm_buf *tb, static int key_seal(struct trusted_key_payload *p, struct trusted_key_options *o) { + struct trusted_key_tpm *private = o->private; int ret; struct tpm_buf *tb __free(kfree) = kzalloc(TPM_BUFSIZE, GFP_KERNEL); @@ -637,9 +640,10 @@ static int key_seal(struct trusted_key_payload *p, /* include migratable flag at end of sealed key */ p->key[p->key_len] = p->migratable; - ret = tpm_seal(tb, o->keytype, o->keyhandle, o->keyauth, + ret = tpm_seal(tb, o->keytype, private->keyhandle, private->keyauth, p->key, p->key_len + 1, p->blob, &p->blob_len, - o->blobauth, o->pcrinfo, o->pcrinfo_len); + private->blobauth, private->pcrinfo, + private->pcrinfo_len); if (ret < 0) pr_info("srkseal failed (%d)\n", ret); @@ -652,6 +656,7 @@ static int key_seal(struct trusted_key_payload *p, static int key_unseal(struct trusted_key_payload *p, struct trusted_key_options *o) { + struct trusted_key_tpm *private = o->private; int ret; struct tpm_buf *tb __free(kfree) = kzalloc(TPM_BUFSIZE, GFP_KERNEL); @@ -660,8 +665,8 @@ static int key_unseal(struct trusted_key_payload *p, tpm_buf_init(tb, TPM_BUFSIZE); - ret = tpm_unseal(tb, o->keyhandle, o->keyauth, p->blob, p->blob_len, - o->blobauth, p->key, &p->key_len); + ret = tpm_unseal(tb, private->keyhandle, private->keyauth, p->blob, + p->blob_len, private->blobauth, p->key, &p->key_len); if (ret < 0) pr_info("srkunseal failed (%d)\n", ret); else @@ -695,8 +700,9 @@ static const match_table_t key_tokens = { /* can have zero or more token= options */ static int getoptions(char *c, struct trusted_key_payload *pay, - struct trusted_key_options *opt) + struct trusted_key_options *opt, bool is_tpm2) { + struct trusted_key_tpm *private = opt->private; substring_t args[MAX_OPT_ARGS]; char *p = c; int token; @@ -706,13 +712,8 @@ static int getoptions(char *c, struct trusted_key_payload *pay, unsigned long token_mask = 0; unsigned int digest_len; int i; - int tpm2; - tpm2 = tpm_is_tpm2(chip); - if (tpm2 < 0) - return tpm2; - - opt->hash = tpm2 ? HASH_ALGO_SHA256 : HASH_ALGO_SHA1; + private->hash = is_tpm2 ? HASH_ALGO_SHA256 : HASH_ALGO_SHA1; if (!c) return 0; @@ -726,11 +727,11 @@ static int getoptions(char *c, struct trusted_key_payload *pay, switch (token) { case Opt_pcrinfo: - opt->pcrinfo_len = strlen(args[0].from) / 2; - if (opt->pcrinfo_len > MAX_PCRINFO_SIZE) + private->pcrinfo_len = strlen(args[0].from) / 2; + if (private->pcrinfo_len > MAX_PCRINFO_SIZE) return -EINVAL; - res = hex2bin(opt->pcrinfo, args[0].from, - opt->pcrinfo_len); + res = hex2bin(private->pcrinfo, args[0].from, + private->pcrinfo_len); if (res < 0) return -EINVAL; break; @@ -739,12 +740,12 @@ static int getoptions(char *c, struct trusted_key_payload *pay, if (res < 0) return -EINVAL; opt->keytype = SEAL_keytype; - opt->keyhandle = handle; + private->keyhandle = handle; break; case Opt_keyauth: if (strlen(args[0].from) != 2 * SHA1_DIGEST_SIZE) return -EINVAL; - res = hex2bin(opt->keyauth, args[0].from, + res = hex2bin(private->keyauth, args[0].from, SHA1_DIGEST_SIZE); if (res < 0) return -EINVAL; @@ -755,21 +756,23 @@ static int getoptions(char *c, struct trusted_key_payload *pay, * hex strings. TPM 2.0 authorizations are simple * passwords (although it can take a hash as well) */ - opt->blobauth_len = strlen(args[0].from); + private->blobauth_len = strlen(args[0].from); - if (opt->blobauth_len == 2 * TPM_DIGEST_SIZE) { - res = hex2bin(opt->blobauth, args[0].from, + if (private->blobauth_len == 2 * TPM_DIGEST_SIZE) { + res = hex2bin(private->blobauth, args[0].from, TPM_DIGEST_SIZE); if (res < 0) return -EINVAL; - opt->blobauth_len = TPM_DIGEST_SIZE; + private->blobauth_len = TPM_DIGEST_SIZE; break; } - if (tpm2 && opt->blobauth_len <= sizeof(opt->blobauth)) { - memcpy(opt->blobauth, args[0].from, - opt->blobauth_len); + if (is_tpm2 && + private->blobauth_len <= + sizeof(private->blobauth)) { + memcpy(private->blobauth, args[0].from, + private->blobauth_len); break; } @@ -787,41 +790,42 @@ static int getoptions(char *c, struct trusted_key_payload *pay, res = kstrtoul(args[0].from, 10, &lock); if (res < 0) return -EINVAL; - opt->pcrlock = lock; + private->pcrlock = lock; break; case Opt_hash: if (test_bit(Opt_policydigest, &token_mask)) return -EINVAL; for (i = 0; i < HASH_ALGO__LAST; i++) { if (!strcmp(args[0].from, hash_algo_name[i])) { - opt->hash = i; + private->hash = i; break; } } if (i == HASH_ALGO__LAST) return -EINVAL; - if (!tpm2 && i != HASH_ALGO_SHA1) { + if (!is_tpm2 && i != HASH_ALGO_SHA1) { pr_info("TPM 1.x only supports SHA-1.\n"); return -EINVAL; } break; case Opt_policydigest: - digest_len = hash_digest_size[opt->hash]; - if (!tpm2 || strlen(args[0].from) != (2 * digest_len)) + digest_len = hash_digest_size[private->hash]; + if (!is_tpm2 || + strlen(args[0].from) != (2 * digest_len)) return -EINVAL; - res = hex2bin(opt->policydigest, args[0].from, + res = hex2bin(private->policydigest, args[0].from, digest_len); if (res < 0) return -EINVAL; - opt->policydigest_len = digest_len; + private->policydigest_len = digest_len; break; case Opt_policyhandle: - if (!tpm2) + if (!is_tpm2) return -EINVAL; res = kstrtoul(args[0].from, 16, &handle); if (res < 0) return -EINVAL; - opt->policyhandle = handle; + private->policyhandle = handle; break; default: return -EINVAL; @@ -830,29 +834,33 @@ static int getoptions(char *c, struct trusted_key_payload *pay, return 0; } -static struct trusted_key_options *trusted_options_alloc(void) +static struct trusted_key_options *trusted_options_alloc(bool is_tpm2) { + struct trusted_key_tpm *private; struct trusted_key_options *options; - int tpm2; - - tpm2 = tpm_is_tpm2(chip); - if (tpm2 < 0) - return NULL; options = kzalloc_obj(*options); if (options) { /* set any non-zero defaults */ options->keytype = SRK_keytype; - if (!tpm2) - options->keyhandle = SRKHANDLE; + private = kzalloc_obj(*private); + if (!private) { + kfree_sensitive(options); + options = NULL; + } else { + if (!is_tpm2) + private->keyhandle = SRKHANDLE; + options->private = private; + } } return options; } static int trusted_tpm_seal(struct trusted_key_payload *p, char *datablob) { - struct trusted_key_options *options = NULL; + struct trusted_key_options *options __free(kfree_sensitive) = NULL; + struct trusted_key_tpm *private __free(kfree_sensitive) = NULL; int ret = 0; int tpm2; @@ -860,19 +868,19 @@ static int trusted_tpm_seal(struct trusted_key_payload *p, char *datablob) if (tpm2 < 0) return tpm2; - options = trusted_options_alloc(); + options = trusted_options_alloc(tpm2); if (!options) return -ENOMEM; - ret = getoptions(datablob, p, options); + private = options->private; + + ret = getoptions(datablob, p, options, tpm2); if (ret < 0) - goto out; + return ret; dump_options(options); - if (!options->keyhandle && !tpm2) { - ret = -EINVAL; - goto out; - } + if (!private->keyhandle && !tpm2) + return -EINVAL; if (tpm2) ret = tpm2_seal_trusted(chip, p, options); @@ -880,24 +888,24 @@ static int trusted_tpm_seal(struct trusted_key_payload *p, char *datablob) ret = key_seal(p, options); if (ret < 0) { pr_info("key_seal failed (%d)\n", ret); - goto out; + return ret; } - if (options->pcrlock) { - ret = pcrlock(options->pcrlock); + if (private->pcrlock) { + ret = pcrlock(private->pcrlock); if (ret < 0) { pr_info("pcrlock failed (%d)\n", ret); - goto out; + return ret; } } -out: - kfree_sensitive(options); + return ret; } static int trusted_tpm_unseal(struct trusted_key_payload *p, char *datablob) { - struct trusted_key_options *options = NULL; + struct trusted_key_options *options __free(kfree_sensitive) = NULL; + struct trusted_key_tpm *private __free(kfree_sensitive) = NULL; int ret = 0; int tpm2; @@ -905,36 +913,36 @@ static int trusted_tpm_unseal(struct trusted_key_payload *p, char *datablob) if (tpm2 < 0) return tpm2; - options = trusted_options_alloc(); + options = trusted_options_alloc(tpm2); if (!options) return -ENOMEM; + private = options->private; - ret = getoptions(datablob, p, options); + ret = getoptions(datablob, p, options, tpm2); if (ret < 0) - goto out; + return ret; dump_options(options); - if (!options->keyhandle && !tpm2) { - ret = -EINVAL; - goto out; - } + if (!private->keyhandle && !tpm2) + return -EINVAL; if (tpm2) ret = tpm2_unseal_trusted(chip, p, options); else ret = key_unseal(p, options); - if (ret < 0) + if (ret < 0) { pr_info("key_unseal failed (%d)\n", ret); + return ret; + } - if (options->pcrlock) { - ret = pcrlock(options->pcrlock); + if (private->pcrlock) { + ret = pcrlock(private->pcrlock); if (ret < 0) { pr_info("pcrlock failed (%d)\n", ret); - goto out; + return ret; } } -out: - kfree_sensitive(options); + return ret; }
diff --git a/security/keys/trusted-keys/trusted_tpm2.c b/security/keys/trusted-keys/trusted_tpm2.c index 01f18bb..30188a0 100644 --- a/security/keys/trusted-keys/trusted_tpm2.c +++ b/security/keys/trusted-keys/trusted_tpm2.c
@@ -23,36 +23,48 @@ static int tpm2_key_encode(struct trusted_key_payload *payload, struct trusted_key_options *options, u8 *src, u32 len) { + struct trusted_key_tpm *private = options->private; const int SCRATCH_SIZE = PAGE_SIZE; - u8 *scratch = kmalloc(SCRATCH_SIZE, GFP_KERNEL); - u8 *work = scratch, *work1; - u8 *end_work = scratch + SCRATCH_SIZE; + u8 *scratch __free(kfree) = NULL; + u8 *work, *work1; + u8 *end_work; u8 *priv, *pub; - u16 priv_len, pub_len; + u32 priv_len, pub_len; int ret; - priv_len = get_unaligned_be16(src) + 2; - priv = src; + if (len < 4) + return -EINVAL; + priv_len = get_unaligned_be16(src) + 2; + if (priv_len + 2 > len) + return -EIO; + + priv = src; src += priv_len; pub_len = get_unaligned_be16(src) + 2; + if (pub_len + priv_len > len) + return -EIO; + pub = src; + scratch = kmalloc(SCRATCH_SIZE, GFP_KERNEL); if (!scratch) return -ENOMEM; + work = scratch; + end_work = scratch + SCRATCH_SIZE; + work = asn1_encode_oid(work, end_work, tpm2key_oid, asn1_oid_len(tpm2key_oid)); - if (options->blobauth_len == 0) { + if (private->blobauth_len == 0) { unsigned char bool[3], *w = bool; /* tag 0 is emptyAuth */ w = asn1_encode_boolean(w, w + sizeof(bool), true); - if (WARN(IS_ERR(w), "BUG: Boolean failed to encode")) { - ret = PTR_ERR(w); - goto err; - } + if (WARN(IS_ERR(w), "BUG: Boolean failed to encode")) + return PTR_ERR(w); + work = asn1_encode_tag(work, end_work, 0, bool, w - bool); } @@ -64,11 +76,10 @@ static int tpm2_key_encode(struct trusted_key_payload *payload, */ if (WARN(work - scratch + pub_len + priv_len + 14 > SCRATCH_SIZE, "BUG: scratch buffer is too small")) { - ret = -EINVAL; - goto err; + return -EINVAL; } - work = asn1_encode_integer(work, end_work, options->keyhandle); + work = asn1_encode_integer(work, end_work, private->keyhandle); work = asn1_encode_octet_string(work, end_work, pub, pub_len); work = asn1_encode_octet_string(work, end_work, priv, priv_len); @@ -78,15 +89,10 @@ static int tpm2_key_encode(struct trusted_key_payload *payload, if (IS_ERR(work1)) { ret = PTR_ERR(work1); pr_err("BUG: ASN.1 encoder failed with %d\n", ret); - goto err; + return ret; } - kfree(scratch); return work1 - payload->blob; - -err: - kfree(scratch); - return ret; } struct tpm2_key_context { @@ -101,6 +107,7 @@ static int tpm2_key_decode(struct trusted_key_payload *payload, struct trusted_key_options *options, u8 **buf, unsigned int *blob_len) { + struct trusted_key_tpm *private = options->private; int ret; struct tpm2_key_context ctx; u8 *blob; @@ -115,13 +122,13 @@ static int tpm2_key_decode(struct trusted_key_payload *payload, if (ctx.priv_len + ctx.pub_len > MAX_BLOB_SIZE) return -EINVAL; - blob = kmalloc(ctx.priv_len + ctx.pub_len + 4, GFP_KERNEL); + blob = kmalloc(ctx.priv_len + ctx.pub_len, GFP_KERNEL); if (!blob) return -ENOMEM; *buf = blob; *blob_len = ctx.priv_len + ctx.pub_len; - options->keyhandle = ctx.parent; + private->keyhandle = ctx.parent; memcpy(blob, ctx.priv, ctx.priv_len); blob += ctx.priv_len; @@ -233,6 +240,7 @@ int tpm2_seal_trusted(struct tpm_chip *chip, struct trusted_key_payload *payload, struct trusted_key_options *options) { + struct trusted_key_tpm *private = options->private; off_t offset = TPM_HEADER_SIZE; struct tpm_buf *buf __free(kfree) = NULL; struct tpm_buf *sized __free(kfree) = NULL; @@ -241,11 +249,11 @@ int tpm2_seal_trusted(struct tpm_chip *chip, u32 flags; int rc; - hash = tpm2_find_hash_alg(options->hash); + hash = tpm2_find_hash_alg(private->hash); if (hash < 0) return hash; - if (!options->keyhandle) + if (!private->keyhandle) return -EINVAL; rc = tpm_try_get_ops(chip); @@ -275,18 +283,18 @@ int tpm2_seal_trusted(struct tpm_chip *chip, tpm_buf_init_sized(sized, TPM_BUFSIZE); - rc = tpm_buf_append_name(chip, buf, options->keyhandle, NULL); + rc = tpm_buf_append_name(chip, buf, private->keyhandle, NULL); if (rc) goto out; tpm_buf_append_hmac_session(chip, buf, TPM2_SA_DECRYPT, - options->keyauth, TPM_DIGEST_SIZE); + private->keyauth, TPM_DIGEST_SIZE); /* sensitive */ - tpm_buf_append_u16(sized, options->blobauth_len); + tpm_buf_append_u16(sized, private->blobauth_len); - if (options->blobauth_len) - tpm_buf_append(sized, options->blobauth, options->blobauth_len); + if (private->blobauth_len) + tpm_buf_append(sized, private->blobauth, private->blobauth_len); tpm_buf_append_u16(sized, payload->key_len); tpm_buf_append(sized, payload->key, payload->key_len); @@ -299,14 +307,15 @@ int tpm2_seal_trusted(struct tpm_chip *chip, /* key properties */ flags = 0; - flags |= options->policydigest_len ? 0 : TPM2_OA_USER_WITH_AUTH; + flags |= private->policydigest_len ? 0 : TPM2_OA_USER_WITH_AUTH; flags |= payload->migratable ? 0 : (TPM2_OA_FIXED_TPM | TPM2_OA_FIXED_PARENT); tpm_buf_append_u32(sized, flags); /* policy */ - tpm_buf_append_u16(sized, options->policydigest_len); - if (options->policydigest_len) - tpm_buf_append(sized, options->policydigest, options->policydigest_len); + tpm_buf_append_u16(sized, private->policydigest_len); + if (private->policydigest_len) + tpm_buf_append(sized, private->policydigest, + private->policydigest_len); /* public parameters */ tpm_buf_append_u16(sized, TPM_ALG_NULL); @@ -336,10 +345,11 @@ int tpm2_seal_trusted(struct tpm_chip *chip, goto out; blob_len = tpm_buf_read_u32(buf, &offset); - if (blob_len > MAX_BLOB_SIZE || buf->flags & TPM_BUF_INVALID) { + if (buf->flags & TPM_BUF_INVALID) { rc = -E2BIG; goto out; } + if (buf->length - offset < blob_len) { rc = -EFAULT; goto out; @@ -377,6 +387,7 @@ static int tpm2_load_cmd(struct tpm_chip *chip, u32 *blob_handle) { u8 *blob_ref __free(kfree) = NULL; + struct trusted_key_tpm *private = options->private; struct tpm_buf *buf __free(kfree) = NULL; unsigned int private_len; unsigned int public_len; @@ -397,7 +408,7 @@ static int tpm2_load_cmd(struct tpm_chip *chip, } /* new format carries keyhandle but old format doesn't */ - if (!options->keyhandle) + if (!private->keyhandle) return -EINVAL; /* must be big enough for at least the two be16 size counts */ @@ -441,11 +452,11 @@ static int tpm2_load_cmd(struct tpm_chip *chip, tpm_buf_init(buf, TPM_BUFSIZE); tpm_buf_reset(buf, TPM2_ST_SESSIONS, TPM2_CC_LOAD); - rc = tpm_buf_append_name(chip, buf, options->keyhandle, NULL); + rc = tpm_buf_append_name(chip, buf, private->keyhandle, NULL); if (rc) return rc; - tpm_buf_append_hmac_session(chip, buf, 0, options->keyauth, + tpm_buf_append_hmac_session(chip, buf, 0, private->keyauth, TPM_DIGEST_SIZE); tpm_buf_append(buf, blob, blob_len); @@ -485,6 +496,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, struct trusted_key_options *options, u32 blob_handle) { + struct trusted_key_tpm *private = options->private; struct tpm_header *head; struct tpm_buf *buf __free(kfree) = NULL; u16 data_len; @@ -509,10 +521,10 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, if (rc) return rc; - if (!options->policyhandle) { + if (!private->policyhandle) { tpm_buf_append_hmac_session(chip, buf, TPM2_SA_ENCRYPT, - options->blobauth, - options->blobauth_len); + private->blobauth, + private->blobauth_len); } else { /* * FIXME: The policy session was generated outside the @@ -525,9 +537,9 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, * could repeat our actions with the exfiltrated * password. */ - tpm2_buf_append_auth(buf, options->policyhandle, + tpm2_buf_append_auth(buf, private->policyhandle, NULL /* nonce */, 0, 0, - options->blobauth, options->blobauth_len); + private->blobauth, private->blobauth_len); if (tpm2_chip_auth(chip)) { tpm_buf_append_hmac_session(chip, buf, TPM2_SA_ENCRYPT, NULL, 0);
diff --git a/security/landlock/Makefile b/security/landlock/Makefile index 2711f48..97cf668 100644 --- a/security/landlock/Makefile +++ b/security/landlock/Makefile
@@ -9,7 +9,9 @@ task.o \ fs.o \ tsync.o \ - domain.o + domain.o \ + ns.o \ + cap.o landlock-$(CONFIG_INET) += net.o
diff --git a/security/landlock/access.h b/security/landlock/access.h index f843835..f9eaa2f 100644 --- a/security/landlock/access.h +++ b/security/landlock/access.h
@@ -19,9 +19,9 @@ /* * All access rights that are denied by default whether they are handled or not - * by a ruleset/layer. This must be ORed with all domain->handled_masks[] - * entries when we need to get the absolute handled access masks, see - * landlock_upgrade_handled_access_masks(). + * by a ruleset/layer. This must be ORed with the .handled field of all + * domain->layers[] entries when we need to get the absolute handled access + * masks, see landlock_upgrade_handled_layer_config(). */ /* clang-format off */ #define _LANDLOCK_ACCESS_FS_INITIALLY_DENIED ( \ @@ -42,14 +42,17 @@ static_assert(BITS_PER_TYPE(access_mask_t) >= LANDLOCK_NUM_ACCESS_FS); static_assert(BITS_PER_TYPE(access_mask_t) >= LANDLOCK_NUM_ACCESS_NET); /* Makes sure all scoped rights can be stored. */ static_assert(BITS_PER_TYPE(access_mask_t) >= LANDLOCK_NUM_SCOPE); +/* Makes sure all permissions can be stored. */ +static_assert(BITS_PER_TYPE(access_mask_t) >= LANDLOCK_NUM_PERMISSION); /* Makes sure for_each_set_bit() and for_each_clear_bit() calls are OK. */ static_assert(sizeof(unsigned long) >= sizeof(access_mask_t)); -/* Ruleset access masks. */ +/* Access and permission masks (bitfields only). */ struct access_masks { access_mask_t fs : LANDLOCK_NUM_ACCESS_FS; access_mask_t net : LANDLOCK_NUM_ACCESS_NET; access_mask_t scope : LANDLOCK_NUM_SCOPE; + access_mask_t permissions : LANDLOCK_NUM_PERMISSION; } __packed __aligned(sizeof(u32)); union access_masks_all { @@ -61,6 +64,46 @@ union access_masks_all { static_assert(sizeof(typeof_member(union access_masks_all, masks)) == sizeof(typeof_member(union access_masks_all, all))); +/** + * struct permission_masks - Per-permission member bitmasks + */ +struct permission_masks { + /** + * @ns_types: Namespace type member mask, indexed in FOR_EACH_NS_TYPE() + * order. + */ + u64 ns_types : LANDLOCK_NUM_NAMESPACE_TYPE; + /** + * @caps: Capability member mask, indexed by CAP_* values. + */ + u64 caps : LANDLOCK_NUM_CAPABILITY; +} __packed __aligned(sizeof(u64)); + +static_assert(sizeof(struct permission_masks) == sizeof(u64)); +/* All permission_masks bitfields must fit in a single u64. */ +static_assert(LANDLOCK_NUM_CAPABILITY + LANDLOCK_NUM_NAMESPACE_TYPE <= + BITS_PER_TYPE(u64)); + +/** + * struct layer_config - Per-layer access configuration + * + * A ruleset stores one mutable layer and a domain stores a flexible array of + * immutable layers. Unlike filesystem and network access rights, namespace + * types and capabilities use flat bitmasks because their keyspaces are small + * and bounded. + */ +struct layer_config { + /** + * @allowed: Members allowed by each handled permission. + */ + struct permission_masks allowed; + /** + * @handled: Bitmask of access rights and permissions handled (i.e. + * restricted) by this layer. + */ + struct access_masks handled; +}; + #define _LANDLOCK_LAYER_MASK_PADDING \ (BITS_PER_TYPE(access_mask_t) - LANDLOCK_NUM_ACCESS_MAX - \ IS_ENABLED(CONFIG_SECURITY_LANDLOCK_LOG)) @@ -131,17 +174,17 @@ static_assert(BITS_PER_TYPE(deny_masks_t) >= static_assert(HWEIGHT(LANDLOCK_MAX_NUM_LAYERS) == 1); /* Upgrades with all initially denied by default access rights. */ -static inline struct access_masks -landlock_upgrade_handled_access_masks(struct access_masks access_masks) +static inline struct layer_config +landlock_upgrade_handled_layer_config(struct layer_config layer_config) { /* * All access rights that are denied by default whether they are * explicitly handled or not. */ - if (access_masks.fs) - access_masks.fs |= _LANDLOCK_ACCESS_FS_INITIALLY_DENIED; + if (layer_config.handled.fs) + layer_config.handled.fs |= _LANDLOCK_ACCESS_FS_INITIALLY_DENIED; - return access_masks; + return layer_config; } /* Checks the subset relation between access masks. */
diff --git a/security/landlock/audit.c b/security/landlock/audit.c index e029638..be49ef4 100644 --- a/security/landlock/audit.c +++ b/security/landlock/audit.c
@@ -21,10 +21,10 @@ #include "log.h" /* - * Access-right and scope names are built from the lists shared with the trace - * events (see <linux/landlock.h>). The designated initializer places each name - * at its bit index, so the lookup stays O(1) and does not depend on the entry - * order. log_blockers() adds the "fs."/"net."/"scope." category prefix. + * Access-right, scope, and permission names are built from the lists shared + * with the trace events (see <linux/landlock.h>). The designated initializer + * places each name at its bit index, so the lookup stays O(1) and does not + * depend on the entry order. log_blockers() adds the related category prefix. */ #define _LANDLOCK_NAME_ENTRY(mask, name) [BIT_INDEX(mask)] = name @@ -40,6 +40,12 @@ static const char *const scope_strings[] = { _LANDLOCK_SCOPE_NAMES }; static_assert(ARRAY_SIZE(scope_strings) == LANDLOCK_NUM_SCOPE); +static const char *const permission_strings[] = { + _LANDLOCK_PERMISSION_BLOCKER_NAMES +}; + +static_assert(ARRAY_SIZE(permission_strings) == LANDLOCK_NUM_PERMISSION); + #undef _LANDLOCK_NAME_ENTRY static __attribute_const__ const char * @@ -73,6 +79,12 @@ get_blocker(const enum landlock_request_type type, case LANDLOCK_REQUEST_SCOPE_SIGNAL: WARN_ON_ONCE(access_bit != -1); return scope_strings[BIT_INDEX(LANDLOCK_SCOPE_SIGNAL)]; + + case LANDLOCK_REQUEST_NAMESPACE: + case LANDLOCK_REQUEST_CAPABILITY: + if (WARN_ON_ONCE(access_bit >= ARRAY_SIZE(permission_strings))) + return "unknown"; + return permission_strings[access_bit]; } WARN_ON_ONCE(1); @@ -82,8 +94,8 @@ get_blocker(const enum landlock_request_type type, /* * Returns the audit category prefix prepended to the unprefixed blocker name * returned by get_blocker() (filesystem and network access rights, - * change_topology, and scopes). The ptrace blocker is standalone and carries - * its full name in get_blocker(), so it uses no prefix. + * change_topology, scopes, and permissions). The ptrace blocker is standalone: + * its full name comes from get_blocker(), so it uses no prefix. */ static __attribute_const__ const char * blocker_prefix(const enum landlock_request_type type) @@ -102,6 +114,12 @@ blocker_prefix(const enum landlock_request_type type) case LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET: case LANDLOCK_REQUEST_SCOPE_SIGNAL: return "scope."; + + case LANDLOCK_REQUEST_NAMESPACE: + return _LANDLOCK_PERMISSION_NAMESPACE_NAME "."; + + case LANDLOCK_REQUEST_CAPABILITY: + return _LANDLOCK_PERMISSION_CAPABILITY_NAME "."; } WARN_ON_ONCE(1); @@ -163,7 +181,7 @@ static void log_domain(struct landlock_hierarchy *const hierarchy) * * @request: Detail of the user space request. * @youngest_denied: The youngest hierarchy node that denied the access. - * @missing: The set of denied access rights. + * @missing: The set of denied access rights or permissions. * @logged: Whether the denial is selected for logging, as computed by * landlock_log_denial() (domain policy and quiet rules). *
diff --git a/security/landlock/cap.c b/security/landlock/cap.c new file mode 100644 index 0000000..b4f491b09 --- /dev/null +++ b/security/landlock/cap.c
@@ -0,0 +1,159 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Landlock - Capability hooks + * + * Copyright © 2026 Cloudflare, Inc. + */ + +#include <linux/capability.h> +#include <linux/cred.h> +#include <linux/lsm_audit.h> +#include <linux/lsm_hooks.h> +#include <uapi/linux/landlock.h> + +#include "cap.h" +#include "cred.h" +#include "domain.h" +#include "limits.h" +#include "log.h" +#include "ruleset.h" +#include "setup.h" + +static const struct access_masks cap_permission = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, +}; + +/** + * hook_capable - Deny capability use for Landlock-sandboxed processes + * + * @cred: Credentials being checked. + * @ns: Target user namespace (intentionally ignored; policy depends on the + * acting credentials and @cap, not namespace ownership). + * @cap: Capability number (CAP_*). + * @opts: Capability check options. CAP_OPT_NOAUDIT skips the denial record: + * no audit record, no trace event, and no denial count. + * + * Pure bitmask check: denies the capability if it is not in the layer's allowed + * set. This hook is purely restrictive: commoncap is registered with + * LSM_ORDER_FIRST so cap_capable() always runs first, which means Landlock can + * deny capabilities that commoncap would allow, but never grant capabilities + * that commoncap denied. + * + * Return: 0 if allowed, -EPERM if capability use is denied. + */ +static int hook_capable(const struct cred *cred, struct user_namespace *ns, + int cap, unsigned int opts) +{ + const struct landlock_cred_security *subject; + size_t denied_layer; + + subject = landlock_get_applicable_subject(cred, cap_permission, NULL); + if (!subject) + return 0; + + denied_layer = landlock_permission_is_denied( + subject->domain, LANDLOCK_PERMISSION_CAPABILITY_USE, + landlock_cap_to_bit(cap)); + if (!denied_layer) + return 0; + + if (!(opts & CAP_OPT_NOAUDIT)) + landlock_log_denial( + subject, + &(struct landlock_request){ + .type = LANDLOCK_REQUEST_CAPABILITY, + .audit.type = LSM_AUDIT_DATA_CAP, + .audit.u.cap = cap, + .permission = + LANDLOCK_PERMISSION_CAPABILITY_USE, + .layer_plus_one = denied_layer, + }); + + return -EPERM; +} + +static struct security_hook_list landlock_hooks[] __ro_after_init = { + LSM_HOOK_INIT(capable, hook_capable), +}; + +__init void landlock_add_cap_hooks(void) +{ + security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), + &landlock_lsmid); +} + +#ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST + +#include <kunit/test.h> + +static void test_cap_to_bit(struct kunit *const test) +{ + KUNIT_EXPECT_EQ(test, BIT_ULL(0), landlock_cap_to_bit(0)); + KUNIT_EXPECT_EQ(test, BIT_ULL(CAP_NET_RAW), + landlock_cap_to_bit(CAP_NET_RAW)); + KUNIT_EXPECT_EQ(test, BIT_ULL(CAP_SYS_ADMIN), + landlock_cap_to_bit(CAP_SYS_ADMIN)); + KUNIT_EXPECT_EQ(test, BIT_ULL(CAP_LAST_CAP), + landlock_cap_to_bit(CAP_LAST_CAP)); +} + +static void test_cap_to_bit_invalid(struct kunit *const test) +{ + if (!IS_ENABLED(CONFIG_BUG)) + kunit_skip(test, "requires CONFIG_BUG"); + + /* clang-format off */ + kunit_warning_suppress(test) { + /* clang-format on */ + KUNIT_EXPECT_EQ(test, 0ULL, landlock_cap_to_bit(-1)); + KUNIT_EXPECT_EQ(test, 0ULL, + landlock_cap_to_bit(CAP_LAST_CAP + 1)); + } +} + +static void test_caps_to_bits_valid(struct kunit *const test) +{ + KUNIT_EXPECT_EQ(test, (u64)CAP_VALID_MASK, + landlock_caps_to_bits(CAP_VALID_MASK)); + KUNIT_EXPECT_EQ(test, BIT_ULL(CAP_NET_RAW), + landlock_caps_to_bits(BIT_ULL(CAP_NET_RAW))); +} + +static void test_caps_to_bits_unknown(struct kunit *const test) +{ + if (!IS_ENABLED(CONFIG_BUG)) + kunit_skip(test, "requires CONFIG_BUG"); + + /* clang-format off */ + kunit_warning_suppress(test) { + /* clang-format on */ + KUNIT_EXPECT_EQ( + test, 0ULL, + landlock_caps_to_bits(BIT_ULL(CAP_LAST_CAP + 1))); + } +} + +static void test_caps_to_bits_zero(struct kunit *const test) +{ + KUNIT_EXPECT_EQ(test, 0ULL, landlock_caps_to_bits(0)); +} + +static struct kunit_case test_cases[] = { + /* clang-format off */ + KUNIT_CASE(test_cap_to_bit), + KUNIT_CASE(test_cap_to_bit_invalid), + KUNIT_CASE(test_caps_to_bits_valid), + KUNIT_CASE(test_caps_to_bits_unknown), + KUNIT_CASE(test_caps_to_bits_zero), + {} + /* clang-format on */ +}; + +static struct kunit_suite test_suite = { + .name = "landlock_cap", + .test_cases = test_cases, +}; + +kunit_test_suite(test_suite); + +#endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */
diff --git a/security/landlock/cap.h b/security/landlock/cap.h new file mode 100644 index 0000000..11208cb --- /dev/null +++ b/security/landlock/cap.h
@@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Landlock - Capability hooks + * + * Copyright © 2026 Cloudflare, Inc. + */ + +#ifndef _SECURITY_LANDLOCK_CAP_H +#define _SECURITY_LANDLOCK_CAP_H + +#include <linux/bitops.h> +#include <linux/bug.h> +#include <linux/capability.h> +#include <linux/types.h> + +/** + * landlock_cap_to_bit - Convert a capability number to a compact bitmask + * + * @cap: Capability number (CAP_*). + * + * Return: BIT_ULL(@cap), or 0 if @cap is invalid (with a WARN). + */ +static inline u64 landlock_cap_to_bit(const int cap) +{ + if (WARN_ON_ONCE(!cap_valid(cap))) + return 0; + + return BIT_ULL(cap); +} + +/** + * landlock_caps_to_bits - Validate and mask a capability bitmask + * + * @capabilities: Bitmask of capabilities (e.g. from user space). + * + * Return: @capabilities masked to known capabilities. Warns if unknown bits + * are present (callers must pre-mask for user input). + */ +static inline u64 landlock_caps_to_bits(const u64 capabilities) +{ + /* Callers pre-mask (CAP_VALID_MASK); the WARN guards future callers. */ + WARN_ON_ONCE(capabilities & ~CAP_VALID_MASK); + return capabilities & CAP_VALID_MASK; +} + +__init void landlock_add_cap_hooks(void); + +#endif /* _SECURITY_LANDLOCK_CAP_H */
diff --git a/security/landlock/cred.h b/security/landlock/cred.h index a5ff995..1c6a483 100644 --- a/security/landlock/cred.h +++ b/security/landlock/cred.h
@@ -138,7 +138,7 @@ landlock_get_applicable_subject(const struct cred *const cred, for (layer_level = domain->num_layers - 1; layer_level >= 0; layer_level--) { union access_masks_all layer = { - .masks = domain->handled_masks[layer_level], + .masks = domain->layers[layer_level].handled, }; if (layer.all & masks_all.all) {
diff --git a/security/landlock/domain.c b/security/landlock/domain.c index 4031b58..4c0b1f0 100644 --- a/security/landlock/domain.c +++ b/security/landlock/domain.c
@@ -50,7 +50,7 @@ static struct landlock_domain *create_domain(const u32 num_layers) struct landlock_domain *new_domain; build_check_domain(); - new_domain = kzalloc_flex(*new_domain, handled_masks, num_layers, + new_domain = kzalloc_flex(*new_domain, layers, num_layers, GFP_KERNEL_ACCOUNT); if (!new_domain) return ERR_PTR(-ENOMEM); @@ -328,8 +328,8 @@ static int merge_ruleset(struct landlock_domain *const dst, if (WARN_ON_ONCE(dst->num_layers < 1)) return -EINVAL; - dst->handled_masks[dst->num_layers - 1] = - landlock_upgrade_handled_access_masks(src->handled_masks); + dst->layers[dst->num_layers - 1] = + landlock_upgrade_handled_layer_config(src->layer); /* Merges the @src inode tree. */ err = merge_tree(dst, src, LANDLOCK_KEY_INODE); @@ -404,8 +404,8 @@ static int inherit_ruleset(struct landlock_domain *const parent, /* * Copies the parent layer stack and leaves a space for the new layer. */ - memcpy(child->handled_masks, parent->handled_masks, - flex_array_size(parent, handled_masks, parent->num_layers)); + memcpy(child->layers, parent->layers, + flex_array_size(parent, layers, parent->num_layers)); if (WARN_ON_ONCE(!parent->hierarchy)) return -EINVAL; @@ -479,7 +479,8 @@ landlock_merge_ruleset(struct landlock_domain *const parent, return ERR_PTR(err); #ifdef CONFIG_SECURITY_LANDLOCK_LOG - new_dom->hierarchy->quiet_masks = ruleset->quiet_masks; + new_dom->hierarchy->quiet_access = ruleset->quiet_access; + new_dom->hierarchy->quiet_permission = ruleset->quiet_permission; #endif /* CONFIG_SECURITY_LANDLOCK_LOG */ return no_free_ptr(new_dom);
diff --git a/security/landlock/domain.h b/security/landlock/domain.h index 428c1d9..935e18b 100644 --- a/security/landlock/domain.h +++ b/security/landlock/domain.h
@@ -130,10 +130,15 @@ struct landlock_hierarchy { */ log_new_exec : 1; /** - * @quiet_masks: Bitmasks of access that should be quieted (i.e. not + * @quiet_access: Bitmasks of access that should be quieted (i.e. not * logged) if the related object is marked as quiet. */ - struct access_masks quiet_masks; + struct access_masks quiet_access; + /** + * @quiet_permission: Per-member quiet bitmasks for permission types in + * this layer. + */ + struct permission_masks quiet_permission; #endif /* CONFIG_SECURITY_LANDLOCK_LOG */ }; @@ -217,7 +222,7 @@ struct landlock_domain { * @work_free: Enables to free a domain within a lockless * section. This is only used by landlock_put_domain_deferred() * when @usage reaches zero. The fields @usage, @num_layers and - * @handled_masks are then unused. + * @layers are then unused. */ struct work_struct work_free; struct { @@ -233,15 +238,14 @@ struct landlock_domain { */ u32 num_layers; /** - * @handled_masks: Contains the subset of filesystem and - * network actions that are restricted by a domain. A - * domain saves all layers of merged rulesets in a stack - * (FAM), starting from the first layer to the last one. - * These layers are used when merging rulesets, for user - * space backward compatibility (i.e. future-proof), and - * to properly handle merged rulesets without - * overlapping access rights. These layers are set once - * and never changed for the lifetime of the domain. + * @layers: Per-layer access configuration. A domain + * saves all layers of merged rulesets in a stack (FAM), + * starting from the first layer to the last one. These + * layers are used when merging rulesets, for user space + * backward compatibility (i.e. future-proof), and to + * properly handle merged rulesets without overlapping + * access rights. These layers are set once and never + * changed for the lifetime of the domain. * * Not annotated with __counted_by(num_layers): clang * miscomputes the counter address for a FAM nested in @@ -249,7 +253,7 @@ struct landlock_domain { * FORTIFY: * https://github.com/llvm/llvm-project/pull/228309 */ - struct access_masks handled_masks[]; + struct layer_config layers[]; }; }; }; @@ -259,7 +263,7 @@ landlock_get_fs_access_mask(const struct landlock_domain *const domain, const u16 layer_level) { /* Handles all initially denied by default access rights. */ - return domain->handled_masks[layer_level].fs | + return domain->layers[layer_level].handled.fs | _LANDLOCK_ACCESS_FS_INITIALLY_DENIED; } @@ -267,14 +271,14 @@ static inline access_mask_t landlock_get_net_access_mask(const struct landlock_domain *const domain, const u16 layer_level) { - return domain->handled_masks[layer_level].net; + return domain->layers[layer_level].handled.net; } static inline access_mask_t landlock_get_scope_mask(const struct landlock_domain *const domain, const u16 layer_level) { - return domain->handled_masks[layer_level].scope; + return domain->layers[layer_level].handled.scope; } /** @@ -293,7 +297,7 @@ landlock_union_access_masks(const struct landlock_domain *const domain) for (layer_level = 0; layer_level < domain->num_layers; layer_level++) { union access_masks_all layer = { - .masks = domain->handled_masks[layer_level], + .masks = domain->layers[layer_level].handled, }; matches.all |= layer.all; @@ -329,4 +333,63 @@ static inline void landlock_get_domain(struct landlock_domain *const domain) refcount_inc(&domain->usage); } +/** + * landlock_permission_is_denied - Check if a permission request is denied + * + * @domain: The enforced domain. + * @permission_bit: The LANDLOCK_PERMISSION_* flag to check. Must have + * exactly one bit set. + * @request_value: Compact bitmask to look for (e.g. the result of + * landlock_ns_type_to_bit()). Must have exactly one bit set. + * + * Iterate from the youngest layer to the oldest. For each layer that handles + * @permission_bit, check whether @request_value is present in the layer's + * allowed bitmask. Return on the first (youngest) denying layer. + * + * Return: The youngest denying layer + 1, or 0 if allowed. + */ +static inline size_t +landlock_permission_is_denied(const struct landlock_domain *const domain, + const access_mask_t permission_bit, + const u64 request_value) +{ + ssize_t layer; + + BUILD_BUG_ON(sizeof(permission_bit) > sizeof(u32)); + + if (WARN_ON_ONCE(hweight32(permission_bit) != 1) || + WARN_ON_ONCE(hweight64(request_value) != 1)) + return domain->num_layers; + + for (layer = domain->num_layers - 1; layer >= 0; layer--) { + u64 allowed; + + if (!(domain->layers[layer].handled.permissions & + permission_bit)) + continue; + + /* + * Current callers pass only permission types with an explicit + * case below. The default catches a new caller missing its + * member mask. + */ + switch (permission_bit) { + case LANDLOCK_PERMISSION_NAMESPACE_USE: + allowed = domain->layers[layer].allowed.ns_types; + break; + case LANDLOCK_PERMISSION_CAPABILITY_USE: + allowed = domain->layers[layer].allowed.caps; + break; + default: + WARN_ONCE(1, "Unknown permission %u\n", + (unsigned int)permission_bit); + return layer + 1; + } + + if (!(allowed & request_value)) + return layer + 1; + } + return 0; +} + #endif /* _SECURITY_LANDLOCK_DOMAIN_H */
diff --git a/security/landlock/fs.c b/security/landlock/fs.c index cab4389..2ab67bc 100644 --- a/security/landlock/fs.c +++ b/security/landlock/fs.c
@@ -61,7 +61,7 @@ static void release_inode(struct landlock_object *const object) __releases(object->lock) { struct inode *const inode = object->underobj; - struct super_block *sb; + atomic_long_t *inode_refs; if (!inode) { spin_unlock(&object->lock); @@ -77,8 +77,8 @@ static void release_inode(struct landlock_object *const object) * Makes sure that if the filesystem is concurrently unmounted, * hook_sb_delete() will wait for us to finish iput(). */ - sb = inode->i_sb; - atomic_long_inc(&landlock_superblock(sb)->inode_refs); + inode_refs = &landlock_superblock(inode->i_sb)->inode_refs; + atomic_long_inc(inode_refs); spin_unlock(&object->lock); /* * Because object->underobj was not NULL, hook_sb_delete() and @@ -92,8 +92,8 @@ static void release_inode(struct landlock_object *const object) */ iput(inode); - if (atomic_long_dec_and_test(&landlock_superblock(sb)->inode_refs)) - wake_up_var(&landlock_superblock(sb)->inode_refs); + if (atomic_long_dec_and_test(inode_refs)) + wake_up_var(inode_refs); } static const struct landlock_object_underops landlock_fs_underops = { @@ -342,7 +342,7 @@ int landlock_append_fs_rule(struct landlock_ruleset *const ruleset, /* Transforms relative access rights to absolute ones. */ access_rights |= LANDLOCK_MASK_ACCESS_FS & - ~(ruleset->handled_masks.fs | + ~(ruleset->layer.handled.fs | _LANDLOCK_ACCESS_FS_INITIALLY_DENIED); id.key.object = get_inode_object(d_backing_inode(path->dentry)); if (IS_ERR(id.key.object))
diff --git a/security/landlock/limits.h b/security/landlock/limits.h index 1a7c5fb8..ddd300e 100644 --- a/security/landlock/limits.h +++ b/security/landlock/limits.h
@@ -11,7 +11,9 @@ #define _SECURITY_LANDLOCK_LIMITS_H #include <linux/bitops.h> +#include <linux/capability.h> #include <linux/limits.h> +#include <linux/ns/ns_common_types.h> #include <uapi/linux/landlock.h> /* clang-format off */ @@ -31,6 +33,13 @@ #define LANDLOCK_MASK_SCOPE ((LANDLOCK_LAST_SCOPE << 1) - 1) #define LANDLOCK_NUM_SCOPE __const_hweight64(LANDLOCK_MASK_SCOPE) +#define LANDLOCK_LAST_PERMISSION LANDLOCK_PERMISSION_CAPABILITY_USE +#define LANDLOCK_MASK_PERMISSION ((LANDLOCK_LAST_PERMISSION << 1) - 1) +#define LANDLOCK_NUM_PERMISSION __const_hweight64(LANDLOCK_MASK_PERMISSION) + +#define LANDLOCK_NUM_NAMESPACE_TYPE __const_hweight64((u64)CLONE_NS_ALL) +#define LANDLOCK_NUM_CAPABILITY (CAP_LAST_CAP + 1) + #define LANDLOCK_NUM_ACCESS_MAX \ MAX(MAX(LANDLOCK_NUM_ACCESS_FS, LANDLOCK_NUM_ACCESS_NET), LANDLOCK_NUM_SCOPE)
diff --git a/security/landlock/log.c b/security/landlock/log.c index a8578a6f..43efbb9 100644 --- a/security/landlock/log.c +++ b/security/landlock/log.c
@@ -12,11 +12,13 @@ #include "access.h" #include "audit.h" +#include "cap.h" #include "common.h" #include "cred.h" #include "domain.h" #include "limits.h" #include "log.h" +#include "ns.h" #include "ruleset.h" #include "trace.h" @@ -382,6 +384,37 @@ static bool is_valid_request(const struct landlock_request *const request) if (WARN_ON_ONCE(!(!!request->layer_plus_one ^ !!request->access))) return false; + if (WARN_ON_ONCE(request->access && request->permission)) + return false; + + switch (request->type) { + case LANDLOCK_REQUEST_NAMESPACE: + if (WARN_ON_ONCE(request->permission != + LANDLOCK_PERMISSION_NAMESPACE_USE) || + WARN_ON_ONCE(request->audit.type != LSM_AUDIT_DATA_NS)) + return false; + break; + case LANDLOCK_REQUEST_CAPABILITY: + if (WARN_ON_ONCE(request->permission != + LANDLOCK_PERMISSION_CAPABILITY_USE) || + WARN_ON_ONCE(request->audit.type != LSM_AUDIT_DATA_CAP)) + return false; + break; + case LANDLOCK_REQUEST_PTRACE: + case LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY: + case LANDLOCK_REQUEST_FS_ACCESS: + case LANDLOCK_REQUEST_NET_ACCESS: + case LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET: + case LANDLOCK_REQUEST_SCOPE_SIGNAL: + if (WARN_ON_ONCE(request->permission)) + return false; + break; + default: + WARN_ONCE(1, "Unknown Landlock request type %d\n", + request->type); + return false; + } + if (request->access) { if (WARN_ON_ONCE(!(!!request->layer_masks ^ !!request->all_existing_optional_access))) @@ -436,22 +469,28 @@ is_denial_quieted(const struct landlock_request *const request, if (object_quiet_flag) { const access_mask_t quiet_mask = pick_access_mask_for_request_type( - request->type, youngest_denied->quiet_masks); + request->type, youngest_denied->quiet_access); return (quiet_mask & missing) == missing; } /* - * Either the object is not quiet, or this is a scope request. We check - * request->type to distinguish between the two cases. + * Per-object quieting did not apply. Check request->type for scope and + * permission quieting; ptrace and topology requests are never quiet. */ switch (request->type) { case LANDLOCK_REQUEST_SCOPE_SIGNAL: - return !!(youngest_denied->quiet_masks.scope & + return !!(youngest_denied->quiet_access.scope & LANDLOCK_SCOPE_SIGNAL); case LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET: - return !!(youngest_denied->quiet_masks.scope & + return !!(youngest_denied->quiet_access.scope & LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); + case LANDLOCK_REQUEST_NAMESPACE: + return !!(youngest_denied->quiet_permission.ns_types & + landlock_ns_type_to_bit(request->audit.u.ns.ns_type)); + case LANDLOCK_REQUEST_CAPABILITY: + return !!(youngest_denied->quiet_permission.caps & + landlock_cap_to_bit(request->audit.u.cap)); /* * Leave LANDLOCK_REQUEST_PTRACE and LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY * unhandled for now - they are never quiet. @@ -508,8 +547,8 @@ void landlock_log_denial(const struct landlock_cred_security *const subject, if (!is_valid_request(request)) return; - missing = request->access; - if (missing) { + missing = request->access ? request->access : request->permission; + if (request->access) { /* Gets the nearest domain that denies the request. */ if (request->layer_masks) { youngest_layer = get_denied_layer(subject->domain,
diff --git a/security/landlock/log.h b/security/landlock/log.h index faa30e2..596feee 100644 --- a/security/landlock/log.h +++ b/security/landlock/log.h
@@ -25,9 +25,12 @@ enum landlock_request_type { LANDLOCK_REQUEST_NET_ACCESS, LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET, LANDLOCK_REQUEST_SCOPE_SIGNAL, + LANDLOCK_REQUEST_NAMESPACE, + LANDLOCK_REQUEST_CAPABILITY, }; struct landlock_blockers { + /* Blocking access rights or permissions, as selected by @type. */ access_mask_t access; enum landlock_request_type type; }; @@ -58,8 +61,13 @@ struct landlock_signal_trace { * CONFIG_SECURITY_LANDLOCK_LOG is not set. */ struct landlock_request { - /* Mandatory fields. */ + /* Mandatory request type. */ enum landlock_request_type type; + + /* Required field for permission requests. */ + access_mask_t permission; + + /* Mandatory audit context. */ struct common_audit_data audit; /**
diff --git a/security/landlock/net.c b/security/landlock/net.c index 6fe0dbd..8fd73cf 100644 --- a/security/landlock/net.c +++ b/security/landlock/net.c
@@ -35,7 +35,7 @@ int landlock_append_net_rule(struct landlock_ruleset *const ruleset, BUILD_BUG_ON(sizeof(port) > sizeof(id.key.data)); /* Transforms relative access rights to absolute ones. */ - access_rights |= LANDLOCK_MASK_ACCESS_NET & ~ruleset->handled_masks.net; + access_rights |= LANDLOCK_MASK_ACCESS_NET & ~ruleset->layer.handled.net; mutex_lock(&ruleset->lock); err = landlock_insert_rule(ruleset, id, access_rights, flags);
diff --git a/security/landlock/ns.c b/security/landlock/ns.c new file mode 100644 index 0000000..cd44c92 --- /dev/null +++ b/security/landlock/ns.c
@@ -0,0 +1,241 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Landlock - Namespace hooks + * + * Copyright © 2026 Cloudflare, Inc. + */ + +#include <linux/bitops.h> +#include <linux/bug.h> +#include <linux/lsm_audit.h> +#include <linux/lsm_hooks.h> +#include <linux/ns/ns_common_types.h> +#include <linux/ns_common.h> +#include <linux/nsproxy.h> +#include <uapi/linux/landlock.h> + +#include "cred.h" +#include "domain.h" +#include "limits.h" +#include "log.h" +#include "ns.h" +#include "ruleset.h" +#include "setup.h" + +#define _LANDLOCK_NS_TYPE(type, flag) flag, + +static const u32 landlock_namespace_types[] = { + /* clang-format off */ + FOR_EACH_NS_TYPE(_LANDLOCK_NS_TYPE) + /* clang-format on */ +}; + +#undef _LANDLOCK_NS_TYPE + +static_assert(ARRAY_SIZE(landlock_namespace_types) == + LANDLOCK_NUM_NAMESPACE_TYPE); + +/* Ensures the audit ns_id field can hold ns_common.ns_id without truncation. */ +static_assert(sizeof(((struct common_audit_data *)NULL)->u.ns.ns_id) >= + sizeof(((struct ns_common *)NULL)->ns_id)); + +/** + * landlock_ns_type_to_bit - Convert a namespace type to a compact bitmask + * + * @ns_type: Namespace type (``CLONE_NEW*``). + * + * Return: The compact bit for @ns_type, or 0 if @ns_type is invalid (with a + * warning). + */ +u64 landlock_ns_type_to_bit(const u32 ns_type) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(landlock_namespace_types); i++) { + if (landlock_namespace_types[i] == ns_type) + return BIT_ULL(i); + } + + WARN_ONCE(1, "Unknown namespace type 0x%x\n", ns_type); + return 0; +} + +/** + * landlock_ns_types_to_bits - Convert namespace types to a compact bitmask + * + * @ns_types: Bitmask of namespace types (``CLONE_NEW*``). + * + * Return: The compact bits for all known @ns_types. Warns if unknown bits are + * present (callers must pre-mask user input). + */ +u64 landlock_ns_types_to_bits(const u64 ns_types) +{ + u64 bits = 0; + size_t i; + + /* Callers pre-mask (CLONE_NS_ALL); the WARN guards future callers. */ + WARN_ON_ONCE(ns_types & ~(u64)CLONE_NS_ALL); + for (i = 0; i < ARRAY_SIZE(landlock_namespace_types); i++) { + if (ns_types & landlock_namespace_types[i]) + bits |= BIT_ULL(i); + } + return bits; +} + +static const struct access_masks ns_permission = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, +}; + +/** + * check_ns_type - Check namespace use permission + * + * @ns: The namespace being allocated or installed. + * + * Shared check for namespace_init (creation via clone(2), unshare(2), + * open_tree(2), or fsmount(2)) and namespace_install (use via setns(2)): denies + * when the namespace type is not in the domain's allowed set. At allocation + * time @ns->ns_id is still zero and is logged as such. + * + * Return: 0 if allowed, -EPERM if denied. + */ +static int check_ns_type(struct ns_common *const ns) +{ + const struct landlock_cred_security *subject; + size_t denied_layer; + + subject = landlock_get_applicable_subject(current_cred(), ns_permission, + NULL); + if (!subject) + return 0; + + denied_layer = landlock_permission_is_denied( + subject->domain, LANDLOCK_PERMISSION_NAMESPACE_USE, + landlock_ns_type_to_bit(ns->ns_type)); + if (!denied_layer) + return 0; + + landlock_log_denial(subject, + &(struct landlock_request){ + .type = LANDLOCK_REQUEST_NAMESPACE, + .audit.type = LSM_AUDIT_DATA_NS, + .permission = + LANDLOCK_PERMISSION_NAMESPACE_USE, + .audit.u.ns.ns_type = ns->ns_type, + .audit.u.ns.ns_id = ns->ns_id, + .layer_plus_one = denied_layer, + }); + return -EPERM; +} + +static int hook_namespace_init(struct ns_common *const ns) +{ + return check_ns_type(ns); +} + +static int hook_namespace_install(const struct nsset *const nsset, + struct ns_common *const ns) +{ + return check_ns_type(ns); +} + +static struct security_hook_list landlock_hooks[] __ro_after_init = { + LSM_HOOK_INIT(namespace_init, hook_namespace_init), + LSM_HOOK_INIT(namespace_install, hook_namespace_install), +}; + +__init void landlock_add_ns_hooks(void) +{ + security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), + &landlock_lsmid); +} + +#ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST + +#include <kunit/test.h> + +static void test_ns_type_to_bit(struct kunit *const test) +{ + u64 seen = 0; + size_t i; + + for (i = 0; i < ARRAY_SIZE(landlock_namespace_types); i++) { + const u64 bit = + landlock_ns_type_to_bit(landlock_namespace_types[i]); + + KUNIT_EXPECT_NE(test, 0ULL, bit); + KUNIT_EXPECT_EQ(test, 0ULL, seen & bit); + seen |= bit; + } + + KUNIT_EXPECT_EQ(test, GENMASK_ULL(LANDLOCK_NUM_NAMESPACE_TYPE - 1, 0), + seen); +} + +static void test_ns_type_to_bit_unknown(struct kunit *const test) +{ + if (!IS_ENABLED(CONFIG_BUG)) + kunit_skip(test, "requires CONFIG_BUG"); + + /* clang-format off */ + kunit_warning_suppress(test) { + /* clang-format on */ + KUNIT_EXPECT_EQ(test, 0ULL, + landlock_ns_type_to_bit(CLONE_THREAD)); + KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1); + } +} + +static void test_ns_types_to_bits_all(struct kunit *const test) +{ + KUNIT_EXPECT_EQ(test, GENMASK_ULL(LANDLOCK_NUM_NAMESPACE_TYPE - 1, 0), + landlock_ns_types_to_bits(CLONE_NS_ALL)); +} + +static void test_ns_types_to_bits_single(struct kunit *const test) +{ + size_t i; + + for (i = 0; i < ARRAY_SIZE(landlock_namespace_types); i++) + KUNIT_EXPECT_EQ( + test, + landlock_ns_type_to_bit(landlock_namespace_types[i]), + landlock_ns_types_to_bits(landlock_namespace_types[i])); +} + +static void test_ns_types_to_bits_unknown(struct kunit *const test) +{ + if (!IS_ENABLED(CONFIG_BUG)) + kunit_skip(test, "requires CONFIG_BUG"); + + /* clang-format off */ + kunit_warning_suppress(test) { + /* clang-format on */ + KUNIT_EXPECT_EQ(test, 0ULL, + landlock_ns_types_to_bits(CLONE_THREAD)); + KUNIT_EXPECT_SUPPRESSED_WARNING_COUNT(test, 1); + } +} + +static void test_ns_types_to_bits_zero(struct kunit *const test) +{ + KUNIT_EXPECT_EQ(test, 0ULL, landlock_ns_types_to_bits(0)); +} + +static struct kunit_case test_cases[] = { + KUNIT_CASE(test_ns_type_to_bit), + KUNIT_CASE(test_ns_type_to_bit_unknown), + KUNIT_CASE(test_ns_types_to_bits_all), + KUNIT_CASE(test_ns_types_to_bits_single), + KUNIT_CASE(test_ns_types_to_bits_unknown), + KUNIT_CASE(test_ns_types_to_bits_zero), + {} +}; + +static struct kunit_suite test_suite = { + .name = "landlock_ns", + .test_cases = test_cases, +}; + +kunit_test_suite(test_suite); + +#endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */
diff --git a/security/landlock/ns.h b/security/landlock/ns.h new file mode 100644 index 0000000..46d3bd1 --- /dev/null +++ b/security/landlock/ns.h
@@ -0,0 +1,18 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Landlock - Namespace hooks + * + * Copyright © 2026 Cloudflare, Inc. + */ + +#ifndef _SECURITY_LANDLOCK_NS_H +#define _SECURITY_LANDLOCK_NS_H + +#include <linux/types.h> + +u64 landlock_ns_type_to_bit(u32 ns_type); +u64 landlock_ns_types_to_bits(u64 ns_types); + +__init void landlock_add_ns_hooks(void); + +#endif /* _SECURITY_LANDLOCK_NS_H */
diff --git a/security/landlock/ruleset.c b/security/landlock/ruleset.c index a5d135d..11776b1 100644 --- a/security/landlock/ruleset.c +++ b/security/landlock/ruleset.c
@@ -31,15 +31,15 @@ #include <trace/events/landlock.h> -struct landlock_ruleset * -landlock_create_ruleset(const access_mask_t fs_access_mask, - const access_mask_t net_access_mask, - const access_mask_t scope_mask) +struct landlock_ruleset *landlock_create_ruleset( + const access_mask_t fs_access_mask, const access_mask_t net_access_mask, + const access_mask_t scope_mask, const access_mask_t permission_mask) { struct landlock_ruleset *new_ruleset; /* Informs about useless ruleset. */ - if (!fs_access_mask && !net_access_mask && !scope_mask) + if (!fs_access_mask && !net_access_mask && !scope_mask && + !permission_mask) return ERR_PTR(-ENOMSG); new_ruleset = kzalloc_obj(*new_ruleset, GFP_KERNEL_ACCOUNT); @@ -64,21 +64,32 @@ landlock_create_ruleset(const access_mask_t fs_access_mask, LANDLOCK_MASK_ACCESS_FS; WARN_ON_ONCE(fs_access_mask != mask); - new_ruleset->handled_masks.fs |= mask; + new_ruleset->layer.handled.fs |= mask; } + if (net_access_mask) { const access_mask_t mask = net_access_mask & LANDLOCK_MASK_ACCESS_NET; WARN_ON_ONCE(net_access_mask != mask); - new_ruleset->handled_masks.net |= mask; + new_ruleset->layer.handled.net |= mask; } + if (scope_mask) { const access_mask_t mask = scope_mask & LANDLOCK_MASK_SCOPE; WARN_ON_ONCE(scope_mask != mask); - new_ruleset->handled_masks.scope |= mask; + new_ruleset->layer.handled.scope |= mask; } + + if (permission_mask) { + const access_mask_t mask = permission_mask & + LANDLOCK_MASK_PERMISSION; + + WARN_ON_ONCE(permission_mask != mask); + new_ruleset->layer.handled.permissions |= mask; + } + return new_ruleset; }
diff --git a/security/landlock/ruleset.h b/security/landlock/ruleset.h index cf77f18..3a38d70 100644 --- a/security/landlock/ruleset.h +++ b/security/landlock/ruleset.h
@@ -182,22 +182,29 @@ struct landlock_ruleset { #endif /* CONFIG_TRACEPOINTS */ /** - * @quiet_masks: Stores the quiet flags for an unmerged ruleset. For a + * @quiet_access: Stores the quiet flags for an unmerged ruleset. For a * merged domain, this is stored in each layer's struct - * landlock_hierarchy instead. + * landlock_hierarchy instead. Its permissions member is unused because + * permission quieting is per member rather than per permission. */ - struct access_masks quiet_masks; + struct access_masks quiet_access; +#ifdef CONFIG_SECURITY_LANDLOCK_LOG /** - * @handled_masks: Contains the subset of filesystem and network actions - * that are handled by this ruleset. + * @quiet_permission: Per-member quiet bitmasks for permission types in + * this ruleset. A denied member whose bit is set here is not submitted + * to audit when this layer denies it. */ - struct access_masks handled_masks; + struct permission_masks quiet_permission; +#endif /* CONFIG_SECURITY_LANDLOCK_LOG */ + /** + * @layer: Access configuration for this ruleset's single mutable layer. + */ + struct layer_config layer; }; -struct landlock_ruleset * -landlock_create_ruleset(const access_mask_t access_mask_fs, - const access_mask_t access_mask_net, - const access_mask_t scope_mask); +struct landlock_ruleset *landlock_create_ruleset( + const access_mask_t access_mask_fs, const access_mask_t access_mask_net, + const access_mask_t scope_mask, const access_mask_t permission_mask); void landlock_put_ruleset(struct landlock_ruleset *const ruleset); @@ -248,4 +255,10 @@ static inline void landlock_get_ruleset(struct landlock_ruleset *const ruleset) refcount_inc(&ruleset->usage); } +static inline access_mask_t +landlock_get_permission_mask(const struct landlock_ruleset *const ruleset) +{ + return ruleset->layer.handled.permissions; +} + #endif /* _SECURITY_LANDLOCK_RULESET_H */
diff --git a/security/landlock/setup.c b/security/landlock/setup.c index 47dac17..971419d 100644 --- a/security/landlock/setup.c +++ b/security/landlock/setup.c
@@ -11,12 +11,14 @@ #include <linux/lsm_hooks.h> #include <uapi/linux/lsm.h> +#include "cap.h" #include "common.h" #include "cred.h" #include "errata.h" #include "fs.h" #include "id.h" #include "net.h" +#include "ns.h" #include "setup.h" #include "task.h" @@ -68,6 +70,8 @@ static int __init landlock_init(void) landlock_add_task_hooks(); landlock_add_fs_hooks(); landlock_add_net_hooks(); + landlock_add_ns_hooks(); + landlock_add_cap_hooks(); landlock_init_id(); landlock_initialized = true; pr_info("Up and running.\n");
diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c index 1d02d57..fb5af31 100644 --- a/security/landlock/syscalls.c +++ b/security/landlock/syscalls.c
@@ -20,6 +20,7 @@ #include <linux/fs.h> #include <linux/limits.h> #include <linux/mount.h> +#include <linux/ns/ns_common_types.h> #include <linux/path.h> #include <linux/sched.h> #include <linux/sched/signal.h> @@ -30,11 +31,13 @@ #include <linux/uaccess.h> #include <uapi/linux/landlock.h> +#include "cap.h" #include "cred.h" #include "domain.h" #include "fs.h" #include "limits.h" #include "net.h" +#include "ns.h" #include "ruleset.h" #include "setup.h" #include "tsync.h" @@ -98,7 +101,10 @@ static void build_check_abi(void) struct landlock_ruleset_attr ruleset_attr; struct landlock_path_beneath_attr path_beneath_attr; struct landlock_net_port_attr net_port_attr; + struct landlock_namespace_attr namespace_attr; + struct landlock_capability_attr capability_attr; size_t ruleset_size, path_beneath_size, net_port_size; + size_t namespace_size, capability_size; /* * For each user space ABI structures, first checks that there is no @@ -111,8 +117,9 @@ static void build_check_abi(void) ruleset_size += sizeof(ruleset_attr.quiet_access_fs); ruleset_size += sizeof(ruleset_attr.quiet_access_net); ruleset_size += sizeof(ruleset_attr.quiet_scoped); + ruleset_size += sizeof(ruleset_attr.handled_permissions); BUILD_BUG_ON(sizeof(ruleset_attr) != ruleset_size); - BUILD_BUG_ON(sizeof(ruleset_attr) != 48); + BUILD_BUG_ON(sizeof(ruleset_attr) != 56); path_beneath_size = sizeof(path_beneath_attr.allowed_access); path_beneath_size += sizeof(path_beneath_attr.parent_fd); @@ -123,6 +130,18 @@ static void build_check_abi(void) net_port_size += sizeof(net_port_attr.port); BUILD_BUG_ON(sizeof(net_port_attr) != net_port_size); BUILD_BUG_ON(sizeof(net_port_attr) != 16); + + namespace_size = sizeof(namespace_attr.permissions); + namespace_size += sizeof(namespace_attr.allowed_namespace_types); + namespace_size += sizeof(namespace_attr.quiet_namespace_types); + BUILD_BUG_ON(sizeof(namespace_attr) != namespace_size); + BUILD_BUG_ON(sizeof(namespace_attr) != 24); + + capability_size = sizeof(capability_attr.permissions); + capability_size += sizeof(capability_attr.allowed_capabilities); + capability_size += sizeof(capability_attr.quiet_capabilities); + BUILD_BUG_ON(sizeof(capability_attr) != capability_size); + BUILD_BUG_ON(sizeof(capability_attr) != 24); } /* Ruleset handling */ @@ -172,7 +191,7 @@ static const struct file_operations ruleset_fops = { * If the change involves a fix that requires userspace awareness, also update * the errata documentation in Documentation/userspace-api/landlock.rst . */ -const int landlock_abi_version = 11; +const int landlock_abi_version = 12; /** * sys_landlock_create_ruleset - Create a new ruleset @@ -197,14 +216,13 @@ const int landlock_abi_version = 11; * returned errors are: * * - %EOPNOTSUPP: Landlock is supported by the kernel but disabled at boot time; - * - %EINVAL: unknown @flags, or unknown access, or unknown scope, or too small - * @size; + * - %EINVAL: unknown @flags, access, scope, or permission, or too small @size; * - %EINVAL: quiet_access_fs, quiet_access_net, or quiet_scoped is not a * subset of the corresponding handled_access_fs, handled_access_net, or * scoped; * - %E2BIG: @attr or @size inconsistencies; * - %EFAULT: @attr or @size inconsistencies; - * - %ENOMSG: empty &landlock_ruleset_attr.handled_access_fs. + * - %ENOMSG: all handled access, scope, and permission fields are empty. * * .. kernel-doc:: include/uapi/linux/landlock.h * :identifiers: landlock_create_ruleset_flags @@ -273,16 +291,22 @@ SYSCALL_DEFINE3(landlock_create_ruleset, ruleset_attr.scoped) return -EINVAL; + /* Checks permission content (and 32-bits cast). */ + if ((ruleset_attr.handled_permissions | LANDLOCK_MASK_PERMISSION) != + LANDLOCK_MASK_PERMISSION) + return -EINVAL; + /* Checks arguments and transforms to kernel struct. */ ruleset = landlock_create_ruleset(ruleset_attr.handled_access_fs, ruleset_attr.handled_access_net, - ruleset_attr.scoped); + ruleset_attr.scoped, + ruleset_attr.handled_permissions); if (IS_ERR(ruleset)) return PTR_ERR(ruleset); - ruleset->quiet_masks.fs = ruleset_attr.quiet_access_fs; - ruleset->quiet_masks.net = ruleset_attr.quiet_access_net; - ruleset->quiet_masks.scope = ruleset_attr.quiet_scoped; + ruleset->quiet_access.fs = ruleset_attr.quiet_access_fs; + ruleset->quiet_access.net = ruleset_attr.quiet_access_net; + ruleset->quiet_access.scope = ruleset_attr.quiet_scoped; /* * Emits before anon_inode_getfd() installs the file descriptor, while @@ -377,12 +401,12 @@ static int add_rule_path_beneath(struct landlock_ruleset *const ruleset, return -ENOMSG; /* Checks that allowed_access matches the @ruleset constraints. */ - mask = ruleset->handled_masks.fs; + mask = ruleset->layer.handled.fs; if ((path_beneath_attr.allowed_access | mask) != mask) return -EINVAL; /* Checks for useless quiet flag. */ - if (flags & LANDLOCK_ADD_RULE_QUIET && !ruleset->quiet_masks.fs) + if (flags & LANDLOCK_ADD_RULE_QUIET && !ruleset->quiet_access.fs) return -EINVAL; /* Gets and checks the new rule. */ @@ -418,12 +442,12 @@ static int add_rule_net_port(struct landlock_ruleset *ruleset, return -ENOMSG; /* Checks that allowed_access matches the @ruleset constraints. */ - mask = ruleset->handled_masks.net; + mask = ruleset->layer.handled.net; if ((net_port_attr.allowed_access | mask) != mask) return -EINVAL; /* Checks for useless quiet flag. */ - if (flags & LANDLOCK_ADD_RULE_QUIET && !ruleset->quiet_masks.net) + if (flags & LANDLOCK_ADD_RULE_QUIET && !ruleset->quiet_access.net) return -EINVAL; /* Denies inserting a rule with port greater than 65535. */ @@ -435,13 +459,164 @@ static int add_rule_net_port(struct landlock_ruleset *ruleset, net_port_attr.allowed_access, flags); } +static int add_rule_namespace(struct landlock_ruleset *const ruleset, + const void __user *const rule_attr, + const u32 flags) +{ + struct landlock_namespace_attr ns_attr; + access_mask_t mask; + u64 allowed_types, quiet_types; + int ret; + + /* + * Namespace rules support no add-rule flags. In particular, + * LANDLOCK_ADD_RULE_QUIET is filesystem/network only. + */ + if (flags) + return -EINVAL; + + /* Copies raw user space buffer. */ + ret = copy_from_user(&ns_attr, rule_attr, sizeof(ns_attr)); + if (ret) + return -EFAULT; + + /* Informs about useless rule: empty permissions. */ + if (!ns_attr.permissions) + return -ENOMSG; + + /* + * The permissions selector must match + * LANDLOCK_PERMISSION_NAMESPACE_USE. The valid set is a single bit + * today, so this is an exact match now; the check broadens to a subset + * test once another supported permission is added. + */ + if (ns_attr.permissions != LANDLOCK_PERMISSION_NAMESPACE_USE) + return -EINVAL; + + /* + * Checks that permissions match the ruleset constraints. This also + * makes quieting require the category to be handled. + */ + mask = landlock_get_permission_mask(ruleset); + if (!(mask & LANDLOCK_PERMISSION_NAMESPACE_USE)) + return -EINVAL; + + /* + * Informs about useless rule: neither allows nor quiets anything. A + * quiet-only rule (empty allowed set) is legal. + */ + if (!ns_attr.allowed_namespace_types && !ns_attr.quiet_namespace_types) + return -ENOMSG; + + /* + * Stores only the namespace types this kernel knows about. Unknown + * bits are silently accepted for forward compatibility: user space + * compiled against newer headers can pass new CLONE_NEW* flags without + * getting EINVAL on older kernels. Unknown bits have no effect because + * no hook checks them. The quiet bitmask suppresses logging of denials + * attributed to this layer; see landlock_log_denial(). + */ + allowed_types = ns_attr.allowed_namespace_types & CLONE_NS_ALL; + quiet_types = ns_attr.quiet_namespace_types & CLONE_NS_ALL; + + mutex_lock(&ruleset->lock); + ruleset->layer.allowed.ns_types |= + landlock_ns_types_to_bits(allowed_types); +#ifdef CONFIG_SECURITY_LANDLOCK_LOG + ruleset->quiet_permission.ns_types |= + landlock_ns_types_to_bits(quiet_types); +#endif /* CONFIG_SECURITY_LANDLOCK_LOG */ +#ifdef CONFIG_TRACEPOINTS + ruleset->version++; +#endif /* CONFIG_TRACEPOINTS */ + trace_landlock_add_rule_namespace(ruleset, flags, ns_attr.permissions, + allowed_types, quiet_types); + mutex_unlock(&ruleset->lock); + return 0; +} + +static int add_rule_capability(struct landlock_ruleset *const ruleset, + const void __user *const rule_attr, + const u32 flags) +{ + struct landlock_capability_attr cap_attr; + access_mask_t mask; + u64 allowed_caps, quiet_caps; + int ret; + + /* + * Capability rules support no add-rule flags. In particular, + * LANDLOCK_ADD_RULE_QUIET is filesystem/network only. + */ + if (flags) + return -EINVAL; + + /* Copies raw user space buffer. */ + ret = copy_from_user(&cap_attr, rule_attr, sizeof(cap_attr)); + if (ret) + return -EFAULT; + + /* Informs about useless rule: empty permissions. */ + if (!cap_attr.permissions) + return -ENOMSG; + + /* + * The permissions selector must match + * LANDLOCK_PERMISSION_CAPABILITY_USE. The valid set is a single bit + * today, so this is an exact match now; the check broadens to a subset + * test once another supported permission is added. + */ + if (cap_attr.permissions != LANDLOCK_PERMISSION_CAPABILITY_USE) + return -EINVAL; + + /* + * Checks that permissions match the ruleset constraints. This also + * makes quieting require the category to be handled. + */ + mask = landlock_get_permission_mask(ruleset); + if (!(mask & LANDLOCK_PERMISSION_CAPABILITY_USE)) + return -EINVAL; + + /* + * Informs about useless rule: neither allows nor quiets anything. A + * quiet-only rule (empty allowed set) is legal. + */ + if (!cap_attr.allowed_capabilities && !cap_attr.quiet_capabilities) + return -ENOMSG; + + /* + * Stores only the capabilities this kernel knows about. Unknown bits + * are silently accepted for forward compatibility: user space compiled + * against newer headers can pass new CAP_* bits without getting EINVAL + * on older kernels. Unknown bits have no effect because no hook checks + * them. The quiet bitmask suppresses logging of denials attributed to + * this layer; see landlock_log_denial(). + */ + allowed_caps = cap_attr.allowed_capabilities & CAP_VALID_MASK; + quiet_caps = cap_attr.quiet_capabilities & CAP_VALID_MASK; + + mutex_lock(&ruleset->lock); + ruleset->layer.allowed.caps |= landlock_caps_to_bits(allowed_caps); +#ifdef CONFIG_SECURITY_LANDLOCK_LOG + ruleset->quiet_permission.caps |= landlock_caps_to_bits(quiet_caps); +#endif /* CONFIG_SECURITY_LANDLOCK_LOG */ +#ifdef CONFIG_TRACEPOINTS + ruleset->version++; +#endif /* CONFIG_TRACEPOINTS */ + trace_landlock_add_rule_capability(ruleset, flags, cap_attr.permissions, + allowed_caps, quiet_caps); + mutex_unlock(&ruleset->lock); + return 0; +} + /** * sys_landlock_add_rule - Add a new rule to a ruleset * * @ruleset_fd: File descriptor tied to the ruleset that should be extended * with the new rule. * @rule_type: Identify the structure type pointed to by @rule_attr: - * %LANDLOCK_RULE_PATH_BENEATH or %LANDLOCK_RULE_NET_PORT. + * %LANDLOCK_RULE_PATH_BENEATH, %LANDLOCK_RULE_NET_PORT, + * %LANDLOCK_RULE_NAMESPACE, or %LANDLOCK_RULE_CAPABILITY. * @rule_attr: Pointer to a rule (matching the @rule_type). * @flags: Must be 0 or %LANDLOCK_ADD_RULE_QUIET. * @@ -458,11 +633,21 @@ static int add_rule_net_port(struct landlock_ruleset *ruleset, * &landlock_path_beneath_attr.allowed_access or * &landlock_net_port_attr.allowed_access is not a subset of the ruleset * handled accesses) + * - %EINVAL: A nonzero &landlock_namespace_attr.permissions is not + * %LANDLOCK_PERMISSION_NAMESPACE_USE or is not handled by the ruleset; + * - %EINVAL: A nonzero &landlock_capability_attr.permissions is not + * %LANDLOCK_PERMISSION_CAPABILITY_USE or is not handled by the ruleset; * - %EINVAL: &landlock_net_port_attr.port is greater than 65535; * - %EINVAL: LANDLOCK_ADD_RULE_QUIET is passed but the ruleset has no * quiet access bits set for the corresponding rule type. * - %ENOMSG: Empty accesses (e.g. &landlock_path_beneath_attr.allowed_access is * 0) and no flags; + * - %ENOMSG: &landlock_namespace_attr.permissions is 0, or both + * &landlock_namespace_attr.allowed_namespace_types and + * &landlock_namespace_attr.quiet_namespace_types are 0; + * - %ENOMSG: &landlock_capability_attr.permissions is 0, or both + * &landlock_capability_attr.allowed_capabilities and + * &landlock_capability_attr.quiet_capabilities are 0; * - %EBADF: @ruleset_fd is not a file descriptor for the current thread, or a * member of @rule_attr is not a file descriptor as expected; * - %EBADFD: @ruleset_fd is not a ruleset file descriptor, or a member of @@ -495,6 +680,10 @@ SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd, return add_rule_path_beneath(ruleset, rule_attr, flags); case LANDLOCK_RULE_NET_PORT: return add_rule_net_port(ruleset, rule_attr, flags); + case LANDLOCK_RULE_NAMESPACE: + return add_rule_namespace(ruleset, rule_attr, flags); + case LANDLOCK_RULE_CAPABILITY: + return add_rule_capability(ruleset, rule_attr, flags); default: return -EINVAL; }
diff --git a/security/landlock/trace.c b/security/landlock/trace.c index 225dbf3..995c6b9 100644 --- a/security/landlock/trace.c +++ b/security/landlock/trace.c
@@ -62,7 +62,7 @@ void landlock_trace_free_domain(const struct landlock_hierarchy *const hierarchy * * @request: Detail of the user space request. * @youngest_denied: The youngest hierarchy node that denied the access. - * @missing: The final missing access subset, when applicable. + * @missing: The final missing access or permission subset, when applicable. * @same_exec: Whether the policy subject is the same executable that called * landlock_restrict_self() for the denying domain, as computed * by landlock_log_denial(). @@ -81,6 +81,31 @@ void landlock_trace_denial( const access_mask_t missing, const bool same_exec, const bool logged) { switch (request->type) { + case LANDLOCK_REQUEST_NAMESPACE: + if (trace_landlock_deny_permission_namespace_enabled()) { + const struct landlock_blockers blockers = { + .access = missing, + .type = request->type, + }; + + trace_landlock_deny_permission_namespace( + youngest_denied, same_exec, logged, &blockers, + request->audit.u.ns.ns_type, + request->audit.u.ns.ns_id); + } + break; + case LANDLOCK_REQUEST_CAPABILITY: + if (trace_landlock_deny_permission_capability_enabled()) { + const struct landlock_blockers blockers = { + .access = missing, + .type = request->type, + }; + + trace_landlock_deny_permission_capability( + youngest_denied, same_exec, logged, &blockers, + request->audit.u.cap); + } + break; case LANDLOCK_REQUEST_FS_ACCESS: case LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY: if (trace_landlock_deny_access_fs_enabled()) {
diff --git a/tools/gpio/gpio-hammer.c b/tools/gpio/gpio-hammer.c index ba0866e..1a21e54 100644 --- a/tools/gpio/gpio-hammer.c +++ b/tools/gpio/gpio-hammer.c
@@ -145,7 +145,7 @@ int main(int argc, char **argv) case 'o': /* * Avoid overflow. Do not immediately error, we want to - * be able to accurately report on the amount of times + * be able to accurately report on the number of times * '-o' was given to give an accurate error message */ if (i < GPIOHANDLES_MAX)
diff --git a/tools/sched_ext/Makefile b/tools/sched_ext/Makefile index 21554f0..70d2503 100644 --- a/tools/sched_ext/Makefile +++ b/tools/sched_ext/Makefile
@@ -89,7 +89,7 @@ GENFLAGS := -DHAVE_GENHDR endif -CFLAGS += -g -O2 -rdynamic -pthread -Wall -Werror $(GENFLAGS) \ +CFLAGS += -g -O2 -pthread -Wall -Werror $(GENFLAGS) \ -I$(INCLUDE_DIR) -I$(GENDIR) -I$(LIBDIR) \ -I$(TOOLSINCDIR) -I$(APIDIR) -I$(CURDIR)/include
diff --git a/tools/sched_ext/include/scx/cid.bpf.h b/tools/sched_ext/include/scx/cid.bpf.h index 69fb4e9..d1e6ad1 100644 --- a/tools/sched_ext/include/scx/cid.bpf.h +++ b/tools/sched_ext/include/scx/cid.bpf.h
@@ -3,8 +3,8 @@ * BPF-side helpers for cids and cmasks. See kernel/sched/ext/cid.h for the * authoritative layout and semantics. The BPF-side helpers use the cmask_* * naming (no scx_ prefix); cmask is the SCX bitmap type so the prefix is - * redundant in BPF code. Atomics use __sync_val_compare_and_swap and every - * helper is inline (no .c counterpart). + * redundant in BPF code. Every helper is inline except the binary operations, + * which are weak global functions defined here, so there is no .c counterpart. * * Included by scx/common.bpf.h; don't include directly. * @@ -16,6 +16,11 @@ #include "bpf_arena_common.bpf.h" +/* libbpf's bpf_helpers.h defines it from 1.4 on */ +#ifndef __arg_arena +#define __arg_arena __attribute((btf_decl_tag("arg:arena"))) +#endif + #ifndef BIT_U64 #define BIT_U64(nr) (1ULL << (nr)) #endif @@ -76,7 +81,7 @@ static __always_inline void __cmask_init(struct scx_cmask __arena *m, u32 base, m->nr_cids = nr_cids; m->alloc_words = alloc_words; - bpf_for(i, 0, CMASK_MAX_WORDS) { + bpf_arena_for(i, 0, CMASK_MAX_WORDS) { if (i >= alloc_words) break; m->bits[i] = 0; @@ -122,24 +127,115 @@ static __always_inline void cmask_reframe(struct scx_cmask __arena *m, u32 base, m->nr_cids = nr_cids; } +/** + * cmask_nr_words - Words of bits[] that @m's active range spans + * @m: cmask to measure + * + * @m->base need not be word aligned: bits[0] covers the whole word @m->base + * falls in, so the count is taken from that word, not from @m->base. + */ +static __always_inline u32 cmask_nr_words(const struct scx_cmask __arena *m) +{ + u32 wbase = m->base / 64; + + return m->nr_cids ? (m->base + m->nr_cids - 1) / 64 - wbase + 1 : 0; +} + +/** + * cmask_word - Read word @k of @m + * @m: cmask to read + * @k: word index, counted from the word @m->base falls in + * + * A word past the active range reads as 0, so a scan that looks one word + * ahead (at an SMT sibling that falls in the next word, say) needs no bound + * of its own. + */ +static __always_inline u64 cmask_word(const struct scx_cmask __arena *m, u32 k) +{ + if (k >= cmask_nr_words(m)) + return 0; + return m->bits[k]; +} + +/** + * cmask_range_word - Bits of word @k of @m that fall in [@start, @start + @nr) + * @m: cmask the word belongs to + * @k: word index, counted from the word @m->base falls in + * @start: first cid of the range + * @nr: number of cids in the range + * + * Scoping a scan to a domain that is contiguous in cid space, an LLC or a + * node, is then one AND per word, rather than a test of the ends of the + * range at every bit or a mask kept per domain. + */ +static __always_inline u64 cmask_range_word(const struct scx_cmask __arena *m, + u32 k, u32 start, u32 nr) +{ + u64 wlo = (u64)(m->base / 64 + k) * 64, whi = wlo + 64; + u64 lo = start, hi = (u64)start + nr; + + if (lo < wlo) + lo = wlo; + if (hi > whi) + hi = whi; + if (lo >= hi) + return 0; + + return GENMASK_U64(hi - wlo - 1, lo - wlo); +} + +/** + * __cmask_test - Test a cid without checking it against the active range + * @cid: cid to test + * @m: cmask to test + * + * The caller must already know that @cid lies within + * [@m->base, @m->base + @m->nr_cids), or the read runs off @m->bits. + * + * For hot scans that have already bounded @cid, where the per-call range check + * is repeated work on every candidate. + */ +static __always_inline bool __cmask_test(u32 cid, const struct scx_cmask __arena *m) +{ + return *__cmask_word(cid, m) & BIT_U64(cid & 63); +} + static __always_inline bool cmask_test(u32 cid, const struct scx_cmask __arena *m) { if (!__cmask_contains(cid, m)) return false; - return *__cmask_word(cid, m) & BIT_U64(cid & 63); + return __cmask_test(cid, m); } /* - * x86 BPF JIT rejects BPF_OR | BPF_FETCH and BPF_AND | BPF_FETCH on arena - * pointers (see bpf_jit_supports_insn() in arch/x86/net/bpf_jit_comp.c). Only - * BPF_CMPXCHG / BPF_XCHG / BPF_ADD with FETCH are allowed. Implement - * test_and_{set,clear} and the atomic set/clear via a cmpxchg loop. + * The bit helpers use the fetching bitwise builtins, which order like the + * cmpxchg they replace, and not every JIT accepts those on arena pointers. The + * loader sets SCX_LIB_FEAT_ARENA_FETCH_BITOPS when a probe with the fetching + * form loads, and the helpers run a cmpxchg loop otherwise. The fetched value + * is consumed through barrier_var() because clang 19 lowers a builtin whose + * result is unused to the non-fetching form, which is relaxed on arm64. * * CMASK_CAS_TRIES is sized so exhausting it means seconds of real spinning - * on one word - past any plausible contention. Abort hard. + * on one word, past any plausible contention. Abort hard. */ #define CMASK_CAS_TRIES (1U << 23) +static __always_inline u64 __cmask_fetch_or(u64 __arena *w, u64 mask) +{ + u64 old = __atomic_fetch_or(w, mask, __ATOMIC_ACQ_REL); + + barrier_var(old); + return old; +} + +static __always_inline u64 __cmask_fetch_andnot(u64 __arena *w, u64 mask) +{ + u64 old = __atomic_fetch_and(w, ~mask, __ATOMIC_ACQ_REL); + + barrier_var(old); + return old; +} + static __always_inline void cmask_set(u32 cid, struct scx_cmask __arena *m) { u64 __arena *w; @@ -150,7 +246,11 @@ static __always_inline void cmask_set(u32 cid, struct scx_cmask __arena *m) return; w = __cmask_word(cid, m); bit = BIT_U64(cid & 63); - bpf_for(i, 0, CMASK_CAS_TRIES) { + if (scx_lib_has(SCX_LIB_FEAT_ARENA_FETCH_BITOPS)) { + __cmask_fetch_or(w, bit); + return; + } + bpf_arena_for(i, 0, CMASK_CAS_TRIES) { old = *w; if (old & bit) return; @@ -171,7 +271,11 @@ static __always_inline void cmask_clear(u32 cid, struct scx_cmask __arena *m) return; w = __cmask_word(cid, m); bit = BIT_U64(cid & 63); - bpf_for(i, 0, CMASK_CAS_TRIES) { + if (scx_lib_has(SCX_LIB_FEAT_ARENA_FETCH_BITOPS)) { + __cmask_fetch_andnot(w, bit); + return; + } + bpf_arena_for(i, 0, CMASK_CAS_TRIES) { old = *w; if (!(old & bit)) return; @@ -192,7 +296,9 @@ static __always_inline bool cmask_test_and_set(u32 cid, struct scx_cmask __arena return false; w = __cmask_word(cid, m); bit = BIT_U64(cid & 63); - bpf_for(i, 0, CMASK_CAS_TRIES) { + if (scx_lib_has(SCX_LIB_FEAT_ARENA_FETCH_BITOPS)) + return __cmask_fetch_or(w, bit) & bit; + bpf_arena_for(i, 0, CMASK_CAS_TRIES) { old = *w; if (old & bit) return true; @@ -214,7 +320,9 @@ static __always_inline bool cmask_test_and_clear(u32 cid, struct scx_cmask __are return false; w = __cmask_word(cid, m); bit = BIT_U64(cid & 63); - bpf_for(i, 0, CMASK_CAS_TRIES) { + if (scx_lib_has(SCX_LIB_FEAT_ARENA_FETCH_BITOPS)) + return __cmask_fetch_andnot(w, bit) & bit; + bpf_arena_for(i, 0, CMASK_CAS_TRIES) { old = *w; if (!(old & bit)) return false; @@ -268,17 +376,242 @@ static __always_inline bool __cmask_test_and_clear(u32 cid, struct scx_cmask __a return prev; } +/* atomically or @mask into *@w */ +static __always_inline void __cmask_word_or(u64 __arena *w, u64 mask) +{ + u64 old, new; + u32 i; + + if (scx_lib_has(SCX_LIB_FEAT_ARENA_FETCH_BITOPS)) { + __cmask_fetch_or(w, mask); + return; + } + bpf_arena_for(i, 0, CMASK_CAS_TRIES) { + old = *w; + if ((old & mask) == mask) + return; + new = old | mask; + if (__sync_val_compare_and_swap(w, old, new) == old) + return; + } + scx_bpf_error("__cmask_word_or CAS exhausted"); +} + +/* atomically clear @mask bits in *@w */ +static __always_inline void __cmask_word_andnot(u64 __arena *w, u64 mask) +{ + u64 old, new; + u32 i; + + if (scx_lib_has(SCX_LIB_FEAT_ARENA_FETCH_BITOPS)) { + __cmask_fetch_andnot(w, mask); + return; + } + bpf_arena_for(i, 0, CMASK_CAS_TRIES) { + old = *w; + if (!(old & mask)) + return; + new = old & ~mask; + if (__sync_val_compare_and_swap(w, old, new) == old) + return; + } + scx_bpf_error("__cmask_word_andnot CAS exhausted"); +} + +/** + * cmask_full_range - Test whether every cid in [@start, @start + @nr) is set + * @m: cmask to test + * @start: first cid of the range + * @nr: number of cids in the range + * + * The range is clamped to @m's active range first. True when no clamped bit is + * clear, including when the clamped range is empty. + */ +static __always_inline bool cmask_full_range(const struct scx_cmask __arena *m, u32 start, + u32 nr) +{ + u64 end = (u64)start + nr; + u32 wbase = m->base / 64; + u32 first_wi, last_wi, first_bit, last_bit, last, i; + + if (start < m->base) + start = m->base; + if (end > m->base + m->nr_cids) + end = m->base + m->nr_cids; + if (start >= end) + return true; + last = end - 1; + + first_wi = start / 64 - wbase; + last_wi = last / 64 - wbase; + first_bit = start & 63; + last_bit = last & 63; + + bpf_arena_for(i, 0, CMASK_MAX_WORDS) { + u32 wi = first_wi + i; + u64 mask = ~0ULL; + + if (wi > last_wi) + break; + if (wi == first_wi) + mask &= GENMASK_U64(63, first_bit); + if (wi == last_wi) + mask &= GENMASK_U64(last_bit, 0); + if ((m->bits[wi] & mask) != mask) + return false; + } + return true; +} + +/** + * cmask_set_range - Set every cid in [@start, @start + @nr) + * @m: cmask to modify + * @start: first cid of the range + * @nr: number of cids in the range + * + * The range is clamped to @m's active range first. Words are updated atomically + * so concurrent updates of other bits sharing a word are never lost. The range + * as a whole does not transition atomically. + */ +static __always_inline void cmask_set_range(struct scx_cmask __arena *m, u32 start, u32 nr) +{ + u64 end = (u64)start + nr; + u32 wbase = m->base / 64; + u32 first_wi, last_wi, first_bit, last_bit, last, i; + + if (start < m->base) + start = m->base; + if (end > m->base + m->nr_cids) + end = m->base + m->nr_cids; + if (start >= end) + return; + last = end - 1; + + first_wi = start / 64 - wbase; + last_wi = last / 64 - wbase; + first_bit = start & 63; + last_bit = last & 63; + + bpf_arena_for(i, 0, CMASK_MAX_WORDS) { + u32 wi = first_wi + i; + u64 mask = ~0ULL; + + if (wi > last_wi) + break; + if (wi == first_wi) + mask &= GENMASK_U64(63, first_bit); + if (wi == last_wi) + mask &= GENMASK_U64(last_bit, 0); + __cmask_word_or(&m->bits[wi], mask); + } +} + +/** + * cmask_clear_range - Clear every cid in [@start, @start + @nr) + * @m: cmask to modify + * @start: first cid of the range + * @nr: number of cids in the range + * + * The range is clamped to @m's active range first. Words are updated atomically + * so concurrent updates of other bits sharing a word are never lost. The range + * as a whole does not transition atomically. + */ +static __always_inline void cmask_clear_range(struct scx_cmask __arena *m, u32 start, u32 nr) +{ + u64 end = (u64)start + nr; + u32 wbase = m->base / 64; + u32 first_wi, last_wi, first_bit, last_bit, last, i; + + if (start < m->base) + start = m->base; + if (end > m->base + m->nr_cids) + end = m->base + m->nr_cids; + if (start >= end) + return; + last = end - 1; + + first_wi = start / 64 - wbase; + last_wi = last / 64 - wbase; + first_bit = start & 63; + last_bit = last & 63; + + bpf_arena_for(i, 0, CMASK_MAX_WORDS) { + u32 wi = first_wi + i; + u64 mask = ~0ULL; + + if (wi > last_wi) + break; + if (wi == first_wi) + mask &= GENMASK_U64(63, first_bit); + if (wi == last_wi) + mask &= GENMASK_U64(last_bit, 0); + __cmask_word_andnot(&m->bits[wi], mask); + } +} + static __always_inline void cmask_zero(struct scx_cmask __arena *m) { u32 nr_words = CMASK_NR_WORDS(m->nr_cids), i; - bpf_for(i, 0, CMASK_MAX_WORDS) { + bpf_arena_for(i, 0, CMASK_MAX_WORDS) { if (i >= nr_words) break; m->bits[i] = 0; } } +/** + * cmask_fill - Set every cid in @m's active range + * @m: cmask to fill + * + * Counterpart to cmask_zero(). Storage past the active range is left as is, + * matching the kernel-side scx_cmask_fill(). + */ +static __always_inline void cmask_fill(struct scx_cmask __arena *m) +{ + u32 nr_words, head_bits, tail_bits, i; + + if (!m->nr_cids) + return; + nr_words = (m->base + m->nr_cids - 1) / 64 - m->base / 64 + 1; + + bpf_arena_for(i, 0, CMASK_MAX_WORDS) { + if (i >= nr_words) + break; + m->bits[i] = ~0LLU; + } + + /* clear word-0 bits below base */ + head_bits = m->base & 63; + if (head_bits) + m->bits[0] &= ~((1LLU << head_bits) - 1); + + /* clear last-word bits at or past base + nr_cids */ + tail_bits = (m->base + m->nr_cids) & 63; + if (tail_bits) + m->bits[nr_words - 1] &= (1LLU << tail_bits) - 1; +} + +/** + * cmask_empty - Test whether no cid is set in @m's active range + * @m: cmask to test + * + * Scans the words the active range spans, whose bits outside the range every + * mutator keeps zero. + */ +static __always_inline bool cmask_empty(const struct scx_cmask __arena *m) +{ + u32 nr_words = cmask_nr_words(m), i; + + bpf_arena_for(i, 0, CMASK_MAX_WORDS) { + if (i >= nr_words) + break; + if (m->bits[i]) + return false; + } + return true; +} + /* * BPF_-prefixed to avoid colliding with the kernel's anonymous CMASK_OP_* * enum in ext/cid.c, which is exported via BTF and reachable through @@ -291,92 +624,136 @@ enum { BPF_CMASK_OP_ANDNOT, }; -static __always_inline void cmask_op_word(struct scx_cmask __arena *dst, - const struct scx_cmask __arena *src, - u32 di, u32 si, u64 mask, int op) +/* range bits of word @k of @m, which spans @nr words: 0 past the span */ +static __always_inline u64 __cmask_word_range(const struct scx_cmask __arena *m, u32 k, + u32 nr) { - u64 dv = dst->bits[di]; - u64 sv = src->bits[si]; - u64 rv; + u64 bits = ~0ULL; - if (op == BPF_CMASK_OP_AND) - rv = dv & sv; - else if (op == BPF_CMASK_OP_OR) - rv = dv | sv; - else if (op == BPF_CMASK_OP_ANDNOT) - rv = dv & ~sv; - else - rv = sv; - - dst->bits[di] = (dv & ~mask) | (rv & mask); -} - -static __always_inline void cmask_op(struct scx_cmask __arena *dst, - const struct scx_cmask __arena *src, int op) -{ - u32 d_end = dst->base + dst->nr_cids; - u32 s_end = src->base + src->nr_cids; - u32 lo = dst->base > src->base ? dst->base : src->base; - u32 hi = d_end < s_end ? d_end : s_end; - u32 d_base = dst->base / 64; - u32 s_base = src->base / 64; - u32 lo_word, hi_word, i; - u64 head_mask, tail_mask; - - if (lo >= hi) - return; - - lo_word = lo / 64; - hi_word = (hi - 1) / 64; - head_mask = GENMASK_U64(63, lo & 63); - tail_mask = GENMASK_U64((hi - 1) & 63, 0); - - bpf_for(i, 0, CMASK_MAX_WORDS) { - u32 w = lo_word + i; - u64 m; - - if (w > hi_word) - break; - - m = GENMASK_U64(63, 0); - if (w == lo_word) - m &= head_mask; - if (w == hi_word) - m &= tail_mask; - - cmask_op_word(dst, src, w - d_base, w - s_base, m, op); - } + if (k >= nr) + return 0; + if (k == 0) + bits &= GENMASK_U64(63, m->base & 63); + if (k == nr - 1) + bits &= GENMASK_U64((m->base + m->nr_cids - 1) & 63, 0); + return bits; } /* - * cmask_and/or/copy only modify @dst bits that lie in the intersection of - * [@dst->base, @dst->base + @dst->nr_cids) and [@src->base, - * @src->base + @src->nr_cids). Bits in @dst outside that window - * keep their prior values - in particular, cmask_copy() does NOT zero @dst - * bits that lie outside @src's range. + * The binary operations combine cmasks of any active ranges. A cmask holds bits + * only for its own range and reads as the operation's identity outside it, all + * ones for AND and all zeros for OR, so an operand alters only the bits it + * covers: ANDing a shard's mask into a global one edits that shard's window and + * leaves the rest of the global mask alone. ANDNOT is AND with @src2 inverted + * over @src2's range, so where only @src2 has range the result is ~@src2. + * + * @dst is written on its range intersected with the union of the sources' + * ranges and untouched elsewhere, and its padding bits outside its own range + * stay zero, the invariant every cmask mutator keeps. @dst may alias either + * source, and the two sources may be one mask. Returns whether @dst has a bit + * set afterwards, over all of @dst's range. + * + * The operations are global functions, verified once per program. Inlined, + * every data-dependent branch in this loop would multiply the states the + * verifier explores per iteration at every call site. */ -static __always_inline void cmask_and(struct scx_cmask __arena *dst, - const struct scx_cmask __arena *src) +static __always_inline bool __cmask_op(struct scx_cmask __arena *dst, + const struct scx_cmask __arena *src1, + const struct scx_cmask __arena *src2, int op) { - cmask_op(dst, src, BPF_CMASK_OP_AND); + u32 d_first = dst->base / 64, d_nr = cmask_nr_words(dst); + u32 s1_first = src1->base / 64, s1_nr = cmask_nr_words(src1); + u32 s2_first = src2->base / 64, s2_nr = cmask_nr_words(src2); + u64 any = bpf_arena_loop_zero; + u32 i; + + bpf_arena_for(i, 0, d_nr) { + u32 k1 = d_first + i - s1_first, k2 = d_first + i - s2_first; + u64 m1 = __cmask_word_range(src1, k1, s1_nr); + u64 m2 = op == BPF_CMASK_OP_COPY ? m1 : __cmask_word_range(src2, k2, s2_nr); + u64 um = __cmask_word_range(dst, i, d_nr) & (m1 | m2); + u64 dv = dst->bits[i], v1, v2, rv; + + if (um) { + /* a word in range holds zeros outside the range */ + v1 = m1 ? src1->bits[k1] : 0; + v2 = m2 ? src2->bits[k2] : 0; + if (op == BPF_CMASK_OP_AND) + rv = (v1 | ~m1) & (v2 | ~m2); + else if (op == BPF_CMASK_OP_OR) + rv = v1 | v2; + else if (op == BPF_CMASK_OP_ANDNOT) + rv = (v1 | ~m1) & ~v2; + else + rv = v1; + dv = (dv & ~um) | (rv & um); + dst->bits[i] = dv; + } + any |= dv; + } + return any != 0; } -static __always_inline void cmask_or(struct scx_cmask __arena *dst, - const struct scx_cmask __arena *src) +/** + * cmask_and - Store @src1 AND @src2 in @dst + * @dst: destination, may be @src1 or @src2 + * @src1: first operand + * @src2: second operand + * + * See __cmask_op() for how the ranges combine. Return whether @dst has a bit + * set afterwards. + */ +__weak bool cmask_and(struct scx_cmask __arena __arg_arena *dst, + const struct scx_cmask __arena __arg_arena *src1, + const struct scx_cmask __arena __arg_arena *src2) { - cmask_op(dst, src, BPF_CMASK_OP_OR); + return __cmask_op(dst, src1, src2, BPF_CMASK_OP_AND); } -static __always_inline void cmask_copy(struct scx_cmask __arena *dst, - const struct scx_cmask __arena *src) +/** + * cmask_or - Store @src1 OR @src2 in @dst + * @dst: destination, may be @src1 or @src2 + * @src1: first operand + * @src2: second operand + * + * See __cmask_op() for how the ranges combine. Return whether @dst has a bit + * set afterwards. + */ +__weak bool cmask_or(struct scx_cmask __arena __arg_arena *dst, + const struct scx_cmask __arena __arg_arena *src1, + const struct scx_cmask __arena __arg_arena *src2) { - cmask_op(dst, src, BPF_CMASK_OP_COPY); + return __cmask_op(dst, src1, src2, BPF_CMASK_OP_OR); } -static __always_inline void cmask_andnot(struct scx_cmask __arena *dst, - const struct scx_cmask __arena *src) +/** + * cmask_andnot - Store @src1 AND NOT @src2 in @dst + * @dst: destination, may be @src1 or @src2 + * @src1: operand to remove bits from + * @src2: bits to remove, inverted over its own range + * + * See __cmask_op() for how the ranges combine. Return whether @dst has a bit + * set afterwards. + */ +__weak bool cmask_andnot(struct scx_cmask __arena __arg_arena *dst, + const struct scx_cmask __arena __arg_arena *src1, + const struct scx_cmask __arena __arg_arena *src2) { - cmask_op(dst, src, BPF_CMASK_OP_ANDNOT); + return __cmask_op(dst, src1, src2, BPF_CMASK_OP_ANDNOT); +} + +/** + * cmask_copy - Copy @src into @dst + * @dst: destination + * @src: source + * + * The single-source case of __cmask_op(): @dst is written over @src's range and + * untouched elsewhere. + */ +__weak void cmask_copy(struct scx_cmask __arena __arg_arena *dst, + const struct scx_cmask __arena __arg_arena *src) +{ + __cmask_op(dst, src, src, BPF_CMASK_OP_COPY); } /* @@ -395,7 +772,7 @@ static __always_inline bool cmask_equal(const struct scx_cmask __arena *a, return true; nr_words = (a->base + a->nr_cids - 1) / 64 - a->base / 64 + 1; - bpf_for(i, 0, CMASK_MAX_WORDS) { + bpf_arena_for(i, 0, CMASK_MAX_WORDS) { if (i >= nr_words) break; if (a->bits[i] != b->bits[i]) @@ -428,7 +805,7 @@ static __always_inline u32 cmask_next_set(const struct scx_cmask __arena *m, u32 start_wi = cid / 64 - base; start_bit = cid & 63; - bpf_for(i, 0, CMASK_MAX_WORDS) { + bpf_arena_for(i, 0, CMASK_MAX_WORDS) { u32 wi = start_wi + i; u64 word; u32 found; @@ -457,7 +834,7 @@ static __always_inline u32 cmask_first_set(const struct scx_cmask __arena *m) #define cmask_for_each(cid, m) \ for ((cid) = cmask_first_set(m); \ - (cid) < (m)->base + (m)->nr_cids; \ + (cid) < (m)->base + (m)->nr_cids && can_loop; \ (cid) = cmask_next_set((m), (cid) + 1)) /* @@ -495,7 +872,7 @@ static __always_inline bool cmask_subset(const struct scx_cmask __arena *a, lo_word = lo / 64; hi_word = (hi - 1) / 64; - bpf_for(i, 0, CMASK_MAX_WORDS) { + bpf_arena_for(i, 0, CMASK_MAX_WORDS) { u32 w = lo_word + i; if (w > hi_word) @@ -514,13 +891,14 @@ static __always_inline bool cmask_subset(const struct scx_cmask __arena *a, static __always_inline u32 cmask_weight(const struct scx_cmask __arena *m) { u32 nr_words, i; - u32 count = 0; + /* callers compare the sum, see bpf_arena_loop_zero */ + u32 count = bpf_arena_loop_zero; if (!m->nr_cids) return 0; nr_words = (m->base + m->nr_cids - 1) / 64 - m->base / 64 + 1; - bpf_for(i, 0, CMASK_MAX_WORDS) { + bpf_arena_for(i, 0, CMASK_MAX_WORDS) { if (i >= nr_words) break; count += __builtin_popcountll(m->bits[i]); @@ -528,10 +906,7 @@ static __always_inline u32 cmask_weight(const struct scx_cmask __arena *m) return count; } -/* - * True if @a and @b share any set bit. Walk only the intersection of their - * ranges, matching the semantics of cmask_and(). - */ +/* true if @a and @b share any set bit, over the intersection of their ranges */ static __always_inline bool cmask_intersects(const struct scx_cmask __arena *a, const struct scx_cmask __arena *b) { @@ -552,7 +927,7 @@ static __always_inline bool cmask_intersects(const struct scx_cmask __arena *a, head_mask = GENMASK_U64(63, lo & 63); tail_mask = GENMASK_U64((hi - 1) & 63, 0); - bpf_for(i, 0, CMASK_MAX_WORDS) { + bpf_arena_for(i, 0, CMASK_MAX_WORDS) { u32 w = lo_word + i; u64 mask, av, bv; @@ -603,7 +978,7 @@ static __always_inline u32 cmask_next_and_set(const struct scx_cmask __arena *a, start_wi = start / 64; start_bit = start & 63; - bpf_for(i, 0, CMASK_MAX_WORDS) { + bpf_arena_for(i, 0, CMASK_MAX_WORDS) { u32 abs_wi = start_wi + i; u64 word; u32 found; @@ -646,6 +1021,17 @@ static __always_inline u32 cmask_next_set_wrap(const struct scx_cmask __arena *m return found < start ? found : end; } +/** + * cmask_end - One past the last cid of @m's active range + * @m: cmask of interest + * + * The scan helpers return this value when no set cid is found. + */ +static __always_inline u32 cmask_end(const struct scx_cmask __arena *m) +{ + return m->base + m->nr_cids; +} + /* * Find the next cid set in both @a and @b at or after @start, wrapping to * @a->base if none found in the forward half. Return a->base + a->nr_cids @@ -669,6 +1055,121 @@ static __always_inline u32 cmask_next_and_set_wrap(const struct scx_cmask __aren } /* + * The distribute helpers rotate through one slot per cid, a cacheline each so + * picks on one CPU do not bounce the line of another. A missing allocation is a + * setup bug and aborts the scheduler. On a CPU outside the scheduler's cid + * space the helpers fall back to the first matching cid. + * + * TODO: The slots are one allocation without node placement. Move them to a + * per-cid arena allocator once the library has one, for node-local slots + * without the cacheline padding. + */ +struct cmask_rotor_slot { + u32 cid; +} __attribute__((aligned(SCX_CACHELINE_SIZE))); + +struct cmask_rotor_slot __arena *cmask_distribute_rotors __weak; + +/** + * cmask_distribute_init - Allocate the distribute rotor from @map + * @map: the scheduler's arena map + * + * The shared arena init calls this once. A scheduler with its own arena calls + * it before the first distribute pick. On a kernel without the cid kfuncs + * nothing can pick, so the call allocates nothing and succeeds. Return 0 on + * success, -ENOMEM if the allocation fails. + */ +static __always_inline int cmask_distribute_init(void *map) +{ + u64 size; + u32 pages; + + /* no cid kfuncs means no picks and nothing to allocate */ + if (!bpf_ksym_exists(scx_bpf_nr_cids)) + return 0; + + size = scx_bpf_nr_cids() * sizeof(*cmask_distribute_rotors); + pages = (size + PAGE_SIZE - 1) / PAGE_SIZE; + cmask_distribute_rotors = bpf_arena_alloc_pages(map, NULL, pages, NUMA_NO_NODE, 0); + return cmask_distribute_rotors ? 0 : -ENOMEM; +} + +static __always_inline u32 __arena *__cmask_distribute_rotor(void) +{ + s32 cid = scx_bpf_this_cid(); + + if (unlikely(!cmask_distribute_rotors)) { + scx_bpf_error("cmask distribute rotor not allocated"); + return NULL; + } + if (cid < 0) + return NULL; + return &cmask_distribute_rotors[cid].cid; +} + +/** + * cmask_any_distribute - Pick a set cid, spreading successive picks + * @m: cmask to pick from + * + * Counterpart of bpf_cpumask_any_distribute(): a per-cid rotor makes successive + * picks rotate through the set cids instead of repeating the first one. Returns + * cmask_end(@m) if @m is empty. + */ +static __always_inline u32 cmask_any_distribute(const struct scx_cmask __arena *m) +{ + u32 __arena *rotor = __cmask_distribute_rotor(); + u32 pick; + + if (unlikely(!rotor)) + return cmask_first_set(m); + + pick = cmask_next_set_wrap(m, *rotor + 1); + if (pick < cmask_end(m)) + *rotor = pick; + return pick; +} + +/** + * cmask_any_and_distribute - Pick a cid set in both masks, spreading picks + * @a: first cmask, the scan is bounded by its range + * @b: second cmask + * + * Counterpart of bpf_cpumask_any_and_distribute(). Shares the rotor with + * cmask_any_distribute() the same way the kernel counterparts share theirs. + * Returns cmask_end(@a) if the intersection is empty. + */ +static __always_inline u32 cmask_any_and_distribute(const struct scx_cmask __arena *a, + const struct scx_cmask __arena *b) +{ + u32 __arena *rotor = __cmask_distribute_rotor(); + u32 pick; + + if (unlikely(!rotor)) + return cmask_next_and_set(a, b, a->base); + + pick = cmask_next_and_set_wrap(a, b, *rotor + 1); + if (pick < cmask_end(a)) + *rotor = pick; + return pick; +} + +/** + * cmask_distribute_rotor_pos - Last cid picked by the distribute helpers + * + * For callers that anchor scans of their own on the shared rotor. Returns 0 + * when nothing has been picked on this cid yet or the CPU is outside the cid + * space. + */ +static __always_inline u32 cmask_distribute_rotor_pos(void) +{ + u32 __arena *rotor = __cmask_distribute_rotor(); + + if (unlikely(!rotor)) + return 0; + return *rotor; +} + +/* * Like cmask_next_and_set() but over the intersection of THREE masks. Return * a->base + a->nr_cids if no cid is set in all three at or after @start. */ @@ -701,7 +1202,7 @@ static __always_inline u32 cmask_next_and2_set(const struct scx_cmask __arena *a start_wi = start / 64; start_bit = start & 63; - bpf_for(i, 0, CMASK_MAX_WORDS) { + bpf_arena_for(i, 0, CMASK_MAX_WORDS) { u32 abs_wi = start_wi + i; u64 word; u32 found; @@ -763,7 +1264,7 @@ static __always_inline void cmask_from_cpumask(struct scx_cmask __arena *m, s32 cpu; cmask_zero(m); - bpf_for(cpu, 0, nr_cpu_ids) { + bpf_arena_for(cpu, 0, nr_cpu_ids) { s32 cid; if (!bpf_cpumask_test_cpu(cpu, cpumask))
diff --git a/tools/sched_ext/include/scx/common.bpf.h b/tools/sched_ext/include/scx/common.bpf.h index 22f24eb..9376d57 100644 --- a/tools/sched_ext/include/scx/common.bpf.h +++ b/tools/sched_ext/include/scx/common.bpf.h
@@ -27,6 +27,7 @@ #include "user_exit_info.bpf.h" #include "enum_defs.autogen.h" #include "bpf_arena_common.bpf.h" +#include "const-defs.h" #define PF_IDLE 0x00000002 /* I am an IDLE thread */ #define PF_IO_WORKER 0x00000010 /* Task is an IO worker */ @@ -74,6 +75,7 @@ struct task_struct *scx_bpf_dsq_peek(u64 dsq_id) __ksym __weak; int bpf_iter_scx_dsq_new(struct bpf_iter_scx_dsq *it, u64 dsq_id, u64 flags) __ksym __weak; struct task_struct *bpf_iter_scx_dsq_next(struct bpf_iter_scx_dsq *it) __ksym __weak; void bpf_iter_scx_dsq_destroy(struct bpf_iter_scx_dsq *it) __ksym __weak; +bool scx_bpf_dsq_reenq_task(struct bpf_iter_scx_dsq *it, struct task_struct *p) __ksym __weak; void scx_bpf_exit_bstr(s64 exit_code, char *fmt, unsigned long long *data, u32 data__sz) __ksym __weak; void scx_bpf_error_bstr(char *fmt, unsigned long long *data, u32 data_len) __ksym; void scx_bpf_dump_bstr(char *fmt, unsigned long long *data, u32 data_len) __ksym __weak; @@ -104,10 +106,11 @@ struct task_struct *scx_bpf_cpu_curr(s32 cpu) __ksym __weak; struct task_struct *scx_bpf_tid_to_task(u64 tid) __ksym __weak; u64 scx_bpf_now(void) __ksym __weak; void scx_bpf_events(struct scx_event_stats *events, size_t events__sz) __ksym __weak; +u32 scx_bpf_cgroup_nr_cpus(struct cgroup *cgrp) __ksym __weak; s32 scx_bpf_cpu_to_cid(s32 cpu) __ksym __weak; s32 scx_bpf_cid_to_cpu(s32 cid) __ksym __weak; -void scx_bpf_cid_topo(s32 cid, struct scx_cid_topo *out, size_t out__sz) __ksym __weak; -void scx_bpf_kick_cid(s32 cid, u64 flags) __ksym __weak; +s32 scx_bpf_cid_node(s32 cid) __ksym __weak; +/* scx_bpf_cid_topo() and scx_bpf_kick_cid() are declared in compat.bpf.h */ s32 scx_bpf_task_cid(const struct task_struct *p) __ksym __weak; s32 scx_bpf_this_cid(void) __ksym __weak; struct task_struct *scx_bpf_cid_curr(s32 cid) __ksym __weak; @@ -116,7 +119,7 @@ u32 scx_bpf_nr_online_cids(void) __ksym __weak; const void __arena *scx_bpf_online_cmask(void) __ksym __weak; u32 scx_bpf_cidperf_cap(s32 cid) __ksym __weak; u32 scx_bpf_cidperf_cur(s32 cid) __ksym __weak; -s32 scx_bpf_cidperf_set(s32 cid, u32 perf) __ksym __weak; +/* scx_bpf_cidperf_set() is declared in compat.bpf.h */ /* sub-scheduler cap control, scx_bpf_sub_caps() cgroup_id 0 == self */ s32 scx_bpf_sub_grant(u64 cgroup_id, u64 caps, const struct scx_cmask __arena *cmask__arena, struct scx_cmask __arena *denied_out__arena__nullable) __ksym __weak; @@ -307,7 +310,7 @@ BPF_PROG(name, ##args) * Similar to MEMBER_VPTR() but is intended for use with arrays where the * element count needs to be explicit. * It can be used in cases where a global array is defined with an initial - * size but is intended to be be resized before loading the BPF program. + * size but is intended to be resized before loading the BPF program. * Without this version of the macro, MEMBER_VPTR() will use the compile time * size of the array to compute the max, which will result in rejection by * the verifier. @@ -533,14 +536,14 @@ static __always_inline const struct cpumask *cast_mask(struct bpf_cpumask *mask) /* * True if the non-sleepable BPF trampoline prolog (__bpf_prog_enter) calls * migrate_disable() for the current task. Recorded once by - * scx_lib_init_probe, an fentry program on bpf_scx_reg() that fires during - * the natural scheduler-attach call chain (auto-attached by scx_ops_attach!). + * scx_lib_init_probe, an fentry program that fires during the natural + * scheduler-attach call chain (auto-attached by scx_ops_attach!). * - * Defaults to true (conservative). Over-reporting in is_migration_disabled() + * Defaults to false (conservative). Over-reporting in is_migration_disabled() * causes local-only dispatch, which is safe. Under-reporting can crash the * scheduler, so we err high if the probe somehow fails to run. */ -bool __scx_prolog_disables_migration __weak = true; +bool __scx_prolog_disables_migration __weak = false; /* * scx_lib_init_probe - non-sleepable prolog probe. @@ -551,13 +554,20 @@ bool __scx_prolog_disables_migration __weak = true; * ops.init() fires. Its address is taken in the vtable, so the symbol * is non-inlinable and has been stable since introduction. * + * A cid-form scheduler registers through bpf_scx_reg_cid(), the .reg + * callback of bpf_sched_ext_ops_cid, and so never enters bpf_scx_reg(). + * The cid-form open paths (SCX_OPS_CID_OPEN(), scx_ops_cid_open!()) + * therefore repoint this program at bpf_scx_reg_cid(). Repointing rather + * than adding a second program keeps the object loadable on kernels + * predating the cid form, where bpf_scx_reg_cid() has no BTF entry. + * * Entering via fentry runs us through __bpf_prog_enter -- the * non-sleepable prolog that consumers of is_migration_disabled() live * under. * * Loud warning: the prolog adds at most 1 to migration_disabled. * Reading > 1 means something upstream in the - * bpf_struct_ops_link_create -> bpf_scx_reg path disabled migration + * bpf_struct_ops_link_create -> .reg path disabled migration * before the prolog ran, invalidating the probe; audit and adjust. */ SEC("fentry/bpf_scx_reg") __weak @@ -1185,8 +1195,75 @@ static inline u64 scx_clock_irq(u32 cpu) #define struct_size_t(type, member, count) \ struct_size((type *)NULL, member, count) +/* + * <linux/stddef.h>'s TRAILING_OVERLAP(): embed a struct that ends in a flexible + * array member together with its storage. @NAME is a complete @TYPE and the + * @MEMBERS declared after the array reserve the space the array grows into. + * Unlike the kernel's, the padding is named after @NAME so that one struct can + * embed several, and it is sized with __builtin_offsetof() because + * bpf_helpers.h redefines offsetof() as a pointer cast, which is not a constant + * expression. + */ +#define __TRAILING_OVERLAP(TYPE, NAME, FAM, ATTRS, MEMBERS) \ + union { \ + TYPE NAME; \ + struct { \ + unsigned char __offset_to_##NAME[__builtin_offsetof(TYPE, FAM)]; \ + MEMBERS \ + } ATTRS; \ + } + +#define TRAILING_OVERLAP(TYPE, NAME, FAM, MEMBERS) \ + __TRAILING_OVERLAP(TYPE, NAME, FAM, /* no attrs */, MEMBERS) + +/* + * Loop counters the verifier cannot see through. + * + * A may_goto loop converges when the state at its head is within the state + * of a previous iteration. A counter tracked as a precise constant prevents + * that convergence: every iteration creates a new state, and the verifier + * unrolls the loop until it runs out of budget whenever the counter feeds an + * operation that requires precision. + * + * Loading a writable global gives the verifier an unknown scalar while its + * runtime value remains one. Using it as the step makes the counter unknown + * after the first iteration, and the load on every increment keeps the loop + * body from making it precise again. volatile is required to keep the compiler + * from hoisting or eliminating the loads, and the value must remain non-const + * so the verifier cannot resolve it. The variable is weak so the objects linked + * into a scheduler share one copy. Its runtime value must never be changed from + * one. + * + * bpf_for() avoids this verifier behavior too, but calls bpf_iter_num_next() + * on every iteration. bpf_arena_for() is intended for hot scheduler walks + * where that cost matters. @var must be no wider than u32, and @start and + * @end must be representable as u32. + */ +volatile u32 bpf_arena_loop_one __weak = 1; + +/* + * A loop-carried accumulator that a caller later compares is kept precise, and + * a precise scalar whose range grows every iteration keeps a may_goto loop from + * converging. Initializing it from this zero makes it unknown from the first + * iteration, so every pass through the loop head looks the same. + */ +volatile u32 bpf_arena_loop_zero __weak = 0; + +#define __bpf_arena_loop_start(var, start) \ + ({ \ + _Static_assert(sizeof(var) <= sizeof(u32), \ + "bpf_arena_for() index must fit in u32"); \ + (start); \ + }) + +#define bpf_arena_for(var, start, end) \ + for (var = __bpf_arena_loop_start(var, start); \ + var < (end) && can_loop; \ + var += bpf_arena_loop_one) + #include "compat.bpf.h" #include "enums.bpf.h" +#include "features.bpf.h" #include "cid.bpf.h" #endif /* __SCX_COMMON_BPF_H */
diff --git a/tools/sched_ext/include/scx/compat.bpf.h b/tools/sched_ext/include/scx/compat.bpf.h index 6944221..254882b 100644 --- a/tools/sched_ext/include/scx/compat.bpf.h +++ b/tools/sched_ext/include/scx/compat.bpf.h
@@ -143,6 +143,69 @@ static inline void scx_bpf_cid_override(const s32 __arena *cpu_to_cid, u32 cpu_t shard_start, shard_start_cnt); } +/* + * v7.3: b38332be61a8 ("sched_ext: Make scx_bpf_kick_cid() return void") flipped + * the return type from s32 to void without renaming the kfunc, so the v7.2 and + * v7.3 kfuncs share a name but have incompatible prototypes. libbpf leaves a + * weak kfunc unresolved when the prototype doesn't match, so declare both + * flavors: the ___vN suffix is stripped on the BPF side, both resolve against + * the same kernel symbol and only the matching one gets bound. Drop the + * wrapper and move the decl back to common.bpf.h after v7.6. + */ +void scx_bpf_kick_cid___v2(s32 cid, u64 flags) __ksym __weak; +s32 scx_bpf_kick_cid___v1(s32 cid, u64 flags) __ksym __weak; + +static inline void scx_bpf_kick_cid(s32 cid, u64 flags) +{ + if (bpf_ksym_exists(scx_bpf_kick_cid___v2)) + scx_bpf_kick_cid___v2(cid, flags); + else if (bpf_ksym_exists(scx_bpf_kick_cid___v1)) + scx_bpf_kick_cid___v1(cid, flags); +} + +/* + * v7.3: 94480606a677 ("sched_ext: Add a size argument to scx_bpf_cid_topo() so + * struct scx_cid_topo can grow") added out__sz without renaming the kfunc, so + * the v7.2 and v7.3 kfuncs share a name with incompatible prototypes. Same + * two-flavor trick as scx_bpf_kick_cid() above. The size is always the output + * buffer's, so a macro supplies it and callers keep the two-argument form. + * Drop the wrapper and move the decl back to common.bpf.h after v7.6. + */ +void scx_bpf_cid_topo___v2(s32 cid, struct scx_cid_topo *out, size_t out__sz) __ksym __weak; +void scx_bpf_cid_topo___v1(s32 cid, struct scx_cid_topo *out) __ksym __weak; + +static inline void __scx_bpf_cid_topo(s32 cid, struct scx_cid_topo *out, size_t out__sz) +{ + if (bpf_ksym_exists(scx_bpf_cid_topo___v2)) + scx_bpf_cid_topo___v2(cid, out, out__sz); + else if (bpf_ksym_exists(scx_bpf_cid_topo___v1)) + scx_bpf_cid_topo___v1(cid, out); +} + +#define scx_bpf_cid_topo(cid, out) __scx_bpf_cid_topo((cid), (out), sizeof(*(out))) + +/* + * v7.3: 3a21e34eb258 ("sched_ext: Gate scx_bpf_cidperf_set() behind a new + * SCX_CAP_PERF") flipped the return type the other way, from void to s32, again + * without renaming the kfunc. Same two-flavor trick as scx_bpf_kick_cid() + * above; the v7.2 kfunc can't fail, so report success for it. Drop the wrapper + * and move the decl back to common.bpf.h after v7.6. + */ +s32 scx_bpf_cidperf_set___v2(s32 cid, u32 perf) __ksym __weak; +void scx_bpf_cidperf_set___v1(s32 cid, u32 perf) __ksym __weak; + +static inline s32 scx_bpf_cidperf_set(s32 cid, u32 perf) +{ + if (bpf_ksym_exists(scx_bpf_cidperf_set___v2)) { + return scx_bpf_cidperf_set___v2(cid, perf); + } else if (bpf_ksym_exists(scx_bpf_cidperf_set___v1)) { + scx_bpf_cidperf_set___v1(cid, perf); + return 0; + } else { + return -EOPNOTSUPP; + } +} + /** * __COMPAT_is_enq_cpu_selected - Test if SCX_ENQ_CPU_SELECTED is on * in a compatible way. We will preserve this __COMPAT helper until v6.16. @@ -243,6 +306,18 @@ static inline bool __COMPAT_is_enq_cpu_selected(u64 enq_flags) scx_bpf_pick_any_cpu_node(cpus_allowed, node, flags) : \ scx_bpf_pick_any_cpu(cpus_allowed, flags)) +/* v7.4: Add scx_bpf_cid_node(). */ +#define __COMPAT_scx_bpf_cid_node(cid) \ + (bpf_ksym_exists(scx_bpf_cid_node) ? \ + scx_bpf_cid_node(cid) : NUMA_NO_NODE) + +/* + * v7.4: Add scx_bpf_cgroup_nr_cpus(). + */ +#define __COMPAT_scx_bpf_cgroup_nr_cpus(cgrp) \ + (bpf_ksym_exists(scx_bpf_cgroup_nr_cpus) ? \ + scx_bpf_cgroup_nr_cpus(cgrp) : scx_bpf_nr_cpu_ids()) + /* * v6.18: Add a helper to retrieve the current task running on a CPU. * @@ -403,6 +478,15 @@ static inline void scx_bpf_task_set_dsq_vtime(struct task_struct *p, u64 vtime) p->scx.dsq_vtime = vtime; } +/* v7.4: Add scx_bpf_task_set_lazy_resched(). */ +bool scx_bpf_task_set_lazy_resched___new(struct task_struct *p, bool lazy) __ksym __weak; + +static inline void scx_bpf_task_set_lazy_resched(struct task_struct *p, bool lazy) +{ + if (bpf_ksym_exists(scx_bpf_task_set_lazy_resched___new)) + scx_bpf_task_set_lazy_resched___new(p, lazy); +} + /* * v7.1: New scx_bpf_dsq_reenq() that allows re-enqueues on more DSQs. This * will eventually deprecate scx_bpf_reenqueue_local(). @@ -414,6 +498,12 @@ static inline bool __COMPAT_has_generic_reenq(void) return bpf_ksym_exists(scx_bpf_dsq_reenq___compat); } +/* v7.4: Add scx_bpf_dsq_reenq_task(). */ +static inline bool __COMPAT_has_dsq_reenq_task(void) +{ + return bpf_ksym_exists(scx_bpf_dsq_reenq_task); +} + /* * v6.19: The new void variant can be called from anywhere while the older v1 * variant can only be called from ops.cpu_release(). The double ___ prefixes on
diff --git a/tools/sched_ext/include/scx/compat.h b/tools/sched_ext/include/scx/compat.h index 7c12df4..07fb55e 100644 --- a/tools/sched_ext/include/scx/compat.h +++ b/tools/sched_ext/include/scx/compat.h
@@ -214,6 +214,7 @@ static inline bool __COMPAT_struct_has_field(const char *type, const char *field #define SCX_OPS_ALLOW_QUEUED_WAKEUP SCX_OPS_FLAG(SCX_OPS_ALLOW_QUEUED_WAKEUP) #define SCX_OPS_BUILTIN_IDLE_PER_NODE SCX_OPS_FLAG(SCX_OPS_BUILTIN_IDLE_PER_NODE) #define SCX_OPS_ALWAYS_ENQ_IMMED SCX_OPS_FLAG(SCX_OPS_ALWAYS_ENQ_IMMED) +#define SCX_OPS_ENQ_BLOCKED SCX_OPS_FLAG(SCX_OPS_ENQ_BLOCKED) #define SCX_PICK_IDLE_FLAG(name) __COMPAT_ENUM_OR_ZERO("scx_pick_idle_cpu_flags", #name) @@ -274,23 +275,23 @@ static inline long scx_hotplug_seq(void) * - v7.1: ops.sub_attach(), ops.sub_detach(), ops.sub_cgroup_id * - v7.3: ops.rescue_bandwidth_ppt, ops.rescue_quantum_us */ -#define __SCX_OPS_OPEN(__ops_name, __scx_name, __ops_struct) ({ \ +#define __SCX_OPS_OPEN(__ops_name, __scx_name, __ops_struct, __opts) ({ \ struct __scx_name *__oskel; \ \ SCX_BUG_ON(!__COMPAT_struct_has_field(__ops_struct, "dump"), \ __ops_struct ".dump() missing, kernel too old?"); \ \ - __oskel = __scx_name##__open(); \ + __oskel = __scx_name##__open_opts(__opts); \ SCX_BUG_ON(!__oskel, "Could not open " #__scx_name); \ __oskel->struct_ops.__ops_name->hotplug_seq = scx_hotplug_seq(); \ SCX_ENUM_INIT(__oskel); \ __oskel; \ }) -#define SCX_OPS_OPEN(__ops_name, __scx_name) ({ \ +#define SCX_OPS_OPEN_OPTS(__ops_name, __scx_name, __opts) ({ \ struct __scx_name *__skel; \ \ - __skel = __SCX_OPS_OPEN(__ops_name, __scx_name, "sched_ext_ops"); \ + __skel = __SCX_OPS_OPEN(__ops_name, __scx_name, "sched_ext_ops", __opts); \ if (__skel->struct_ops.__ops_name->cgroup_set_bandwidth && \ !__COMPAT_struct_has_field("sched_ext_ops", "cgroup_set_bandwidth")) { \ fprintf(stderr, "WARNING: kernel doesn't support ops.cgroup_set_bandwidth()\n"); \ @@ -329,12 +330,29 @@ static inline long scx_hotplug_seq(void) __skel; \ }) +#define SCX_OPS_OPEN(__ops_name, __scx_name) \ + SCX_OPS_OPEN_OPTS(__ops_name, __scx_name, 0) + /* * Open a cid-form (struct sched_ext_ops_cid) skeleton. The cid form postdates * every op the load-time fix-ups above handle, so none of them apply. + * + * A cid-form scheduler registers through bpf_scx_reg_cid() rather than + * bpf_scx_reg(), so repoint common.bpf.h's prolog probe at it. Both the cid + * form and bpf_scx_reg_cid() appeared in v7.2, so a kernel that accepts this + * skeleton always has the symbol. */ +#define SCX_OPS_CID_OPEN_OPTS(__ops_name, __scx_name, __opts) ({ \ + struct __scx_name *__cskel; \ + \ + __cskel = __SCX_OPS_OPEN(__ops_name, __scx_name, "sched_ext_ops_cid", __opts); \ + bpf_program__set_attach_target(__cskel->progs.scx_lib_init_probe, 0, \ + "bpf_scx_reg_cid"); \ + __cskel; \ +}) + #define SCX_OPS_CID_OPEN(__ops_name, __scx_name) \ - __SCX_OPS_OPEN(__ops_name, __scx_name, "sched_ext_ops_cid") + SCX_OPS_CID_OPEN_OPTS(__ops_name, __scx_name, 0) /* * Associate non-struct_ops BPF programs with the scheduler's struct_ops map so
diff --git a/tools/sched_ext/include/scx/const-defs.h b/tools/sched_ext/include/scx/const-defs.h new file mode 100644 index 0000000..4c8f457 --- /dev/null +++ b/tools/sched_ext/include/scx/const-defs.h
@@ -0,0 +1,20 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2026 Tejun Heo <tj@kernel.org> */ +#pragma once + +/* + * Constants shared across the BPF headers, the lib and the schedulers. + * Freestanding so that scheduler interface headers consumed by bindgen can + * include it. Rust code cannot, so rust/scx_arena/scx_arena/src/lib.rs mirrors + * the values. Keep them in sync. + */ +enum scx_const_defs { + /* mirrors the kernel's per-arch L1_CACHE_SHIFT */ +#if defined(__TARGET_ARCH_s390) || defined(__s390x__) + SCX_CACHELINE_SIZE = 256, +#elif defined(__TARGET_ARCH_powerpc) || defined(__powerpc64__) + SCX_CACHELINE_SIZE = 128, +#else + SCX_CACHELINE_SIZE = 64, +#endif +};
diff --git a/tools/sched_ext/include/scx/enum_defs.autogen.h b/tools/sched_ext/include/scx/enum_defs.autogen.h index 63b6b14..4fa8203 100644 --- a/tools/sched_ext/include/scx/enum_defs.autogen.h +++ b/tools/sched_ext/include/scx/enum_defs.autogen.h
@@ -85,10 +85,12 @@ #define HAVE_SCX_ENQ_HEAD #define HAVE_SCX_ENQ_CPU_SELECTED #define HAVE_SCX_ENQ_PREEMPT +#define HAVE_SCX_ENQ_PREEMPT_LAZY #define HAVE_SCX_ENQ_IMMED #define HAVE_SCX_ENQ_RESCUE #define HAVE_SCX_ENQ_REENQ #define HAVE_SCX_ENQ_LAST +#define HAVE_SCX_ENQ_BLOCKED #define HAVE___SCX_ENQ_INTERNAL_MASK #define HAVE_SCX_ENQ_CLEAR_OPSS #define HAVE_SCX_ENQ_DSQ_PRIQ @@ -105,6 +107,7 @@ #define HAVE_SCX_TASK_SUB_INIT #define HAVE_SCX_TASK_IMMED #define HAVE_SCX_TASK_PROTECTED +#define HAVE_SCX_TASK_RUN_TRACKED #define HAVE_SCX_TASK_STATE_SHIFT #define HAVE_SCX_TASK_STATE_BITS #define HAVE_SCX_TASK_STATE_MASK @@ -122,6 +125,7 @@ #define HAVE_SCX_TASK_REENQ_IMMED #define HAVE_SCX_TASK_REENQ_PREEMPTED #define HAVE_SCX_TASK_REENQ_CAP +#define HAVE_SCX_TASK_REENQ_PROXY #define HAVE_SCX_TASK_CURSOR #define HAVE_SCX_ECODE_RSN_HOTPLUG #define HAVE_SCX_ECODE_RSN_CGROUP_OFFLINE @@ -149,6 +153,8 @@ #define HAVE_SCX_KICK_IDLE #define HAVE_SCX_KICK_PREEMPT #define HAVE_SCX_KICK_WAIT +#define HAVE_SCX_KICK_PREEMPT_LAZY +#define HAVE_SCX_KICK_ALL_FLAGS #define HAVE_SCX_OPI_BEGIN #define HAVE_SCX_OPI_NORMAL_BEGIN #define HAVE_SCX_OPI_NORMAL_END @@ -164,6 +170,8 @@ #define HAVE_SCX_OPS_BUILTIN_IDLE_PER_NODE #define HAVE_SCX_OPS_ALWAYS_ENQ_IMMED #define HAVE_SCX_OPS_TID_TO_TASK +#define HAVE_SCX_OPS_LAZY_RESCHED +#define HAVE_SCX_OPS_ENQ_BLOCKED #define HAVE_SCX_OPS_ALL_FLAGS #define HAVE___SCX_OPS_INTERNAL_MASK #define HAVE_SCX_OPS_HAS_CPU_PREEMPT @@ -191,6 +199,8 @@ #define HAVE_SCX_RQ_BAL_CB_PENDING #define HAVE_SCX_RQ_SUB_IDLE_RENOTIFY #define HAVE_SCX_RQ_ROOT_IDLE_RENOTIFY +#define HAVE_SCX_RQ_PROXY_RETRY +#define HAVE_SCX_RQ_PROXY_TICK #define HAVE_SCX_RQ_IN_WAKEUP #define HAVE_SCX_RQ_IN_DISPATCH #define HAVE_SCX_SCHED_PCPU_BYPASSING
diff --git a/tools/sched_ext/include/scx/enums.autogen.bpf.h b/tools/sched_ext/include/scx/enums.autogen.bpf.h index 7268131..405a3e6 100644 --- a/tools/sched_ext/include/scx/enums.autogen.bpf.h +++ b/tools/sched_ext/include/scx/enums.autogen.bpf.h
@@ -1,9 +1,9 @@ /* - * WARNING: This file is autogenerated from scripts/gen_enums.py. If you would - * like to access an enum that is currently missing, add it to the script - * and run it from the root directory to update this file. + * Definitions for SCX constants. Keep this table in sync + * with rust/scx_utils/src/enums.rs. */ + const volatile u64 __SCX_OPS_NAME_LEN __weak; #define SCX_OPS_NAME_LEN __SCX_OPS_NAME_LEN @@ -22,6 +22,9 @@ const volatile u64 __SCX_RQ_CAN_STOP_TICK __weak; const volatile u64 __SCX_RQ_BAL_PENDING __weak; #define SCX_RQ_BAL_PENDING __SCX_RQ_BAL_PENDING +const volatile u64 __SCX_RQ_BAL_KEEP __weak; +#define SCX_RQ_BAL_KEEP __SCX_RQ_BAL_KEEP + const volatile u64 __SCX_RQ_BYPASSING __weak; #define SCX_RQ_BYPASSING __SCX_RQ_BYPASSING @@ -112,6 +115,12 @@ const volatile u64 __SCX_KICK_PREEMPT __weak; const volatile u64 __SCX_KICK_WAIT __weak; #define SCX_KICK_WAIT __SCX_KICK_WAIT +const volatile u64 __SCX_KICK_PREEMPT_LAZY __weak; +#define SCX_KICK_PREEMPT_LAZY __SCX_KICK_PREEMPT_LAZY + +const volatile u64 __SCX_KICK_ALL_FLAGS __weak; +#define SCX_KICK_ALL_FLAGS __SCX_KICK_ALL_FLAGS + const volatile u64 __SCX_ENQ_WAKEUP __weak; #define SCX_ENQ_WAKEUP __SCX_ENQ_WAKEUP @@ -121,12 +130,18 @@ const volatile u64 __SCX_ENQ_HEAD __weak; const volatile u64 __SCX_ENQ_PREEMPT __weak; #define SCX_ENQ_PREEMPT __SCX_ENQ_PREEMPT +const volatile u64 __SCX_ENQ_PREEMPT_LAZY __weak; +#define SCX_ENQ_PREEMPT_LAZY __SCX_ENQ_PREEMPT_LAZY + const volatile u64 __SCX_ENQ_IMMED __weak; #define SCX_ENQ_IMMED __SCX_ENQ_IMMED const volatile u64 __SCX_ENQ_RESCUE __weak; #define SCX_ENQ_RESCUE __SCX_ENQ_RESCUE +const volatile u64 __SCX_ENQ_BLOCKED __weak; +#define SCX_ENQ_BLOCKED __SCX_ENQ_BLOCKED + const volatile u64 __SCX_ENQ_REENQ __weak; #define SCX_ENQ_REENQ __SCX_ENQ_REENQ
diff --git a/tools/sched_ext/include/scx/enums.autogen.h b/tools/sched_ext/include/scx/enums.autogen.h index e616326..7ec2e5e 100644 --- a/tools/sched_ext/include/scx/enums.autogen.h +++ b/tools/sched_ext/include/scx/enums.autogen.h
@@ -1,7 +1,8 @@ +#pragma once + /* - * WARNING: This file is autogenerated from scripts/gen_enums.py. If you would - * like to access an enum that is currently missing, add it to the script - * and run it from the root directory to update this file. + * BTF enum lookups for SCX constants. Keep this table in sync + * with rust/scx_utils/src/enums.rs. */ #define SCX_ENUM_INIT(skel) do { \ @@ -11,6 +12,7 @@ SCX_ENUM_SET(skel, scx_rq_flags, SCX_RQ_ONLINE); \ SCX_ENUM_SET(skel, scx_rq_flags, SCX_RQ_CAN_STOP_TICK); \ SCX_ENUM_SET(skel, scx_rq_flags, SCX_RQ_BAL_PENDING); \ + SCX_ENUM_SET(skel, scx_rq_flags, SCX_RQ_BAL_KEEP); \ SCX_ENUM_SET(skel, scx_rq_flags, SCX_RQ_BYPASSING); \ SCX_ENUM_SET(skel, scx_rq_flags, SCX_RQ_CLK_VALID); \ SCX_ENUM_SET(skel, scx_rq_flags, SCX_RQ_IN_WAKEUP); \ @@ -32,20 +34,24 @@ SCX_ENUM_SET(skel, scx_ent_flags, SCX_TASK_STATE_BITS); \ SCX_ENUM_SET(skel, scx_ent_flags, SCX_TASK_STATE_MASK); \ SCX_ENUM_SET(skel, scx_ent_flags, SCX_TASK_CURSOR); \ - SCX_ENUM_SET(skel, scx_task_state, SCX_TASK_NONE); \ - SCX_ENUM_SET(skel, scx_task_state, SCX_TASK_INIT); \ - SCX_ENUM_SET(skel, scx_task_state, SCX_TASK_READY); \ - SCX_ENUM_SET(skel, scx_task_state, SCX_TASK_ENABLED); \ - SCX_ENUM_SET(skel, scx_task_state, SCX_TASK_NR_STATES); \ + SCX_ENUM_SET(skel, scx_ent_flags, SCX_TASK_NONE); \ + SCX_ENUM_SET(skel, scx_ent_flags, SCX_TASK_INIT); \ + SCX_ENUM_SET(skel, scx_ent_flags, SCX_TASK_READY); \ + SCX_ENUM_SET(skel, scx_ent_flags, SCX_TASK_ENABLED); \ + SCX_ENUM_SET(skel, scx_ent_flags, SCX_TASK_NR_STATES); \ SCX_ENUM_SET(skel, scx_ent_dsq_flags, SCX_TASK_DSQ_ON_PRIQ); \ SCX_ENUM_SET(skel, scx_kick_flags, SCX_KICK_IDLE); \ SCX_ENUM_SET(skel, scx_kick_flags, SCX_KICK_PREEMPT); \ SCX_ENUM_SET(skel, scx_kick_flags, SCX_KICK_WAIT); \ + SCX_ENUM_SET(skel, scx_kick_flags, SCX_KICK_PREEMPT_LAZY); \ + SCX_ENUM_SET(skel, scx_kick_flags, SCX_KICK_ALL_FLAGS); \ SCX_ENUM_SET(skel, scx_enq_flags, SCX_ENQ_WAKEUP); \ SCX_ENUM_SET(skel, scx_enq_flags, SCX_ENQ_HEAD); \ SCX_ENUM_SET(skel, scx_enq_flags, SCX_ENQ_PREEMPT); \ + SCX_ENUM_SET(skel, scx_enq_flags, SCX_ENQ_PREEMPT_LAZY); \ SCX_ENUM_SET(skel, scx_enq_flags, SCX_ENQ_IMMED); \ SCX_ENUM_SET(skel, scx_enq_flags, SCX_ENQ_RESCUE); \ + SCX_ENUM_SET(skel, scx_enq_flags, SCX_ENQ_BLOCKED); \ SCX_ENUM_SET(skel, scx_enq_flags, SCX_ENQ_REENQ); \ SCX_ENUM_SET(skel, scx_enq_flags, SCX_ENQ_LAST); \ SCX_ENUM_SET(skel, scx_enq_flags, SCX_ENQ_CLEAR_OPSS); \
diff --git a/tools/sched_ext/include/scx/enums_abi.autogen.h b/tools/sched_ext/include/scx/enums_abi.autogen.h index d538997..1186daa 100644 --- a/tools/sched_ext/include/scx/enums_abi.autogen.h +++ b/tools/sched_ext/include/scx/enums_abi.autogen.h
@@ -97,10 +97,12 @@ static const struct __scx_enum_abi_val __scx_enum_abi_vals[] { "scx_enq_flags", "SCX_ENQ_HEAD", 0x10000LLU }, { "scx_enq_flags", "SCX_ENQ_CPU_SELECTED", 0x100000LLU }, { "scx_enq_flags", "SCX_ENQ_PREEMPT", 0x100000000LLU }, + { "scx_enq_flags", "SCX_ENQ_PREEMPT_LAZY", 0x800000000LLU }, { "scx_enq_flags", "SCX_ENQ_IMMED", 0x200000000LLU }, { "scx_enq_flags", "SCX_ENQ_RESCUE", 0x400000000LLU }, { "scx_enq_flags", "SCX_ENQ_REENQ", 0x10000000000LLU }, { "scx_enq_flags", "SCX_ENQ_LAST", 0x20000000000LLU }, + { "scx_enq_flags", "SCX_ENQ_BLOCKED", 0x40000000000LLU }, { "scx_enq_flags", "__SCX_ENQ_INTERNAL_MASK", 0xff00000000000000LLU }, { "scx_enq_flags", "SCX_ENQ_CLEAR_OPSS", 0x100000000000000LLU }, { "scx_enq_flags", "SCX_ENQ_DSQ_PRIQ", 0x200000000000000LLU }, @@ -117,6 +119,7 @@ static const struct __scx_enum_abi_val __scx_enum_abi_vals[] { "scx_ent_flags", "SCX_TASK_SUB_INIT", 0x10LLU }, { "scx_ent_flags", "SCX_TASK_IMMED", 0x20LLU }, { "scx_ent_flags", "SCX_TASK_PROTECTED", 0x40LLU }, + { "scx_ent_flags", "SCX_TASK_RUN_TRACKED", 0x80LLU }, { "scx_ent_flags", "SCX_TASK_STATE_SHIFT", 0x8LLU }, { "scx_ent_flags", "SCX_TASK_STATE_BITS", 0x3LLU }, { "scx_ent_flags", "SCX_TASK_STATE_MASK", 0x700LLU }, @@ -134,6 +137,7 @@ static const struct __scx_enum_abi_val __scx_enum_abi_vals[] { "scx_ent_flags", "SCX_TASK_REENQ_IMMED", 0x2000LLU }, { "scx_ent_flags", "SCX_TASK_REENQ_PREEMPTED", 0x3000LLU }, { "scx_ent_flags", "SCX_TASK_REENQ_CAP", 0x4000LLU }, + { "scx_ent_flags", "SCX_TASK_REENQ_PROXY", 0x5000LLU }, { "scx_ent_flags", "SCX_TASK_CURSOR", 0xffffffff80000000LLU }, { "scx_exit_code", "SCX_ECODE_RSN_HOTPLUG", 0x100000000LLU }, { "scx_exit_code", "SCX_ECODE_RSN_CGROUP_OFFLINE", 0x200000000LLU }, @@ -161,6 +165,8 @@ static const struct __scx_enum_abi_val __scx_enum_abi_vals[] { "scx_kick_flags", "SCX_KICK_IDLE", 0x1LLU }, { "scx_kick_flags", "SCX_KICK_PREEMPT", 0x2LLU }, { "scx_kick_flags", "SCX_KICK_WAIT", 0x4LLU }, + { "scx_kick_flags", "SCX_KICK_PREEMPT_LAZY", 0x8LLU }, + { "scx_kick_flags", "SCX_KICK_ALL_FLAGS", 0xfLLU }, { "scx_opi", "SCX_OPI_BEGIN", 0x0LLU }, { "scx_opi", "SCX_OPI_NORMAL_BEGIN", 0x0LLU }, { "scx_opi", "SCX_OPI_NORMAL_END", 0x21LLU }, @@ -176,7 +182,9 @@ static const struct __scx_enum_abi_val __scx_enum_abi_vals[] { "scx_ops_flags", "SCX_OPS_BUILTIN_IDLE_PER_NODE", 0x40LLU }, { "scx_ops_flags", "SCX_OPS_ALWAYS_ENQ_IMMED", 0x80LLU }, { "scx_ops_flags", "SCX_OPS_TID_TO_TASK", 0x100LLU }, - { "scx_ops_flags", "SCX_OPS_ALL_FLAGS", 0x1ffLLU }, + { "scx_ops_flags", "SCX_OPS_LAZY_RESCHED", 0x200LLU }, + { "scx_ops_flags", "SCX_OPS_ENQ_BLOCKED", 0x400LLU }, + { "scx_ops_flags", "SCX_OPS_ALL_FLAGS", 0x7ffLLU }, { "scx_ops_flags", "__SCX_OPS_INTERNAL_MASK", 0xff00000000000000LLU }, { "scx_ops_flags", "SCX_OPS_HAS_CPU_PREEMPT", 0x100000000000000LLU }, { "scx_ops_state", "SCX_OPSS_NONE", 0x0LLU }, @@ -203,6 +211,8 @@ static const struct __scx_enum_abi_val __scx_enum_abi_vals[] { "scx_rq_flags", "SCX_RQ_BAL_CB_PENDING", 0x40LLU }, { "scx_rq_flags", "SCX_RQ_SUB_IDLE_RENOTIFY", 0x80LLU }, { "scx_rq_flags", "SCX_RQ_ROOT_IDLE_RENOTIFY", 0x100LLU }, + { "scx_rq_flags", "SCX_RQ_PROXY_RETRY", 0x200LLU }, + { "scx_rq_flags", "SCX_RQ_PROXY_TICK", 0x400LLU }, { "scx_rq_flags", "SCX_RQ_IN_WAKEUP", 0x10000LLU }, { "scx_rq_flags", "SCX_RQ_IN_DISPATCH", 0x20000LLU }, { "scx_sched_pcpu_flags", "SCX_SCHED_PCPU_BYPASSING", 0x1LLU },
diff --git a/tools/sched_ext/include/scx/features.bpf.h b/tools/sched_ext/include/scx/features.bpf.h new file mode 100644 index 0000000..992f4a7 --- /dev/null +++ b/tools/sched_ext/include/scx/features.bpf.h
@@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Kernel features the loader probes before load and hands to the BPF side in + * one rodata word, so that a program can carry both the path a feature enables + * and its fallback while the verifier prunes the one the running kernel cannot + * take. scx_utils sets the word in the ops open macros. The bits are mirrored + * in rust/scx_utils/src/compat.rs. + * + * Included by scx/common.bpf.h; don't include directly. + * + * Copyright (c) 2026 Meta Platforms, Inc. and affiliates. + * Copyright (c) 2026 Tejun Heo <tj@kernel.org> + */ +#ifndef __SCX_FEATURES_BPF_H +#define __SCX_FEATURES_BPF_H + +enum scx_lib_feature { + /* the JIT lowers fetching AND, OR and XOR on arena pointers */ + SCX_LIB_FEAT_ARENA_FETCH_BITOPS = 1ULL << 0, +}; + +const volatile u64 scx_lib_features __weak; + +static __always_inline bool scx_lib_has(u64 feat) +{ + return scx_lib_features & feat; +} + +#endif /* __SCX_FEATURES_BPF_H */
diff --git a/tools/sched_ext/include/scx/user_exit_info.h b/tools/sched_ext/include/scx/user_exit_info.h index 56a02b5..cf27ac2 100644 --- a/tools/sched_ext/include/scx/user_exit_info.h +++ b/tools/sched_ext/include/scx/user_exit_info.h
@@ -52,6 +52,7 @@ enum scx_exit_code { /* Reasons */ SCX_ECODE_RSN_HOTPLUG = 1LLU << 32, + SCX_ECODE_RSN_CGROUP_OFFLINE = 2LLU << 32, /* Actions */ SCX_ECODE_ACT_RESTART = 1LLU << 48,
diff --git a/tools/sched_ext/scx_flatcg.bpf.c b/tools/sched_ext/scx_flatcg.bpf.c index 454ebb8..5e6abd0 100644 --- a/tools/sched_ext/scx_flatcg.bpf.c +++ b/tools/sched_ext/scx_flatcg.bpf.c
@@ -144,7 +144,7 @@ static bool cgv_node_less(struct bpf_rb_node *a, const struct bpf_rb_node *b) cgc_a = container_of(a, struct cgv_node, rb_node); cgc_b = container_of(b, struct cgv_node, rb_node); - return cgc_a->cvtime < cgc_b->cvtime; + return time_before(cgc_a->cvtime, cgc_b->cvtime); } static struct fcg_cpu_ctx *find_cpu_ctx(void)
diff --git a/tools/sched_ext/scx_qmap.bpf.c b/tools/sched_ext/scx_qmap.bpf.c index 2f36531..e8e451b 100644 --- a/tools/sched_ext/scx_qmap.bpf.c +++ b/tools/sched_ext/scx_qmap.bpf.c
@@ -369,6 +369,22 @@ static u64 needs_immed(s32 cid) return qa.cid_shared[cid] ? SCX_ENQ_IMMED : 0; } +static void dispatch_to_rescue(struct task_struct *p, task_ctx_t *taskc, + u64 enq_flags) +{ + u32 cid = cmask_next_set_wrap(&taskc->cpus_allowed, 0); + + if (cid >= scx_bpf_nr_cids()) { + scx_bpf_error("task %d has no allowed cid", p->pid); + return; + } + + taskc->force_local = false; + __sync_fetch_and_add(&qa.nr_rescue_dsp, 1); + scx_bpf_dsq_insert(p, SCX_DSQ_LOCAL_ON | cid, slice_ns, + enq_flags | SCX_ENQ_RESCUE); +} + /* first cid this node does NOT hold for fault injection, -1 if none */ static s32 first_unavail_cid(void) { @@ -442,6 +458,9 @@ void BPF_STRUCT_OPS(qmap_enqueue, struct task_struct *p, u64 enq_flags) */ taskc->core_sched_seq = qa.core_sched_tail_seqs[idx]++; + if (enq_flags & SCX_ENQ_BLOCKED) + __sync_fetch_and_add(&qa.nr_enq_blocked, 1); + /* * A task of ours that can run on none of our self cids - the parent * didn't grant them or we delegated them to children - would starve in @@ -451,18 +470,64 @@ void BPF_STRUCT_OPS(qmap_enqueue, struct task_struct *p, u64 enq_flags) * If we hold ENQ on that cid it runs. Otherwise the kernel diverts the * task to its rescue path. IMMED would turn the insert into a legal * placement on a time-shared cid and the kernel would bounce it back - * here instead of rescuing it. + * here instead of rescuing it. Do this before the blocked-donor fast + * paths, which also require an eligible self cid to make progress. */ if (!cmask_intersects(&taskc->cpus_allowed, &qa.self_cids.mask)) { - s32 c = cmask_next_set_wrap(&taskc->cpus_allowed, 0); + dispatch_to_rescue(p, taskc, enq_flags); + return; + } - if (c >= 0 && c < scx_bpf_nr_cids()) { - taskc->force_local = false; - __sync_fetch_and_add(&qa.nr_rescue_dsp, 1); - scx_bpf_dsq_insert(p, SCX_DSQ_LOCAL_ON | c, slice_ns, - enq_flags | SCX_ENQ_RESCUE); + /* + * SCX_OPS_ALWAYS_ENQ_IMMED makes the local insertion below implicitly + * carry SCX_ENQ_IMMED. If the CPU can't run the blocked donor immediately, + * the core returns it through ops.enqueue() with SCX_ENQ_REENQ. Inserting + * it into the same local DSQ would repeat the IMMED handback until the + * scheduler is ejected. Move reenqueued blocked donors to the shared DSQ, + * which doesn't carry SCX_ENQ_IMMED, so another CPU can consume them. + */ + if ((enq_flags & (SCX_ENQ_BLOCKED | SCX_ENQ_REENQ)) == + (SCX_ENQ_BLOCKED | SCX_ENQ_REENQ)) { + taskc->force_local = false; + scx_bpf_dsq_insert(p, SHARED_DSQ, 0, enq_flags); + cid = cmask_next_and2_set_wrap(&taskc->cpus_allowed, + &qa.idle_cids.mask, + &qa.self_cids.mask, 0); + if (cid < scx_bpf_nr_cids()) + scx_bpf_kick_cid(cid, SCX_KICK_IDLE); + return; + } + + /* + * Insert a blocked mutex donor at the head of an eligible local DSQ with + * a fresh slice and %SCX_ENQ_PREEMPT, requesting an immediate reschedule. + * The test above guarantees that cpus_allowed intersects self_cids, but + * the donor's current cid may have been delegated to a child. Search the + * intersection starting at the current cid, preserving it when qmap still + * holds it and wrapping to another eligible self cid otherwise. + * + * A self cid may be held exclusively with SCX_CAP_ENQ or time-shared with + * only SCX_CAP_ENQ_IMMED. Add needs_immed() so either kind can accept the + * local insertion instead of rejecting and reenqueuing the donor for a + * capability miss. Once selected, the core proxy-exec path can run the + * mutex owner using the donor's scheduling context. + * + * This policy is intentionally unfair and can strongly prioritize tasks + * using contended mutexes; scx_qmap is a demonstration scheduler and + * this behavior makes proxy-exec support easy to observe. + */ + if (enq_flags & SCX_ENQ_BLOCKED) { + cid = cmask_next_and_set_wrap(&taskc->cpus_allowed, + &qa.self_cids.mask, + scx_bpf_task_cid(p)); + if (cid >= scx_bpf_nr_cids()) { + /* self_cids may have changed since the intersection test */ + dispatch_to_rescue(p, taskc, enq_flags); return; } + scx_bpf_dsq_insert(p, SCX_DSQ_LOCAL_ON | cid, slice_ns, + enq_flags | needs_immed(cid) | SCX_ENQ_PREEMPT); + return; } /* @@ -587,9 +652,34 @@ static void update_core_sched_head_seq(struct task_struct *p) } /* + * Send @p, stranded on the DSQ @it iterates, to the kernel rescue path. To + * exercise both kfuncs, move tasks with an even pid there with + * scx_bpf_dsq_move() and re-enqueue the others with scx_bpf_dsq_reenq_task(), + * which takes them through qmap_enqueue()'s rescue. The choice is per task so + * that a marked task isn't moved by another scan before the re-enqueue reaches + * it. + */ +static __always_inline void rescue_stranded(struct bpf_iter_scx_dsq *it, + struct task_struct *p, task_ctx_t *taskc) +{ + s32 c; + + if (p->pid & 1) { + scx_bpf_dsq_reenq_task(it, p); + return; + } + + c = cmask_next_set_wrap(&taskc->cpus_allowed, 0); + if (c >= 0 && c < scx_bpf_nr_cids()) { + __sync_fetch_and_add(&qa.nr_rescue_dsp, 1); + scx_bpf_dsq_move(it, p, SCX_DSQ_LOCAL_ON | c, SCX_ENQ_RESCUE); + } +} + +/* * One pass over SHARED_DSQ: rescue stranded tasks and boost highpri ones. A * task whose cids were lost while it was queued in the fifos would strand on - * SHARED_DSQ, which is consumed only on self cids it can't run on - move it to + * SHARED_DSQ, which is consumed only on self cids it can't run on - send it to * the kernel rescue path. One whose cids were lost after the highpri cull is * likewise rescued out of HIGHPRI_DSQ below. * @@ -598,9 +688,9 @@ static void update_core_sched_head_seq(struct task_struct *p) * consuming them first. This makes minor difference only when dsp_batch is * larger than 1. * - * scx_bpf_dsq_move[_vtime]() are allowed both from ops.dispatch() and - * non-rq-lock holding BPF programs. As demonstration, this function is called - * from qmap_dispatch() and monitor_timerfn(). + * scx_bpf_dsq_move[_vtime]() and scx_bpf_dsq_reenq_task() are allowed both from + * ops.dispatch() and non-rq-lock holding BPF programs. As demonstration, this + * function is called from qmap_dispatch() and monitor_timerfn(). */ static bool scan_shared_dsq(bool from_timer) { @@ -612,19 +702,13 @@ static bool scan_shared_dsq(bool from_timer) bpf_for_each(scx_dsq, p, SHARED_DSQ, 0) { static u64 highpri_seq; task_ctx_t *taskc; - s32 c; if (!(taskc = lookup_task_ctx(p))) return false; /* stranded? rescue - it can't be dispatched here either way */ if (!cmask_intersects(&taskc->cpus_allowed, &qa.self_cids.mask)) { - c = cmask_next_set_wrap(&taskc->cpus_allowed, 0); - if (c >= 0 && c < scx_bpf_nr_cids()) { - __sync_fetch_and_add(&qa.nr_rescue_dsp, 1); - scx_bpf_dsq_move(BPF_FOR_EACH_ITER, p, SCX_DSQ_LOCAL_ON | c, - SCX_ENQ_RESCUE); - } + rescue_stranded(BPF_FOR_EACH_ITER, p, taskc); continue; } @@ -658,19 +742,12 @@ static bool scan_shared_dsq(bool from_timer) &qa.usable_cids.mask, this_cid + 1); if (cid >= nr_cids) { - s32 c; - /* self cids lack caps in effect yet, leave it queued */ if (cmask_intersects(&taskc->cpus_allowed, &qa.self_cids.mask)) continue; /* stranded after the cull - rescue it from here */ - c = cmask_next_set_wrap(&taskc->cpus_allowed, 0); - if (c >= 0 && c < nr_cids) { - __sync_fetch_and_add(&qa.nr_rescue_dsp, 1); - scx_bpf_dsq_move(BPF_FOR_EACH_ITER, p, SCX_DSQ_LOCAL_ON | c, - SCX_ENQ_RESCUE); - } + rescue_stranded(BPF_FOR_EACH_ITER, p, taskc); continue; } @@ -1408,7 +1485,8 @@ __noinline void compute_partition(void) /* find out the cids we hold */ scx_bpf_sub_caps(0, SCX_CAP_ENQ, &qa.held_excl.mask); scx_bpf_sub_caps(0, SCX_CAP_ENQ_IMMED, &qa.held_shared.mask); - cmask_andnot(&qa.held_shared.mask, &qa.held_excl.mask); /* held only as ENQ_IMMED */ + /* held only as ENQ_IMMED */ + cmask_andnot(&qa.held_shared.mask, &qa.held_shared.mask, &qa.held_excl.mask); qa.part.nr_shared = 0; qa.part.nr_rr = 0; @@ -1563,8 +1641,7 @@ static __noinline void account_alloc(void) */ static void refresh_usable(void) { - cmask_copy(&qa.usable_scratch.mask, &qa.self_cids.mask); - cmask_and(&qa.usable_scratch.mask, &qa.avail_cids.mask); + cmask_and(&qa.usable_scratch.mask, &qa.self_cids.mask, &qa.avail_cids.mask); cmask_copy(&qa.usable_cids.mask, &qa.usable_scratch.mask); } @@ -1643,10 +1720,8 @@ __noinline void apply_partition(void) if (!cgid) continue; - cmask_copy(&qa.to_revoke_cids.mask, &ssc->prev_granted.mask); - cmask_andnot(&qa.to_revoke_cids.mask, &ssc->granted_cids.mask); - cmask_copy(&qa.to_grant_cids.mask, &ssc->granted_cids.mask); - cmask_andnot(&qa.to_grant_cids.mask, &ssc->prev_granted.mask); + cmask_andnot(&qa.to_revoke_cids.mask, &ssc->prev_granted.mask, &ssc->granted_cids.mask); + cmask_andnot(&qa.to_grant_cids.mask, &ssc->granted_cids.mask, &ssc->prev_granted.mask); scx_bpf_sub_revoke(cgid, SCX_CAP_ENQ_IMMED | SCX_CAP_PERF, &qa.prev_rr_cids.mask); @@ -1719,13 +1794,90 @@ static void redistribute(void) } /* - * Userspace pokes this (PROG_RUN) to bring alloc_ns[] current before reading - * it for the stats display. Skipping when the partition guard is held is - * fine - alloc_ts is untouched, so the elapsed time is charged next time. + * Owner id for a @sched value of ops.sub_cid_sched_updated(). A child is + * attached before its first task runs and its tasks are re-homed before it + * detaches, so a child's cgroup id always has its slot. + */ +static s32 cid_sched_owner(u64 sched) +{ + s32 i; + + if (sched == SCX_CID_SCHED_NONE) + return CID_NONE; + if (sched == SCX_CID_SCHED_SELF) + return CID_SELF; + bpf_for(i, 0, MAX_SUB_SCHEDS) + if (qa.sub_sched_ctxs[i].cgroup_id == sched) + return i; + return CID_NONE; +} + +/* used_ns[] is summed from every cpu, hence the atomic adds */ +static void cid_sched_charge(s32 cid, u64 now) +{ + s32 owner = qa.cid_sched[cid]; + u64 delta = now - qa.cid_sched_since[cid]; + + if (owner >= 0 && owner < MAX_SUB_SCHEDS) + __sync_fetch_and_add(&qa.used_ns[owner], delta); + else if (owner == CID_SELF) + __sync_fetch_and_add(&qa.self_used_ns, delta); + qa.cid_sched_since[cid] = now; +} + +void BPF_STRUCT_OPS(qmap_sub_cid_sched_updated, s32 cid, u64 sched) +{ + if (cid < 0 || cid >= SCX_QMAP_MAX_CPUS) + return; + + cid_sched_charge(cid, bpf_ktime_get_ns()); + qa.cid_sched[cid] = cid_sched_owner(sched); +} + +/* + * Snapshot the used time for the stats display: the closed intervals plus the + * ones still open. The reads race the notifications on other cpus, so an + * interval closing in between can be missing from one snapshot or counted in + * two. The next snapshot evens it out and the display floors a negative + * difference at zero. + */ +static void snapshot_used(void) +{ + u64 now = bpf_ktime_get_ns(); + s32 nr_cids = qa.nr_cids; + s32 cid, i; + + if (nr_cids < 0 || nr_cids > SCX_QMAP_MAX_CPUS) + return; + + bpf_for(i, 0, MAX_SUB_SCHEDS) + qa.used_snap_ns[i] = qa.used_ns[i]; + qa.self_used_snap_ns = qa.self_used_ns; + + bpf_for(cid, 0, nr_cids) { + s32 owner = qa.cid_sched[cid]; + u64 since = qa.cid_sched_since[cid]; + + /* restarted after @now by a notification on another cpu */ + if (since > now) + continue; + if (owner >= 0 && owner < MAX_SUB_SCHEDS) + qa.used_snap_ns[owner] += now - since; + else if (owner == CID_SELF) + qa.self_used_snap_ns += now - since; + } +} + +/* + * Userspace pokes this (PROG_RUN) to bring alloc_ns[] and the used snapshot + * current before reading them for the stats display. Skipping the alloc part + * when the partition guard is held is fine - alloc_ts is untouched, so the + * elapsed time is charged next time. */ SEC("syscall") int flush_alloc(void *ctx) { + snapshot_used(); if (part_try_start()) { account_alloc(); part_end(); @@ -1877,6 +2029,9 @@ s32 BPF_STRUCT_OPS_SLEEPABLE(qmap_init) /* cache the cid count, trusted to be <= SCX_QMAP_MAX_CPUS hereafter */ qa.nr_cids = nr_cids; + bpf_for(i, 0, nr_cids) + qa.cid_sched[i] = CID_NONE; + /* cmasks are embedded in qa, so they only need initializing */ cmask_init(&qa.idle_cids.mask, 0, nr_cids); cmask_init(&qa.rr_cids.mask, 0, nr_cids); @@ -1892,7 +2047,7 @@ s32 BPF_STRUCT_OPS_SLEEPABLE(qmap_init) scx_bpf_sub_caps(0, SCX_CAP_ENQ, &qa.held_excl.mask); scx_bpf_sub_caps(0, SCX_CAP_ENQ_IMMED, &qa.held_shared.mask); - cmask_andnot(&qa.held_shared.mask, &qa.held_excl.mask); + cmask_andnot(&qa.held_shared.mask, &qa.held_shared.mask, &qa.held_excl.mask); bpf_for(i, 0, MAX_SUB_SCHEDS) { cmask_init(&qa.sub_sched_ctxs[i].granted_cids.mask, 0, nr_cids); @@ -2024,12 +2179,36 @@ s32 BPF_STRUCT_OPS(qmap_sub_attach, struct scx_sub_attach_args *args) void BPF_STRUCT_OPS(qmap_sub_detach, struct scx_sub_detach_args *args) { - s32 i; + u64 cgid = args->ops->sub_cgroup_id; + s32 nr_cids = qa.nr_cids; + s32 pos = qa.part.rr_pos; + u64 holder_cgid; + bool reset_pool; + s32 i, cid; + + if (nr_cids < 0 || nr_cids > SCX_QMAP_MAX_CPUS || pos < 0 || pos >= MAX_PARTS) { + scx_bpf_error("-ERANGE"); + return; + } + + /* + * The child's caps are gone without a report, see ops.sub_detach(). + * cpuperf targets persist until the next write. Reset the child's excl + * cids, and the pool unless another child holds it: that child's revoke + * report or its own detach resets it then. + */ + holder_cgid = qa.part.rr_slots[pos]; + reset_pool = !holder_cgid || holder_cgid == cgid; for (i = 0; i < MAX_SUB_SCHEDS; i++) { - if (qa.sub_sched_ctxs[i].cgroup_id != args->ops->sub_cgroup_id) + if (qa.sub_sched_ctxs[i].cgroup_id != cgid) continue; + bpf_arena_for(cid, 0, nr_cids) + if (cmask_test(cid, &qa.sub_sched_ctxs[i].granted_cids.mask) || + (reset_pool && cmask_test(cid, &qa.rr_cids.mask))) + scx_bpf_cidperf_set(cid, SCX_CPUPERF_ONE); + qa.sub_sched_ctxs[i].cgroup_id = 0; qa.sub_sched_ctxs[i].weight = 100; cmask_init(&qa.sub_sched_ctxs[i].granted_cids.mask, 0, qa.nr_cids); @@ -2065,6 +2244,16 @@ void BPF_STRUCT_OPS(qmap_sub_ecaps_updated, s32 cid, u64 before, u64 after) execute_partition(); } +void BPF_STRUCT_OPS(qmap_sub_child_ecaps_updated, u64 cgroup_id, s32 cid, u64 before, + u64 after) +{ + __sync_fetch_and_add(&qa.nr_child_ecaps, 1); + + /* a child's last target must not outlive its PERF cap */ + if ((before & ~after) & SCX_CAP_PERF) + scx_bpf_cidperf_set(cid, SCX_CPUPERF_ONE); +} + SCX_OPS_CID_DEFINE(qmap_ops, .flags = SCX_OPS_ENQ_EXITING | SCX_OPS_TID_TO_TASK, .select_cid = (void *)qmap_select_cid, @@ -2088,6 +2277,8 @@ SCX_OPS_CID_DEFINE(qmap_ops, .sub_detach = (void *)qmap_sub_detach, .sub_caps_updated = (void *)qmap_sub_caps_updated, .sub_ecaps_updated = (void *)qmap_sub_ecaps_updated, + .sub_cid_sched_updated = (void *)qmap_sub_cid_sched_updated, + .sub_child_ecaps_updated = (void *)qmap_sub_child_ecaps_updated, .init_cids = (void *)qmap_init_cids, .init = (void *)qmap_init, .exit = (void *)qmap_exit,
diff --git a/tools/sched_ext/scx_qmap.c b/tools/sched_ext/scx_qmap.c index 5bb5f68..17cf584 100644 --- a/tools/sched_ext/scx_qmap.c +++ b/tools/sched_ext/scx_qmap.c
@@ -46,7 +46,7 @@ const char help_fmt[] = "See the top-of-file comment in .bpf.c for the design.\n" "\n" "Usage: %s [-s SLICE_US] [-e COUNT] [-t COUNT] [-T COUNT] [-l COUNT] [-b COUNT]\n" -" [-N COUNT] [-P] [-M] [-H] [-c CG_PATH] [-d PID] [-D LEN] [-S] [-p] [-I]\n" +" [-N COUNT] [-P] [-M] [-H] [-c CG_PATH] [-d PID] [-D LEN] [-S] [-p] [-I] [-X]\n" " [-F COUNT] [-i SEC] [-R MS] [-J MODE] [-v]\n" "\n" " -s SLICE_US Override slice duration\n" @@ -65,6 +65,7 @@ const char help_fmt[] = " -S Suppress qmap-specific debug dump\n" " -p Switch only tasks on SCHED_EXT policy instead of all\n" " -I Turn on SCX_OPS_ALWAYS_ENQ_IMMED\n" +" -X Turn on SCX_OPS_ENQ_BLOCKED\n" " -F COUNT IMMED stress: force every COUNT'th enqueue to a busy local DSQ (use with -I)\n" " -C MODE cid-override test (shuffle|bad-dup|bad-range|bad-mono)\n" " -i SEC Stats interval, seconds (default 5)\n" @@ -104,11 +105,15 @@ struct hier_prev { u64 alloc_ns[MAX_SUB_SCHEDS]; u64 self_alloc_ns; u64 alloc_window_ns; + u64 used_snap_ns[MAX_SUB_SCHEDS]; + u64 self_used_snap_ns; u64 nr_dsps[MAX_SUB_SCHEDS]; u64 nr_reenq_cap; u64 nr_reenq_immed; + u64 nr_enq_blocked; u64 nr_inject_attempts; u64 nr_rescue_dsp; + u64 nr_child_ecaps; }; /* current wall-clock time as "HH:MM:SS" for the startup and interval headers */ @@ -157,10 +162,24 @@ static void format_cid_ranges(struct qmap_arena *qa, s32 owner, char *buf, size_ strcpy(buf, "-"); } +/* + * Delta of a cumulative ns counter over the interval, as a fraction of the + * interval. The used snapshot can briefly run behind the previous one (see + * snapshot_used()), hence the floor. + */ +static double delta_ratio(u64 cur, u64 prev, double secs) +{ + s64 delta = cur - prev; + + return secs > 0 && delta > 0 ? delta / (secs * 1e9) : 0.0; +} + /* partition summary + one row per sched: weight, cpus, dispatch rate, cids */ static void print_hier(struct qmap_arena *qa, struct hier_prev *prev, u64 own_cgid) { - char ranges[128], who[16]; + /* worst case, no ranges: a comma and up to six digits per cid */ + static char ranges[SCX_QMAP_MAX_CPUS * 7]; + char who[16]; const char *rr = "-"; double secs; u32 i; @@ -190,26 +209,39 @@ static void print_hier(struct qmap_arena *qa, struct hier_prev *prev, u64 own_cg } format_cid_ranges(qa, CID_SHARED, ranges, sizeof(ranges)); - printf("hier : nsub=%llu excl=%u shared=%s rr=%s reenq cap/immed +%llu/+%llu inj=+%llu rescue=+%llu\n", + printf("hier : nsub=%llu excl=%u shared=%s rr=%s reenq cap/immed +%llu/+%llu blocked=+%llu inj=+%llu rescue=+%llu child_ecaps=+%llu\n", (unsigned long long)qa->nr_sub_scheds, qa->part.nr_excl, ranges, rr, (unsigned long long)(qa->nr_reenq_cap - prev->nr_reenq_cap), (unsigned long long)(qa->nr_reenq_immed - prev->nr_reenq_immed), + (unsigned long long)(qa->nr_enq_blocked - prev->nr_enq_blocked), (unsigned long long)(qa->nr_inject_attempts - prev->nr_inject_attempts), - (unsigned long long)(qa->nr_rescue_dsp - prev->nr_rescue_dsp)); + (unsigned long long)(qa->nr_rescue_dsp - prev->nr_rescue_dsp), + (unsigned long long)(qa->nr_child_ecaps - prev->nr_child_ecaps)); prev->nr_reenq_cap = qa->nr_reenq_cap; prev->nr_reenq_immed = qa->nr_reenq_immed; + prev->nr_enq_blocked = qa->nr_enq_blocked; prev->nr_inject_attempts = qa->nr_inject_attempts; prev->nr_rescue_dsp = qa->nr_rescue_dsp; + prev->nr_child_ecaps = qa->nr_child_ecaps; - printf("hier : %-4s %10s %4s %6s %8s %s\n", - "", "cgroup", "w", "alloc", "disp/s", "cids"); + /* + * alloc is the cid-time the partition handed each participant, and used + * is the cid-time its tasks actually ran, per + * ops.sub_cid_sched_updated(). Both are in cpus over the window. + */ + printf("hier : %-4s %10s %4s %6s %6s %8s %s\n", + "", "cgroup", "w", "alloc", "used", "disp/s", "cids"); format_cid_ranges(qa, CID_SELF, ranges, sizeof(ranges)); - printf("hier : %-4s %10llu %4u %6.2f %8s %s\n", "self", + printf("hier : %-4s %10llu %4u %6.2f %6.2f %8s %s\n", "self", (unsigned long long)own_cgid, 100, - secs > 0 ? (qa->self_alloc_ns - prev->self_alloc_ns) / (secs * 1e9) : 0.0, + delta_ratio(qa->self_alloc_ns, prev->self_alloc_ns, secs), + delta_ratio(qa->self_used_snap_ns, prev->self_used_snap_ns, secs), "-", ranges); prev->self_alloc_ns = qa->self_alloc_ns; + /* used accrues without a window, so prev moves only with the window */ + if (secs > 0) + prev->self_used_snap_ns = qa->self_used_snap_ns; for (i = 0; i < MAX_SUB_SCHEDS; i++) { struct sub_sched_ctx *sc = &qa->sub_sched_ctxs[i]; @@ -219,12 +251,15 @@ static void print_hier(struct qmap_arena *qa, struct hier_prev *prev, u64 own_cg snprintf(who, sizeof(who), "sub%u", i); format_cid_ranges(qa, i, ranges, sizeof(ranges)); - printf("hier : %-4s %10llu %4u %6.2f %8.1f %s\n", who, + printf("hier : %-4s %10llu %4u %6.2f %6.2f %8.1f %s\n", who, (unsigned long long)sc->cgroup_id, sc->weight, - secs > 0 ? (qa->alloc_ns[i] - prev->alloc_ns[i]) / (secs * 1e9) : 0.0, + delta_ratio(qa->alloc_ns[i], prev->alloc_ns[i], secs), + delta_ratio(qa->used_snap_ns[i], prev->used_snap_ns[i], secs), secs > 0 ? (sc->nr_dsps - prev->nr_dsps[i]) / secs : 0.0, ranges); prev->alloc_ns[i] = qa->alloc_ns[i]; + if (secs > 0) + prev->used_snap_ns[i] = qa->used_snap_ns[i]; prev->nr_dsps[i] = sc->nr_dsps; } } @@ -263,7 +298,7 @@ int main(int argc, char **argv) skel->rodata->max_tasks = 16384; while ((opt = getopt(argc, argv, - "s:e:t:T:l:b:N:PMHc:d:D:SpIF:C:i:R:J:B:q:vh")) != -1) { + "s:e:t:T:l:b:N:PMHc:d:D:SpIXF:C:i:R:J:B:q:vh")) != -1) { switch (opt) { case 's': skel->rodata->slice_ns = strtoull(optarg, NULL, 0) * 1000; @@ -324,6 +359,9 @@ int main(int argc, char **argv) case 'I': skel->struct_ops.qmap_ops->flags |= SCX_OPS_ALWAYS_ENQ_IMMED; break; + case 'X': + skel->struct_ops.qmap_ops->flags |= SCX_OPS_ENQ_BLOCKED; + break; case 'F': skel->rodata->immed_stress_nth = strtoul(optarg, NULL, 0); break;
diff --git a/tools/sched_ext/scx_qmap.h b/tools/sched_ext/scx_qmap.h index e95fffc..9e6eefb 100644 --- a/tools/sched_ext/scx_qmap.h +++ b/tools/sched_ext/scx_qmap.h
@@ -163,6 +163,17 @@ struct qmap_arena { u64 alloc_ts; /* last accounting timestamp */ u64 alloc_window_ns; /* total accounted time, the alloc denominator */ + /* + * The per-cid fields are written only by that cid's notifications and + * read by flush_alloc() for the snapshot userspace displays. + */ + s32 cid_sched[SCX_QMAP_MAX_CPUS]; /* per cid: owner id of the sched running there */ + u64 cid_sched_since[SCX_QMAP_MAX_CPUS]; /* when that last changed */ + u64 used_ns[MAX_SUB_SCHEDS]; /* per child slot, closed intervals */ + u64 self_used_ns; + u64 used_snap_ns[MAX_SUB_SCHEDS]; /* used_ns[] plus the intervals open at the flush */ + u64 self_used_snap_ns; + /* bpf-internal cmasks (embedded, see struct qmap_cmask) */ struct qmap_cmask self_cids; /* cids this node runs its own tasks on */ struct qmap_cmask avail_cids; /* cids with caps in effect on the cpu */ @@ -181,8 +192,10 @@ struct qmap_arena { /* bpf -> userspace: stats */ u64 nr_reenq_cap; /* SCX_TASK_REENQ_CAP bounces */ u64 nr_reenq_immed; /* SCX_TASK_REENQ_IMMED bounces */ + u64 nr_enq_blocked; /* SCX_ENQ_BLOCKED dispatches */ u64 nr_inject_attempts; /* fault-injection: dispatches to an unheld cid */ u64 nr_rescue_dsp; /* SCX_ENQ_RESCUE dispatch attempts */ + u64 nr_child_ecaps; /* ops.sub_child_ecaps_updated() deliveries */ u32 inject_mode; /* fault-injection mode (QMAP_INJ_*) */ };
diff --git a/tools/spi/Makefile b/tools/spi/Makefile index 7fccd24..8cf21ff 100644 --- a/tools/spi/Makefile +++ b/tools/spi/Makefile
@@ -12,7 +12,7 @@ # (this improves performance and avoids hard-to-debug behaviour); MAKEFLAGS += -r -CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include +CFLAGS += -O2 -Wall -g -D_GNU_SOURCE -I$(OUTPUT)include -I$(srctree)/tools/include ALL_TARGETS := spidev_test spidev_fdx ALL_PROGRAMS := $(patsubst %,$(OUTPUT)%,$(ALL_TARGETS))
diff --git a/tools/spi/spidev_test.c b/tools/spi/spidev_test.c index f2135d6..5bd3159 100644 --- a/tools/spi/spidev_test.c +++ b/tools/spi/spidev_test.c
@@ -4,8 +4,6 @@ * * Copyright (c) 2007 MontaVista Software, Inc. * Copyright (c) 2007 Anton Vorontsov <avorontsov@ru.mvista.com> - * - * Cross-compile with cross-gcc -I/path/to/cross-kernel/include */ #include <stdint.h> @@ -13,6 +11,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <ctype.h> #include <errno.h> #include <getopt.h> #include <fcntl.h> @@ -22,8 +21,7 @@ #include <sys/stat.h> #include <linux/types.h> #include <linux/spi/spidev.h> - -#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) +#include <linux/kernel.h> static void pabort(const char *s) { @@ -44,9 +42,16 @@ static uint32_t speed = 500000; static uint16_t delay; static uint16_t word_delay; static int verbose; -static int transfer_size; +static int transfer_size = -1; +static int transfers = 1; static int iterations; static int interval = 5; /* interval in seconds for showing transfer rate */ +static int compare; +static int nonzero; +static int do_tx = 1, do_rx = 1; +static int random_input; +static int predictable; +static int input_choices; static uint8_t default_tx[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, @@ -69,6 +74,10 @@ static void hex_dump(const void *src, size_t length, size_t line_size, unsigned char c; printf("%s | ", prefix); + + if (length == 0) + printf("__ ||\n"); + while (length-- > 0) { printf("%02X ", *address++); if (!(++i % line_size) || (length == 0 && i % line_size)) { @@ -92,68 +101,120 @@ static void hex_dump(const void *src, size_t length, size_t line_size, * Unescape - process hexadecimal escape character * converts shell input "\x23" -> 0x23 */ -static int unescape(char *_dst, char *_src, size_t len) +static int unescape(char *src, char *dst, size_t size) { - int ret = 0; - int match; - char *src = _src; - char *dst = _dst; + char *out = dst; unsigned int ch; - while (*src) { - if (*src == '\\' && *(src+1) == 'x') { - match = sscanf(src + 2, "%2x", &ch); - if (!match) - pabort("malformed input string"); + while (*src && size--) { + if (src[0] == '\\' && src[1] != '\0') { + src++; - src += 4; - *dst++ = (unsigned char)ch; - } else { - *dst++ = *src++; + if (src[0] == 'x' && + isxdigit((unsigned char)src[1]) && + isxdigit((unsigned char)src[2]) && + sscanf(&src[1], "%2x", &ch)) { + *out++ = (unsigned char)ch; + src += 3; + continue; + } + + *out++ = '\\'; + if (!size--) + break; } - ret++; + *out++ = *src++; } - return ret; + return out - dst; } -static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len) +static void transfer(int fd, uint8_t const * const tx, uint8_t const * const rx, size_t len) { int ret; int out_fd; - struct spi_ioc_transfer tr = { - .tx_buf = (unsigned long)tx, - .rx_buf = (unsigned long)rx, - .len = len, - .delay_usecs = delay, - .word_delay_usecs = word_delay, - .speed_hz = speed, - .bits_per_word = bits, - }; + size_t bytes_per_word = DIV_ROUND_UP(bits, 8); + int effective_transfers; + struct spi_ioc_transfer *tr; + size_t len_per_transfer; + const uint8_t *tx_buf = tx; + const uint8_t *rx_buf = rx; + size_t rem; - if (mode & SPI_TX_OCTAL) - tr.tx_nbits = 8; - else if (mode & SPI_TX_QUAD) - tr.tx_nbits = 4; - else if (mode & SPI_TX_DUAL) - tr.tx_nbits = 2; - if (mode & SPI_RX_OCTAL) - tr.rx_nbits = 8; - else if (mode & SPI_RX_QUAD) - tr.rx_nbits = 4; - else if (mode & SPI_RX_DUAL) - tr.rx_nbits = 2; - if (!(mode & SPI_LOOP)) { - if (mode & (SPI_TX_OCTAL | SPI_TX_QUAD | SPI_TX_DUAL)) - tr.rx_buf = 0; - else if (mode & (SPI_RX_OCTAL | SPI_RX_QUAD | SPI_RX_DUAL)) - tr.tx_buf = 0; + if (len) { + effective_transfers = min_t(size_t, transfers, DIV_ROUND_UP(len, bytes_per_word)); + len_per_transfer = roundup(DIV_ROUND_UP(len, effective_transfers), bytes_per_word); + } else { + /* zero-length transfers may be handled by the driver, deliver as ordered */ + effective_transfers = transfers; + len_per_transfer = 0; } - ret = ioctl(fd, SPI_IOC_MESSAGE(1), &tr); - if (ret < 1) - pabort("can't send spi message"); + if (SPI_MSGSIZE(effective_transfers) == 0) + pabort("too many transfers, SPI_IOC_MESSAGE size limit exceeded"); - if (verbose) + tr = calloc(effective_transfers, sizeof(*tr)); + if (!tr) + pabort("can't allocate transfer array"); + + rem = len; + + for (int i = 0; i < effective_transfers; i++) { + size_t n = min(rem, len_per_transfer); + + tr[i] = (struct spi_ioc_transfer) { + .tx_buf = (unsigned long)tx_buf, + .rx_buf = (unsigned long)rx_buf, + .len = n, + .delay_usecs = delay, + .word_delay_usecs = word_delay, + .speed_hz = speed, + .bits_per_word = bits, + }; + + if (tx_buf) + tx_buf += n; + + if (rx_buf) + rx_buf += n; + + rem -= n; + + if (mode & SPI_TX_OCTAL) + tr[i].tx_nbits = 8; + else if (mode & SPI_TX_QUAD) + tr[i].tx_nbits = 4; + else if (mode & SPI_TX_DUAL) + tr[i].tx_nbits = 2; + if (mode & SPI_RX_OCTAL) + tr[i].rx_nbits = 8; + else if (mode & SPI_RX_QUAD) + tr[i].rx_nbits = 4; + else if (mode & SPI_RX_DUAL) + tr[i].rx_nbits = 2; + if (!(mode & SPI_LOOP)) { + if (mode & (SPI_TX_OCTAL | SPI_TX_QUAD | SPI_TX_DUAL)) + tr[i].rx_buf = 0; + else if (mode & (SPI_RX_OCTAL | SPI_RX_QUAD | SPI_RX_DUAL)) + tr[i].tx_buf = 0; + } + } + + ret = ioctl(fd, SPI_IOC_MESSAGE(effective_transfers), tr); + free(tr); + if (ret < 0) { + const size_t dump_len = min_t(size_t, len, 256); + int saved_errno = errno; + + if (tx) { + hex_dump(tx, dump_len, 32, "TX"); + if (len > dump_len) + printf("... (%zu more bytes)\n", len - dump_len); + } + errno = saved_errno; + pabort("can't send spi message"); + } + + if (verbose && tx) hex_dump(tx, len, 32, "TX"); if (output_file) { @@ -168,19 +229,31 @@ static void transfer(int fd, uint8_t const *tx, uint8_t const *rx, size_t len) close(out_fd); } - if (verbose) + if (verbose && rx) hex_dump(rx, len, 32, "RX"); + + if (tx && rx && (compare || mode & SPI_LOOP)) { + if (memcmp(tx, rx, len)) { + fprintf(stderr, "transfer error !\n"); + hex_dump(tx, len, 32, "TX"); + hex_dump(rx, len, 32, "RX"); + exit(1); + } + } } static void print_usage(const char *prog) { - printf("Usage: %s [-2348CDFHILMNORSZbdilopsvw]\n", prog); + printf("Usage: %s [-2348CDFHILMNOPRSTZbcdiloprstvwz]\n", prog); puts("general device settings:\n" " -D --device device to use (default /dev/spidev1.1)\n" " -s --speed max speed (Hz)\n" " -d --delay delay (usec)\n" " -w --word-delay word delay (usec)\n" " -l --loop loopback\n" + " -c --compare compare RX'ed and TX'ed data\n" + " -t --no-tx don't send data\n" + " -r --no-rx don't receive data\n" "spi mode:\n" " -H --cpha clock phase\n" " -O --cpol clock polarity\n" @@ -194,8 +267,10 @@ static void print_usage(const char *prog) "data:\n" " -i --input input data from a file (e.g. \"test.bin\")\n" " -o --output output data to a file (e.g. \"results.bin\")\n" - " -p Send data (e.g. \"1234\\xde\\xad\")\n" - " -S --size transfer size\n" + " -p send data (e.g. \"1234\\xde\\xad\")\n" + " -z --nonzero don't send 0x00 or 0xff bytes\n" + " -P --predictable transfer the given number of sequential bytes\n" + " -S --size transfer the given number of random bytes\n" " -I --iter iterations\n" "additional parameters:\n" " -b --bpw bits per word\n" @@ -204,6 +279,7 @@ static void print_usage(const char *prog) " -N --no-cs no chip select\n" " -R --ready slave pulls low to pause\n" " -M --mosi-idle-low leave mosi line low when idle\n" + " -T --transfers number of transfers\n" "misc:\n" " -v --verbose Verbose (show tx buffer)\n"); exit(1); @@ -218,6 +294,9 @@ static void parse_opts(int argc, char *argv[]) { "delay", 1, 0, 'd' }, { "word-delay", 1, 0, 'w' }, { "loop", 0, 0, 'l' }, + { "compare", 0, 0, 'c' }, + { "no-tx", 0, 0, 't' }, + { "no-rx", 0, 0, 'r' }, { "cpha", 0, 0, 'H' }, { "cpol", 0, 0, 'O' }, { "rx-cpha-flip", 0, 0, 'F' }, @@ -229,6 +308,7 @@ static void parse_opts(int argc, char *argv[]) { "input", 1, 0, 'i' }, { "output", 1, 0, 'o' }, { "size", 1, 0, 'S' }, + { "nonzero", 0, 0, 'z' }, { "iter", 1, 0, 'I' }, { "bpw", 1, 0, 'b' }, { "lsb", 0, 0, 'L' }, @@ -236,12 +316,14 @@ static void parse_opts(int argc, char *argv[]) { "no-cs", 0, 0, 'N' }, { "ready", 0, 0, 'R' }, { "mosi-idle-low", 0, 0, 'M' }, + { "predictable", 1, 0, 'P' }, + { "transfers", 1, 0, 'T' }, { "verbose", 0, 0, 'v' }, { NULL, 0, 0, 0 }, }; int c; - c = getopt_long(argc, argv, "D:s:d:w:b:i:o:lHOLC3ZFMNR248p:vS:I:", + c = getopt_long(argc, argv, "D:s:d:w:b:i:o:lctrHOLC3ZFMNR248p:P:T:vS:zI:", lopts, NULL); if (c == -1) @@ -265,6 +347,7 @@ static void parse_opts(int argc, char *argv[]) break; case 'i': input_file = optarg; + input_choices++; break; case 'o': output_file = optarg; @@ -272,6 +355,15 @@ static void parse_opts(int argc, char *argv[]) case 'l': mode |= SPI_LOOP; break; + case 'c': + compare = 1; + break; + case 't': + do_tx = 0; + break; + case 'r': + do_rx = 0; + break; case 'H': mode |= SPI_CPHA; break; @@ -296,6 +388,9 @@ static void parse_opts(int argc, char *argv[]) case 'M': mode |= SPI_MOSI_IDLE_LOW; break; + case 'T': + transfers = atoi(optarg); + break; case 'N': mode |= SPI_NO_CS; break; @@ -307,6 +402,12 @@ static void parse_opts(int argc, char *argv[]) break; case 'p': input_tx = optarg; + input_choices++; + break; + case 'P': + transfer_size = atoi(optarg); + predictable = 1; + input_choices++; break; case '2': mode |= SPI_TX_DUAL; @@ -319,6 +420,11 @@ static void parse_opts(int argc, char *argv[]) break; case 'S': transfer_size = atoi(optarg); + random_input = 1; + input_choices++; + break; + case 'z': + nonzero = 1; break; case 'I': iterations = atoi(optarg); @@ -341,17 +447,19 @@ static void transfer_escaped_string(int fd, char *str) { size_t size = strlen(str); uint8_t *tx; - uint8_t *rx; + uint8_t *rx = NULL; tx = malloc(size); if (!tx) pabort("can't allocate tx buffer"); - rx = malloc(size); - if (!rx) - pabort("can't allocate rx buffer"); + if (do_rx) { + rx = malloc(size); + if (!rx) + pabort("can't allocate rx buffer"); + } - size = unescape((char *)tx, str, size); + size = unescape(str, (char *)tx, size); transfer(fd, tx, rx, size); free(rx); free(tx); @@ -363,7 +471,7 @@ static void transfer_file(int fd, char *filename) struct stat sb; int tx_fd; uint8_t *tx; - uint8_t *rx; + uint8_t *rx = NULL; if (stat(filename, &sb) == -1) pabort("can't stat input file"); @@ -376,9 +484,12 @@ static void transfer_file(int fd, char *filename) if (!tx) pabort("can't allocate tx buffer"); - rx = malloc(sb.st_size); - if (!rx) - pabort("can't allocate rx buffer"); + + if (do_rx) { + rx = malloc(sb.st_size); + if (!rx) + pabort("can't allocate rx buffer"); + } bytes = read(tx_fd, tx, sb.st_size); if (bytes != sb.st_size) @@ -409,34 +520,41 @@ static void show_transfer_rate(void) static void transfer_buf(int fd, int len) { - uint8_t *tx; - uint8_t *rx; + uint8_t *tx = NULL; + uint8_t *rx = NULL; int i; - tx = malloc(len); - if (!tx) - pabort("can't allocate tx buffer"); - for (i = 0; i < len; i++) - tx[i] = random(); + if (do_tx) { + tx = malloc(len); + if (!tx) + pabort("can't allocate tx buffer"); + for (i = 0; i < len; i++) { + if (predictable) { + int v = i - iterations; - rx = malloc(len); - if (!rx) - pabort("can't allocate rx buffer"); - - transfer(fd, tx, rx, len); - - _write_count += len; - _read_count += len; - - if (mode & SPI_LOOP) { - if (memcmp(tx, rx, len)) { - fprintf(stderr, "transfer error !\n"); - hex_dump(tx, len, 32, "TX"); - hex_dump(rx, len, 32, "RX"); - exit(1); + if (nonzero) + v = ((v % 254) + 254) % 254 + 1; + tx[i] = (char)v; + } else { + do { + tx[i] = random(); + } while (nonzero && (tx[i] == 0x0 || tx[i] == 0xff)); + } } } + if (do_rx) { + rx = malloc(len); + if (!rx) + pabort("can't allocate rx buffer"); + } + + transfer(fd, tx, rx, len); + if (do_tx) + _write_count += len; + if (do_rx) + _read_count += len; + free(rx); free(tx); } @@ -449,8 +567,36 @@ int main(int argc, char *argv[]) parse_opts(argc, argv); - if (input_tx && input_file) - pabort("only one of -p and --input may be selected"); + if (input_choices > 1) + pabort("at most one of -S (--size), -p, -i (--input), -P (--predictable) may be selected, " + "and each may be specified only once"); + + if ((random_input || predictable) && transfer_size < 0) + pabort("a size argument is mandatory for -S (--size) and -P (--predictable)"); + + if (iterations && transfer_size < 0) + pabort("-I (--iter) is only implemented for -S (--size) and -P (--predictable)"); + + if (nonzero && transfer_size < 0) + pabort("-z (--nonzero) is only implemented for -S (--size) and -P (--predictable)"); + + if (compare && (!do_tx || !do_rx)) + pabort("-c (--compare) conflicts with -t (--no-tx) or -r (--no-rx)"); + + if (!do_rx && output_file) + pabort("-r (--no-rx) conflicts with -o (--output)"); + + if (!do_tx && transfer_size < 0) + pabort("-t (--no-tx) is only implemented for -S (--size) and -P (--predictable)"); + + if (compare && mode & (SPI_TX_OCTAL | SPI_TX_QUAD | SPI_TX_DUAL)) + pabort("-c (--compare) conflicts with -2 (--dual), -4 (--quad) or -8 (--octal)"); + + if (transfers < 1) + pabort("-T (--transfers) must be 1 or above"); + + if (bits < 1) + pabort("-b (--bpw) must be 1 or above"); fd = open(device, O_RDWR); if (fd < 0) @@ -507,7 +653,7 @@ int main(int argc, char *argv[]) transfer_escaped_string(fd, input_tx); else if (input_file) transfer_file(fd, input_file); - else if (transfer_size) { + else if (transfer_size >= 0) { struct timespec last_stat; clock_gettime(CLOCK_MONOTONIC, &last_stat); @@ -526,7 +672,7 @@ int main(int argc, char *argv[]) printf("total: tx %.1fKB, rx %.1fKB\n", _write_count/1024.0, _read_count/1024.0); } else - transfer(fd, default_tx, default_rx, sizeof(default_tx)); + transfer(fd, default_tx, do_rx ? default_rx : NULL, sizeof(default_tx)); close(fd);
diff --git a/tools/testing/selftests/Makefile b/tools/testing/selftests/Makefile index 7e8d579..1198e57 100644 --- a/tools/testing/selftests/Makefile +++ b/tools/testing/selftests/Makefile
@@ -178,6 +178,10 @@ # of the targets gets built. FORCE_TARGETS ?= +# Remember dry runs for the build report before MAKEFLAGS may be cleared. +KSFT_BUILD_REPORT_DRY_RUN := $(strip $(foreach f,n t q,$(findstring $(f),$(firstword -$(MAKEFLAGS))))) +export KSFT_BUILD_REPORT_DRY_RUN + # Clear LDFLAGS and MAKEFLAGS when implicit rules are missing. This provides # implicit rules to sub-test Makefiles which avoids build failures in test # Makefile that don't have explicit build rules. @@ -222,6 +226,10 @@ export BUILD export KHDR_INCLUDES +# Version of the optional KSFT_BUILD_REPORT format written by these rules. +KSFT_BUILD_REPORT_VERSION := 1 +include $(top_srcdir)/tools/testing/selftests/build_report.mk + # set default goal to all, so make without a target runs all, even when # all isn't the first target in the file. .DEFAULT_GOAL := all @@ -230,11 +238,13 @@ @ret=1; \ for TARGET in $(TARGETS) $(INSTALL_DEP_TARGETS); do \ BUILD_TARGET=$$BUILD/$$TARGET; \ - mkdir $$BUILD_TARGET -p; \ + mkdir -p $$BUILD_TARGET && \ $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET \ - O=$(abs_objtree) \ - $(if $(FORCE_TARGETS),|| exit); \ - ret=$$((ret * $$?)); \ + O=$(abs_objtree); \ + status=$$?; \ + $(call ksft_record_build_status,all,$$TARGET); \ + $(if $(FORCE_TARGETS),[ $$status -eq 0 ] || exit $$status;) \ + [ $$status -eq 0 ] && ret=0; \ done; exit $$ret; run_tests: all @@ -291,7 +301,7 @@ install -m 744 kselftest/ktap_helpers.sh $(INSTALL_PATH)/kselftest/ install -m 744 kselftest/ksft.py $(INSTALL_PATH)/kselftest/ install -m 744 run_kselftest.sh $(INSTALL_PATH)/ - rm -f $(TEST_LIST) + : > $(TEST_LIST) @ret=1; \ for TARGET in $(TARGETS) $(INSTALL_DEP_TARGETS); do \ BUILD_TARGET=$$BUILD/$$TARGET; \ @@ -299,9 +309,11 @@ INSTALL_PATH=$(INSTALL_PATH)/$$TARGET \ SRC_PATH=$(shell readlink -e $$(pwd)) \ OBJ_PATH=$(INSTALL_PATH) \ - O=$(abs_objtree) \ - $(if $(FORCE_TARGETS),|| exit); \ - ret=$$((ret * $$?)); \ + O=$(abs_objtree); \ + status=$$?; \ + $(call ksft_record_build_status,install,$$TARGET); \ + $(if $(FORCE_TARGETS),[ $$status -eq 0 ] || exit $$status;) \ + [ $$status -eq 0 ] && ret=0; \ done; exit $$ret; @@ -315,6 +327,9 @@ printf "Emit Tests for $$TARGET\n"; \ $(MAKE) -s --no-print-directory OUTPUT=$$BUILD_TARGET COLLECTION=$$TARGET \ -C $$TARGET emit_tests >> $(TEST_LIST); \ + status=$$?; \ + $(call ksft_record_build_status,install,$$TARGET); \ + (exit $$status); \ done; @VERSION=$$(git describe HEAD 2>/dev/null); \ if [ -n "$$VERSION" ]; then \
diff --git a/tools/testing/selftests/breakpoints/step_after_suspend_test.c b/tools/testing/selftests/breakpoints/step_after_suspend_test.c index ca2aaab9..7277902 100644 --- a/tools/testing/selftests/breakpoints/step_after_suspend_test.c +++ b/tools/testing/selftests/breakpoints/step_after_suspend_test.c
@@ -18,6 +18,7 @@ #include <sys/timerfd.h> #include <sys/types.h> #include <sys/wait.h> +#include <time.h> #include "kselftest.h" @@ -158,11 +159,21 @@ void suspend(void) int err; int count_before; int count_after; + struct timespec res; struct itimerspec spec = {}; if (getuid() != 0) ksft_exit_skip("Please run the test as root - Exiting.\n"); + /* + * CLOCK_BOOTTIME_ALARM cannot wake up systems that don't have a + * wakeup capable RTC from suspend. Check if we have a wakeup-capable + * RTC to prevent this test from causing the system to hang after + * it suspends. + */ + if (clock_getres(CLOCK_BOOTTIME_ALARM, &res) != 0) + ksft_exit_skip("No wakeup-capable RTC for CLOCK_BOOTTIME_ALARM\n"); + timerfd = timerfd_create(CLOCK_BOOTTIME_ALARM, 0); if (timerfd < 0) ksft_exit_fail_msg("timerfd_create() failed\n");
diff --git a/tools/testing/selftests/build_report.mk b/tools/testing/selftests/build_report.mk new file mode 100644 index 0000000..047c239 --- /dev/null +++ b/tools/testing/selftests/build_report.mk
@@ -0,0 +1,26 @@ +# SPDX-License-Identifier: GPL-2.0 +# +# Optional per-suite build report, see "Recording suite build results" in +# Documentation/dev-tools/kselftest.rst. Callers set KSFT_BUILD_REPORT to an +# absolute filename and use ksft_record_build_status from a shell loop that +# has stored the exit status of the recorded step in $status. + +ifneq (x$(KSFT_BUILD_REPORT)x,xx) +ifeq ($(filter x/%,$(firstword x$(KSFT_BUILD_REPORT))),) +$(error KSFT_BUILD_REPORT must be an absolute path: '$(KSFT_BUILD_REPORT)') +endif +endif +export KSFT_BUILD_REPORT + +ksft_build_report_dry_run := $(KSFT_BUILD_REPORT_DRY_RUN) \ + $(foreach f,n t q,$(findstring $(f),$(firstword -$(MAKEFLAGS)))) + +ifneq ($(strip $(ksft_build_report_dry_run)),) +ksft_record_build_status = : +else +define ksft_record_build_status +if [ -n "$$KSFT_BUILD_REPORT" ]; then \ + printf '%s\t%s\t%d\n' '$(1)' "$(2)" "$$status" >> "$$KSFT_BUILD_REPORT" || exit 1; \ +fi +endef +endif
diff --git a/tools/testing/selftests/cgroup/lib/cgroup_util.c b/tools/testing/selftests/cgroup/lib/cgroup_util.c index 2596c12..823b031 100644 --- a/tools/testing/selftests/cgroup/lib/cgroup_util.c +++ b/tools/testing/selftests/cgroup/lib/cgroup_util.c
@@ -24,20 +24,43 @@ bool cg_test_v1_named; /* Returns read len on success, or -errno on failure. */ ssize_t read_text(const char *path, char *buf, size_t max_len) { - ssize_t len; + size_t total = 0; + ssize_t len, ret; int fd; fd = open(path, O_RDONLY); if (fd < 0) return -errno; - len = read(fd, buf, max_len - 1); + /* + * A single read() is not enough. procfs and sysfs are backed by + * seq_file, and seq_read_iter() copies out at most one internal + * buffer (PAGE_SIZE) per call, leaving the rest for the next read(). + * Reading only once therefore silently drops everything past the + * first page, no matter how big the caller's buffer is. + * + * Loop until the buffer is full or EOF. A full buffer still means + * the file may be longer than max_len, but that is now limited by + * the caller's buffer rather than by a page of seq_file output. + */ + while (total < max_len - 1) { + len = read(fd, buf + total, max_len - 1 - total); + if (len < 0) { + if (errno == EINTR) + continue; + ret = -errno; + goto out; + } + if (!len) + break; + total += len; + } - if (len >= 0) - buf[len] = 0; - + buf[total] = 0; + ret = total; +out: close(fd); - return len < 0 ? -errno : len; + return ret; } /* Returns written len on success, or -errno on failure. */ @@ -279,6 +302,16 @@ static int cg_find_root(char *root, size_t len, const char *controller, options = strtok(NULL, delim); strtok(NULL, delim); strtok(NULL, delim); + + /* + * A mount entry is "device mountpoint type options freq + * passno". A field can only be missing if the last entry was + * cut short by the buffer being too small for the file, and + * there is no complete entry left to look at. + */ + if (!mount || !type || !options) + break; + if (strcmp(type, "cgroup") == 0) { if (!controller || !strstr(options, controller)) continue; @@ -626,18 +659,25 @@ int clone_into_cgroup_run_wait(const char *cgroup) static int __prepare_for_wait(const char *cgroup, const char *filename) { - int fd, ret = -1; + char *path; + int fd, ret; + + path = cg_control(cgroup, filename); + if (!path) + return -1; fd = inotify_init1(0); if (fd == -1) - return fd; + goto out; - ret = inotify_add_watch(fd, cg_control(cgroup, filename), IN_MODIFY); + ret = inotify_add_watch(fd, path, IN_MODIFY); if (ret == -1) { close(fd); fd = -1; } +out: + free(path); return fd; }
diff --git a/tools/testing/selftests/cgroup/lib/include/cgroup_util.h b/tools/testing/selftests/cgroup/lib/include/cgroup_util.h index 5d39c70..5307f3b 100644 --- a/tools/testing/selftests/cgroup/lib/include/cgroup_util.h +++ b/tools/testing/selftests/cgroup/lib/include/cgroup_util.h
@@ -21,6 +21,9 @@ #define DEFAULT_WAIT_INTERVAL_US (100 * 1000) /* 100 ms */ +/* from include/linux/memcontrol.h, which userspace cannot include */ +#define MEMCG_CHARGE_BATCH 64 + /* * Checks if two given values differ by less than err% of their sum. */
diff --git a/tools/testing/selftests/cgroup/settings b/tools/testing/selftests/cgroup/settings new file mode 100644 index 0000000..6091b45 --- /dev/null +++ b/tools/testing/selftests/cgroup/settings
@@ -0,0 +1 @@ +timeout=120
diff --git a/tools/testing/selftests/cgroup/test_cpu.c b/tools/testing/selftests/cgroup/test_cpu.c index 735a53b..3456e3e 100644 --- a/tools/testing/selftests/cgroup/test_cpu.c +++ b/tools/testing/selftests/cgroup/test_cpu.c
@@ -835,9 +835,8 @@ int main(int argc, char *argv[]) if (cg_find_unified_root(root, sizeof(root), NULL)) ksft_exit_skip("cgroup v2 isn't mounted\n"); - if (cg_read_strstr(root, "cgroup.subtree_control", "cpu")) - if (cg_write(root, "cgroup.subtree_control", "+cpu")) - ksft_exit_skip("Failed to set cpu controller\n"); + if (cg_write(root, "cgroup.subtree_control", "+cpu")) + ksft_exit_skip("Failed to set cpu controller\n"); ksft_set_plan(ARRAY_SIZE(tests)); for (i = 0; i < ARRAY_SIZE(tests); i++) {
diff --git a/tools/testing/selftests/cgroup/test_kmem.c b/tools/testing/selftests/cgroup/test_kmem.c index 437f2d3..30af47a 100644 --- a/tools/testing/selftests/cgroup/test_kmem.c +++ b/tools/testing/selftests/cgroup/test_kmem.c
@@ -24,7 +24,7 @@ * the maximum discrepancy between charge and vmstat entries is number * of cpus multiplied by 64 pages. */ -#define MAX_VMSTAT_ERROR (sysconf(_SC_PAGESIZE) * 64 * get_nprocs()) +#define MAX_VMSTAT_ERROR (sysconf(_SC_PAGESIZE) * MEMCG_CHARGE_BATCH * get_nprocs()) #define KMEM_DEAD_WAIT_RETRIES 80
diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c index 0ed8234..bb67301 100644 --- a/tools/testing/selftests/cgroup/test_memcontrol.c +++ b/tools/testing/selftests/cgroup/test_memcontrol.c
@@ -18,11 +18,14 @@ #include <netdb.h> #include <errno.h> #include <sys/mman.h> +#include <sys/sysinfo.h> #include "kselftest.h" #include "cgroup_util.h" -#define MEMCG_SOCKSTAT_WAIT_RETRIES 30 +/* enough page updates for a memory.stat read to flush, see MAX_VMSTAT_ERROR in test_kmem.c */ +#define MEMCG_FLUSH_BYTES \ + (2 * sysconf(_SC_PAGESIZE) * MEMCG_CHARGE_BATCH * get_nprocs()) static bool has_localevents; static bool has_recursiveprot; @@ -1333,7 +1336,8 @@ static int tcp_client(const char *cgroup, unsigned short port) const char server[] = "localhost"; struct addrinfo *ai; char servport[6]; - int retries = 0x10; /* nice round number */ + long budget = 4 * MEMCG_FLUSH_BYTES; + int rcvbuf = 64 * 1024; int sk, ret; long allocated; @@ -1347,17 +1351,25 @@ static int tcp_client(const char *cgroup, unsigned short port) if (sk < 0) goto free_ainfo; + /* keep the data in the server's socket, the one charged to the cgroup */ + ret = setsockopt(sk, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)); + if (ret < 0) + goto close_sk; + ret = connect(sk, ai->ai_addr, ai->ai_addrlen); if (ret < 0) goto close_sk; ret = KSFT_FAIL; - while (retries--) { + while (budget > 0) { uint8_t buf[0x100000]; long current, sock; + ssize_t len; - if (read(sk, buf, sizeof(buf)) <= 0) + len = read(sk, buf, sizeof(buf)); + if (len <= 0) goto close_sk; + budget -= len; current = cg_read_long(cgroup, "memory.current"); sock = cg_read_key_long(cgroup, "memory.stat", "sock "); @@ -1366,7 +1378,7 @@ static int tcp_client(const char *cgroup, unsigned short port) goto close_sk; /* exclude the memory not related to socket connection */ - if (values_close(current - allocated, sock, 10)) { + if (sock > 0 && values_close(current - allocated, sock, 10)) { ret = KSFT_PASS; break; } @@ -1379,6 +1391,24 @@ static int tcp_client(const char *cgroup, unsigned short port) return ret; } +static bool memcg_sockets_disabled(void) +{ + char buf[4 * BUF_SIZE], *opt; + + if (read_text("/proc/cmdline", buf, sizeof(buf)) <= 0) + return false; + + for (opt = strstr(buf, "cgroup.memory="); opt; + opt = strstr(opt + 1, "cgroup.memory=")) { + char *end = strchrnul(opt, ' '); + char *ns = strstr(opt, "nosocket"); + + if (ns && ns < end) + return true; + } + return false; +} + /* * This test checks socket memory accounting. * The test forks a TCP server listens on a random port between 1000 @@ -1393,6 +1423,10 @@ static int test_memcg_sock(const char *root) unsigned short port; char *memcg; long sock_post = -1; + int flush_rounds = 3; + + if (memcg_sockets_disabled()) + return KSFT_SKIP; memcg = cg_name(root, "memcg_test"); if (!memcg) @@ -1447,21 +1481,15 @@ static int test_memcg_sock(const char *root) if (cg_read_long(memcg, "memory.current") < 0) goto cleanup; - /* - * memory.stat is updated asynchronously via the memcg rstat - * flushing worker, which runs periodically (every 2 seconds, - * see FLUSH_TIME). On a busy system, the "sock " counter may - * stay non-zero for a short period of time after the TCP - * connection is closed and all socket memory has been - * uncharged. - * - * Poll memory.stat for up to 3 seconds (~FLUSH_TIME plus some - * scheduling slack) and require that the "sock " counter - * eventually drops to zero. - */ - sock_post = cg_read_key_long_poll(memcg, "memory.stat", "sock ", 0, - MEMCG_SOCKSTAT_WAIT_RETRIES, - DEFAULT_WAIT_INTERVAL_US); + /* the uncharge is done, but a flush still walking the CPUs can hide it from a read */ + while (flush_rounds--) { + if (cg_run(memcg, alloc_anon, (void *)MEMCG_FLUSH_BYTES)) + goto cleanup; + + sock_post = cg_read_key_long(memcg, "memory.stat", "sock "); + if (!sock_post) + break; + } if (sock_post) goto cleanup; @@ -1677,8 +1705,8 @@ static int read_event(int inotify_fd, int expected_event, int expected_wd) static int test_memcg_inotify_delete_file(const char *root) { int ret = KSFT_FAIL; - char *memcg = NULL; - int fd, wd; + char *memcg = NULL, *events = NULL; + int fd = -1, wd; memcg = cg_name(root, "memcg_test_0"); @@ -1692,7 +1720,11 @@ static int test_memcg_inotify_delete_file(const char *root) if (fd == -1) goto cleanup; - wd = inotify_add_watch(fd, cg_control(memcg, "memory.events"), IN_DELETE_SELF); + events = cg_control(memcg, "memory.events"); + if (!events) + goto cleanup; + + wd = inotify_add_watch(fd, events, IN_DELETE_SELF); if (wd == -1) goto cleanup; @@ -1714,6 +1746,7 @@ static int test_memcg_inotify_delete_file(const char *root) close(fd); if (memcg) cg_destroy(memcg); + free(events); free(memcg); return ret; @@ -1723,7 +1756,7 @@ static int test_memcg_inotify_delete_dir(const char *root) { int ret = KSFT_FAIL; char *memcg = NULL; - int fd, wd; + int fd = -1, wd; memcg = cg_name(root, "memcg_test_0");
diff --git a/tools/testing/selftests/cgroup/test_pids.c b/tools/testing/selftests/cgroup/test_pids.c index 710109b..e775c55 100644 --- a/tools/testing/selftests/cgroup/test_pids.c +++ b/tools/testing/selftests/cgroup/test_pids.c
@@ -3,8 +3,11 @@ #include <errno.h> #include <linux/limits.h> +#include <poll.h> #include <signal.h> +#include <stdlib.h> #include <string.h> +#include <sys/inotify.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> @@ -133,6 +136,75 @@ static int test_pids_events(const char *root) +/* + * This test checks that a fork rejected by pids.max increments pids.events + * and notifies pollers of that file, with or without pids_localevents. + */ +static int test_pids_events_notify(const char *root) +{ + union { + struct inotify_event align; + char bytes[sizeof(struct inotify_event) + NAME_MAX + 1]; + } event; + int ret = KSFT_FAIL; + int inotify_fd = -1; + char *cg_pids = NULL, *events_path = NULL; + struct pollfd pfd; + ssize_t n; + + cg_pids = cg_name(root, "pids_notify_test"); + if (!cg_pids) + goto cleanup; + + if (cg_create(cg_pids)) + goto cleanup; + + if (cg_write(cg_pids, "pids.max", "1")) + goto cleanup; + + events_path = cg_control(cg_pids, "pids.events"); + if (!events_path) + goto cleanup; + + inotify_fd = inotify_init1(IN_CLOEXEC | IN_NONBLOCK); + if (inotify_fd < 0) + goto cleanup; + + if (inotify_add_watch(inotify_fd, events_path, IN_MODIFY) < 0) + goto cleanup; + + if (cg_enter_current(cg_pids)) + goto cleanup; + + if (cg_run_nowait(cg_pids, run_success, NULL) != -1 || errno != EAGAIN) + goto cleanup; + + if (cg_read_key_long(cg_pids, "pids.events", "max ") != 1) + goto cleanup; + + pfd.fd = inotify_fd; + pfd.events = POLLIN; + if (poll(&pfd, 1, 1000) <= 0) + goto cleanup; + + n = read(inotify_fd, event.bytes, sizeof(event.bytes)); + if (n < (ssize_t)sizeof(event.align) || !(event.align.mask & IN_MODIFY)) + goto cleanup; + + ret = KSFT_PASS; + +cleanup: + cg_enter_current(root); + if (inotify_fd >= 0) + close(inotify_fd); + if (cg_pids) + cg_destroy(cg_pids); + free(events_path); + free(cg_pids); + + return ret; +} + #define T(x) { x, #x } struct pids_test { int (*fn)(const char *root); @@ -140,6 +212,7 @@ struct pids_test { } tests[] = { T(test_pids_max), T(test_pids_events), + T(test_pids_events_notify), }; #undef T
diff --git a/tools/testing/selftests/cgroup/with_stress.sh b/tools/testing/selftests/cgroup/with_stress.sh index e28c350..a95fb38 100755 --- a/tools/testing/selftests/cgroup/with_stress.sh +++ b/tools/testing/selftests/cgroup/with_stress.sh
@@ -87,7 +87,7 @@ start=$(date +%s) while [ $time -lt $duration ] ; do - $* + "$@" rc=$? [ $rc -eq 0 ] || break time=$(($(date +%s) - $start))
diff --git a/tools/testing/selftests/ftrace/ftracetest b/tools/testing/selftests/ftrace/ftracetest index 246d7e1..9580461 100755 --- a/tools/testing/selftests/ftrace/ftracetest +++ b/tools/testing/selftests/ftrace/ftracetest
@@ -243,7 +243,7 @@ mkdir -p $LOG_DIR || errexit "Failed to make a log directory: $LOG_DIR" date > $LOG_FILE if [ "x-$LINK_PTR" != "x-" ]; then - unlink $LINK_PTR + rm -f $LINK_PTR ln -fs $LOG_DATE $LINK_PTR fi fi
diff --git a/tools/testing/selftests/ftrace/test.d/00basic/ringbuffer_subbuf_size.tc b/tools/testing/selftests/ftrace/test.d/00basic/ringbuffer_subbuf_size.tc index d44d09a..8cfe59d 100644 --- a/tools/testing/selftests/ftrace/test.d/00basic/ringbuffer_subbuf_size.tc +++ b/tools/testing/selftests/ftrace/test.d/00basic/ringbuffer_subbuf_size.tc
@@ -60,7 +60,7 @@ # the size must be greater than or equal to page_size - data_offset page_size=$((page_size-data_offset)) if [ $size -lt $page_size ]; then - exit fail + exit_fail fi # Now add a little more the meta data overhead will overflow @@ -71,14 +71,14 @@ new_str=`awk ' /tracing_mark_write:/ { sub(/^.*tracing_mark_write: /,"");printf "%s", $0; exit}' trace` if [ "$new_str" = "$str" ]; then - exit fail; + exit_fail fi # Make sure the entire line can be found new_str=`awk ' /tracing_mark_write:/ { sub(/^.*tracing_mark_write: /,"");printf "%s", $0; }' trace` if [ "$new_str" != "$str" ]; then - exit fail; + exit_fail fi }
diff --git a/tools/testing/selftests/ftrace/test.d/00basic/trace_marker.tc b/tools/testing/selftests/ftrace/test.d/00basic/trace_marker.tc index 9aa0db2..1986c1b 100644 --- a/tools/testing/selftests/ftrace/test.d/00basic/trace_marker.tc +++ b/tools/testing/selftests/ftrace/test.d/00basic/trace_marker.tc
@@ -68,14 +68,14 @@ new_str=`awk ' /tracing_mark_write:/ { sub(/^.*tracing_mark_write: /,"");printf "%s", $0; exit}' trace` if [ "$new_str" = "$str" ]; then - exit fail; + exit_fail fi # Make sure the entire line can be found new_str=`awk ' /tracing_mark_write:/ { sub(/^.*tracing_mark_write: /,"");printf "%s", $0; }' trace` if [ "$new_str" != "$str" ]; then - exit fail; + exit_fail fi }
diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc index ba19b81..0688a5c 100644 --- a/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc +++ b/tools/testing/selftests/ftrace/test.d/kprobe/kprobe_eventname.tc
@@ -5,7 +5,7 @@ :;: "Add an event on function without name" ;: -FUNC=`grep " [tT] .*vfs_read$" /proc/kallsyms | tail -n 1 | cut -f 3 -d " "` +FUNC=`grep " [tT] .*vfs_read$" /proc/kallsyms | grep -v __gcov | tail -n 1 | cut -f 3 -d " "` [ "x" != "x$FUNC" ] || exit_unresolved echo "p $FUNC" > kprobe_events PROBE_NAME=`echo $FUNC | tr ".:" "_"`
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onchange-action-hist.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onchange-action-hist.tc index 55ab027..04e6db2 100644 --- a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onchange-action-hist.tc +++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-onchange-action-hist.tc
@@ -1,7 +1,7 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 # description: event trigger - test inter-event histogram trigger onchange action -# requires: set_event "onchange(var)":README ping:program +# requires: set_event "onchange(var)":README ping:program nice:program # flags: instance fail() { #msg
diff --git a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-snapshot-action-hist.tc b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-snapshot-action-hist.tc index 9eb37c2..64bb0dc 100644 --- a/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-snapshot-action-hist.tc +++ b/tools/testing/selftests/ftrace/test.d/trigger/inter-event/trigger-snapshot-action-hist.tc
@@ -1,7 +1,7 @@ #!/bin/sh # SPDX-License-Identifier: GPL-2.0 # description: event trigger - test inter-event histogram trigger snapshot action -# requires: set_event snapshot events/sched/sched_process_fork/hist "onchange(var)":README "snapshot()":README ping:program +# requires: set_event snapshot events/sched/sched_process_fork/hist "onchange(var)":README "snapshot()":README ping:program nice:program # flags: instance fail() { #msg
diff --git a/tools/testing/selftests/kselftest_deps.sh b/tools/testing/selftests/kselftest_deps.sh index 487e49f..70b83436 100755 --- a/tools/testing/selftests/kselftest_deps.sh +++ b/tools/testing/selftests/kselftest_deps.sh
@@ -10,13 +10,20 @@ usage() { -echo -e "Usage: $0 -[p] <compiler> [test_name]\n" +echo -e "Usage: $0 -[p] <compiler> [ARCH=<arch>] [test_name]\n" echo -e "\tkselftest_deps.sh [-p] gcc" echo -e "\tkselftest_deps.sh [-p] gcc mm" echo -e "\tkselftest_deps.sh [-p] aarch64-linux-gnu-gcc" -echo -e "\tkselftest_deps.sh [-p] aarch64-linux-gnu-gcc mm\n" +echo -e "\tkselftest_deps.sh [-p] aarch64-linux-gnu-gcc mm" +echo -e "\tkselftest_deps.sh [-p] LLVM" +echo -e "\tkselftest_deps.sh [-p] LLVM ARCH=arm64 mm\n" echo "- Should be run in selftests directory in the kernel repo." echo "- Checks if Kselftests can be built/cross-built on a system." +echo "- Compiler can be given as LLVM to use clang, as with LLVM=1 in" +echo " the kselftest build. LLVM=<prefix>/ and LLVM=-<suffix> select" +echo " the clang binary as in the kselftest build. ARCH=<arch> selects" +echo " the clang target architecture, defaulting to the host; it is" +echo " ignored for other compilers." echo "- Parses all test/sub-test Makefile to find library dependencies." echo "- Runs compile test on a trivial C file with LDLIBS specified" echo " in the test Makefiles to identify missing library dependencies." @@ -53,13 +60,32 @@ esac done +# Pull an optional ARCH=<arch> out of the remaining arguments. The +# environment is used if it is not given on the command line, as with +# make. +args=() +for arg in "$@"; do + case "$arg" in + ARCH=*) + ARCH=${arg#ARCH=};; + *) + args+=("$arg");; + esac +done +set -- "${args[@]}" + if [ $# -eq 0 ] then usage fi # Compiler -CC=$1 +case "$1" in + LLVM|LLVM=*) + setup_llvm "${1#LLVM}";; + *) + CC=$1;; +esac tmp_file=$(mktemp).c trap "rm -f $tmp_file.o $tmp_file $tmp_file.bin" EXIT @@ -178,6 +204,56 @@ } # end main() +# Mirror the LLVM handling in lib.mk: LLVM=<prefix>/ or LLVM=-<suffix> +# select the clang binary, and ARCH selects the target triple with the +# host as the default. +setup_llvm() +{ + local llvm=${1#=} + local llvm_prefix="" + local llvm_suffix="" + local clang + local target + + declare -A clang_target + clang_target[arm]=arm-linux-gnueabi + clang_target[arm64]=aarch64-linux-gnu + clang_target[hexagon]=hexagon-linux-musl + clang_target[i386]=i386-linux-gnu + clang_target[m68k]=m68k-linux-gnu + clang_target[mips]=mipsel-linux-gnu + clang_target[powerpc]=powerpc64le-linux-gnu + clang_target[riscv]=riscv64-linux-gnu + clang_target[s390]=s390x-linux-gnu + clang_target[x86]=x86_64-linux-gnu + clang_target[x86_64]=x86_64-linux-gnu + + case "$llvm" in + */) + llvm_prefix=$llvm;; + -*) + llvm_suffix=$llvm;; + esac + clang=${llvm_prefix}clang${llvm_suffix} + + if [ -z "$ARCH" ]; then + target=$($clang -print-target-triple 2>/dev/null) + if [ -z "$target" ]; then + echo -e "\tUnable to run $clang ..." + exit 1 + fi + else + target=${clang_target[$ARCH]} + if [ -z "$target" ]; then + echo -e "\tUnknown ARCH $ARCH for LLVM, supported:" + echo -e "\t$(echo "${!clang_target[*]}" | xargs -n1 | sort | xargs)" + exit 1 + fi + fi + + CC="$clang --target=$target -fintegrated-as" +} + all_tests() { for test in $l1_tests; do @@ -285,6 +361,7 @@ { echo -e "========================================================"; echo -e "Kselftest Dependency Check for [$0 $1 $2] results..." + echo -e "Compiler: $CC" if [ $print_targets -ne 0 ] then
diff --git a/tools/testing/selftests/landlock/audit_test.c b/tools/testing/selftests/landlock/audit_test.c index 72b5612..4bea8c8 100644 --- a/tools/testing/selftests/landlock/audit_test.c +++ b/tools/testing/selftests/landlock/audit_test.c
@@ -31,7 +31,7 @@ static int matches_log_signal(struct __test_metadata *const _metadata, log_match_len = snprintf(log_match, sizeof(log_match), log_template, opid); - if (log_match_len > sizeof(log_match)) + if (log_match_len >= sizeof(log_match)) return -E2BIG; return audit_match_record(audit_fd, AUDIT_LANDLOCK_ACCESS, log_match,
diff --git a/tools/testing/selftests/landlock/base_test.c b/tools/testing/selftests/landlock/base_test.c index d20ab8f..89c0d96 100644 --- a/tools/testing/selftests/landlock/base_test.c +++ b/tools/testing/selftests/landlock/base_test.c
@@ -76,7 +76,7 @@ TEST(abi_version) const struct landlock_ruleset_attr ruleset_attr = { .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE, }; - ASSERT_EQ(11, landlock_create_ruleset(NULL, 0, + ASSERT_EQ(12, landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION)); ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0, @@ -142,6 +142,25 @@ TEST(errata) ASSERT_EQ(EINVAL, errno); } +#define PERMISSION_LAST LANDLOCK_PERMISSION_CAPABILITY_USE + +TEST(ruleset_with_unknown_permission) +{ + __u64 permission_mask; + + for (permission_mask = 1ULL << 63; permission_mask != PERMISSION_LAST; + permission_mask >>= 1) { + struct landlock_ruleset_attr ruleset_attr = { + .handled_permissions = permission_mask, + }; + + /* Unknown handled_permissions values must be rejected. */ + ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, + sizeof(ruleset_attr), 0)); + ASSERT_EQ(EINVAL, errno); + } +} + /* Tests ordering of syscall argument checks. */ TEST(create_ruleset_checks_ordering) {
diff --git a/tools/testing/selftests/landlock/cap_test.c b/tools/testing/selftests/landlock/cap_test.c new file mode 100644 index 0000000..3d7fd02 --- /dev/null +++ b/tools/testing/selftests/landlock/cap_test.c
@@ -0,0 +1,1370 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Landlock tests - Capability restriction + * + * Copyright © 2026 Cloudflare, Inc. + */ + +#define _GNU_SOURCE +#include <errno.h> +#include <fcntl.h> +#include <linux/capability.h> +#include <linux/landlock.h> +#include <sched.h> +#include <stdio.h> +#include <string.h> +#include <sys/mount.h> +#include <sys/wait.h> +#include <sys/xattr.h> +#include <unistd.h> + +#include "audit.h" +#include "common.h" +#include "trace.h" + +#define TRACE_TASK "cap_test" + +static bool list_has_xattr(const char *list, ssize_t len, const char *name) +{ + const char *p; + + for (p = list; p < list + len; p += strlen(p) + 1) + if (strcmp(p, name) == 0) + return true; + return false; +} + +static int create_cap_ruleset(void) +{ + const struct landlock_ruleset_attr attr = { + .handled_permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + }; + + return landlock_create_ruleset(&attr, sizeof(attr), 0); +} + +static int add_cap_rule(int ruleset_fd, __u64 cap) +{ + const struct landlock_capability_attr attr = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + .allowed_capabilities = (1ULL << cap), + }; + + return landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, &attr, + 0); +} + +static int add_cap_rule_full(int ruleset_fd, __u64 allowed, __u64 quiet) +{ + const struct landlock_capability_attr attr = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + .allowed_capabilities = allowed, + .quiet_capabilities = quiet, + }; + + return landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, &attr, + 0); +} + +TEST(add_rule_bad_attr) +{ + const struct landlock_ruleset_attr ns_only_attr = { + .handled_permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + }; + int ruleset_fd; + struct landlock_capability_attr attr = {}; + + ruleset_fd = create_cap_ruleset(); + ASSERT_LE(0, ruleset_fd); + + /* Invalid rule pointer returns EFAULT. */ + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + NULL, 0)); + ASSERT_EQ(EFAULT, errno); + + /* Empty permissions selector returns ENOMSG. */ + attr.permissions = 0; + attr.allowed_capabilities = (1ULL << CAP_NET_RAW); + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &attr, 0)); + ASSERT_EQ(ENOMSG, errno); + + /* Useless rule: neither allowed nor quiet capabilities set. */ + attr.permissions = LANDLOCK_PERMISSION_CAPABILITY_USE; + attr.allowed_capabilities = 0; + attr.quiet_capabilities = 0; + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &attr, 0)); + ASSERT_EQ(ENOMSG, errno); + + /* Quiet-only rule (empty allowed set) is legal. */ + attr.permissions = LANDLOCK_PERMISSION_CAPABILITY_USE; + attr.allowed_capabilities = 0; + attr.quiet_capabilities = (1ULL << CAP_NET_RAW); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &attr, 0)); + + /* Allow and quiet different members in the same rule. */ + attr.permissions = LANDLOCK_PERMISSION_CAPABILITY_USE; + attr.allowed_capabilities = (1ULL << CAP_SYS_ADMIN); + attr.quiet_capabilities = (1ULL << CAP_NET_RAW); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &attr, 0)); + + /* Valid capability selector plus an extra unhandled selector bit. */ + attr.permissions = LANDLOCK_PERMISSION_CAPABILITY_USE | + LANDLOCK_PERMISSION_NAMESPACE_USE; + attr.allowed_capabilities = (1ULL << CAP_NET_RAW); + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &attr, 0)); + ASSERT_EQ(EINVAL, errno); + + /* permissions with wrong type. */ + attr.permissions = LANDLOCK_PERMISSION_NAMESPACE_USE; + attr.allowed_capabilities = (1ULL << CAP_NET_RAW); + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &attr, 0)); + ASSERT_EQ(EINVAL, errno); + + /* + * Unknown capability bits (e.g. bit 63) are silently accepted for + * forward compatibility. Only known bits are stored. + */ + attr.permissions = LANDLOCK_PERMISSION_CAPABILITY_USE; + attr.allowed_capabilities = 1ULL << 63; + attr.quiet_capabilities = 0; + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &attr, 0)); + + /* + * LANDLOCK_ADD_RULE_QUIET (and any other flag) is filesystem/network + * only and must be rejected for capability rules, even when every attr + * field is otherwise valid. + */ + attr.permissions = LANDLOCK_PERMISSION_CAPABILITY_USE; + attr.allowed_capabilities = (1ULL << CAP_NET_RAW); + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &attr, LANDLOCK_ADD_RULE_QUIET)); + ASSERT_EQ(EINVAL, errno); + + EXPECT_EQ(0, close(ruleset_fd)); + + /* + * Ruleset handles LANDLOCK_PERMISSION_NAMESPACE_USE but not + * LANDLOCK_PERMISSION_CAPABILITY_USE: adding a capability rule must be + * rejected. + */ + ruleset_fd = + landlock_create_ruleset(&ns_only_attr, sizeof(ns_only_attr), 0); + ASSERT_LE(0, ruleset_fd); + attr.permissions = LANDLOCK_PERMISSION_CAPABILITY_USE; + attr.allowed_capabilities = (1ULL << CAP_NET_RAW); + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &attr, 0)); + ASSERT_EQ(EINVAL, errno); + EXPECT_EQ(0, close(ruleset_fd)); +} + +/* + * Unknown capability values above CAP_LAST_CAP are silently accepted + * (allow-list: they have no effect since the kernel never checks them). + */ +TEST(add_rule_unknown) +{ + int ruleset_fd; + struct landlock_capability_attr attr = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + }; + + ruleset_fd = create_cap_ruleset(); + ASSERT_LE(0, ruleset_fd); + + /* Just above CAP_LAST_CAP should succeed. */ + attr.allowed_capabilities = (1ULL << (CAP_LAST_CAP + 1)); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &attr, 0)); + + /* High values (below bit 63) should succeed. */ + attr.allowed_capabilities = (1ULL << 62); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &attr, 0)); + + EXPECT_EQ(0, close(ruleset_fd)); +} + +/* + * A rule that lists only capability bits unknown to the running kernel is + * accepted by landlock_add_rule() but has no runtime effect: once the domain is + * enforced, any actual CAP_* capability is still denied by the per-category + * deny-by-default behaviour. This documents the forward-compatibility + * contract: unknown bits are silently accepted so the same policy can be loaded + * across kernels, but they never grant a capability that the running kernel + * knows nothing about. + */ +TEST(add_rule_unknown_no_runtime_effect) +{ + const struct landlock_ruleset_attr ruleset_attr = { + .handled_permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + }; + struct landlock_capability_attr attr = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + /* Only unknown bits above CAP_LAST_CAP. */ + .allowed_capabilities = (1ULL << (CAP_LAST_CAP + 1)) | + (1ULL << 62), + }; + int ruleset_fd; + + disable_caps(_metadata); + + ruleset_fd = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + ASSERT_LE(0, ruleset_fd); + + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &attr, 0)); + + /* + * Isolate hostname changes and establish a baseline: with CAP_SYS_ADMIN + * and absent the domain, sethostname(2) succeeds. This ensures the + * EPERM below is attributable to Landlock rather than to a missing + * capability, and fails if the hook always allows. + */ + set_cap(_metadata, CAP_SYS_ADMIN); + ASSERT_EQ(0, unshare(CLONE_NEWUTS)); + ASSERT_EQ(0, sethostname("baseline", 8)); + clear_cap(_metadata, CAP_SYS_ADMIN); + + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* + * CAP_SYS_ADMIN is a real, known capability but was not authorised by + * the rule above; deny-by-default applies. sethostname(2) requires + * CAP_SYS_ADMIN. + */ + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(-1, sethostname("test", 4)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); +} + +/* clang-format off */ +FIXTURE(cap_enforce) {}; +/* clang-format on */ + +FIXTURE_VARIANT(cap_enforce) +{ + const bool is_sandboxed; + const bool handle_caps; + const __u64 allowed_cap; + const int expected_sysadmin; + const int expected_chroot; +}; + +/* + * Unsandboxed baseline: no Landlock domain is enforced. Both capabilities + * should work normally. + */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(cap_enforce, unsandboxed) { + .is_sandboxed = false, + .handle_caps = false, + .allowed_cap = 0, + .expected_sysadmin = 0, + .expected_chroot = 0, +}; +/* clang-format on */ + +/* + * Denied: capabilities are handled but no rule allows them. All capability + * checks must be denied by Landlock even if the capability is effective. + */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(cap_enforce, denied) { + .is_sandboxed = true, + .handle_caps = true, + .allowed_cap = 0, + .expected_sysadmin = EPERM, + .expected_chroot = EPERM, +}; +/* clang-format on */ + +/* + * Allowed: CAP_SYS_ADMIN is allowed by rule, CAP_SYS_CHROOT is not. Only the + * explicitly allowed capability should succeed. + */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(cap_enforce, allowed) { + .is_sandboxed = true, + .handle_caps = true, + .allowed_cap = CAP_SYS_ADMIN, + .expected_sysadmin = 0, + .expected_chroot = EPERM, +}; +/* clang-format on */ + +/* + * Unhandled: the ruleset does not handle LANDLOCK_PERMISSION_CAPABILITY_USE at + * all (only handles FS access). Both capabilities should work since the domain + * does not restrict them. + */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(cap_enforce, unhandled) { + .is_sandboxed = true, + .handle_caps = false, + .allowed_cap = 0, + .expected_sysadmin = 0, + .expected_chroot = 0, +}; +/* clang-format on */ + +FIXTURE_SETUP(cap_enforce) +{ + disable_caps(_metadata); +} + +FIXTURE_TEARDOWN(cap_enforce) +{ +} + +/* + * Capability enforcement: tests the four fundamental enforcement scenarios + * (unsandboxed baseline, denied, allowed, unhandled) using two independent + * capability checks (sethostname for CAP_SYS_ADMIN, chroot for CAP_SYS_CHROOT). + */ +TEST_F(cap_enforce, use) +{ + int ruleset_fd; + + /* Isolate hostname changes from other tests. */ + set_cap(_metadata, CAP_SYS_ADMIN); + ASSERT_EQ(0, unshare(CLONE_NEWUTS)); + clear_cap(_metadata, CAP_SYS_ADMIN); + + if (variant->is_sandboxed) { + if (variant->handle_caps) { + ruleset_fd = create_cap_ruleset(); + } else { + const struct landlock_ruleset_attr attr = { + .handled_access_fs = + LANDLOCK_ACCESS_FS_READ_FILE, + }; + + ruleset_fd = + landlock_create_ruleset(&attr, sizeof(attr), 0); + } + ASSERT_LE(0, ruleset_fd); + + if (variant->allowed_cap) + ASSERT_EQ(0, add_cap_rule(ruleset_fd, + variant->allowed_cap)); + + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + } + + /* Test CAP_SYS_ADMIN via sethostname. */ + set_cap(_metadata, CAP_SYS_ADMIN); + if (variant->expected_sysadmin) { + EXPECT_EQ(-1, sethostname("test", 4)); + EXPECT_EQ(variant->expected_sysadmin, errno); + } else { + EXPECT_EQ(0, sethostname("test", 4)); + } + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* Test CAP_SYS_CHROOT via chroot. */ + set_cap(_metadata, CAP_SYS_CHROOT); + if (variant->expected_chroot) { + EXPECT_EQ(-1, chroot("/")); + EXPECT_EQ(variant->expected_chroot, errno); + } else { + EXPECT_EQ(0, chroot("/")); + } + clear_cap(_metadata, CAP_SYS_CHROOT); +} + +/* + * Layer stacking: both layers must allow CAP_SYS_ADMIN for the capability to be + * exercisable. Variants cover the three per-layer combinations that exercise + * distinct walker paths (allow/deny, allow/allow, deny/allow), an unsandboxed + * baseline, and a mixed-layer case where one layer does not handle + * LANDLOCK_PERMISSION_CAPABILITY_USE at all. + */ +/* clang-format off */ +FIXTURE(cap_stacking) {}; +/* clang-format on */ + +FIXTURE_VARIANT(cap_stacking) +{ + const bool is_sandboxed; + const bool first_layer_allows; + const bool second_layer_allows; + const bool second_layer_is_fs_only; + const int expected_sysadmin; + const int expected_chroot; +}; + +/* + * Unsandboxed baseline: no Landlock layers are stacked. Both capabilities + * should work normally. + */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(cap_stacking, unsandboxed) { + .is_sandboxed = false, + .first_layer_allows = false, + .second_layer_allows = false, + .expected_sysadmin = 0, + .expected_chroot = 0, +}; +/* clang-format on */ + +/* Layer 1 allows CAP_SYS_ADMIN, layer 2 denies -> denied. */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(cap_stacking, deny) { + .is_sandboxed = true, + .first_layer_allows = true, + .second_layer_allows = false, + .expected_sysadmin = EPERM, + .expected_chroot = EPERM, +}; +/* clang-format on */ + +/* Both layers allow CAP_SYS_ADMIN -> sysadmin succeeds, chroot still denied. */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(cap_stacking, allow) { + .is_sandboxed = true, + .first_layer_allows = true, + .second_layer_allows = true, + .expected_sysadmin = 0, + .expected_chroot = EPERM, +}; +/* clang-format on */ + +/* + * Layer 1 denies CAP_SYS_ADMIN, layer 2 allows -> still denied: a child layer + * cannot grant what an ancestor layer withheld. Complements the + * parent-allows/child-denies variant; together they verify the walker checks + * both layers and accepts only the (allow, allow) cell. + */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(cap_stacking, parent_denies) { + .is_sandboxed = true, + .first_layer_allows = false, + .second_layer_allows = true, + .expected_sysadmin = EPERM, + .expected_chroot = EPERM, +}; +/* clang-format on */ + +/* + * Mixed layers: first layer handles LANDLOCK_PERMISSION_CAPABILITY_USE (denies + * all caps), second layer is FS-only (does not handle it). The permission + * walker iterates from youngest (layer 1) to oldest (layer 0) and must skip the + * FS-only layer to find the denying layer beneath. + */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(cap_stacking, mixed_layers) { + /* clang-format on */ + .is_sandboxed = true, + .first_layer_allows = false, + .second_layer_is_fs_only = true, + .expected_sysadmin = EPERM, + .expected_chroot = EPERM, +}; + +FIXTURE_SETUP(cap_stacking) +{ + disable_caps(_metadata); + + /* Isolate every successful sethostname() from the other tests. */ + set_cap(_metadata, CAP_SYS_ADMIN); + ASSERT_EQ(0, unshare(CLONE_NEWUTS)); + clear_cap(_metadata, CAP_SYS_ADMIN); +} + +FIXTURE_TEARDOWN(cap_stacking) +{ +} + +TEST_F(cap_stacking, two_layers) +{ + int ruleset_fd; + + if (variant->is_sandboxed) { + /* + * First layer: handles LANDLOCK_PERMISSION_CAPABILITY_USE; rule + * added per variant. + */ + ruleset_fd = create_cap_ruleset(); + ASSERT_LE(0, ruleset_fd); + if (variant->first_layer_allows) + ASSERT_EQ(0, add_cap_rule(ruleset_fd, CAP_SYS_ADMIN)); + + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + if (variant->second_layer_is_fs_only) { + /* + * Second layer: FS-only (does not handle + * LANDLOCK_PERMISSION_CAPABILITY_USE). The permission + * walker must skip this layer. + */ + const struct landlock_ruleset_attr fs_attr = { + .handled_access_fs = + LANDLOCK_ACCESS_FS_READ_FILE, + }; + + ruleset_fd = landlock_create_ruleset( + &fs_attr, sizeof(fs_attr), 0); + } else { + /* Second layer: cap allow or deny. */ + ruleset_fd = create_cap_ruleset(); + if (variant->second_layer_allows) + ASSERT_EQ(0, add_cap_rule(ruleset_fd, + CAP_SYS_ADMIN)); + } + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + } + + /* Test CAP_SYS_ADMIN via sethostname. */ + set_cap(_metadata, CAP_SYS_ADMIN); + if (variant->expected_sysadmin) { + EXPECT_EQ(-1, sethostname("test", 4)); + EXPECT_EQ(variant->expected_sysadmin, errno); + } else { + EXPECT_EQ(0, sethostname("test", 4)); + } + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* Test CAP_SYS_CHROOT via chroot. */ + set_cap(_metadata, CAP_SYS_CHROOT); + if (variant->expected_chroot) { + EXPECT_EQ(-1, chroot("/")); + EXPECT_EQ(variant->expected_chroot, errno); + } else { + EXPECT_EQ(0, chroot("/")); + } + clear_cap(_metadata, CAP_SYS_CHROOT); +} + +/* + * Verify that LANDLOCK_PERMISSION_CAPABILITY_USE enforces when the domain is + * applied without no_new_privs, using CAP_SYS_ADMIN for + * landlock_restrict_self() authorization instead. Privileged processes (e.g. + * container managers) can sandbox themselves this way. + */ +TEST(cap_without_nnp) +{ + int ruleset_fd; + + disable_caps(_metadata); + + /* Isolate an unexpected successful sethostname(). */ + set_cap(_metadata, CAP_SYS_ADMIN); + ASSERT_EQ(0, unshare(CLONE_NEWUTS)); + clear_cap(_metadata, CAP_SYS_ADMIN); + + ruleset_fd = create_cap_ruleset(); + ASSERT_LE(0, ruleset_fd); + + /* Allow CAP_SYS_CHROOT but not CAP_SYS_ADMIN. */ + ASSERT_EQ(0, add_cap_rule(ruleset_fd, CAP_SYS_CHROOT)); + + /* + * Enforce WITHOUT NNP: landlock_restrict_self() succeeds when the + * caller has CAP_SYS_ADMIN (checked before the new domain takes + * effect). + */ + set_cap(_metadata, CAP_SYS_ADMIN); + ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0)); + EXPECT_EQ(0, close(ruleset_fd)); + + /* + * CAP_SYS_ADMIN is still in effective set but Landlock denies it: + * cap_capable() returns 0, then hook_capable() returns -EPERM. + */ + EXPECT_EQ(-1, sethostname("test", 4)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* CAP_SYS_CHROOT is allowed by the rule. */ + set_cap(_metadata, CAP_SYS_CHROOT); + EXPECT_EQ(0, chroot("/")); + clear_cap(_metadata, CAP_SYS_CHROOT); +} + +/* + * Verify that capabilities gained through user namespace ownership are still + * restricted by LANDLOCK_PERMISSION_CAPABILITY_USE. When a process creates a + * user namespace, the kernel grants CAP_FULL_SET in the new namespace via + * cap_capable_helper()'s ownership bypass. Landlock's hook_capable() must + * still deny capabilities not in the allowed set, ensuring that user namespace + * creation cannot be used to escape capability restrictions. + */ +TEST(cap_userns_ownership_bypass) +{ + pid_t child; + int status; + + child = fork(); + ASSERT_LE(0, child); + if (child == 0) { + int ruleset_fd; + + disable_caps(_metadata); + + ruleset_fd = create_cap_ruleset(); + ASSERT_LE(0, ruleset_fd); + + /* Allow CAP_SYS_ADMIN only. */ + ASSERT_EQ(0, add_cap_rule(ruleset_fd, CAP_SYS_ADMIN)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* + * Create a user namespace. This is unprivileged and does not + * require capabilities. LANDLOCK_PERMISSION_NAMESPACE_USE is + * not handled so namespace creation is unrestricted. + */ + ASSERT_EQ(0, unshare(CLONE_NEWUSER)); + + /* + * After unshare(CLONE_NEWUSER), the kernel set cap_effective = + * CAP_FULL_SET in the new namespace. Create a UTS namespace + * (requires CAP_SYS_ADMIN in the new user NS). Landlock allows + * CAP_SYS_ADMIN. + */ + ASSERT_EQ(0, unshare(CLONE_NEWUTS)) + { + TH_LOG("unshare(CLONE_NEWUTS): %s", strerror(errno)); + } + + /* + * sethostname checks against uts_ns->user_ns, which is now the + * new user NS. CAP_SYS_ADMIN is allowed. + */ + EXPECT_EQ(0, sethostname("test", 4)); + + /* + * chroot checks against current_user_ns(), which is the new + * user NS. The process has CAP_SYS_CHROOT in cap_effective + * (from user NS creation), so cap_capable() returns 0. But + * Landlock denies because no rule allows CAP_SYS_CHROOT. + */ + EXPECT_EQ(-1, chroot("/")); + EXPECT_EQ(EPERM, errno); + + _exit(_metadata->exit_code); + return; + } + + ASSERT_EQ(child, waitpid(child, &status, 0)); + if (WIFSIGNALED(status) || !WIFEXITED(status) || + WEXITSTATUS(status) != EXIT_SUCCESS) + _metadata->exit_code = KSFT_FAIL; +} + +/* + * Verify that capability restrictions do not depend on which user namespace the + * kernel checks. An actor in the initial user namespace can enter a descendant + * user namespace with CAP_SYS_ADMIN. With the same Linux capability state, + * handling capability use without an allow rule must deny that target-namespace + * check even though the target differs from current_user_ns(). + */ +TEST(cap_target_userns_independent) +{ + int sockets[2], status, target_userns_fd; + pid_t actor, target; + + disable_caps(_metadata); + ASSERT_EQ(0, + socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, sockets)); + + target = fork(); + ASSERT_LE(0, target); + if (target == 0) { + int fd; + + close(sockets[0]); + if (unshare(CLONE_NEWUSER)) + _exit(255); + fd = open("/proc/self/ns/user", O_RDONLY | O_CLOEXEC); + if (fd < 0 || send_fd(sockets[1], fd)) + _exit(255); + close(fd); + close(sockets[1]); + _exit(EXIT_SUCCESS); + } + + close(sockets[1]); + target_userns_fd = recv_fd(sockets[0]); + ASSERT_LE(0, target_userns_fd); + EXPECT_EQ(0, close(sockets[0])); + ASSERT_EQ(target, waitpid(target, &status, 0)); + ASSERT_TRUE(WIFEXITED(status)); + ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); + + set_cap(_metadata, CAP_SYS_ADMIN); + for (int sandboxed = 0; sandboxed <= 1; sandboxed++) { + actor = fork(); + ASSERT_LE(0, actor); + if (actor == 0) { + int ret, saved_errno; + + if (sandboxed) { + int ruleset_fd = create_cap_ruleset(); + + if (ruleset_fd < 0 || + prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) || + landlock_restrict_self(ruleset_fd, 0) || + close(ruleset_fd)) + _exit(255); + } + + ret = setns(target_userns_fd, CLONE_NEWUSER); + saved_errno = errno; + _exit(ret ? saved_errno : EXIT_SUCCESS); + } + + ASSERT_EQ(actor, waitpid(actor, &status, 0)); + ASSERT_TRUE(WIFEXITED(status)); + EXPECT_EQ(sandboxed ? EPERM : EXIT_SUCCESS, + WEXITSTATUS(status)); + } + clear_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, close(target_userns_fd)); +} + +/* Audit tests */ + +static int matches_log_cap(int audit_fd, int cap_number) +{ + static const char log_template[] = REGEX_LANDLOCK_PREFIX + " blockers=capability\\.use capability=%d $"; + char log_match[sizeof(log_template) + 10]; + int log_match_len; + + log_match_len = snprintf(log_match, sizeof(log_match), log_template, + cap_number); + if (log_match_len >= sizeof(log_match)) + return -E2BIG; + + return audit_match_record(audit_fd, AUDIT_LANDLOCK_ACCESS, log_match, + NULL); +} + +FIXTURE(cap_audit) +{ + struct audit_filter audit_filter; + int audit_fd; +}; + +FIXTURE_SETUP(cap_audit) +{ + ASSERT_TRUE(is_in_init_user_ns()); + + disable_caps(_metadata); + + /* Isolate successful sethostname() calls. */ + set_cap(_metadata, CAP_SYS_ADMIN); + ASSERT_EQ(0, unshare(CLONE_NEWUTS)); + clear_cap(_metadata, CAP_SYS_ADMIN); + + set_cap(_metadata, CAP_AUDIT_CONTROL); + self->audit_fd = audit_init_with_exe_filter(&self->audit_filter); + EXPECT_LE(0, self->audit_fd); + clear_cap(_metadata, CAP_AUDIT_CONTROL); +} + +FIXTURE_TEARDOWN(cap_audit) +{ + set_cap(_metadata, CAP_AUDIT_CONTROL); + EXPECT_EQ(0, audit_cleanup(self->audit_fd, &self->audit_filter)); + clear_cap(_metadata, CAP_AUDIT_CONTROL); +} + +/* + * Verifies that a denied capability produces the expected audit record with the + * correct capability number and blocker string. + */ +TEST_F(cap_audit, denied) +{ + struct audit_records records = {}; + int ruleset_fd; + __u64 domain_id; + + /* Baseline: chroot works before Landlock. */ + set_cap(_metadata, CAP_SYS_CHROOT); + ASSERT_EQ(0, chroot("/")); + clear_cap(_metadata, CAP_SYS_CHROOT); + + ruleset_fd = create_cap_ruleset(); + ASSERT_LE(0, ruleset_fd); + /* Allow CAP_AUDIT_CONTROL for child-side audit cleanup. */ + ASSERT_EQ(0, add_cap_rule(ruleset_fd, CAP_AUDIT_CONTROL)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* Deny CAP_SYS_CHROOT (no allow rule). */ + set_cap(_metadata, CAP_SYS_CHROOT); + EXPECT_EQ(-1, chroot("/")); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_CHROOT); + + EXPECT_EQ(0, matches_log_cap(self->audit_fd, CAP_SYS_CHROOT)); + + /* + * The domain allocation record is emitted in the same event as the + * first denial; anchor its status=allocated and enforcing pid. Both + * access and domain records are now consumed, so none remain. + */ + EXPECT_EQ(0, matches_log_domain_allocated(self->audit_fd, getpid(), + &domain_id)); + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); + EXPECT_EQ(0, records.domain); +} + +TEST_F(cap_audit, allowed) +{ + struct audit_records records = {}; + int ruleset_fd; + + ruleset_fd = create_cap_ruleset(); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, add_cap_rule(ruleset_fd, CAP_SYS_ADMIN)); + /* Allow CAP_AUDIT_CONTROL for child-side audit cleanup. */ + ASSERT_EQ(0, add_cap_rule(ruleset_fd, CAP_AUDIT_CONTROL)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, sethostname("test", 4)); + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* No records: allowed operations never trigger audit logging. */ + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); +} + +/* An allowed capability remains allowed when the same rule also quiets it. */ +TEST_F(cap_audit, allow_and_quiet_same_member) +{ + struct audit_records records = {}; + int ruleset_fd; + + ruleset_fd = create_cap_ruleset(); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, add_cap_rule_full(ruleset_fd, + (1ULL << CAP_SYS_ADMIN) | + (1ULL << CAP_AUDIT_CONTROL), + 1ULL << CAP_SYS_ADMIN)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, sethostname("test", 4)); + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* + * Quiet is inert for the allowed member: nothing is denied or logged. + */ + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); +} + +/* + * A quieted capability denial is still denied (EPERM); only its audit record is + * suppressed. Quiet-only rule (empty allowed set). + */ +TEST_F(cap_audit, quieted) +{ + struct audit_records records = {}; + int ruleset_fd; + __u64 domain_id; + + ruleset_fd = create_cap_ruleset(); + ASSERT_LE(0, ruleset_fd); + /* Allow CAP_AUDIT_CONTROL for child-side audit cleanup. */ + ASSERT_EQ(0, add_cap_rule(ruleset_fd, CAP_AUDIT_CONTROL)); + ASSERT_EQ(0, + add_cap_rule_full(ruleset_fd, 0, (1ULL << CAP_SYS_CHROOT))); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + set_cap(_metadata, CAP_SYS_CHROOT); + EXPECT_EQ(-1, chroot("/")); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_CHROOT); + + /* + * Positive control: CAP_SYS_ADMIN is denied but not quieted, so its + * denial IS logged. This proves quieting is per-member, not global. + */ + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(-1, sethostname("test", 4)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* + * The quieted CAP_SYS_CHROOT denial is suppressed; the CAP_SYS_ADMIN + * denial is logged. + */ + EXPECT_EQ(0, matches_log_cap(self->audit_fd, CAP_SYS_ADMIN)); + EXPECT_EQ(0, matches_log_domain_allocated(self->audit_fd, getpid(), + &domain_id)); + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); + EXPECT_EQ(0, records.domain); +} + +/* + * Only the youngest denying layer decides quieting: a parent cannot silence a + * denial by a deeper layer that handles but does not quiet the capability. + */ +TEST_F(cap_audit, quiet_youngest_layer_wins) +{ + struct audit_records records = {}; + int ruleset_fd; + __u64 domain_id; + + /* Baseline: commoncap allows chroot before Landlock. */ + set_cap(_metadata, CAP_SYS_CHROOT); + ASSERT_EQ(0, chroot("/")); + clear_cap(_metadata, CAP_SYS_CHROOT); + + /* Parent layer: denies and quiets CAP_SYS_CHROOT. */ + ruleset_fd = create_cap_ruleset(); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, add_cap_rule_full(ruleset_fd, 1ULL << CAP_AUDIT_CONTROL, + 1ULL << CAP_SYS_CHROOT)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* Child layer: denies CAP_SYS_CHROOT without quieting it. */ + ruleset_fd = create_cap_ruleset(); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, add_cap_rule(ruleset_fd, CAP_AUDIT_CONTROL)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + set_cap(_metadata, CAP_SYS_CHROOT); + EXPECT_EQ(-1, chroot("/")); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_CHROOT); + + /* + * The child is the youngest denier and does not quiet: log the denial. + */ + EXPECT_EQ(0, matches_log_cap(self->audit_fd, CAP_SYS_CHROOT)); + EXPECT_EQ(0, matches_log_domain_allocated(self->audit_fd, getpid(), + &domain_id)); + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); + EXPECT_EQ(0, records.domain); +} + +/* + * Quieting an unknown capability bit has no effect: a rule that quiets only a + * bit above CAP_LAST_CAP still logs the denial of a known capability. + */ +TEST_F(cap_audit, quiet_unknown_bit_no_effect) +{ + struct audit_records records = {}; + int ruleset_fd; + __u64 domain_id; + + ruleset_fd = create_cap_ruleset(); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, add_cap_rule(ruleset_fd, CAP_AUDIT_CONTROL)); + /* Quiet only an unknown bit (bit 63 is above CAP_LAST_CAP). */ + ASSERT_EQ(0, add_cap_rule_full(ruleset_fd, 0, (1ULL << 63))); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + set_cap(_metadata, CAP_SYS_CHROOT); + EXPECT_EQ(-1, chroot("/")); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_CHROOT); + + /* The unknown quiet bit does not suppress the known denial. */ + EXPECT_EQ(0, matches_log_cap(self->audit_fd, CAP_SYS_CHROOT)); + EXPECT_EQ(0, matches_log_domain_allocated(self->audit_fd, getpid(), + &domain_id)); + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); + EXPECT_EQ(0, records.domain); +} + +/* + * A capability check made with CAP_OPT_NOAUDIT is denied by Landlock but not + * logged: hook_capable() emits no Landlock audit record when the caller passes + * CAP_OPT_NOAUDIT, so the denial is silent here even though CAP_SYS_ADMIN is + * neither allowed nor quieted. The probe is the + * ns_capable_noaudit(CAP_SYS_ADMIN) call in simple_xattr_list(), reached + * through tmpfs, which decides whether trusted.* xattrs are visible to + * listxattr(2). + */ +TEST_F(cap_audit, noaudit_probe_not_logged) +{ + struct audit_records records = {}; + int ruleset_fd, fd; + __u64 domain_id; + char list[256]; + ssize_t len; + + /* + * Private tmpfs holding a trusted.* xattr so its listxattr(2) + * visibility depends only on the CAP_SYS_ADMIN noaudit probe. + */ + set_cap(_metadata, CAP_SYS_ADMIN); + ASSERT_EQ(0, unshare(CLONE_NEWNS)); + ASSERT_EQ(0, mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL)); + ASSERT_EQ(0, mount("test", "/tmp", "tmpfs", 0, NULL)); + fd = open("/tmp/f", O_CREAT | O_RDWR | O_CLOEXEC, 0600); + ASSERT_LE(0, fd); + ASSERT_EQ(0, fsetxattr(fd, "trusted.landlock_test", "x", 1, 0)); + + /* Baseline: with CAP_SYS_ADMIN, the trusted xattr is listed. */ + len = flistxattr(fd, list, sizeof(list)); + ASSERT_LE(0, len); + ASSERT_TRUE(list_has_xattr(list, len, "trusted.landlock_test")); + + ruleset_fd = create_cap_ruleset(); + ASSERT_LE(0, ruleset_fd); + /* Allow CAP_AUDIT_CONTROL for child-side audit cleanup. */ + ASSERT_EQ(0, add_cap_rule(ruleset_fd, CAP_AUDIT_CONTROL)); + /* CAP_SYS_ADMIN is neither allowed nor quieted. */ + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* + * CAP_SYS_ADMIN is still effective, but Landlock denies the noaudit + * probe, so the trusted.* xattr is filtered out of the listing. + */ + len = flistxattr(fd, list, sizeof(list)); + ASSERT_LE(0, len); + EXPECT_FALSE(list_has_xattr(list, len, "trusted.landlock_test")); + EXPECT_EQ(0, close(fd)); + + /* The denied noaudit probe leaves no audit record nor denial. */ + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); + + /* + * Positive control: a normal (audited) CAP_SYS_ADMIN denial in the same + * domain IS logged. This proves the empty record set above is caused + * by CAP_OPT_NOAUDIT, not by an always-allow or always-silent bug. + */ + EXPECT_EQ(-1, sethostname("test", 4)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + + EXPECT_EQ(0, matches_log_cap(self->audit_fd, CAP_SYS_ADMIN)); + EXPECT_EQ(0, matches_log_domain_allocated(self->audit_fd, getpid(), + &domain_id)); + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); + EXPECT_EQ(0, records.domain); +} + +/* Trace tests */ + +/* clang-format off */ +FIXTURE(cap_trace) { + /* clang-format on */ + int tracefs_ok; +}; + +FIXTURE_SETUP(cap_trace) +{ + int ret; + + set_cap(_metadata, CAP_SYS_ADMIN); + ASSERT_EQ(0, unshare(CLONE_NEWNS)); + ASSERT_EQ(0, mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL)); + + ret = tracefs_fixture_setup(); + if (ret) { + clear_cap(_metadata, CAP_SYS_ADMIN); + self->tracefs_ok = 0; + SKIP(return, "tracefs not available"); + } + self->tracefs_ok = 1; + + ASSERT_EQ(0, tracefs_enable_event(TRACEFS_CREATE_RULESET_ENABLE, true)); + ASSERT_EQ(0, tracefs_enable_event(TRACEFS_ADD_RULE_CAPABILITY_ENABLE, + true)); + ASSERT_EQ(0, tracefs_enable_event( + TRACEFS_DENY_PERMISSION_CAPABILITY_ENABLE, true)); + ASSERT_EQ(0, tracefs_clear()); + clear_cap(_metadata, CAP_SYS_ADMIN); +} + +FIXTURE_TEARDOWN(cap_trace) +{ + if (!self->tracefs_ok) + return; + + set_cap(_metadata, CAP_SYS_ADMIN); + tracefs_enable_event(TRACEFS_CREATE_RULESET_ENABLE, false); + tracefs_enable_event(TRACEFS_ADD_RULE_CAPABILITY_ENABLE, false); + tracefs_enable_event(TRACEFS_DENY_PERMISSION_CAPABILITY_ENABLE, false); + tracefs_fixture_teardown(); + clear_cap(_metadata, CAP_SYS_ADMIN); +} + +/* + * Check the permission fields and version history, including two rejected calls + * and two successful calls that do not extend the effective policy: a repeated + * rule and an unknown-only rule. + */ +TEST_F(cap_trace, rule_events) +{ + const char *const version_1 = + REGEX_ADD_RULE_CAPABILITY_VERSION(TRACE_TASK, "1"); + const char *const version_2 = + REGEX_ADD_RULE_CAPABILITY_VERSION(TRACE_TASK, "2"); + const char *const version_3 = + REGEX_ADD_RULE_CAPABILITY_VERSION(TRACE_TASK, "3"); + const struct landlock_capability_attr valid_attr = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + .allowed_capabilities = 1ULL << CAP_SYS_ADMIN, + .quiet_capabilities = 1ULL << CAP_SYS_CHROOT, + }; + const struct landlock_capability_attr invalid_attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + .allowed_capabilities = 1ULL << CAP_SYS_ADMIN, + }; + char expected[32], field[64]; + char *buf; + int ruleset_fd; + + if (!self->tracefs_ok) + SKIP(return, "tracefs not available"); + + ASSERT_EQ(0, tracefs_clear_buf()); + + ruleset_fd = create_cap_ruleset(); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, add_cap_rule_full(ruleset_fd, 1ULL << CAP_SYS_ADMIN, + 1ULL << CAP_SYS_CHROOT)); + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &invalid_attr, 0)); + ASSERT_EQ(EINVAL, errno); + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &valid_attr, LANDLOCK_ADD_RULE_QUIET)); + ASSERT_EQ(EINVAL, errno); + ASSERT_EQ(0, add_cap_rule_full(ruleset_fd, 1ULL << CAP_SYS_ADMIN, + 1ULL << CAP_SYS_CHROOT)); + ASSERT_EQ(0, add_cap_rule(ruleset_fd, 63)); + EXPECT_EQ(0, close(ruleset_fd)); + + buf = tracefs_read_buf(); + ASSERT_NE(NULL, buf); + + ASSERT_EQ(1, + tracefs_count_matches(buf, REGEX_CREATE_RULESET(TRACE_TASK))); + ASSERT_EQ(0, tracefs_extract_field( + buf, REGEX_CREATE_RULESET(TRACE_TASK), + "handled_permissions", field, sizeof(field))); + EXPECT_STREQ("capability.use", field); + + ASSERT_EQ(3, + tracefs_count_matches(buf, "landlock_add_rule_capability: ")); + ASSERT_EQ(3, tracefs_count_matches( + buf, REGEX_ADD_RULE_CAPABILITY(TRACE_TASK))); + EXPECT_EQ(1, tracefs_count_matches(buf, version_1)); + EXPECT_EQ(1, tracefs_count_matches(buf, version_2)); + EXPECT_EQ(1, tracefs_count_matches(buf, version_3)); + + ASSERT_EQ(0, tracefs_extract_field(buf, version_1, "permissions", field, + sizeof(field))); + EXPECT_STREQ("capability.use", field); + ASSERT_EQ(0, + tracefs_extract_field(buf, version_1, "allowed_capabilities", + field, sizeof(field))); + snprintf(expected, sizeof(expected), "0x%llx", 1ULL << CAP_SYS_ADMIN); + EXPECT_STREQ(expected, field); + ASSERT_EQ(0, tracefs_extract_field(buf, version_1, "quiet_capabilities", + field, sizeof(field))); + snprintf(expected, sizeof(expected), "0x%llx", 1ULL << CAP_SYS_CHROOT); + EXPECT_STREQ(expected, field); + + /* The rejected calls emit no event and do not consume version 2. */ + ASSERT_EQ(0, tracefs_extract_field(buf, version_2, "permissions", field, + sizeof(field))); + EXPECT_STREQ("capability.use", field); + ASSERT_EQ(0, + tracefs_extract_field(buf, version_2, "allowed_capabilities", + field, sizeof(field))); + snprintf(expected, sizeof(expected), "0x%llx", 1ULL << CAP_SYS_ADMIN); + EXPECT_STREQ(expected, field); + ASSERT_EQ(0, tracefs_extract_field(buf, version_2, "quiet_capabilities", + field, sizeof(field))); + snprintf(expected, sizeof(expected), "0x%llx", 1ULL << CAP_SYS_CHROOT); + EXPECT_STREQ(expected, field); + + /* The unknown-only call succeeds but contributes no effective bits. */ + ASSERT_EQ(0, tracefs_extract_field(buf, version_3, "permissions", field, + sizeof(field))); + EXPECT_STREQ("capability.use", field); + ASSERT_EQ(0, + tracefs_extract_field(buf, version_3, "allowed_capabilities", + field, sizeof(field))); + EXPECT_STREQ("0x0", field); + ASSERT_EQ(0, tracefs_extract_field(buf, version_3, "quiet_capabilities", + field, sizeof(field))); + EXPECT_STREQ("0x0", field); + + free(buf); +} + +enum cap_trace_denial_kind { + CAP_TRACE_DENY, + CAP_TRACE_DENY_QUIET, + CAP_TRACE_DENY_NOAUDIT, +}; + +static void exercise_cap_trace_denial(struct __test_metadata *const _metadata, + const enum cap_trace_denial_kind kind) +{ + int ruleset_fd, fd = -1; + char list[256]; + ssize_t len; + + disable_caps(_metadata); + + if (kind == CAP_TRACE_DENY_NOAUDIT) { + set_cap(_metadata, CAP_SYS_ADMIN); + set_cap(_metadata, CAP_SYS_CHROOT); + ASSERT_EQ(0, mount("test", "/tmp", "tmpfs", 0, NULL)); + fd = open("/tmp/f", O_CREAT | O_RDWR | O_CLOEXEC, 0600); + ASSERT_LE(0, fd); + ASSERT_EQ(0, fsetxattr(fd, "trusted.landlock_test", "x", 1, 0)); + + /* Baseline: CAP_SYS_ADMIN exposes the trusted xattr. */ + len = flistxattr(fd, list, sizeof(list)); + ASSERT_LE(0, len); + ASSERT_TRUE(list_has_xattr(list, len, "trusted.landlock_test")); + } else { + set_cap(_metadata, CAP_SYS_CHROOT); + } + + ruleset_fd = create_cap_ruleset(); + ASSERT_LE(0, ruleset_fd); + if (kind == CAP_TRACE_DENY_QUIET) + ASSERT_EQ(0, add_cap_rule_full(ruleset_fd, 0, + 1ULL << CAP_SYS_CHROOT)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + if (kind == CAP_TRACE_DENY_NOAUDIT) { + /* Probe CAP_SYS_ADMIN with CAP_OPT_NOAUDIT. */ + len = flistxattr(fd, list, sizeof(list)); + ASSERT_LE(0, len); + EXPECT_FALSE( + list_has_xattr(list, len, "trusted.landlock_test")); + EXPECT_EQ(0, close(fd)); + + /* Control: an ordinary denial in the same domain is traced. */ + EXPECT_EQ(-1, chroot("/")); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + clear_cap(_metadata, CAP_SYS_CHROOT); + } else { + EXPECT_EQ(-1, chroot("/")); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_CHROOT); + } +} + +static void test_cap_trace_denial(struct __test_metadata *const _metadata, + const enum cap_trace_denial_kind kind, + const int expected_capability, + const char *const expected_logged) +{ + char expected[16], field[64]; + int status; + char *buf; + pid_t child; + + ASSERT_EQ(0, tracefs_clear_buf()); + + child = fork(); + ASSERT_LE(0, child); + if (child == 0) { + exercise_cap_trace_denial(_metadata, kind); + _exit(_metadata->exit_code); + } + + ASSERT_EQ(child, waitpid(child, &status, 0)); + ASSERT_TRUE(WIFEXITED(status)); + ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); + + buf = tracefs_read_buf(); + ASSERT_NE(NULL, buf); + ASSERT_EQ(1, tracefs_count_matches( + buf, REGEX_DENY_PERMISSION_CAPABILITY(TRACE_TASK))) + { + TH_LOG("Expected one capability denial event\n%s", buf); + } + + ASSERT_EQ(0, tracefs_extract_field( + buf, REGEX_DENY_PERMISSION_CAPABILITY(TRACE_TASK), + "domain", field, sizeof(field))); + EXPECT_STRNE("0", field); + ASSERT_EQ(0, tracefs_extract_field( + buf, REGEX_DENY_PERMISSION_CAPABILITY(TRACE_TASK), + "same_exec", field, sizeof(field))); + EXPECT_STREQ("1", field); + ASSERT_EQ(0, tracefs_extract_field( + buf, REGEX_DENY_PERMISSION_CAPABILITY(TRACE_TASK), + "logged", field, sizeof(field))); + EXPECT_STREQ(expected_logged, field); + ASSERT_EQ(0, tracefs_extract_field( + buf, REGEX_DENY_PERMISSION_CAPABILITY(TRACE_TASK), + "blockers", field, sizeof(field))); + EXPECT_STREQ("use", field); + ASSERT_EQ(0, tracefs_extract_field( + buf, REGEX_DENY_PERMISSION_CAPABILITY(TRACE_TASK), + "capability", field, sizeof(field))); + snprintf(expected, sizeof(expected), "%d", expected_capability); + EXPECT_STREQ(expected, field); + + free(buf); +} + +TEST_F(cap_trace, deny) +{ + if (!self->tracefs_ok) + SKIP(return, "tracefs not available"); + test_cap_trace_denial(_metadata, CAP_TRACE_DENY, CAP_SYS_CHROOT, "1"); +} + +TEST_F(cap_trace, deny_quiet) +{ + if (!self->tracefs_ok) + SKIP(return, "tracefs not available"); + test_cap_trace_denial(_metadata, CAP_TRACE_DENY_QUIET, CAP_SYS_CHROOT, + "0"); +} + +/* + * A CAP_OPT_NOAUDIT probe is denied without any record. The audit counterpart + * checks the missing audit record; this one checks that the CAP_SYS_ADMIN probe + * emits no trace event, while the CAP_SYS_CHROOT denial that follows it in the + * same domain still does. + */ +TEST_F(cap_trace, noaudit_probe_not_traced) +{ + if (!self->tracefs_ok) + SKIP(return, "tracefs not available"); + test_cap_trace_denial(_metadata, CAP_TRACE_DENY_NOAUDIT, CAP_SYS_CHROOT, + "1"); +} + +TEST_HARNESS_MAIN
diff --git a/tools/testing/selftests/landlock/common.h b/tools/testing/selftests/landlock/common.h index c5124de..e294069 100644 --- a/tools/testing/selftests/landlock/common.h +++ b/tools/testing/selftests/landlock/common.h
@@ -9,10 +9,12 @@ #include <arpa/inet.h> #include <errno.h> +#include <linux/nsfs.h> #include <linux/securebits.h> #include <sys/capability.h> #include <sys/prctl.h> #include <sys/socket.h> +#include <sys/stat.h> #include <sys/un.h> #include <sys/wait.h> #include <unistd.h> @@ -130,6 +132,17 @@ static void __maybe_unused clear_ambient_cap( EXPECT_EQ(0, cap_get_ambient(cap)); } +/* Returns true if the current process is in the initial user namespace. */ +static bool __maybe_unused is_in_init_user_ns(void) +{ + struct stat user_ns; + + if (stat("/proc/self/ns/user", &user_ns)) + return false; + + return user_ns.st_ino == USER_NS_INIT_INO; +} + /* Receives an FD from a UNIX socket. Returns the received FD, or -errno. */ static int __maybe_unused recv_fd(int usock) {
diff --git a/tools/testing/selftests/landlock/config b/tools/testing/selftests/landlock/config index d863219..5568d7a 100644 --- a/tools/testing/selftests/landlock/config +++ b/tools/testing/selftests/landlock/config
@@ -5,6 +5,7 @@ CONFIG_ENABLE_DEFAULT_TRACERS=y CONFIG_FTRACE=y CONFIG_INET=y +CONFIG_IPC_NS=y CONFIG_IPV6=y CONFIG_KEYS=y CONFIG_MPTCP=y @@ -12,10 +13,14 @@ CONFIG_NET=y CONFIG_NET_NS=y CONFIG_OVERLAY_FS=y +CONFIG_PID_NS=y CONFIG_PROC_FS=y CONFIG_SECURITY=y CONFIG_SECURITY_LANDLOCK=y CONFIG_SHMEM=y CONFIG_SYSFS=y +CONFIG_TIME_NS=y CONFIG_TMPFS=y CONFIG_TMPFS_XATTR=y +CONFIG_USER_NS=y +CONFIG_UTS_NS=y
diff --git a/tools/testing/selftests/landlock/fs_test.c b/tools/testing/selftests/landlock/fs_test.c index fd20a2b..f725882 100644 --- a/tools/testing/selftests/landlock/fs_test.c +++ b/tools/testing/selftests/landlock/fs_test.c
@@ -57,13 +57,6 @@ int renameat2(int olddirfd, const char *oldpath, int newdirfd, } #endif -#ifndef open_tree -int open_tree(int dfd, const char *filename, unsigned int flags) -{ - return syscall(__NR_open_tree, dfd, filename, flags); -} -#endif - static int sys_execveat(int dirfd, const char *pathname, char *const argv[], char *const envp[], int flags) { @@ -2628,9 +2621,9 @@ TEST_F_FORK(layout1, refer_mount_root_deny) /* Creates a mount object from a non-mount point. */ set_cap(_metadata, CAP_SYS_ADMIN); - root_fd = - open_tree(AT_FDCWD, dir_s1d1, - AT_EMPTY_PATH | OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC); + root_fd = sys_open_tree(AT_FDCWD, dir_s1d1, + AT_EMPTY_PATH | OPEN_TREE_CLONE | + OPEN_TREE_CLOEXEC); clear_cap(_metadata, CAP_SYS_ADMIN); ASSERT_LE(0, root_fd);
diff --git a/tools/testing/selftests/landlock/net_test.c b/tools/testing/selftests/landlock/net_test.c index 16afbfd..50b6373 100644 --- a/tools/testing/selftests/landlock/net_test.c +++ b/tools/testing/selftests/landlock/net_test.c
@@ -2878,7 +2878,7 @@ static int matches_auditlog(const int audit_fd, const char *const blockers, log_match_len = snprintf(log_match, sizeof(log_match), log_with_addrport_tmpl, blockers, dir_addr, addr, dir_port, port); - if (log_match_len > sizeof(log_match)) + if (log_match_len >= sizeof(log_match)) return -E2BIG; return audit_match_record(audit_fd, AUDIT_LANDLOCK_ACCESS, log_match, @@ -3173,7 +3173,7 @@ static int matches_log_connect_bound(int audit_fd, const char *const blockers, log_match_len = snprintf(log_match, sizeof(log_match), log_template, blockers, addr, lport, addr, dport); - if (log_match_len > sizeof(log_match)) + if (log_match_len >= sizeof(log_match)) return -E2BIG; return audit_match_record(audit_fd, AUDIT_LANDLOCK_ACCESS, log_match,
diff --git a/tools/testing/selftests/landlock/ns_test.c b/tools/testing/selftests/landlock/ns_test.c new file mode 100644 index 0000000..f5d4b86 --- /dev/null +++ b/tools/testing/selftests/landlock/ns_test.c
@@ -0,0 +1,2647 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Landlock tests - Namespace restriction + * + * Copyright © 2026 Cloudflare, Inc. + */ + +#define _GNU_SOURCE +#include <errno.h> +#include <fcntl.h> +#include <linux/capability.h> +#include <linux/landlock.h> +#include <linux/mount.h> +#include <linux/nsfs.h> +#include <sched.h> +#include <stdio.h> +#include <sys/ioctl.h> +#include <sys/prctl.h> +#include <sys/wait.h> +#include <syscall.h> +#include <unistd.h> + +/* Defines AT_RECURSIVE without type conflicts. */ +#define _ASM_GENERIC_FCNTL_H +#include <linux/fcntl.h> + +#include "audit.h" +#include "common.h" +#include "trace.h" + +#define TRACE_TASK "ns_test" + +/* + * Max length for /proc/self/ns/<name> paths (longest: "/proc/self/ns/cgroup"). + */ +#define NS_PROC_PATH_MAX 32 + +static int create_ns_ruleset(void) +{ + const struct landlock_ruleset_attr attr = { + .handled_permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + }; + + return landlock_create_ruleset(&attr, sizeof(attr), 0); +} + +static int add_ns_rule(int ruleset_fd, __u64 ns_type) +{ + const struct landlock_namespace_attr attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + .allowed_namespace_types = ns_type, + }; + + return landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, &attr, 0); +} + +static int add_ns_rule_full(int ruleset_fd, __u64 allowed, __u64 quiet) +{ + const struct landlock_namespace_attr attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + .allowed_namespace_types = allowed, + .quiet_namespace_types = quiet, + }; + + return landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, &attr, 0); +} + +/* + * Returns the /proc/self/NS entry name for a given CLONE_NEW* type, or NULL if + * unknown. Used to check kernel support without side effects. + */ +static const char *ns_proc_name(__u64 ns_type) +{ + switch (ns_type) { + case CLONE_NEWNS: + return "mnt"; + case CLONE_NEWCGROUP: + return "cgroup"; + case CLONE_NEWUTS: + return "uts"; + case CLONE_NEWIPC: + return "ipc"; + case CLONE_NEWUSER: + return "user"; + case CLONE_NEWPID: + return "pid"; + case CLONE_NEWNET: + return "net"; + case CLONE_NEWTIME: + return "time"; + default: + return NULL; + } +} + +static bool ns_is_supported(__u64 ns_type, char *proc_path, size_t size) +{ + const char *ns_name; + + ns_name = ns_proc_name(ns_type); + if (!ns_name) + return false; + + snprintf(proc_path, size, "/proc/self/ns/%s", ns_name); + return access(proc_path, F_OK) == 0; +} + +/* Rule validation tests */ + +TEST(add_rule_bad_attr) +{ + const struct landlock_ruleset_attr cap_only_attr = { + .handled_permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + }; + int ruleset_fd; + struct landlock_namespace_attr attr = {}; + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + + /* Invalid rule pointer returns EFAULT. */ + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + NULL, 0)); + ASSERT_EQ(EFAULT, errno); + + /* Empty permissions selector returns ENOMSG. */ + attr.permissions = 0; + attr.allowed_namespace_types = CLONE_NEWUTS; + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &attr, 0)); + ASSERT_EQ(ENOMSG, errno); + + /* Valid namespace selector plus an extra unhandled selector bit. */ + attr.permissions = LANDLOCK_PERMISSION_NAMESPACE_USE | + LANDLOCK_PERMISSION_CAPABILITY_USE; + attr.allowed_namespace_types = CLONE_NEWUTS; + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &attr, 0)); + ASSERT_EQ(EINVAL, errno); + + /* permissions with wrong type. */ + attr.permissions = LANDLOCK_PERMISSION_CAPABILITY_USE; + attr.allowed_namespace_types = CLONE_NEWUTS; + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &attr, 0)); + ASSERT_EQ(EINVAL, errno); + + /* + * Unknown namespace bits (e.g. bit 63) are silently accepted for + * forward compatibility. Only known CLONE_NEW* bits are stored. + */ + attr.permissions = LANDLOCK_PERMISSION_NAMESPACE_USE; + attr.allowed_namespace_types = 1ULL << 63; + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &attr, 0)); + + /* Useless rule: neither allowed nor quiet types set returns ENOMSG. */ + attr.permissions = LANDLOCK_PERMISSION_NAMESPACE_USE; + attr.allowed_namespace_types = 0; + attr.quiet_namespace_types = 0; + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &attr, 0)); + ASSERT_EQ(ENOMSG, errno); + + /* Quiet-only rule (empty allowed set) is legal. */ + attr.permissions = LANDLOCK_PERMISSION_NAMESPACE_USE; + attr.allowed_namespace_types = 0; + attr.quiet_namespace_types = CLONE_NEWUTS; + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &attr, 0)); + + /* Allow and quiet in the same rule. */ + attr.permissions = LANDLOCK_PERMISSION_NAMESPACE_USE; + attr.allowed_namespace_types = CLONE_NEWNET; + attr.quiet_namespace_types = CLONE_NEWUTS; + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &attr, 0)); + attr.quiet_namespace_types = 0; + + /* + * Bit 1 is not a CLONE_NEW* value but is silently accepted for forward + * compatibility (no hole rejection). + */ + attr.permissions = LANDLOCK_PERMISSION_NAMESPACE_USE; + attr.allowed_namespace_types = (1ULL << 1); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &attr, 0)); + + /* Multi-bit values are valid (bitmask allows multiple types). */ + attr.permissions = LANDLOCK_PERMISSION_NAMESPACE_USE; + attr.allowed_namespace_types = CLONE_NEWUTS | CLONE_NEWNET; + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &attr, 0)); + + /* + * LANDLOCK_ADD_RULE_QUIET (and any other flag) is filesystem/network + * only and must be rejected for namespace rules, even when every attr + * field is otherwise valid. + */ + attr.permissions = LANDLOCK_PERMISSION_NAMESPACE_USE; + attr.allowed_namespace_types = CLONE_NEWUTS; + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &attr, LANDLOCK_ADD_RULE_QUIET)); + ASSERT_EQ(EINVAL, errno); + + EXPECT_EQ(0, close(ruleset_fd)); + + /* + * Ruleset handles LANDLOCK_PERMISSION_CAPABILITY_USE but not + * LANDLOCK_PERMISSION_NAMESPACE_USE: adding a namespace rule must be + * rejected. + */ + ruleset_fd = landlock_create_ruleset(&cap_only_attr, + sizeof(cap_only_attr), 0); + ASSERT_LE(0, ruleset_fd); + attr.permissions = LANDLOCK_PERMISSION_NAMESPACE_USE; + attr.allowed_namespace_types = CLONE_NEWUTS; + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &attr, 0)); + ASSERT_EQ(EINVAL, errno); + EXPECT_EQ(0, close(ruleset_fd)); +} + +/* + * Unknown namespace types in the upper range are silently accepted (allow-list: + * they have no effect since the kernel never checks them). + */ +TEST(add_rule_unknown) +{ + int ruleset_fd; + struct landlock_namespace_attr attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + }; + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + + /* + * Bit 31 is in the lower 32 bits but not a CLONE_NEW* value. Silently + * accepted for forward compatibility (no hole rejection). + */ + attr.allowed_namespace_types = 1ULL << 31; + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &attr, 0)); + + /* Bit 32 is in the unknown upper range: silently accepted. */ + attr.allowed_namespace_types = 1ULL << 32; + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &attr, 0)); + + EXPECT_EQ(0, close(ruleset_fd)); +} + +/* + * A rule that lists only namespace bits unknown to the running kernel is + * accepted by landlock_add_rule() but has no runtime effect: once the domain is + * enforced, any actual CLONE_NEW* operation is still denied by the per-category + * deny-by-default behaviour. This documents the forward-compatibility + * contract: unknown bits are silently accepted so the same policy can be loaded + * across kernels, but they never grant a permission that the running kernel + * knows nothing about. + */ +TEST(add_rule_unknown_no_runtime_effect) +{ + const struct landlock_ruleset_attr ruleset_attr = { + .handled_permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + }; + struct landlock_namespace_attr attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + /* Only unknown bits: bit 31 (in lower 32) and bit 32. */ + .allowed_namespace_types = (1ULL << 31) | (1ULL << 32), + }; + int ruleset_fd; + + disable_caps(_metadata); + + ruleset_fd = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + ASSERT_LE(0, ruleset_fd); + + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &attr, 0)); + + /* + * Baseline: absent the domain, creating CLONE_NEWUTS succeeds. This + * ensures the EPERM below is attributable to Landlock rather than to a + * missing capability, and fails if the hook always allows. + */ + set_cap(_metadata, CAP_SYS_ADMIN); + ASSERT_EQ(0, unshare(CLONE_NEWUTS)); + + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* + * CLONE_NEWUTS is a real, known CLONE_NEW* type but was not authorised + * by the rule above; deny-by-default applies. + */ + EXPECT_EQ(-1, unshare(CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); +} + +/* + * The install-hook mirror of add_rule_unknown_no_runtime_effect: a rule listing + * only unknown namespace bits has no runtime effect on setns(2) either. Once + * enforced, entering a known namespace type is still denied by the per-category + * deny-by-default behaviour. + */ +TEST(add_rule_unknown_no_runtime_effect_setns) +{ + const struct landlock_ruleset_attr ruleset_attr = { + .handled_permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + }; + struct landlock_namespace_attr attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + /* Only unknown bits: bit 31 (in lower 32) and bit 32. */ + .allowed_namespace_types = (1ULL << 31) | (1ULL << 32), + }; + int ruleset_fd, ns_fd; + + disable_caps(_metadata); + + /* Open the NS FD before enforcing the domain. */ + ns_fd = open("/proc/self/ns/uts", O_RDONLY); + ASSERT_LE(0, ns_fd); + + ruleset_fd = + landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &attr, 0)); + + /* + * Baseline: absent the domain, entering the process's own UTS namespace + * succeeds, so the later EPERM is attributable to Landlock rather than + * to a missing capability, and fails if the hook always allows. + */ + set_cap(_metadata, CAP_SYS_ADMIN); + ASSERT_EQ(0, setns(ns_fd, CLONE_NEWUTS)); + + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* + * CLONE_NEWUTS is a real, known CLONE_NEW* type but was not authorised + * by the rule above; deny-by-default applies at the install hook. + */ + EXPECT_EQ(-1, setns(ns_fd, CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, close(ns_fd)); +} + +/* Namespace creation tests (variant-based positive/negative) */ + +/* clang-format off */ +FIXTURE(ns_create) { + /* clang-format on */ + char proc_path[NS_PROC_PATH_MAX]; +}; + +FIXTURE_VARIANT(ns_create) +{ + const __u64 namespace_types; + const bool is_sandboxed; + const bool has_rule; + const bool drop_all_caps; + const int expected_result; +}; + +/* + * Unsandboxed baseline: no Landlock domain is enforced. User namespace creation + * should succeed without any restriction. + */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, user_unsandboxed) { + /* clang-format on */ + .namespace_types = CLONE_NEWUSER, + .is_sandboxed = false, + .has_rule = false, + .drop_all_caps = false, + .expected_result = 0, +}; + +/* + * User namespace creation denied: handled by Landlock but no rule allows + * CLONE_NEWUSER. + */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, user_denied) { + /* clang-format on */ + .namespace_types = CLONE_NEWUSER, + .is_sandboxed = true, + .has_rule = false, + .drop_all_caps = false, + .expected_result = EPERM, +}; + +/* User namespace creation allowed: Landlock rule permits CLONE_NEWUSER. */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, user_allowed) { + /* clang-format on */ + .namespace_types = CLONE_NEWUSER, + .is_sandboxed = true, + .has_rule = true, + .drop_all_caps = false, + .expected_result = 0, +}; + +/* + * User namespace creation while unprivileged: the process has no capabilities + * but unshare(CLONE_NEWUSER) is an unprivileged operation so it still succeeds. + * The Landlock rule allows it. For setns, the capability check (CAP_SYS_ADMIN) + * fails first since the process has no capabilities, yielding EPERM. + */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, user_unprivileged) { + /* clang-format on */ + .namespace_types = CLONE_NEWUSER, + .is_sandboxed = true, + .has_rule = true, + .drop_all_caps = true, + .expected_result = 0, +}; + +/* + * Unsandboxed baseline for non-user namespace: no Landlock domain, process has + * CAP_SYS_ADMIN. UTS creation should succeed. + */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, uts_unsandboxed) { + /* clang-format on */ + .namespace_types = CLONE_NEWUTS, + .is_sandboxed = false, + .has_rule = false, + .drop_all_caps = false, + .expected_result = 0, +}; + +/* + * Non-user namespace denied: process has CAP_SYS_ADMIN (passes ns_capable), but + * Landlock denies (no rule). + */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, uts_denied) { + /* clang-format on */ + .namespace_types = CLONE_NEWUTS, + .is_sandboxed = true, + .has_rule = false, + .drop_all_caps = false, + .expected_result = EPERM, +}; + +/* + * Non-user namespace allowed: process has CAP_SYS_ADMIN and Landlock rule + * permits CLONE_NEWUTS. + */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, uts_allowed) { + .namespace_types = CLONE_NEWUTS, + .is_sandboxed = true, + .has_rule = true, + .drop_all_caps = false, + .expected_result = 0, +}; +/* clang-format on */ + +/* + * Unprivileged namespace creation: process lacks CAP_SYS_ADMIN, so the kernel + * denies creation regardless of Landlock rules. Landlock cannot authorize what + * the kernel denied (LSM hooks are restriction-only). The rule is present to + * verify Landlock does not change the error code. + */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, uts_unprivileged) { + /* clang-format on */ + .namespace_types = CLONE_NEWUTS, + .is_sandboxed = true, + .has_rule = true, + .drop_all_caps = true, + .expected_result = EPERM, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, ipc_denied) { + /* clang-format on */ + .namespace_types = CLONE_NEWIPC, + .is_sandboxed = true, + .has_rule = false, + .drop_all_caps = false, + .expected_result = EPERM, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, ipc_allowed) { + .namespace_types = CLONE_NEWIPC, + .is_sandboxed = true, + .has_rule = true, + .drop_all_caps = false, + .expected_result = 0, +}; +/* clang-format on */ + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, ipc_unprivileged) { + /* clang-format on */ + .namespace_types = CLONE_NEWIPC, + .is_sandboxed = true, + .has_rule = true, + .drop_all_caps = true, + .expected_result = EPERM, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, mnt_denied) { + /* clang-format on */ + .namespace_types = CLONE_NEWNS, + .is_sandboxed = true, + .has_rule = false, + .drop_all_caps = false, + .expected_result = EPERM, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, mnt_allowed) { + .namespace_types = CLONE_NEWNS, + .is_sandboxed = true, + .has_rule = true, + .drop_all_caps = false, + .expected_result = 0, +}; +/* clang-format on */ + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, mnt_unprivileged) { + /* clang-format on */ + .namespace_types = CLONE_NEWNS, + .is_sandboxed = true, + .has_rule = true, + .drop_all_caps = true, + .expected_result = EPERM, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, cgroup_denied) { + /* clang-format on */ + .namespace_types = CLONE_NEWCGROUP, + .is_sandboxed = true, + .has_rule = false, + .drop_all_caps = false, + .expected_result = EPERM, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, cgroup_allowed) { + /* clang-format on */ + .namespace_types = CLONE_NEWCGROUP, + .is_sandboxed = true, + .has_rule = true, + .drop_all_caps = false, + .expected_result = 0, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, cgroup_unprivileged) { + /* clang-format on */ + .namespace_types = CLONE_NEWCGROUP, + .is_sandboxed = true, + .has_rule = true, + .drop_all_caps = true, + .expected_result = EPERM, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, pid_denied) { + /* clang-format on */ + .namespace_types = CLONE_NEWPID, + .is_sandboxed = true, + .has_rule = false, + .drop_all_caps = false, + .expected_result = EPERM, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, pid_allowed) { + .namespace_types = CLONE_NEWPID, + .is_sandboxed = true, + .has_rule = true, + .drop_all_caps = false, + .expected_result = 0, +}; +/* clang-format on */ + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, pid_unprivileged) { + /* clang-format on */ + .namespace_types = CLONE_NEWPID, + .is_sandboxed = true, + .has_rule = true, + .drop_all_caps = true, + .expected_result = EPERM, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, net_denied) { + /* clang-format on */ + .namespace_types = CLONE_NEWNET, + .is_sandboxed = true, + .has_rule = false, + .drop_all_caps = false, + .expected_result = EPERM, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, net_allowed) { + .namespace_types = CLONE_NEWNET, + .is_sandboxed = true, + .has_rule = true, + .drop_all_caps = false, + .expected_result = 0, +}; +/* clang-format on */ + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, net_unprivileged) { + /* clang-format on */ + .namespace_types = CLONE_NEWNET, + .is_sandboxed = true, + .has_rule = true, + .drop_all_caps = true, + .expected_result = EPERM, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, time_denied) { + /* clang-format on */ + .namespace_types = CLONE_NEWTIME, + .is_sandboxed = true, + .has_rule = false, + .drop_all_caps = false, + .expected_result = EPERM, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, time_allowed) { + /* clang-format on */ + .namespace_types = CLONE_NEWTIME, + .is_sandboxed = true, + .has_rule = true, + .drop_all_caps = false, + .expected_result = 0, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create, time_unprivileged) { + /* clang-format on */ + .namespace_types = CLONE_NEWTIME, + .is_sandboxed = true, + .has_rule = true, + .drop_all_caps = true, + .expected_result = EPERM, +}; + +FIXTURE_SETUP(ns_create) +{ + ASSERT_TRUE(ns_is_supported(variant->namespace_types, self->proc_path, + sizeof(self->proc_path))) + { + TH_LOG("Namespace type 0x%llx not supported", + (unsigned long long)variant->namespace_types); + } + + if (variant->drop_all_caps) + drop_caps(_metadata); + else + disable_caps(_metadata); +} + +FIXTURE_TEARDOWN(ns_create) +{ +} + +TEST_F(ns_create, unshare) +{ + int ruleset_fd, err; + + if (variant->is_sandboxed) { + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + + if (variant->has_rule) + ASSERT_EQ(0, add_ns_rule(ruleset_fd, + variant->namespace_types)); + + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + } + + /* + * Non-user namespaces need CAP_SYS_ADMIN for the privileged path. User + * namespaces and unprivileged tests skip this. + */ + if (!variant->drop_all_caps && + variant->namespace_types != CLONE_NEWUSER) + set_cap(_metadata, CAP_SYS_ADMIN); + + err = unshare(variant->namespace_types); + if (variant->expected_result) { + EXPECT_EQ(-1, err); + EXPECT_EQ(variant->expected_result, errno); + } else { + EXPECT_EQ(0, err); + } + + if (!variant->drop_all_caps && + variant->namespace_types != CLONE_NEWUSER) + clear_cap(_metadata, CAP_SYS_ADMIN); +} + +/* + * clone3 exercises a different kernel entry point than unshare: it goes through + * kernel_clone() -> copy_process() -> copy_namespaces() -> + * create_new_namespaces(). Both paths converge at __ns_common_init() -> + * security_namespace_init(), but the entry point and argument handling differ. + */ +TEST_F(ns_create, clone3) +{ + int ruleset_fd, status; + pid_t pid; + struct clone_args args = {}; + + if (variant->is_sandboxed) { + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + + if (variant->has_rule) + ASSERT_EQ(0, add_ns_rule(ruleset_fd, + variant->namespace_types)); + + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + } + + if (!variant->drop_all_caps && + variant->namespace_types != CLONE_NEWUSER) + set_cap(_metadata, CAP_SYS_ADMIN); + + args.flags = variant->namespace_types; + args.exit_signal = SIGCHLD; + pid = sys_clone3(&args, sizeof(args)); + if (pid == 0) + _exit(EXIT_SUCCESS); + + if (variant->expected_result) { + EXPECT_EQ(-1, pid); + EXPECT_EQ(variant->expected_result, errno); + } else { + ASSERT_LE(0, pid); + ASSERT_EQ(pid, waitpid(pid, &status, 0)); + ASSERT_EQ(1, WIFEXITED(status)); + ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); + } + + if (!variant->drop_all_caps && + variant->namespace_types != CLONE_NEWUSER) + clear_cap(_metadata, CAP_SYS_ADMIN); +} + +/* + * setns exercises the namespace install path: validate_ns() -> + * security_namespace_install() -> hook_namespace_install(). This is a + * different LSM hook than creation, so it must be tested separately for each + * type. + * + * Mount namespace setns requires both CAP_SYS_ADMIN and CAP_SYS_CHROOT (checked + * by mntns_install), so the allowed variant sets both. + */ +TEST_F(ns_create, setns) +{ + int ruleset_fd, ns_fd, err, expected; + + /* + * setns into the process's own user NS returns EINVAL from + * userns_install() (rejects re-entry), but when Landlock denies the + * operation, security_namespace_install() returns EPERM before + * userns_install() runs. + */ + if (variant->namespace_types == CLONE_NEWUSER && + !variant->expected_result) { + expected = EINVAL; + } else { + expected = variant->expected_result; + } + + /* Open the NS FD before enforcing the domain. */ + ns_fd = open(self->proc_path, O_RDONLY); + ASSERT_LE(0, ns_fd); + + if (variant->is_sandboxed) { + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + + if (variant->has_rule) + ASSERT_EQ(0, add_ns_rule(ruleset_fd, + variant->namespace_types)); + + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + } + + if (!variant->drop_all_caps) { + set_cap(_metadata, CAP_SYS_ADMIN); + /* + * mntns_install() requires CAP_SYS_CHROOT in addition to + * CAP_SYS_ADMIN. + */ + if (variant->namespace_types == CLONE_NEWNS) + set_cap(_metadata, CAP_SYS_CHROOT); + } + + err = setns(ns_fd, variant->namespace_types); + if (expected) { + EXPECT_EQ(-1, err); + EXPECT_EQ(expected, errno); + } else { + EXPECT_EQ(0, err); + } + + if (!variant->drop_all_caps) { + clear_cap(_metadata, CAP_SYS_ADMIN); + if (variant->namespace_types == CLONE_NEWNS) + clear_cap(_metadata, CAP_SYS_CHROOT); + } + + EXPECT_EQ(0, close(ns_fd)); +} + +/* Additional namespace creation tests */ + +/* + * When LANDLOCK_PERMISSION_NAMESPACE_USE is not handled by any domain, + * namespace creation must produce the same result as without Landlock. Unlike + * the unsandboxed variants of ns_create (which have no domain at all), this + * test verifies that a domain handling only FS access does not interfere with + * namespace operations. + */ +TEST(ns_create_unhandled) +{ + const struct landlock_ruleset_attr attr = { + .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE, + }; + int ruleset_fd; + + disable_caps(_metadata); + + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* User namespace creation should still work (unhandled). */ + EXPECT_EQ(0, unshare(CLONE_NEWUSER)); +} + +/* + * Layer stacking: both layers must allow CLONE_NEWUSER for the operation to + * succeed. Variants exercise the three combinations of per-layer allow/deny + * that exercise distinct semantics; the (deny, deny) combination is omitted + * because it is covered by every other "deny" test in this file. + */ +/* clang-format off */ +FIXTURE(ns_stacking) {}; +/* clang-format on */ + +FIXTURE_VARIANT(ns_stacking) +{ + bool first_layer_allows; + bool second_layer_allows; +}; + +/* Layer 1 allows, layer 2 denies -> child denies. */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_stacking, deny) { + /* clang-format on */ + .first_layer_allows = true, + .second_layer_allows = false, +}; + +/* Both layers allow CLONE_NEWUSER -> operation succeeds. */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_stacking, allow) { + /* clang-format on */ + .first_layer_allows = true, + .second_layer_allows = true, +}; + +/* + * Layer 1 denies, layer 2 allows -> still denied: a child layer cannot grant + * what an ancestor layer withheld. This complements the + * parent-allows/child-denies variant above; together they verify the walker + * checks both layers and accepts only the (allow, allow) cell. + */ +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_stacking, parent_denies) { + /* clang-format on */ + .first_layer_allows = false, + .second_layer_allows = true, +}; + +FIXTURE_SETUP(ns_stacking) +{ + disable_caps(_metadata); +} + +FIXTURE_TEARDOWN(ns_stacking) +{ +} + +/* + * Verify that any layer can deny an operation: enforcement requires all layers + * to allow. Variants exercise the three combinations that exercise distinct + * walker paths (allow/deny, allow/allow, deny/allow); only allow/allow lets the + * operation through. + */ +TEST_F(ns_stacking, two_layers) +{ + int ruleset_fd; + const bool expect_success = variant->first_layer_allows && + variant->second_layer_allows; + + /* First layer: allow or deny depending on variant. */ + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + if (variant->first_layer_allows) + ASSERT_EQ(0, add_ns_rule(ruleset_fd, CLONE_NEWUSER)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* Second layer: allow or deny depending on variant. */ + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + if (variant->second_layer_allows) + ASSERT_EQ(0, add_ns_rule(ruleset_fd, CLONE_NEWUSER)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + if (expect_success) { + EXPECT_EQ(0, unshare(CLONE_NEWUSER)); + } else { + EXPECT_EQ(-1, unshare(CLONE_NEWUSER)); + EXPECT_EQ(EPERM, errno); + } +} + +/* + * Combined capability and namespace permissions in a single domain. Verifies + * that both permission types can coexist and are enforced independently. + */ +TEST(combined_cap_ns) +{ + const struct landlock_ruleset_attr attr = { + .handled_permissions = LANDLOCK_PERMISSION_CAPABILITY_USE | + LANDLOCK_PERMISSION_NAMESPACE_USE, + }; + const struct landlock_capability_attr cap_attr = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + .allowed_capabilities = (1ULL << CAP_SYS_ADMIN), + }; + const struct landlock_namespace_attr ns_attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + .allowed_namespace_types = CLONE_NEWUSER, + }; + int ruleset_fd; + + /* Isolate hostname changes from other tests. */ + ASSERT_EQ(0, unshare(CLONE_NEWUTS)); + + disable_caps(_metadata); + + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &cap_attr, 0)); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &ns_attr, 0)); + + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* CAP_SYS_ADMIN use allowed by capability rule. */ + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, sethostname("test", 4)); + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* CAP_SYS_CHROOT denied (not in allowed capability rules). */ + set_cap(_metadata, CAP_SYS_CHROOT); + EXPECT_EQ(-1, chroot("/")); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_CHROOT); + + /* + * UTS namespace creation denied by Landlock (not in allowed namespace + * rules). CAP_SYS_ADMIN is needed for the kernel's ns_capable() check + * to pass, so that Landlock's hook is actually reached. + */ + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(-1, unshare(CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* User namespace creation allowed by namespace rule. */ + EXPECT_EQ(0, unshare(CLONE_NEWUSER)); +} + +/* + * Partial allow: one namespace type is allowed, another is denied. Verifies + * that rules are per-type. + */ +TEST(ns_create_partial) +{ + int ruleset_fd; + + disable_caps(_metadata); + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + + /* Only allow UTS namespace creation. */ + ASSERT_EQ(0, add_ns_rule(ruleset_fd, CLONE_NEWUTS)); + + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* UTS namespace should be allowed. */ + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, unshare(CLONE_NEWUTS)); + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* User namespace should be denied (no rule). */ + EXPECT_EQ(-1, unshare(CLONE_NEWUSER)); + EXPECT_EQ(EPERM, errno); +} + +/* + * open_tree(2) and fsmount(2) acquire a file descriptor referring to a + * newly-created mount namespace. Both call paths funnel into + * security_namespace_init() with CLONE_NEWNS, gated by + * LANDLOCK_PERMISSION_NAMESPACE_USE. Without coverage here, regressions in + * those paths would slip past the suite. + */ +/* clang-format off */ +FIXTURE(ns_mount_fd) {}; +/* clang-format on */ + +FIXTURE_VARIANT(ns_mount_fd) +{ + bool sandboxed; + bool has_rule; + int expected_errno; +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_mount_fd, denied) { + /* clang-format on */ + .sandboxed = true, + .has_rule = false, + .expected_errno = EPERM, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_mount_fd, allowed) { + /* clang-format on */ + .sandboxed = true, + .has_rule = true, + .expected_errno = 0, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_mount_fd, unsandboxed) { + /* clang-format on */ + .sandboxed = false, + .has_rule = false, + .expected_errno = 0, +}; + +FIXTURE_SETUP(ns_mount_fd) +{ +} + +FIXTURE_TEARDOWN(ns_mount_fd) +{ +} + +/* + * open_tree(OPEN_TREE_CLONE) creates an anonymous mount namespace to hold the + * cloned mount tree. hook_namespace_init() fires with CLONE_NEWNS. + */ +TEST_F(ns_mount_fd, open_tree_clone) +{ + int ruleset_fd, fd; + + disable_caps(_metadata); + + if (variant->sandboxed) { + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + if (variant->has_rule) + ASSERT_EQ(0, add_ns_rule(ruleset_fd, CLONE_NEWNS)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + } + + set_cap(_metadata, CAP_SYS_ADMIN); + fd = sys_open_tree(AT_FDCWD, "/", + OPEN_TREE_CLONE | OPEN_TREE_CLOEXEC | AT_RECURSIVE); + if (variant->expected_errno) { + EXPECT_EQ(-1, fd); + EXPECT_EQ(variant->expected_errno, errno); + } else { + ASSERT_LE(0, fd); + EXPECT_EQ(0, close(fd)); + } + clear_cap(_metadata, CAP_SYS_ADMIN); +} + +/* + * open_tree(OPEN_TREE_NAMESPACE) clones the mount tree into a new + * (non-anonymous) mount namespace. Same hook (CLONE_NEWNS) but a different + * code path inside fs/namespace.c (open_new_namespace -> alloc_mnt_ns). + * OPEN_TREE_NAMESPACE and OPEN_TREE_CLONE are mutually exclusive. + */ +TEST_F(ns_mount_fd, open_tree_namespace) +{ + int ruleset_fd, fd; + + disable_caps(_metadata); + + if (variant->sandboxed) { + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + if (variant->has_rule) + ASSERT_EQ(0, add_ns_rule(ruleset_fd, CLONE_NEWNS)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + } + + set_cap(_metadata, CAP_SYS_ADMIN); + fd = sys_open_tree(AT_FDCWD, "/", + OPEN_TREE_NAMESPACE | OPEN_TREE_CLOEXEC | + AT_RECURSIVE); + if (variant->expected_errno) { + EXPECT_EQ(-1, fd); + EXPECT_EQ(variant->expected_errno, errno); + } else { + ASSERT_LE(0, fd); + EXPECT_EQ(0, close(fd)); + } + clear_cap(_metadata, CAP_SYS_ADMIN); +} + +/* + * fsmount(2) without FSMOUNT_NAMESPACE creates an anonymous mount namespace to + * attach the new superblock. hook_namespace_init() fires with CLONE_NEWNS. + * The fs context (fsopen + fsconfig) is set up before sandboxing because + * Landlock here only handles the namespace permission. + */ +TEST_F(ns_mount_fd, fsmount_default) +{ + int ruleset_fd, fs_fd, mnt_fd; + + disable_caps(_metadata); + + set_cap(_metadata, CAP_SYS_ADMIN); + fs_fd = sys_fsopen("tmpfs", 0); + ASSERT_LE(0, fs_fd); + ASSERT_EQ(0, sys_fsconfig(fs_fd, FSCONFIG_CMD_CREATE, NULL, NULL, 0)); + + if (variant->sandboxed) { + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + if (variant->has_rule) + ASSERT_EQ(0, add_ns_rule(ruleset_fd, CLONE_NEWNS)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + } + + mnt_fd = sys_fsmount(fs_fd, FSMOUNT_CLOEXEC, 0); + if (variant->expected_errno) { + EXPECT_EQ(-1, mnt_fd); + EXPECT_EQ(variant->expected_errno, errno); + } else { + ASSERT_LE(0, mnt_fd); + EXPECT_EQ(0, close(mnt_fd)); + } + EXPECT_EQ(0, close(fs_fd)); + clear_cap(_metadata, CAP_SYS_ADMIN); +} + +/* + * fsmount(2) with FSMOUNT_NAMESPACE creates a (non-anonymous) mount namespace + * for the new mount. Same hook as the default path, different code path. + */ +TEST_F(ns_mount_fd, fsmount_namespace) +{ + int ruleset_fd, fs_fd, mnt_fd; + + disable_caps(_metadata); + + set_cap(_metadata, CAP_SYS_ADMIN); + fs_fd = sys_fsopen("tmpfs", 0); + ASSERT_LE(0, fs_fd); + ASSERT_EQ(0, sys_fsconfig(fs_fd, FSCONFIG_CMD_CREATE, NULL, NULL, 0)); + + if (variant->sandboxed) { + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + if (variant->has_rule) + ASSERT_EQ(0, add_ns_rule(ruleset_fd, CLONE_NEWNS)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + } + + mnt_fd = sys_fsmount(fs_fd, FSMOUNT_CLOEXEC | FSMOUNT_NAMESPACE, 0); + if (variant->expected_errno) { + EXPECT_EQ(-1, mnt_fd); + EXPECT_EQ(variant->expected_errno, errno); + } else { + ASSERT_LE(0, mnt_fd); + EXPECT_EQ(0, close(mnt_fd)); + } + EXPECT_EQ(0, close(fs_fd)); + clear_cap(_metadata, CAP_SYS_ADMIN); +} + +/* + * unshare(2) with multiple CLONE_NEW* flags: when + * LANDLOCK_PERMISSION_NAMESPACE_USE denies any of the requested types, the + * entire syscall fails with EPERM. This documents the kernel's atomic + * behavior: create_new_namespaces(), called by copy_namespaces(), creates + * namespaces sequentially, and the first Landlock denial rolls back the whole + * operation. Mixing CLONE_NEWUSER (no capability check) with another + * CLONE_NEW* type is the typical container-runtime bootstrap pattern. + */ +/* clang-format off */ +FIXTURE(ns_create_multi_flag) {}; +/* clang-format on */ + +FIXTURE_VARIANT(ns_create_multi_flag) +{ + __u64 allowed_types; + int expected_errno; +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create_multi_flag, partial_denied) { + /* clang-format on */ + /* User namespace allowed; UTS namespace denied. */ + .allowed_types = CLONE_NEWUSER, + .expected_errno = EPERM, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_create_multi_flag, both_allowed) { + /* clang-format on */ + .allowed_types = CLONE_NEWUSER | CLONE_NEWUTS, + .expected_errno = 0, +}; + +FIXTURE_SETUP(ns_create_multi_flag) +{ +} + +FIXTURE_TEARDOWN(ns_create_multi_flag) +{ +} + +TEST_F(ns_create_multi_flag, unshare) +{ + int ruleset_fd, status, err; + pid_t child; + + disable_caps(_metadata); + + /* Run unshare(2) in a child to avoid polluting the test process. */ + child = fork(); + ASSERT_LE(0, child); + + if (child == 0) { + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, add_ns_rule(ruleset_fd, variant->allowed_types)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + err = unshare(CLONE_NEWUSER | CLONE_NEWUTS); + if (variant->expected_errno) { + EXPECT_EQ(-1, err); + EXPECT_EQ(variant->expected_errno, errno); + } else { + EXPECT_EQ(0, err); + } + _exit(_metadata->exit_code); + } + + ASSERT_EQ(child, waitpid(child, &status, 0)); + ASSERT_EQ(1, WIFEXITED(status)); + ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); +} + +/* clang-format off */ +FIXTURE(setns_cross_process) {}; +/* clang-format on */ + +FIXTURE_VARIANT(setns_cross_process) +{ + bool is_sandboxed; + bool has_rule; + int expected_setns; +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(setns_cross_process, denied) { + /* clang-format on */ + .is_sandboxed = true, + .has_rule = false, + .expected_setns = EPERM, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(setns_cross_process, sandboxed_allowed) { + /* clang-format on */ + .is_sandboxed = true, + .has_rule = true, + .expected_setns = 0, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(setns_cross_process, unsandboxed) { + /* clang-format on */ + .is_sandboxed = false, + .has_rule = false, + .expected_setns = 0, +}; + +FIXTURE_SETUP(setns_cross_process) +{ +} + +FIXTURE_TEARDOWN(setns_cross_process) +{ +} + +/* + * setns into a child's UTS namespace: when sandboxed with + * LANDLOCK_PERMISSION_NAMESPACE_USE denying UTS, the rule-based check applies + * regardless of which process created the namespace. This fixture exercises + * only CLONE_NEWUTS; the same enforcement applies to every namespace type (see + * hook_namespace_install() in security/landlock/ns.c), so per-type variants + * would not exercise different code paths. + */ +TEST_F(setns_cross_process, setns) +{ + int ruleset_fd, ns_fd, status; + pid_t child; + int pipe_parent[2], pipe_child[2]; + char buf, path[64]; + + disable_caps(_metadata); + + /* + * Enable dumpable so the parent can read /proc/<child>/ns/uts. Without + * this, ptrace access checks (PTRACE_MODE_READ) prevent opening another + * process's namespace entries. + */ + ASSERT_EQ(0, prctl(PR_SET_DUMPABLE, 1, 0, 0, 0)); + + ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC)); + ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC)); + + child = fork(); + ASSERT_LE(0, child); + + if (child == 0) { + EXPECT_EQ(0, close(pipe_parent[1])); + EXPECT_EQ(0, close(pipe_child[0])); + + /* Child: create a UTS namespace. */ + set_cap(_metadata, CAP_SYS_ADMIN); + ASSERT_EQ(0, unshare(CLONE_NEWUTS)); + + drop_caps(_metadata); + ASSERT_EQ(0, prctl(PR_SET_DUMPABLE, 1, 0, 0, 0)); + + /* Signal parent that the namespace is ready. */ + ASSERT_EQ(1, write(pipe_child[1], ".", 1)); + + /* Wait for parent to finish testing. */ + ASSERT_EQ(1, read(pipe_parent[0], &buf, 1)); + _exit(_metadata->exit_code); + } + + EXPECT_EQ(0, close(pipe_parent[0])); + EXPECT_EQ(0, close(pipe_child[1])); + + /* Wait for child namespace. */ + ASSERT_EQ(1, read(pipe_child[0], &buf, 1)); + EXPECT_EQ(0, close(pipe_child[0])); + + /* Open the child's NS FD BEFORE creating the domain. */ + snprintf(path, sizeof(path), "/proc/%d/ns/uts", child); + ns_fd = open(path, O_RDONLY); + ASSERT_LE(0, ns_fd); + + if (variant->is_sandboxed) { + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + if (variant->has_rule) + ASSERT_EQ(0, add_ns_rule(ruleset_fd, CLONE_NEWUTS)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + } + + set_cap(_metadata, CAP_SYS_ADMIN); + if (variant->expected_setns) { + EXPECT_EQ(-1, setns(ns_fd, CLONE_NEWUTS)); + EXPECT_EQ(variant->expected_setns, errno); + } else { + EXPECT_EQ(0, setns(ns_fd, CLONE_NEWUTS)); + } + clear_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, close(ns_fd)); + + /* Release child. */ + ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); + EXPECT_EQ(0, close(pipe_parent[1])); + ASSERT_EQ(child, waitpid(child, &status, 0)); + ASSERT_EQ(1, WIFEXITED(status)); + ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); +} + +/* + * Verify that LANDLOCK_PERMISSION_NAMESPACE_USE and + * LANDLOCK_PERMISSION_CAPABILITY_USE apply simultaneously: creating/entering a + * non-user namespace requires both the namespace type to be allowed AND + * CAP_SYS_ADMIN to be allowed. User namespace creation is the exception (no + * capable() call from the kernel). + */ +TEST(setns_and_create) +{ + int ruleset_fd, ns_fd; + const struct landlock_ruleset_attr attr = { + .handled_permissions = LANDLOCK_PERMISSION_NAMESPACE_USE | + LANDLOCK_PERMISSION_CAPABILITY_USE, + }; + const struct landlock_namespace_attr ns_attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + .allowed_namespace_types = CLONE_NEWUTS, + }; + const struct landlock_capability_attr cap_attr = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + .allowed_capabilities = (1ULL << CAP_SYS_ADMIN), + }; + + disable_caps(_metadata); + + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &ns_attr, 0)); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &cap_attr, 0)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* UTS unshare: allowed by NS rule + CAP_SYS_ADMIN allowed. */ + set_cap(_metadata, CAP_SYS_ADMIN); + ASSERT_EQ(0, unshare(CLONE_NEWUTS)); + + /* IPC unshare: denied by NS rule (type not allowed). */ + EXPECT_EQ(-1, unshare(CLONE_NEWIPC)); + EXPECT_EQ(EPERM, errno); + + /* setns into current UTS: allowed by NS rule. */ + ns_fd = open("/proc/self/ns/uts", O_RDONLY); + ASSERT_LE(0, ns_fd); + EXPECT_EQ(0, setns(ns_fd, CLONE_NEWUTS)); + clear_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, close(ns_fd)); + + /* + * User namespace creation: only LANDLOCK_PERMISSION_NAMESPACE_USE + * needed (no capable() call from the kernel for user NS). Denied + * because CLONE_NEWUSER is not in the allowed namespace types. + */ + EXPECT_EQ(-1, unshare(CLONE_NEWUSER)); + EXPECT_EQ(EPERM, errno); +} + +/* + * Verify that LANDLOCK_PERMISSION_CAPABILITY_USE can deny the CAP_SYS_ADMIN + * check that the kernel performs before the Landlock namespace hook is reached. + * The NS type is allowed but the required capability is not, so the operation + * fails on the capability check. + * + * User namespace creation is the exception: no capable() call, so the operation + * succeeds with just LANDLOCK_PERMISSION_NAMESPACE_USE. + */ +TEST(two_permissions_cap_denied) +{ + const struct landlock_ruleset_attr attr = { + .handled_permissions = LANDLOCK_PERMISSION_NAMESPACE_USE | + LANDLOCK_PERMISSION_CAPABILITY_USE, + }; + const struct landlock_namespace_attr ns_attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + .allowed_namespace_types = CLONE_NEWUTS | CLONE_NEWUSER, + }; + /* CAP_SYS_ADMIN is NOT allowed. */ + const struct landlock_capability_attr cap_attr = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + .allowed_capabilities = (1ULL << CAP_SYS_CHROOT), + }; + int ruleset_fd, ns_fd; + + disable_caps(_metadata); + + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &ns_attr, 0)); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &cap_attr, 0)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* + * UTS creation: the process holds CAP_SYS_ADMIN but Landlock denies it + * (not in the cap rule), so the kernel's ns_capable(CAP_SYS_ADMIN) gate + * fails before the namespace hook is reached. + */ + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(-1, unshare(CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + + /* + * setns into the current UTS namespace: the type is allowed but + * CAP_SYS_ADMIN is denied, so the kernel's ns_capable(CAP_SYS_ADMIN) + * gate fails before the namespace hook is reached (the setns capability + * leg, complementing the unshare/create leg above). + */ + ns_fd = open("/proc/self/ns/uts", O_RDONLY); + ASSERT_LE(0, ns_fd); + EXPECT_EQ(-1, setns(ns_fd, CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + EXPECT_EQ(0, close(ns_fd)); + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* + * User NS creation: no capable() call from the kernel, so only + * LANDLOCK_PERMISSION_NAMESPACE_USE applies. CLONE_NEWUSER is in the + * allowed set, so this succeeds. + */ + EXPECT_EQ(0, unshare(CLONE_NEWUSER)); +} + +/* + * Combining CLONE_NEWUSER with another namespace type in a single unshare(2) + * call does not exempt the non-user namespace from the capability check: the + * kernel checks ns_capable(new_user_ns, CAP_SYS_ADMIN) for it, and the + * namespace-agnostic capability hook denies it when the domain handles + * LANDLOCK_PERMISSION_CAPABILITY_USE without allowing CAP_SYS_ADMIN. Both + * namespace types are allowed here, yet the combined call fails atomically, + * exactly like the equivalent two-call sequence. + */ +TEST(two_permissions_combined_unshare_denied) +{ + const struct landlock_ruleset_attr attr = { + .handled_permissions = LANDLOCK_PERMISSION_NAMESPACE_USE | + LANDLOCK_PERMISSION_CAPABILITY_USE, + }; + /* Both namespace types are allowed; no capability is allowed. */ + const struct landlock_namespace_attr ns_attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + .allowed_namespace_types = CLONE_NEWUSER | CLONE_NEWUTS, + }; + int ruleset_fd; + + disable_caps(_metadata); + + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &ns_attr, 0)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* + * CAP_SYS_ADMIN is held so the kernel's commoncap check passes (via + * ownership of the new user namespace) and the denial is attributable + * to Landlock. The UTS leg needs CAP_SYS_ADMIN, which the capability + * hook denies, so the atomic unshare(2) fails and no namespace is + * created. + */ + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(-1, unshare(CLONE_NEWUSER | CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* The user namespace alone has no capability check, so it succeeds. */ + EXPECT_EQ(0, unshare(CLONE_NEWUSER)); +} + +/* + * Positive complement to two_permissions_combined_unshare_denied: allowing + * CAP_SYS_ADMIN lets the same combined unshare(CLONE_NEWUSER | CLONE_NEWUTS) + * succeed, proving the denial above comes from the missing capability allowance + * and not the namespace rule. Run in a child because a successful unshare(2) + * mutates the caller. + */ +TEST(two_permissions_combined_unshare_allowed) +{ + const struct landlock_ruleset_attr attr = { + .handled_permissions = LANDLOCK_PERMISSION_NAMESPACE_USE | + LANDLOCK_PERMISSION_CAPABILITY_USE, + }; + const struct landlock_namespace_attr ns_attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + .allowed_namespace_types = CLONE_NEWUSER | CLONE_NEWUTS, + }; + const struct landlock_capability_attr cap_attr = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + .allowed_capabilities = (1ULL << CAP_SYS_ADMIN), + }; + int ruleset_fd, status; + pid_t child; + + disable_caps(_metadata); + + child = fork(); + ASSERT_LE(0, child); + if (child == 0) { + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, + landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &ns_attr, 0)); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, + LANDLOCK_RULE_CAPABILITY, + &cap_attr, 0)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, unshare(CLONE_NEWUSER | CLONE_NEWUTS)); + clear_cap(_metadata, CAP_SYS_ADMIN); + _exit(_metadata->exit_code); + } + ASSERT_EQ(child, waitpid(child, &status, 0)); + ASSERT_EQ(1, WIFEXITED(status)); + ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); +} + +/* + * Inverse of two_permissions_cap_denied: the required capability is allowed but + * the namespace type is not, so the Landlock namespace hook denies the + * operation (the capability leg passes). A positive control (an allowed type + * creates successfully with the same allowed capability) proves CAP_SYS_ADMIN + * is genuinely exercisable, so the UTS denial is attributable to the namespace + * hook rather than the capability hook. + */ +TEST(two_permissions_ns_denied) +{ + const struct landlock_ruleset_attr attr = { + .handled_permissions = LANDLOCK_PERMISSION_NAMESPACE_USE | + LANDLOCK_PERMISSION_CAPABILITY_USE, + }; + /* CLONE_NEWUTS is NOT allowed; CLONE_NEWNET is. */ + const struct landlock_namespace_attr ns_attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + .allowed_namespace_types = CLONE_NEWNET, + }; + const struct landlock_capability_attr cap_attr = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + .allowed_capabilities = (1ULL << CAP_SYS_ADMIN), + }; + int ruleset_fd; + + disable_caps(_metadata); + + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &ns_attr, 0)); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &cap_attr, 0)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* + * Positive control: CLONE_NEWNET is allowed and CAP_SYS_ADMIN is + * allowed, so the kernel's ns_capable() gate passes and the namespace + * hook allows it. + */ + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, unshare(CLONE_NEWNET)); + + /* + * CAP_SYS_ADMIN is allowed (ns_capable passes), but CLONE_NEWUTS is not + * in the allowed namespace types, so the Landlock namespace hook denies + * it. + */ + EXPECT_EQ(-1, unshare(CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); +} + +/* + * Mount namespace setns is unique: the kernel checks both CAP_SYS_ADMIN and + * CAP_SYS_CHROOT in mntns_install(). Verify that allowing CAP_SYS_ADMIN alone + * is not sufficient. + */ +TEST(two_permissions_mnt_setns) +{ + const struct landlock_ruleset_attr attr = { + .handled_permissions = LANDLOCK_PERMISSION_NAMESPACE_USE | + LANDLOCK_PERMISSION_CAPABILITY_USE, + }; + const struct landlock_namespace_attr ns_attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + .allowed_namespace_types = CLONE_NEWNS, + }; + const struct landlock_capability_attr cap_admin = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + .allowed_capabilities = (1ULL << CAP_SYS_ADMIN), + }; + const struct landlock_capability_attr cap_admin_chroot = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + .allowed_capabilities = (1ULL << CAP_SYS_ADMIN) | + (1ULL << CAP_SYS_CHROOT), + }; + int ruleset_fd, ns_fd; + + disable_caps(_metadata); + + /* Layer 1: allow mount NS + CAP_SYS_ADMIN only (no CAP_SYS_CHROOT). */ + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &ns_attr, 0)); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &cap_admin, 0)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + ns_fd = open("/proc/self/ns/mnt", O_RDONLY); + ASSERT_LE(0, ns_fd); + + /* + * Fails: mntns_install() checks CAP_SYS_ADMIN (allowed) then + * CAP_SYS_CHROOT (denied by LANDLOCK_PERMISSION_CAPABILITY_USE). + */ + set_cap(_metadata, CAP_SYS_ADMIN); + set_cap(_metadata, CAP_SYS_CHROOT); + EXPECT_EQ(-1, setns(ns_fd, CLONE_NEWNS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + clear_cap(_metadata, CAP_SYS_CHROOT); + + /* Layer 2: also allows CAP_SYS_CHROOT. */ + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &ns_attr, 0)); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &cap_admin_chroot, 0)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* + * Still fails: layer 1 still denies CAP_SYS_CHROOT. Landlock layer + * stacking means the most restrictive layer wins. + */ + set_cap(_metadata, CAP_SYS_ADMIN); + set_cap(_metadata, CAP_SYS_CHROOT); + EXPECT_EQ(-1, setns(ns_fd, CLONE_NEWNS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + clear_cap(_metadata, CAP_SYS_CHROOT); + EXPECT_EQ(0, close(ns_fd)); +} + +/* + * Positive complement to two_permissions_mnt_setns: a single layer that allows + * the mount namespace type AND both CAP_SYS_ADMIN and CAP_SYS_CHROOT lets + * setns(CLONE_NEWNS) into the process's own mount namespace succeed. Proves + * the denial legs above are caused by the withheld CAP_SYS_CHROOT, not an + * unconditional block of mount setns. + */ +TEST(two_permissions_mnt_setns_allowed) +{ + const struct landlock_ruleset_attr attr = { + .handled_permissions = LANDLOCK_PERMISSION_NAMESPACE_USE | + LANDLOCK_PERMISSION_CAPABILITY_USE, + }; + const struct landlock_namespace_attr ns_attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + .allowed_namespace_types = CLONE_NEWNS, + }; + const struct landlock_capability_attr cap_attr = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + .allowed_capabilities = (1ULL << CAP_SYS_ADMIN) | + (1ULL << CAP_SYS_CHROOT), + }; + int ruleset_fd, ns_fd; + + disable_caps(_metadata); + + /* Open the NS FD before enforcing the domain. */ + ns_fd = open("/proc/self/ns/mnt", O_RDONLY); + ASSERT_LE(0, ns_fd); + + ruleset_fd = landlock_create_ruleset(&attr, sizeof(attr), 0); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &ns_attr, 0)); + ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_CAPABILITY, + &cap_attr, 0)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* + * mntns_install() checks CAP_SYS_ADMIN then CAP_SYS_CHROOT (both + * allowed by the rule) and the mount NS type is allowed, so setns into + * the process's own mount namespace succeeds. + */ + set_cap(_metadata, CAP_SYS_ADMIN); + set_cap(_metadata, CAP_SYS_CHROOT); + EXPECT_EQ(0, setns(ns_fd, CLONE_NEWNS)); + clear_cap(_metadata, CAP_SYS_ADMIN); + clear_cap(_metadata, CAP_SYS_CHROOT); + EXPECT_EQ(0, close(ns_fd)); +} + +/* + * setns() through a namespace fd inherited across fork() is still governed by + * the child's own Landlock domain: the child enforces a domain denying + * CLONE_NEWUTS, then joining the inherited /proc/self/ns/uts fd is denied. + */ +TEST(setns_inherited_fd) +{ + int ns_fd, status; + pid_t child; + + disable_caps(_metadata); + + /* Open the UTS ns fd before fork() so the child inherits it. */ + ns_fd = open("/proc/self/ns/uts", O_RDONLY); + ASSERT_LE(0, ns_fd); + + child = fork(); + ASSERT_LE(0, child); + if (child == 0) { + int ruleset_fd; + + /* + * Baseline: joining the inherited fd works before the domain, + * so the later EPERM is attributable to Landlock. + */ + set_cap(_metadata, CAP_SYS_ADMIN); + ASSERT_EQ(0, setns(ns_fd, CLONE_NEWUTS)); + clear_cap(_metadata, CAP_SYS_ADMIN); + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + /* No rule allows UTS. */ + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(-1, setns(ns_fd, CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + + _exit(_metadata->exit_code); + return; + } + + EXPECT_EQ(0, close(ns_fd)); + ASSERT_EQ(child, waitpid(child, &status, 0)); + if (WIFSIGNALED(status) || !WIFEXITED(status) || + WEXITSTATUS(status) != EXIT_SUCCESS) + _metadata->exit_code = KSFT_FAIL; +} + +/* Audit tests */ + +static int matches_log_ns_create(int audit_fd, __u64 ns_type) +{ + static const char log_template[] = REGEX_LANDLOCK_PREFIX + " blockers=namespace\\.use namespace_type=0x%x namespace_id=0$"; + char log_match[sizeof(log_template) + 10]; + int log_match_len; + + log_match_len = snprintf(log_match, sizeof(log_match), log_template, + (unsigned int)ns_type); + if (log_match_len >= sizeof(log_match)) + return -E2BIG; + + return audit_match_record(audit_fd, AUDIT_LANDLOCK_ACCESS, log_match, + NULL); +} + +static int matches_log_ns_setns(int audit_fd, __u64 ns_type, __u64 ns_id) +{ + static const char log_template[] = REGEX_LANDLOCK_PREFIX + " blockers=namespace\\.use namespace_type=0x%x namespace_id=%llu$"; + char log_match[sizeof(log_template) + 32]; + int log_match_len; + + log_match_len = snprintf(log_match, sizeof(log_match), log_template, + (unsigned int)ns_type, + (unsigned long long)ns_id); + if (log_match_len >= sizeof(log_match)) + return -E2BIG; + + return audit_match_record(audit_fd, AUDIT_LANDLOCK_ACCESS, log_match, + NULL); +} + +FIXTURE(ns_audit) +{ + struct audit_filter audit_filter; + int audit_fd; +}; + +FIXTURE_SETUP(ns_audit) +{ + ASSERT_TRUE(is_in_init_user_ns()); + + disable_caps(_metadata); + + set_cap(_metadata, CAP_AUDIT_CONTROL); + self->audit_fd = audit_init_with_exe_filter(&self->audit_filter); + EXPECT_LE(0, self->audit_fd); + clear_cap(_metadata, CAP_AUDIT_CONTROL); +} + +FIXTURE_TEARDOWN(ns_audit) +{ + set_cap(_metadata, CAP_AUDIT_CONTROL); + EXPECT_EQ(0, audit_cleanup(self->audit_fd, &self->audit_filter)); + clear_cap(_metadata, CAP_AUDIT_CONTROL); +} + +/* + * Verifies that a denied namespace creation produces the expected audit record + * with the namespace.use blocker string and namespace_type. + */ +TEST_F(ns_audit, create_denied) +{ + struct audit_records records = {}; + int ruleset_fd; + __u64 domain_id; + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(-1, unshare(CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + + EXPECT_EQ(0, matches_log_ns_create(self->audit_fd, CLONE_NEWUTS)); + + /* + * The domain allocation record is emitted in the same event as the + * first denial; anchor its status=allocated and enforcing pid. Both + * access and domain records are now consumed, so none remain. + */ + EXPECT_EQ(0, matches_log_domain_allocated(self->audit_fd, getpid(), + &domain_id)); + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); + EXPECT_EQ(0, records.domain); +} + +TEST_F(ns_audit, create_allowed) +{ + struct audit_records records = {}; + int ruleset_fd; + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, add_ns_rule(ruleset_fd, CLONE_NEWUTS)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, unshare(CLONE_NEWUTS)); + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* No records: allowed operations never trigger audit logging. */ + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); +} + +TEST_F(ns_audit, setns_allowed) +{ + struct audit_records records = {}; + int ruleset_fd, ns_fd; + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, add_ns_rule(ruleset_fd, CLONE_NEWUTS)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + ns_fd = open("/proc/self/ns/uts", O_RDONLY); + ASSERT_LE(0, ns_fd); + + /* Allowed: should succeed with no audit record. */ + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, setns(ns_fd, CLONE_NEWUTS)); + clear_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, close(ns_fd)); + + /* No records: allowed setns never triggers audit logging. */ + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); +} + +TEST_F(ns_audit, setns_denied) +{ + struct audit_records records = {}; + int ruleset_fd, ns_fd; + __u64 ns_id, domain_id; + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + /* No rule allows UTS -> denied. */ + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + ns_fd = open("/proc/self/ns/uts", O_RDONLY); + ASSERT_LE(0, ns_fd); + + /* The audit record logs the target namespace's exact ns_id. */ + ASSERT_EQ(0, ioctl(ns_fd, NS_GET_ID, &ns_id)); + + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(-1, setns(ns_fd, CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, close(ns_fd)); + + /* Verify the audit record for setns denial, anchored to the ns_id. */ + EXPECT_EQ(0, matches_log_ns_setns(self->audit_fd, CLONE_NEWUTS, ns_id)); + + /* + * The domain allocation record is emitted in the same event as the + * first denial; anchor its status=allocated and enforcing pid. Both + * access and domain records are now consumed, so none remain. + */ + EXPECT_EQ(0, matches_log_domain_allocated(self->audit_fd, getpid(), + &domain_id)); + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); + EXPECT_EQ(0, records.domain); +} + +/* + * A quieted denial is still denied (EPERM); only its audit record is + * suppressed. Quiet-only rule (empty allowed set). + */ +TEST_F(ns_audit, create_quieted) +{ + struct audit_records records = {}; + int ruleset_fd; + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, add_ns_rule_full(ruleset_fd, 0, CLONE_NEWUTS)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(-1, unshare(CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* The denial is suppressed: no access record. */ + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); +} + +/* + * A quieted setns denial is still denied (EPERM); only its audit record is + * suppressed. The install-hook mirror of create_quieted. + */ +TEST_F(ns_audit, setns_quieted) +{ + struct audit_records records = {}; + int ruleset_fd, ns_fd; + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, add_ns_rule_full(ruleset_fd, 0, CLONE_NEWUTS)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + ns_fd = open("/proc/self/ns/uts", O_RDONLY); + ASSERT_LE(0, ns_fd); + + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(-1, setns(ns_fd, CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, close(ns_fd)); + + /* The denial is suppressed: no access record. */ + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); +} + +/* + * Quiet is per-member: quieting one namespace type does not silence the denial + * of another type denied by the same layer. + */ +TEST_F(ns_audit, quiet_is_per_member) +{ + struct audit_records records = {}; + int ruleset_fd; + __u64 domain_id; + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + /* + * Quiet CLONE_NEWNET only; CLONE_NEWUTS is neither allowed nor quiet. + */ + ASSERT_EQ(0, add_ns_rule_full(ruleset_fd, 0, CLONE_NEWNET)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(-1, unshare(CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* The unquieted CLONE_NEWUTS denial is still logged. */ + EXPECT_EQ(0, matches_log_ns_create(self->audit_fd, CLONE_NEWUTS)); + EXPECT_EQ(0, matches_log_domain_allocated(self->audit_fd, getpid(), + &domain_id)); + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); + EXPECT_EQ(0, records.domain); +} + +/* + * Quieting an unknown namespace bit has no effect: a rule that quiets only a + * bit the running kernel does not know still logs the denial of a known type. + * Mirrors the forward-compatibility contract for the quiet mask. + */ +TEST_F(ns_audit, quiet_unknown_bit_no_effect) +{ + struct audit_records records = {}; + int ruleset_fd; + __u64 domain_id; + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + /* Quiet only an unknown bit (bit 31 is not a CLONE_NEW* value). */ + ASSERT_EQ(0, add_ns_rule_full(ruleset_fd, 0, (1ULL << 31))); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(-1, unshare(CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* The unknown quiet bit does not suppress the known denial. */ + EXPECT_EQ(0, matches_log_ns_create(self->audit_fd, CLONE_NEWUTS)); + EXPECT_EQ(0, matches_log_domain_allocated(self->audit_fd, getpid(), + &domain_id)); + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); + EXPECT_EQ(0, records.domain); +} + +/* A single rule can both allow one member and quiet the denial of another. */ +TEST_F(ns_audit, allow_and_quiet) +{ + struct audit_records records = {}; + int ruleset_fd; + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, add_ns_rule_full(ruleset_fd, CLONE_NEWNET, CLONE_NEWUTS)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* Allowed member: succeeds. */ + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, unshare(CLONE_NEWNET)); + /* Quieted member: denied but not logged. */ + EXPECT_EQ(-1, unshare(CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); +} + +/* + * Quieting a member that is also allowed is inert: an allowed member is never + * denied, so its quiet bit has no effect. + */ +TEST_F(ns_audit, allow_and_quiet_same_member) +{ + struct audit_records records = {}; + int ruleset_fd; + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + /* Same member both allowed and quieted. */ + ASSERT_EQ(0, add_ns_rule_full(ruleset_fd, CLONE_NEWNET, CLONE_NEWNET)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* The member is allowed (quiet is inert), so it succeeds. */ + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(0, unshare(CLONE_NEWNET)); + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* Nothing denied, nothing logged. */ + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); +} + +/* + * Only the youngest denying layer decides quieting: a parent that quiets a + * member cannot silence a denial by a deeper layer that handles but does not + * quiet it. + */ +TEST_F(ns_audit, quiet_youngest_layer_wins) +{ + struct audit_records records = {}; + int ruleset_fd; + + /* Parent layer: handles namespaces and quiets CLONE_NEWUTS. */ + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, add_ns_rule_full(ruleset_fd, 0, CLONE_NEWUTS)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* Child layer: handles namespaces but does not quiet CLONE_NEWUTS. */ + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(-1, unshare(CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* The child layer denies and does not quiet: logged. */ + EXPECT_EQ(0, matches_log_ns_create(self->audit_fd, CLONE_NEWUTS)); + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); +} + +/* + * A parent layer that quiets and denies a member suppresses its own denial even + * when it is not the youngest layer: a child layer allows the member, so the + * parent is the youngest (and only) denying layer and its stored quiet mask + * fires. Complements quiet_youngest_layer_wins. + */ +TEST_F(ns_audit, quiet_parent_only_denying_layer) +{ + struct audit_records records = {}; + int ruleset_fd; + + /* Parent layer: quiet-only, so it denies CLONE_NEWUTS. */ + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, add_ns_rule_full(ruleset_fd, 0, CLONE_NEWUTS)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + /* Child layer: allows CLONE_NEWUTS, so only the parent denies it. */ + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, add_ns_rule(ruleset_fd, CLONE_NEWUTS)); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + set_cap(_metadata, CAP_SYS_ADMIN); + EXPECT_EQ(-1, unshare(CLONE_NEWUTS)); + EXPECT_EQ(EPERM, errno); + clear_cap(_metadata, CAP_SYS_ADMIN); + + /* The parent quiets and is the youngest denying layer: suppressed. */ + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); +} + +/* Trace tests */ + +/* clang-format off */ +FIXTURE(ns_trace) { + /* clang-format on */ + int tracefs_ok; +}; + +FIXTURE_SETUP(ns_trace) +{ + int ret; + + set_cap(_metadata, CAP_SYS_ADMIN); + ASSERT_EQ(0, unshare(CLONE_NEWNS)); + ASSERT_EQ(0, mount(NULL, "/", NULL, MS_REC | MS_PRIVATE, NULL)); + + ret = tracefs_fixture_setup(); + if (ret) { + clear_cap(_metadata, CAP_SYS_ADMIN); + self->tracefs_ok = 0; + SKIP(return, "tracefs not available"); + } + self->tracefs_ok = 1; + + ASSERT_EQ(0, tracefs_enable_event(TRACEFS_CREATE_RULESET_ENABLE, true)); + ASSERT_EQ(0, tracefs_enable_event(TRACEFS_ADD_RULE_NAMESPACE_ENABLE, + true)); + ASSERT_EQ(0, tracefs_enable_event( + TRACEFS_DENY_PERMISSION_NAMESPACE_ENABLE, true)); + ASSERT_EQ(0, tracefs_clear()); + clear_cap(_metadata, CAP_SYS_ADMIN); +} + +FIXTURE_TEARDOWN(ns_trace) +{ + if (!self->tracefs_ok) + return; + + set_cap(_metadata, CAP_SYS_ADMIN); + tracefs_enable_event(TRACEFS_CREATE_RULESET_ENABLE, false); + tracefs_enable_event(TRACEFS_ADD_RULE_NAMESPACE_ENABLE, false); + tracefs_enable_event(TRACEFS_DENY_PERMISSION_NAMESPACE_ENABLE, false); + tracefs_fixture_teardown(); + clear_cap(_metadata, CAP_SYS_ADMIN); +} + +/* + * Check the permission fields and version history, including two rejected calls + * and two successful calls that do not extend the effective policy: a repeated + * rule and an unknown-only rule. + */ +TEST_F(ns_trace, rule_events) +{ + const char *const version_1 = + REGEX_ADD_RULE_NAMESPACE_VERSION(TRACE_TASK, "1"); + const char *const version_2 = + REGEX_ADD_RULE_NAMESPACE_VERSION(TRACE_TASK, "2"); + const char *const version_3 = + REGEX_ADD_RULE_NAMESPACE_VERSION(TRACE_TASK, "3"); + const struct landlock_namespace_attr valid_attr = { + .permissions = LANDLOCK_PERMISSION_NAMESPACE_USE, + .allowed_namespace_types = CLONE_NEWUTS, + .quiet_namespace_types = CLONE_NEWNET, + }; + const struct landlock_namespace_attr invalid_attr = { + .permissions = LANDLOCK_PERMISSION_CAPABILITY_USE, + .allowed_namespace_types = CLONE_NEWUTS, + }; + char expected[32], field[64]; + char *buf; + int ruleset_fd; + + if (!self->tracefs_ok) + SKIP(return, "tracefs not available"); + + ASSERT_EQ(0, tracefs_clear_buf()); + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + ASSERT_EQ(0, add_ns_rule_full(ruleset_fd, CLONE_NEWUTS, CLONE_NEWNET)); + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &invalid_attr, 0)); + ASSERT_EQ(EINVAL, errno); + ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NAMESPACE, + &valid_attr, LANDLOCK_ADD_RULE_QUIET)); + ASSERT_EQ(EINVAL, errno); + ASSERT_EQ(0, add_ns_rule_full(ruleset_fd, CLONE_NEWUTS, CLONE_NEWNET)); + ASSERT_EQ(0, add_ns_rule(ruleset_fd, 1ULL << 63)); + EXPECT_EQ(0, close(ruleset_fd)); + + buf = tracefs_read_buf(); + ASSERT_NE(NULL, buf); + + ASSERT_EQ(1, + tracefs_count_matches(buf, REGEX_CREATE_RULESET(TRACE_TASK))); + ASSERT_EQ(0, tracefs_extract_field( + buf, REGEX_CREATE_RULESET(TRACE_TASK), + "handled_permissions", field, sizeof(field))); + EXPECT_STREQ("namespace.use", field); + + ASSERT_EQ(3, + tracefs_count_matches(buf, "landlock_add_rule_namespace: ")); + ASSERT_EQ(3, tracefs_count_matches( + buf, REGEX_ADD_RULE_NAMESPACE(TRACE_TASK))); + EXPECT_EQ(1, tracefs_count_matches(buf, version_1)); + EXPECT_EQ(1, tracefs_count_matches(buf, version_2)); + EXPECT_EQ(1, tracefs_count_matches(buf, version_3)); + + ASSERT_EQ(0, tracefs_extract_field(buf, version_1, "permissions", field, + sizeof(field))); + EXPECT_STREQ("namespace.use", field); + ASSERT_EQ(0, tracefs_extract_field(buf, version_1, + "allowed_namespace_types", field, + sizeof(field))); + /* Trace fields use raw CLONE_NEW* values, not internal bit indexes. */ + snprintf(expected, sizeof(expected), "0x%llx", + (unsigned long long)CLONE_NEWUTS); + EXPECT_STREQ(expected, field); + ASSERT_EQ(0, + tracefs_extract_field(buf, version_1, "quiet_namespace_types", + field, sizeof(field))); + snprintf(expected, sizeof(expected), "0x%llx", + (unsigned long long)CLONE_NEWNET); + EXPECT_STREQ(expected, field); + + /* The rejected calls emit no event and do not consume version 2. */ + ASSERT_EQ(0, tracefs_extract_field(buf, version_2, "permissions", field, + sizeof(field))); + EXPECT_STREQ("namespace.use", field); + ASSERT_EQ(0, tracefs_extract_field(buf, version_2, + "allowed_namespace_types", field, + sizeof(field))); + snprintf(expected, sizeof(expected), "0x%llx", + (unsigned long long)CLONE_NEWUTS); + EXPECT_STREQ(expected, field); + ASSERT_EQ(0, + tracefs_extract_field(buf, version_2, "quiet_namespace_types", + field, sizeof(field))); + snprintf(expected, sizeof(expected), "0x%llx", + (unsigned long long)CLONE_NEWNET); + EXPECT_STREQ(expected, field); + + /* The unknown-only call succeeds but contributes no effective bits. */ + ASSERT_EQ(0, tracefs_extract_field(buf, version_3, "permissions", field, + sizeof(field))); + EXPECT_STREQ("namespace.use", field); + ASSERT_EQ(0, tracefs_extract_field(buf, version_3, + "allowed_namespace_types", field, + sizeof(field))); + EXPECT_STREQ("0x0", field); + ASSERT_EQ(0, + tracefs_extract_field(buf, version_3, "quiet_namespace_types", + field, sizeof(field))); + EXPECT_STREQ("0x0", field); + + free(buf); +} + +static void test_ns_trace_denial(struct __test_metadata *const _metadata, + const bool use_setns, const bool quiet) +{ + char expected[32], field[64]; + int ruleset_fd, ns_fd = -1, ret; + __u64 expected_ns_id = 0; + char *buf; + + ASSERT_EQ(0, tracefs_clear_buf()); + + if (use_setns) { + ns_fd = open("/proc/self/ns/uts", O_RDONLY | O_CLOEXEC); + ASSERT_LE(0, ns_fd); + ASSERT_EQ(0, ioctl(ns_fd, NS_GET_ID, &expected_ns_id)); + } + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + if (quiet) + ASSERT_EQ(0, add_ns_rule_full(ruleset_fd, 0, CLONE_NEWUTS)); + + set_cap(_metadata, CAP_SYS_ADMIN); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + if (use_setns) + ret = setns(ns_fd, CLONE_NEWUTS); + else + ret = unshare(CLONE_NEWUTS); + EXPECT_EQ(-1, ret); + EXPECT_EQ(EPERM, errno); + + clear_cap(_metadata, CAP_SYS_ADMIN); + if (ns_fd >= 0) + EXPECT_EQ(0, close(ns_fd)); + + buf = tracefs_read_buf(); + ASSERT_NE(NULL, buf); + ASSERT_EQ(1, tracefs_count_matches( + buf, REGEX_DENY_PERMISSION_NAMESPACE(TRACE_TASK))) + { + TH_LOG("Expected one namespace denial event\n%s", buf); + } + + ASSERT_EQ(0, tracefs_extract_field( + buf, REGEX_DENY_PERMISSION_NAMESPACE(TRACE_TASK), + "domain", field, sizeof(field))); + EXPECT_STRNE("0", field); + ASSERT_EQ(0, tracefs_extract_field( + buf, REGEX_DENY_PERMISSION_NAMESPACE(TRACE_TASK), + "same_exec", field, sizeof(field))); + EXPECT_STREQ("1", field); + ASSERT_EQ(0, tracefs_extract_field( + buf, REGEX_DENY_PERMISSION_NAMESPACE(TRACE_TASK), + "logged", field, sizeof(field))); + EXPECT_STREQ(quiet ? "0" : "1", field); + ASSERT_EQ(0, tracefs_extract_field( + buf, REGEX_DENY_PERMISSION_NAMESPACE(TRACE_TASK), + "blockers", field, sizeof(field))); + EXPECT_STREQ("use", field); + ASSERT_EQ(0, tracefs_extract_field( + buf, REGEX_DENY_PERMISSION_NAMESPACE(TRACE_TASK), + "namespace_type", field, sizeof(field))); + snprintf(expected, sizeof(expected), "0x%llx", + (unsigned long long)CLONE_NEWUTS); + EXPECT_STREQ(expected, field); + ASSERT_EQ(0, tracefs_extract_field( + buf, REGEX_DENY_PERMISSION_NAMESPACE(TRACE_TASK), + "namespace_id", field, sizeof(field))); + EXPECT_EQ(use_setns ? expected_ns_id : 0, strtoull(field, NULL, 10)); + + free(buf); +} + +TEST_F(ns_trace, deny_create) +{ + if (!self->tracefs_ok) + SKIP(return, "tracefs not available"); + test_ns_trace_denial(_metadata, false, false); +} + +TEST_F(ns_trace, deny_create_quiet) +{ + if (!self->tracefs_ok) + SKIP(return, "tracefs not available"); + test_ns_trace_denial(_metadata, false, true); +} + +TEST_F(ns_trace, deny_setns) +{ + if (!self->tracefs_ok) + SKIP(return, "tracefs not available"); + test_ns_trace_denial(_metadata, true, false); +} + +/* clang-format off */ +FIXTURE(ns_proc_open) { + /* clang-format on */ + struct audit_filter audit_filter; + int audit_fd; +}; + +FIXTURE_VARIANT(ns_proc_open) +{ + __u64 ns_type; +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_proc_open, mnt) { + /* clang-format on */ + .ns_type = CLONE_NEWNS, +}; + +/* clang-format off */ +FIXTURE_VARIANT_ADD(ns_proc_open, user) { + /* clang-format on */ + .ns_type = CLONE_NEWUSER, +}; + +FIXTURE_SETUP(ns_proc_open) +{ + ASSERT_TRUE(is_in_init_user_ns()); + + disable_caps(_metadata); + + set_cap(_metadata, CAP_AUDIT_CONTROL); + self->audit_fd = audit_init_with_exe_filter(&self->audit_filter); + EXPECT_LE(0, self->audit_fd); + clear_cap(_metadata, CAP_AUDIT_CONTROL); +} + +FIXTURE_TEARDOWN(ns_proc_open) +{ + set_cap(_metadata, CAP_AUDIT_CONTROL); + EXPECT_EQ(0, audit_cleanup(self->audit_fd, &self->audit_filter)); + clear_cap(_metadata, CAP_AUDIT_CONTROL); +} + +/* + * Opening /proc/self/ns/<type> only acquires a procfs reference, not membership + * or an acquired fd of the kind LANDLOCK_PERMISSION_NAMESPACE_USE gates. + * Verify the open is unrestricted even when the permission is handled with no + * rules. + */ +TEST_F(ns_proc_open, open_unrestricted) +{ + char proc_path[NS_PROC_PATH_MAX]; + struct audit_records records = {}; + int ruleset_fd, fd; + + ASSERT_TRUE( + ns_is_supported(variant->ns_type, proc_path, sizeof(proc_path))) + { + TH_LOG("Namespace type 0x%llx not supported", + (unsigned long long)variant->ns_type); + } + + ruleset_fd = create_ns_ruleset(); + ASSERT_LE(0, ruleset_fd); + enforce_ruleset(_metadata, ruleset_fd); + EXPECT_EQ(0, close(ruleset_fd)); + + fd = open(proc_path, O_RDONLY); + ASSERT_LE(0, fd) + { + TH_LOG("open(%s) failed: %s", proc_path, strerror(errno)); + } + + /* No Landlock denial. */ + EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); + EXPECT_EQ(0, records.access); + + EXPECT_EQ(0, close(fd)); +} + +TEST_HARNESS_MAIN
diff --git a/tools/testing/selftests/landlock/ptrace_test.c b/tools/testing/selftests/landlock/ptrace_test.c index 2644445..e0e7f95 100644 --- a/tools/testing/selftests/landlock/ptrace_test.c +++ b/tools/testing/selftests/landlock/ptrace_test.c
@@ -305,7 +305,7 @@ static int matches_log_ptrace(struct __test_metadata *const _metadata, log_match_len = snprintf(log_match, sizeof(log_match), log_template, opid); - if (log_match_len > sizeof(log_match)) + if (log_match_len >= sizeof(log_match)) return -E2BIG; return audit_match_record(audit_fd, AUDIT_LANDLOCK_ACCESS, log_match,
diff --git a/tools/testing/selftests/landlock/trace.h b/tools/testing/selftests/landlock/trace.h index 2ec8633..36e8f16 100644 --- a/tools/testing/selftests/landlock/trace.h +++ b/tools/testing/selftests/landlock/trace.h
@@ -31,6 +31,10 @@ TRACEFS_LANDLOCK_DIR "/landlock_add_rule_path_beneath/enable" #define TRACEFS_ADD_RULE_NET_PORT_ENABLE \ TRACEFS_LANDLOCK_DIR "/landlock_add_rule_net_port/enable" +#define TRACEFS_ADD_RULE_NAMESPACE_ENABLE \ + TRACEFS_LANDLOCK_DIR "/landlock_add_rule_namespace/enable" +#define TRACEFS_ADD_RULE_CAPABILITY_ENABLE \ + TRACEFS_LANDLOCK_DIR "/landlock_add_rule_capability/enable" #define TRACEFS_CHECK_RULE_FS_ENABLE \ TRACEFS_LANDLOCK_DIR "/landlock_check_rule_inode/enable" #define TRACEFS_CHECK_RULE_NET_ENABLE \ @@ -39,6 +43,10 @@ TRACEFS_LANDLOCK_DIR "/landlock_deny_access_fs/enable" #define TRACEFS_DENY_ACCESS_NET_ENABLE \ TRACEFS_LANDLOCK_DIR "/landlock_deny_access_net/enable" +#define TRACEFS_DENY_PERMISSION_NAMESPACE_ENABLE \ + TRACEFS_LANDLOCK_DIR "/landlock_deny_permission_namespace/enable" +#define TRACEFS_DENY_PERMISSION_CAPABILITY_ENABLE \ + TRACEFS_LANDLOCK_DIR "/landlock_deny_permission_capability/enable" #define TRACEFS_DENY_PTRACE_ENABLE \ TRACEFS_LANDLOCK_DIR "/landlock_deny_ptrace/enable" #define TRACEFS_DENY_SCOPE_SIGNAL_ENABLE \ @@ -95,13 +103,36 @@ "access_rights=[a-z_|]* " \ "port=[0-9]\\+$" +#define REGEX_ADD_RULE_NAMESPACE_VERSION(task, version) \ + TRACE_PREFIX(task) \ + "landlock_add_rule_namespace: " \ + "ruleset=[0-9a-f]\\+\\." version " " \ + "permissions=[a-z._|]* " \ + "allowed_namespace_types=0x[0-9a-f]\\+ " \ + "quiet_namespace_types=0x[0-9a-f]\\+$" + +#define REGEX_ADD_RULE_NAMESPACE(task) \ + REGEX_ADD_RULE_NAMESPACE_VERSION(task, "[0-9]\\+") + +#define REGEX_ADD_RULE_CAPABILITY_VERSION(task, version) \ + TRACE_PREFIX(task) \ + "landlock_add_rule_capability: " \ + "ruleset=[0-9a-f]\\+\\." version " " \ + "permissions=[a-z._|]* " \ + "allowed_capabilities=0x[0-9a-f]\\+ " \ + "quiet_capabilities=0x[0-9a-f]\\+$" + +#define REGEX_ADD_RULE_CAPABILITY(task) \ + REGEX_ADD_RULE_CAPABILITY_VERSION(task, "[0-9]\\+") + #define REGEX_CREATE_RULESET(task) \ TRACE_PREFIX(task) \ "landlock_create_ruleset: " \ "ruleset=[0-9a-f]\\+\\.[0-9]\\+ " \ "handled_fs=[a-z_|]* " \ "handled_net=[a-z_|]* " \ - "scoped=[a-z_|]*$" + "scoped=[a-z_|]* " \ + "handled_permissions=[a-z._|]*$" #define REGEX_CREATE_DOMAIN(task) \ TRACE_PREFIX(task) \ @@ -147,6 +178,25 @@ "blockers=[a-z_|]* " \ "port=-\\?[0-9]\\+$" +#define REGEX_DENY_PERMISSION_NAMESPACE(task) \ + TRACE_PREFIX(task) \ + "landlock_deny_permission_namespace: " \ + "domain=[0-9a-f]\\+ " \ + "same_exec=[01] " \ + "logged=[01] " \ + "blockers=[a-z_|]* " \ + "namespace_type=0x[0-9a-f]\\+ " \ + "namespace_id=[0-9]\\+$" + +#define REGEX_DENY_PERMISSION_CAPABILITY(task) \ + TRACE_PREFIX(task) \ + "landlock_deny_permission_capability: " \ + "domain=[0-9a-f]\\+ " \ + "same_exec=[01] " \ + "logged=[01] " \ + "blockers=[a-z_|]* " \ + "capability=[0-9]\\+$" + #define REGEX_DENY_PTRACE(task) \ TRACE_PREFIX(task) \ "landlock_deny_ptrace: " \
diff --git a/tools/testing/selftests/landlock/trace_test.c b/tools/testing/selftests/landlock/trace_test.c index f9b293a..cb49ce8 100644 --- a/tools/testing/selftests/landlock/trace_test.c +++ b/tools/testing/selftests/landlock/trace_test.c
@@ -148,7 +148,7 @@ TEST_F(trace, no_trace_when_disabled) /* * Verifies that landlock_create_ruleset emits a trace event with the correct - * handled access masks. + * handled access and permission masks. */ TEST_F(trace, create_ruleset) { @@ -186,6 +186,12 @@ TEST_F(trace, create_ruleset) "handled_net", field, sizeof(field))); EXPECT_STREQ("bind_tcp", field); + /* Verify that no permission is handled. */ + EXPECT_EQ(0, tracefs_extract_field( + buf, REGEX_CREATE_RULESET(TRACE_TASK), + "handled_permissions", field, sizeof(field))); + EXPECT_STREQ("", field); + /* Verify version is 0 at creation (no rules added yet). */ EXPECT_EQ(0, tracefs_extract_field(buf, REGEX_CREATE_RULESET(TRACE_TASK),
diff --git a/tools/testing/selftests/landlock/wrappers.h b/tools/testing/selftests/landlock/wrappers.h index 6554832..e6fe46b 100644 --- a/tools/testing/selftests/landlock/wrappers.h +++ b/tools/testing/selftests/landlock/wrappers.h
@@ -9,6 +9,7 @@ #define _GNU_SOURCE #include <linux/landlock.h> +#include <linux/sched.h> #include <sys/syscall.h> #include <sys/types.h> #include <unistd.h> @@ -45,3 +46,31 @@ static inline pid_t sys_gettid(void) { return syscall(__NR_gettid); } + +static inline pid_t sys_clone3(struct clone_args *args, size_t size) +{ + return syscall(__NR_clone3, args, size); +} + +static inline int sys_open_tree(int dfd, const char *filename, + unsigned int flags) +{ + return syscall(__NR_open_tree, dfd, filename, flags); +} + +static inline int sys_fsopen(const char *fsname, unsigned int flags) +{ + return syscall(__NR_fsopen, fsname, flags); +} + +static inline int sys_fsconfig(int fs_fd, unsigned int cmd, const char *key, + const void *value, int aux) +{ + return syscall(__NR_fsconfig, fs_fd, cmd, key, value, aux); +} + +static inline int sys_fsmount(int fs_fd, unsigned int flags, + unsigned int attr_flags) +{ + return syscall(__NR_fsmount, fs_fd, flags, attr_flags); +}
diff --git a/tools/testing/selftests/lib.mk b/tools/testing/selftests/lib.mk index f02cc8a..881f13e 100644 --- a/tools/testing/selftests/lib.mk +++ b/tools/testing/selftests/lib.mk
@@ -106,7 +106,8 @@ if [ "X$(summary)" != "X" ]; then \ per_test_logging=1; \ fi; \ - run_many $(1) + run_many $(1); \ + ktap_print_totals endef define INSTALL_INCLUDES @@ -155,7 +156,7 @@ define INSTALL_MODS_RULE $(if $(INSTALL_LIST),@mkdir -p $(INSTALL_PATH)/$(INSTALL_LIST)) - $(if $(INSTALL_LIST),rsync -a --copy-unsafe-links $(INSTALL_LIST)/*.ko $(INSTALL_PATH)/$(INSTALL_LIST)) + $(if $(wildcard $(INSTALL_LIST)/*.ko),rsync -a --copy-unsafe-links $(INSTALL_LIST)/*.ko $(INSTALL_PATH)/$(INSTALL_LIST)) endef define INSTALL_RULE
diff --git a/tools/testing/selftests/resctrl/cat_test.c b/tools/testing/selftests/resctrl/cat_test.c index 371a2f2..0a41726 100644 --- a/tools/testing/selftests/resctrl/cat_test.c +++ b/tools/testing/selftests/resctrl/cat_test.c
@@ -357,11 +357,32 @@ static bool noncont_cat_feature_check(const struct resctrl_test *test) return resource_info_file_exists(test->resource, "sparse_masks"); } +static bool cat_feature_check(const struct resctrl_test *test) +{ + unsigned long mask; + + if (!test_resource_feature_check(test)) + return false; + + /* + * Test requires an exclusive cache portion. Some platforms may + * legitimately report all bits as shareable, skip the test if that + * is the case. + */ + if (get_mask_no_shareable(test->resource, &mask)) { + ksft_print_msg("All %s bits are shareable, test requires an exclusive cache portion\n", + test->resource); + return false; + } + + return true; +} + struct resctrl_test l3_cat_test = { .name = "L3_CAT", .group = "CAT", .resource = "L3", - .feature_check = test_resource_feature_check, + .feature_check = cat_feature_check, .run_test = cat_run_test, .cleanup = cat_test_cleanup, };
diff --git a/tools/testing/selftests/resctrl/mba_test.c b/tools/testing/selftests/resctrl/mba_test.c index 39cee98..4bb1a82 100644 --- a/tools/testing/selftests/resctrl/mba_test.c +++ b/tools/testing/selftests/resctrl/mba_test.c
@@ -166,6 +166,7 @@ static int check_results(void) static void mba_test_cleanup(void) { + cleanup_read_mem_bw_imc(); remove(RESULT_FILE_NAME); }
diff --git a/tools/testing/selftests/resctrl/mbm_test.c b/tools/testing/selftests/resctrl/mbm_test.c index 6dbbc3b..68c89f5 100644 --- a/tools/testing/selftests/resctrl/mbm_test.c +++ b/tools/testing/selftests/resctrl/mbm_test.c
@@ -125,6 +125,7 @@ static int mbm_measure(const struct user_params *uparams, static void mbm_test_cleanup(void) { + cleanup_read_mem_bw_imc(); remove(RESULT_FILE_NAME); }
diff --git a/tools/testing/selftests/resctrl/resctrl.h b/tools/testing/selftests/resctrl/resctrl.h index 1751010..a7556cda 100644 --- a/tools/testing/selftests/resctrl/resctrl.h +++ b/tools/testing/selftests/resctrl/resctrl.h
@@ -24,6 +24,7 @@ #include <linux/perf_event.h> #include <linux/compiler.h> #include <linux/bits.h> +#include <linux/list.h> #include "kselftest.h" #define MB (1024 * 1024) @@ -183,6 +184,7 @@ void mem_flush(unsigned char *buf, size_t buf_size); void fill_cache_read(unsigned char *buf, size_t buf_size, bool once); ssize_t get_fill_buf_size(int cpu_no, const char *cache_type); int initialize_read_mem_bw_imc(void); +void cleanup_read_mem_bw_imc(void); int measure_read_mem_bw(const struct user_params *uparams, struct resctrl_val_param *param, pid_t bm_pid); void initialize_mem_bw_resctrl(const struct resctrl_val_param *param,
diff --git a/tools/testing/selftests/resctrl/resctrl_val.c b/tools/testing/selftests/resctrl/resctrl_val.c index f20d219..7e7d0f9 100644 --- a/tools/testing/selftests/resctrl/resctrl_val.c +++ b/tools/testing/selftests/resctrl/resctrl_val.c
@@ -14,7 +14,6 @@ #define READ_FILE_NAME "cas_count_read" #define DYN_PMU_PATH "/sys/bus/event_source/devices" #define SCALE 0.00006103515625 -#define MAX_IMCS 40 #define MAX_TOKENS 5 #define CON_MBM_LOCAL_BYTES_PATH \ @@ -28,6 +27,7 @@ struct membw_read_format { }; struct imc_counter_config { + struct list_head entry; __u32 type; __u64 event; __u64 umask; @@ -36,44 +36,40 @@ struct imc_counter_config { }; static char mbm_total_path[1024]; -static int imcs; -static struct imc_counter_config imc_counters_config[MAX_IMCS]; +LIST_HEAD(imc_counters_list); static const struct resctrl_test *current_test; -static void read_mem_bw_initialize_perf_event_attr(int i) +static void read_mem_bw_initialize_perf_event_attr(struct imc_counter_config *imc_counter) { - memset(&imc_counters_config[i].pe, 0, - sizeof(struct perf_event_attr)); - imc_counters_config[i].pe.type = imc_counters_config[i].type; - imc_counters_config[i].pe.size = sizeof(struct perf_event_attr); - imc_counters_config[i].pe.disabled = 1; - imc_counters_config[i].pe.inherit = 1; - imc_counters_config[i].pe.exclude_guest = 0; - imc_counters_config[i].pe.config = - imc_counters_config[i].umask << 8 | - imc_counters_config[i].event; - imc_counters_config[i].pe.sample_type = PERF_SAMPLE_IDENTIFIER; - imc_counters_config[i].pe.read_format = + memset(&imc_counter->pe, 0, sizeof(struct perf_event_attr)); + imc_counter->pe.type = imc_counter->type; + imc_counter->pe.size = sizeof(struct perf_event_attr); + imc_counter->pe.disabled = 1; + imc_counter->pe.inherit = 1; + imc_counter->pe.exclude_guest = 0; + imc_counter->pe.config = imc_counter->umask << 8 | imc_counter->event; + imc_counter->pe.sample_type = PERF_SAMPLE_IDENTIFIER; + imc_counter->pe.read_format = PERF_FORMAT_TOTAL_TIME_ENABLED | PERF_FORMAT_TOTAL_TIME_RUNNING; } -static void read_mem_bw_ioctl_perf_event_ioc_reset_enable(int i) +static void read_mem_bw_ioctl_perf_event_ioc_reset_enable(struct imc_counter_config *imc_counter) { - ioctl(imc_counters_config[i].fd, PERF_EVENT_IOC_RESET, 0); - ioctl(imc_counters_config[i].fd, PERF_EVENT_IOC_ENABLE, 0); + ioctl(imc_counter->fd, PERF_EVENT_IOC_RESET, 0); + ioctl(imc_counter->fd, PERF_EVENT_IOC_ENABLE, 0); } -static void read_mem_bw_ioctl_perf_event_ioc_disable(int i) +static void read_mem_bw_ioctl_perf_event_ioc_disable(struct imc_counter_config *imc_counter) { - ioctl(imc_counters_config[i].fd, PERF_EVENT_IOC_DISABLE, 0); + ioctl(imc_counter->fd, PERF_EVENT_IOC_DISABLE, 0); } /* * get_read_event_and_umask: Parse config into event and umask * @cas_count_cfg: Config - * @count: iMC number + * @imc_counter: iMC counter config */ -static void get_read_event_and_umask(char *cas_count_cfg, unsigned int count) +static void get_read_event_and_umask(char *cas_count_cfg, struct imc_counter_config *imc_counter) { char *token[MAX_TOKENS]; int i = 0; @@ -87,21 +83,20 @@ static void get_read_event_and_umask(char *cas_count_cfg, unsigned int count) if (!token[i]) break; if (strcmp(token[i], "event") == 0) - imc_counters_config[count].event = strtol(token[i + 1], NULL, 16); + imc_counter->event = strtol(token[i + 1], NULL, 16); if (strcmp(token[i], "umask") == 0) - imc_counters_config[count].umask = strtol(token[i + 1], NULL, 16); + imc_counter->umask = strtol(token[i + 1], NULL, 16); } } -static int open_perf_read_event(int i, int cpu_no) +static int open_perf_read_event(int cpu_no, struct imc_counter_config *imc_counter) { - imc_counters_config[i].fd = - perf_event_open(&imc_counters_config[i].pe, -1, cpu_no, -1, - PERF_FLAG_FD_CLOEXEC); + imc_counter->fd = perf_event_open(&imc_counter->pe, -1, cpu_no, -1, + PERF_FLAG_FD_CLOEXEC); - if (imc_counters_config[i].fd == -1) { + if (imc_counter->fd == -1) { fprintf(stderr, "Error opening leader %llx\n", - imc_counters_config[i].pe.config); + imc_counter->pe.config); return -1; } @@ -109,11 +104,11 @@ static int open_perf_read_event(int i, int cpu_no) return 0; } -static int parse_imc_read_bw_events(char *imc_dir, unsigned int type, - unsigned int *count) +static int parse_imc_read_bw_events(char *imc_dir, unsigned int type) { char imc_events_dir[PATH_MAX], imc_counter_cfg[PATH_MAX]; - unsigned int orig_count = *count; + struct imc_counter_config *imc_counter; + bool found_event = false; char cas_count_cfg[1024]; struct dirent *ep; int path_len; @@ -126,13 +121,13 @@ static int parse_imc_read_bw_events(char *imc_dir, unsigned int type, imc_dir); if (path_len >= sizeof(imc_events_dir)) { ksft_print_msg("Unable to create path to %sevents\n", imc_dir); - return -1; + goto out; } dp = opendir(imc_events_dir); if (!dp) { ksft_perror("Unable to open PMU events directory"); - return -1; + goto out; } while ((ep = readdir(dp))) { @@ -163,28 +158,33 @@ static int parse_imc_read_bw_events(char *imc_dir, unsigned int type, ksft_perror("Could not get iMC cas count read"); goto out_close; } - if (*count >= MAX_IMCS) { - ksft_print_msg("Maximum iMC count exceeded\n"); + imc_counter = calloc(1, sizeof(*imc_counter)); + if (!imc_counter) { + ksft_perror("Unable to allocate memory for iMC counters"); goto out_close; } - imc_counters_config[*count].type = type; - get_read_event_and_umask(cas_count_cfg, *count); - /* Do not fail after incrementing *count. */ - *count += 1; + imc_counter->type = type; + get_read_event_and_umask(cas_count_cfg, imc_counter); + list_add(&imc_counter->entry, &imc_counters_list); + found_event = true; } - if (*count == orig_count) { + if (!found_event) { ksft_print_msg("Unable to find events in %s\n", imc_events_dir); goto out_close; } ret = 0; out_close: closedir(dp); +out: + if (ret) + cleanup_read_mem_bw_imc(); + return ret; } /* Get type and config of an iMC counter's read event. */ -static int read_from_imc_dir(char *imc_dir, unsigned int *count) +static int read_from_imc_dir(char *imc_dir) { char imc_counter_type[PATH_MAX]; unsigned int type; @@ -212,7 +212,7 @@ static int read_from_imc_dir(char *imc_dir, unsigned int *count) ksft_perror("Could not get iMC type"); return -1; } - ret = parse_imc_read_bw_events(imc_dir, type, count); + ret = parse_imc_read_bw_events(imc_dir, type); if (ret) { ksft_print_msg("Unable to parse bandwidth event and umask\n"); return ret; @@ -222,21 +222,18 @@ static int read_from_imc_dir(char *imc_dir, unsigned int *count) } /* - * A system can have 'n' number of iMC (Integrated Memory Controller) - * counters, get that 'n'. Discover the properties of the available - * counters in support of needed performance measurement via perf. - * For each iMC counter get it's type and config. Also obtain each - * counter's event and umask for the memory read events that will be - * measured. + * Discover the properties of the available iMC (Integrated Memory Controller) + * counters in support of needed performance measurement via perf. For each iMC + * counter get it's type and config. Also obtain each counter's event and umask + * for the memory read events that will be measured. * - * Enumerate all these details into an array of structures. + * Enumerate all these details into a linked list of structures. * * Return: >= 0 on success. < 0 on failure. */ -static int num_of_imcs(void) +static int enumerate_imcs(void) { char imc_dir[512], *temp; - unsigned int count = 0; struct dirent *ep; int ret; DIR *dp; @@ -265,7 +262,7 @@ static int num_of_imcs(void) if (temp[0] >= '0' && temp[0] <= '9') { sprintf(imc_dir, "%s/%s/", DYN_PMU_PATH, ep->d_name); - ret = read_from_imc_dir(imc_dir, &count); + ret = read_from_imc_dir(imc_dir); if (ret) { closedir(dp); @@ -274,7 +271,7 @@ static int num_of_imcs(void) } } closedir(dp); - if (count == 0) { + if (list_empty(&imc_counters_list)) { ksft_print_msg("Unable to find iMC counters\n"); return -1; @@ -285,31 +282,42 @@ static int num_of_imcs(void) return -1; } - return count; + return 0; } int initialize_read_mem_bw_imc(void) { - int imc; + struct imc_counter_config *imc_counter; + int ret; - imcs = num_of_imcs(); - if (imcs <= 0) - return imcs; + ret = enumerate_imcs(); + if (ret < 0) + return ret; /* Initialize perf_event_attr structures for all iMC's */ - for (imc = 0; imc < imcs; imc++) - read_mem_bw_initialize_perf_event_attr(imc); + list_for_each_entry(imc_counter, &imc_counters_list, entry) + read_mem_bw_initialize_perf_event_attr(imc_counter); return 0; } +void cleanup_read_mem_bw_imc(void) +{ + struct imc_counter_config *imc_counter, *tmp; + + list_for_each_entry_safe(imc_counter, tmp, &imc_counters_list, entry) { + list_del(&imc_counter->entry); + free(imc_counter); + } +} + static void perf_close_imc_read_mem_bw(void) { - int mc; + struct imc_counter_config *imc_counter; - for (mc = 0; mc < imcs; mc++) { - if (imc_counters_config[mc].fd != -1) - close(imc_counters_config[mc].fd); + list_for_each_entry(imc_counter, &imc_counters_list, entry) { + if (imc_counter->fd != -1) + close(imc_counter->fd); } } @@ -321,13 +329,14 @@ static void perf_close_imc_read_mem_bw(void) */ static int perf_open_imc_read_mem_bw(int cpu_no) { - int imc, ret; + struct imc_counter_config *imc_counter; + int ret; - for (imc = 0; imc < imcs; imc++) - imc_counters_config[imc].fd = -1; + list_for_each_entry(imc_counter, &imc_counters_list, entry) + imc_counter->fd = -1; - for (imc = 0; imc < imcs; imc++) { - ret = open_perf_read_event(imc, cpu_no); + list_for_each_entry(imc_counter, &imc_counters_list, entry) { + ret = open_perf_read_event(cpu_no, imc_counter); if (ret) goto close_fds; } @@ -347,16 +356,16 @@ static int perf_open_imc_read_mem_bw(int cpu_no) */ static void do_imc_read_mem_bw_test(void) { - int imc; + struct imc_counter_config *imc_counter; - for (imc = 0; imc < imcs; imc++) - read_mem_bw_ioctl_perf_event_ioc_reset_enable(imc); + list_for_each_entry(imc_counter, &imc_counters_list, entry) + read_mem_bw_ioctl_perf_event_ioc_reset_enable(imc_counter); sleep(1); /* Stop counters after a second to get results. */ - for (imc = 0; imc < imcs; imc++) - read_mem_bw_ioctl_perf_event_ioc_disable(imc); + list_for_each_entry(imc_counter, &imc_counters_list, entry) + read_mem_bw_ioctl_perf_event_ioc_disable(imc_counter); } /* @@ -371,17 +380,15 @@ static void do_imc_read_mem_bw_test(void) static int get_read_mem_bw_imc(float *bw_imc) { float reads = 0, of_mul_read = 1; - int imc; + struct imc_counter_config *r; /* * Log read event values from all iMC counters into * struct imc_counter_config. * Take overflow into consideration before calculating total bandwidth. */ - for (imc = 0; imc < imcs; imc++) { + list_for_each_entry(r, &imc_counters_list, entry) { struct membw_read_format measurement; - struct imc_counter_config *r = - &imc_counters_config[imc]; if (read(r->fd, &measurement, sizeof(measurement)) == -1) { ksft_perror("Couldn't get read bandwidth through iMC");
diff --git a/tools/testing/selftests/sched_ext/.gitignore b/tools/testing/selftests/sched_ext/.gitignore index ae5491a..54a1fd2 100644 --- a/tools/testing/selftests/sched_ext/.gitignore +++ b/tools/testing/selftests/sched_ext/.gitignore
@@ -4,3 +4,7 @@ !Makefile !.gitignore !config +!test_modules/ +!test_modules/scx_enq_blocked_test.c +!test_modules/Makefile +test_modules/*.mod.c
diff --git a/tools/testing/selftests/sched_ext/Makefile b/tools/testing/selftests/sched_ext/Makefile index af919a5..c5d3a2e 100644 --- a/tools/testing/selftests/sched_ext/Makefile +++ b/tools/testing/selftests/sched_ext/Makefile
@@ -5,10 +5,12 @@ include ../../../scripts/Makefile.include TEST_GEN_PROGS := runner +TEST_GEN_MODS_DIR := test_modules # override lib.mk's default rules OVERRIDE_TARGETS := 1 include ../lib.mk +include ../cgroup/lib/libcgroup.mk CURDIR := $(abspath .) REPOROOT := $(abspath ../../../..) @@ -53,7 +55,7 @@ GENFLAGS := -DHAVE_GENHDR endif -CFLAGS += -g -O2 -rdynamic -pthread -Wall -Werror $(GENFLAGS) \ +CFLAGS += -g -O2 -pthread -Wall -Werror $(GENFLAGS) \ -I$(INCLUDE_DIR) -I$(GENDIR) -I$(LIBDIR) \ -I$(TOOLSINCDIR) -I$(APIDIR) -I$(CURDIR)/include -I$(SCXTOOLSINCDIR) @@ -62,7 +64,7 @@ CFLAGS += -Wno-unused-command-line-argument endif -LDFLAGS = -lelf -lz -lpthread -lzstd +LDFLAGS += -lelf -lz -lpthread -lzstd IS_LITTLE_ENDIAN = $(shell $(CC) -dM -E - </dev/null | \ grep 'define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__') @@ -153,7 +155,7 @@ override define CLEAN rm -rf $(OUTPUT_DIR) - rm -f $(TEST_GEN_PROGS) + rm -f $(TEST_GEN_PROGS) $(EXTRA_CLEAN) endef # Every testcase takes all of the BPF progs are dependencies by default. This @@ -162,10 +164,12 @@ all_test_bpfprogs := $(foreach prog,$(wildcard *.bpf.c),$(INCLUDE_DIR)/$(patsubst %.c,%.skel.h,$(prog))) auto-test-targets := \ + cgroup_nr_cpus \ create_dsq \ dequeue \ dequeue_iter \ dequeue_remote \ + enq_blocked \ enq_last_no_enq_fails \ ddsp_bogus_dsq_fail \ ddsp_vtimelocal_fail \ @@ -175,6 +179,7 @@ exit \ hotplug \ init_enable_count \ + kick \ maximal \ maybe_null \ minimal \ @@ -214,7 +219,7 @@ $(SCXOBJ_DIR)/util.o: util.c | $(SCXOBJ_DIR) $(CC) $(CFLAGS) -c $< -o $@ -$(OUTPUT)/runner: $(SCXOBJ_DIR)/runner.o $(SCXOBJ_DIR)/util.o $(BPFOBJ) $(testcase-targets) +$(OUTPUT)/runner: $(SCXOBJ_DIR)/runner.o $(SCXOBJ_DIR)/util.o $(BPFOBJ) $(LIBCGROUP_O) $(testcase-targets) @echo "$(testcase-targets)" $(CC) $(CFLAGS) -o $@ $^ $(LDFLAGS)
diff --git a/tools/testing/selftests/sched_ext/allowed_cpus.bpf.c b/tools/testing/selftests/sched_ext/allowed_cpus.bpf.c index 9dd72d0..f14d7e5 100644 --- a/tools/testing/selftests/sched_ext/allowed_cpus.bpf.c +++ b/tools/testing/selftests/sched_ext/allowed_cpus.bpf.c
@@ -147,23 +147,41 @@ void BPF_STRUCT_OPS(allowed_cpus_exit, struct scx_exit_info *ei) } struct task_cpu_arg { - pid_t pid; + u64 pid; + s64 custom_cpu; }; SEC("syscall") int select_cpu_from_user(struct task_cpu_arg *input) { struct task_struct *p; - int cpu; + struct bpf_cpumask *mask; + s32 cpu; p = bpf_task_from_pid(input->pid); if (!p) return -EINVAL; + mask = bpf_cpumask_create(); + if (!mask) { + bpf_task_release(p); + return -ENOMEM; + } + + /* A negative custom_cpu leaves the custom mask empty. */ + if (input->custom_cpu >= 0) + bpf_cpumask_set_cpu(input->custom_cpu, mask); + bpf_rcu_read_lock(); - cpu = scx_bpf_select_cpu_and(p, bpf_get_smp_processor_id(), 0, p->cpus_ptr, 0); + cpu = scx_bpf_select_cpu_and(p, bpf_get_smp_processor_id(), 0, + cast_mask(mask), 0); + if (cpu >= 0 && + (!bpf_cpumask_test_cpu(cpu, cast_mask(mask)) || + !bpf_cpumask_test_cpu(cpu, &p->cpus_mask))) + cpu = -ERANGE; bpf_rcu_read_unlock(); + bpf_cpumask_release(mask); bpf_task_release(p); return cpu;
diff --git a/tools/testing/selftests/sched_ext/allowed_cpus.c b/tools/testing/selftests/sched_ext/allowed_cpus.c index 093f285..7631172 100644 --- a/tools/testing/selftests/sched_ext/allowed_cpus.c +++ b/tools/testing/selftests/sched_ext/allowed_cpus.c
@@ -2,7 +2,10 @@ /* * Copyright (c) 2025 Andrea Righi <arighi@nvidia.com> */ +#define _GNU_SOURCE #include <bpf/bpf.h> +#include <limits.h> +#include <sched.h> #include <scx/common.h> #include <sys/wait.h> #include <unistd.h> @@ -23,17 +26,19 @@ static enum scx_test_status setup(void **ctx) return SCX_TEST_PASS; } -static int test_select_cpu_from_user(const struct allowed_cpus *skel) +static int test_select_cpu_from_user(const struct allowed_cpus *skel, + const char *name, int custom_cpu, + bool expect_busy) { int fd, ret; - __u64 args[1]; + __s32 cpu; + __u64 args[] = { getpid(), (__u64)(__s64)custom_cpu }; LIBBPF_OPTS(bpf_test_run_opts, attr, .ctx_in = args, .ctx_size_in = sizeof(args), ); - args[0] = getpid(); fd = bpf_program__fd(skel->progs.select_cpu_from_user); if (fd < 0) return fd; @@ -42,29 +47,123 @@ static int test_select_cpu_from_user(const struct allowed_cpus *skel) if (ret < 0) return ret; - fprintf(stderr, "%s: CPU %d\n", __func__, attr.retval); + /* test_run returns the signed BPF result through an unsigned field. */ + cpu = (__s32)attr.retval; + if ((expect_busy && cpu != -EBUSY) || + (!expect_busy && cpu != -EBUSY && cpu != custom_cpu)) { + SCX_ERR("%s: unexpected CPU selection result %d", name, cpu); + return -EINVAL; + } return 0; } +/* Grow until the mask covers the kernel's CPU range, including offline CPUs. */ +static int alloc_affinity(cpu_set_t **mask, size_t *size) +{ + int nr_cpus = CPU_SETSIZE; + cpu_set_t *cpus; + int err; + + for (;;) { + *size = CPU_ALLOC_SIZE(nr_cpus); + cpus = CPU_ALLOC(nr_cpus); + if (!cpus) + return -ENOMEM; + CPU_ZERO_S(*size, cpus); + if (!sched_getaffinity(0, *size, cpus)) { + *mask = cpus; + return nr_cpus; + } + err = errno; + CPU_FREE(cpus); + if (err != EINVAL) + return -err; + if (nr_cpus > INT_MAX / 2) + return -EOVERFLOW; + nr_cpus *= 2; + } +} + static enum scx_test_status run(void *ctx) { struct allowed_cpus *skel = ctx; - struct bpf_link *link; + enum scx_test_status status = SCX_TEST_FAIL; + cpu_set_t *original = NULL, *pinned = NULL; + bool affinity_changed = false; + size_t size; + int first = -1, second = -1, cpu, nr_cpus; + struct bpf_link *link = NULL; + + nr_cpus = alloc_affinity(&original, &size); + if (nr_cpus < 0) { + SCX_ERR("Failed to get affinity (%d)", -nr_cpus); + goto out; + } + pinned = CPU_ALLOC(nr_cpus); + if (!pinned) { + SCX_ERR("Failed to allocate affinity mask"); + goto out; + } + for (cpu = 0; cpu < nr_cpus; cpu++) { + if (!CPU_ISSET_S(cpu, size, original)) + continue; + if (first < 0) { + first = cpu; + } else { + second = cpu; + break; + } + } + if (first < 0) { + SCX_ERR("No CPU in affinity mask"); + goto out; + } link = bpf_map__attach_struct_ops(skel->maps.allowed_cpus_ops); - SCX_FAIL_IF(!link, "Failed to attach scheduler"); + if (!link) { + SCX_ERR("Failed to attach scheduler"); + goto out; + } - /* Pick an idle CPU from user-space */ - SCX_FAIL_IF(test_select_cpu_from_user(skel), "Failed to pick idle CPU"); + if (test_select_cpu_from_user(skel, "empty mask", -1, true)) + goto out; - /* Just sleeping is fine, plenty of scheduling events happening */ + /* A legal candidate may be busy; selection need not succeed. */ + if (test_select_cpu_from_user(skel, "legal candidate", first, false)) + goto out; + + if (second >= 0) { + CPU_ZERO_S(size, pinned); + CPU_SET_S(first, size, pinned); + if (sched_setaffinity(0, size, pinned)) { + SCX_ERR("Failed to pin task (%d)", errno); + goto out; + } + affinity_changed = true; + if (test_select_cpu_from_user(skel, "disjoint masks", second, true)) + goto out; + } else { + fprintf(stderr, "Skipping disjoint masks: need two allowed CPUs\n"); + } + + /* Just sleeping is fine, plenty of scheduling events happening. */ sleep(1); + if (UEI_EXITED(skel, uei)) { + SCX_ERR("Scheduler exited unexpectedly"); + goto out; + } + status = SCX_TEST_PASS; - SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_NONE)); +out: + if (affinity_changed && sched_setaffinity(0, size, original)) { + SCX_ERR("Failed to restore affinity (%d)", errno); + status = SCX_TEST_FAIL; + } bpf_link__destroy(link); - - return SCX_TEST_PASS; + CPU_FREE(pinned); + CPU_FREE(original); + return status; } static void cleanup(void *ctx)
diff --git a/tools/testing/selftests/sched_ext/cgroup_nr_cpus.bpf.c b/tools/testing/selftests/sched_ext/cgroup_nr_cpus.bpf.c new file mode 100644 index 0000000..841c83a --- /dev/null +++ b/tools/testing/selftests/sched_ext/cgroup_nr_cpus.bpf.c
@@ -0,0 +1,60 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Validate scx_bpf_cgroup_nr_cpus() from both BPF_PROG_TYPE_SYSCALL and + * struct_ops contexts. + * + * Copyright (c) 2026 NVIDIA Corporation. + */ + +#include <scx/common.bpf.h> + +char _license[] SEC("license") = "GPL"; + +UEI_DEFINE(uei); + +/* input to cgroup_nr_cpus_read() */ +u64 query_cgid; +/* output of cgroup_nr_cpus_read(), -1 if @query_cgid couldn't be resolved */ +s64 query_nr_cpus = -1; + +/* recorded by ops.cgroup_init() for @init_cgid */ +u64 init_cgid; +s64 init_nr_cpus = -1; + +SEC("syscall") +int cgroup_nr_cpus_read(void *ctx) +{ + struct cgroup *cgrp; + + query_nr_cpus = -1; + + cgrp = bpf_cgroup_from_id(query_cgid); + if (!cgrp) + return -ENOENT; + + query_nr_cpus = scx_bpf_cgroup_nr_cpus(cgrp); + bpf_cgroup_release(cgrp); + + return 0; +} + +s32 BPF_STRUCT_OPS(cgroup_nr_cpus_cgroup_init, struct cgroup *cgrp, + struct scx_cgroup_init_args *args) +{ + if (cgrp->kn->id == init_cgid) + init_nr_cpus = scx_bpf_cgroup_nr_cpus(cgrp); + + return 0; +} + +void BPF_STRUCT_OPS(cgroup_nr_cpus_exit, struct scx_exit_info *ei) +{ + UEI_RECORD(uei, ei); +} + +SEC(".struct_ops.link") +struct sched_ext_ops cgroup_nr_cpus_ops = { + .cgroup_init = (void *)cgroup_nr_cpus_cgroup_init, + .exit = (void *)cgroup_nr_cpus_exit, + .name = "cgroup_nr_cpus", +};
diff --git a/tools/testing/selftests/sched_ext/cgroup_nr_cpus.c b/tools/testing/selftests/sched_ext/cgroup_nr_cpus.c new file mode 100644 index 0000000..1475a8b --- /dev/null +++ b/tools/testing/selftests/sched_ext/cgroup_nr_cpus.c
@@ -0,0 +1,419 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Verify that scx_bpf_cgroup_nr_cpus() reports the number of CPUs in a + * cgroup's effective cpuset, including inherited and updated cpusets. + * + * Copyright (c) 2026 NVIDIA Corporation. + */ + +#define _GNU_SOURCE +#include <bpf/bpf.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <linux/limits.h> +#include <scx/common.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "cgroup_nr_cpus.bpf.skel.h" +#include "cgroup_util.h" +#include "scx_test.h" + +/* + * Hierarchy under the cgroup2 root, all with the cpu controller enabled so + * that ops.cgroup_init() runs for each of them: + * + * parent cpuset enabled by the root, enables cpuset for its children + * parent/child owns a cpuset + * parent/child/leaf no cpuset of its own, inherits child's + */ +struct cgroup_nr_cpus_ctx { + struct cgroup_nr_cpus *skel; + struct bpf_link *link; + char root[PATH_MAX]; + char parent[PATH_MAX]; + char child[PATH_MAX]; + char leaf[PATH_MAX]; + bool parent_created; + bool child_created; + bool leaf_created; +}; + +static int join_path(char *dst, size_t dst_size, const char *parent, const char *name) +{ + int ret; + + ret = snprintf(dst, dst_size, "%s/%s", parent, name); + if (ret < 0 || (size_t)ret >= dst_size) + return -ENAMETOOLONG; + return 0; +} + +static u64 cgroup_id(const char *path) +{ + union { + u64 id; + unsigned char bytes[8]; + } id = {}; + struct file_handle *handle; + int mount_id, ret; + + handle = calloc(1, sizeof(*handle) + sizeof(id)); + if (!handle) + return 0; + handle->handle_bytes = sizeof(id); + ret = name_to_handle_at(AT_FDCWD, path, handle, &mount_id, 0); + if (!ret && handle->handle_bytes == sizeof(id)) + memcpy(id.bytes, handle->f_handle, sizeof(id)); + free(handle); + + return ret ? 0 : id.id; +} + +/* + * Parse a cpulist such as "0-3,8,10-11". Return the number of CPUs and the + * lowest and highest CPU in @first and @last, or -errno on failure. + */ +static int parse_cpulist(const char *cpulist, u32 *first, u32 *last) +{ + const char *p = cpulist; + u32 lowest = UINT_MAX, highest = 0; + int count = 0; + + while (*p && *p != '\n') { + unsigned long start, end_cpu; + char *end; + + errno = 0; + start = strtoul(p, &end, 10); + if (errno || end == p || start > INT_MAX) + return -EINVAL; + end_cpu = start; + p = end; + if (*p == '-') { + end_cpu = strtoul(p + 1, &end, 10); + if (errno || end == p + 1 || end_cpu > INT_MAX || end_cpu < start) + return -EINVAL; + p = end; + } + if (end_cpu - start + 1 > (unsigned long)(INT_MAX - count)) + return -EOVERFLOW; + if (start < lowest) + lowest = start; + if (end_cpu > highest) + highest = end_cpu; + count += end_cpu - start + 1; + if (*p == ',') + p++; + else if (*p && *p != '\n') + return -EINVAL; + } + + if (first) + *first = lowest; + if (last) + *last = highest; + return count; +} + +/* + * Number of CPUs in @cgroup's cpuset.cpus.effective, or -errno. + * + * A sparse cpulist can exceed a page on large systems. cg_read() does a single + * bounded read, so size the buffer for the worst case of NR_CPUS=8192 and + * reject a read that fills it rather than parsing a truncated list. + */ +static int effective_nr_cpus(const char *cgroup, u32 *first, u32 *last) +{ + static char buf[65536]; + + if (cg_read(cgroup, "cpuset.cpus.effective", buf, sizeof(buf))) + return -EIO; + if (strlen(buf) >= sizeof(buf) - 1) + return -EOVERFLOW; + return parse_cpulist(buf, first, last); +} + +/* Run the SYSCALL program to sample scx_bpf_cgroup_nr_cpus() for @path. */ +static int kfunc_nr_cpus(struct cgroup_nr_cpus_ctx *ctx, const char *path, s64 *nr_cpus) +{ + LIBBPF_OPTS(bpf_test_run_opts, topts); + u64 cgid; + int err; + + cgid = cgroup_id(path); + if (!cgid) { + SCX_ERR("Failed to read cgroup ID of %s", path); + return -ENOENT; + } + + ctx->skel->bss->query_cgid = cgid; + err = bpf_prog_test_run_opts(bpf_program__fd(ctx->skel->progs.cgroup_nr_cpus_read), + &topts); + if (err || topts.retval) { + SCX_ERR("BPF_PROG_RUN failed for %s (err=%d retval=%d)", + path, err, (int)topts.retval); + return err ?: -EIO; + } + + *nr_cpus = ctx->skel->data->query_nr_cpus; + return 0; +} + +static bool check_nr_cpus(struct cgroup_nr_cpus_ctx *ctx, const char *path, int expected, + const char *what) +{ + s64 nr_cpus; + + if (kfunc_nr_cpus(ctx, path, &nr_cpus)) + return false; + if (nr_cpus != expected) { + SCX_ERR("%s: expected %d CPUs, got %lld", what, expected, + (long long)nr_cpus); + return false; + } + return true; +} + +/* + * Like check_nr_cpus() but tolerate a transient mismatch. A cpuset css being + * disabled stays attached to its cgroup until it's asynchronously offlined, and + * cpuset_num_cpus() keeps reporting its stale mask until then. + */ +static bool wait_nr_cpus(struct cgroup_nr_cpus_ctx *ctx, const char *path, int expected, + const char *what) +{ + s64 nr_cpus = -1; + int i; + + for (i = 0; i < 1000; i++) { + if (kfunc_nr_cpus(ctx, path, &nr_cpus)) + return false; + if (nr_cpus == expected) + return true; + usleep(1000); + } + SCX_ERR("%s: expected %d CPUs, got %lld", what, expected, (long long)nr_cpus); + return false; +} + +static bool controller_enabled(const char *cgroup, const char *file, const char *controller) +{ + char buf[4096], *saveptr, *token; + + if (cg_read(cgroup, file, buf, sizeof(buf))) + return false; + for (token = strtok_r(buf, "\n ", &saveptr); token; + token = strtok_r(NULL, "\n ", &saveptr)) + if (!strcmp(token, controller)) + return true; + return false; +} + +static void cleanup_ctx(struct cgroup_nr_cpus_ctx *ctx) +{ + bpf_link__destroy(ctx->link); + cgroup_nr_cpus__destroy(ctx->skel); + if (ctx->leaf_created) + cg_destroy(ctx->leaf); + if (ctx->child_created) + cg_destroy(ctx->child); + if (ctx->parent_created) + cg_destroy(ctx->parent); +} + +/* + * Enable @controller in the root's subtree_control if needed. Like the cgroup + * selftests, leave it enabled afterwards: the root is shared, and another + * manager may start relying on the controller while the test runs. + */ +static enum scx_test_status enable_controller(const char *root, const char *controller) +{ + char value[32]; + + if (controller_enabled(root, "cgroup.subtree_control", controller)) + return SCX_TEST_PASS; + if (!controller_enabled(root, "cgroup.controllers", controller)) + return SCX_TEST_SKIP; + + snprintf(value, sizeof(value), "+%s", controller); + if (cg_write(root, "cgroup.subtree_control", value)) + return SCX_TEST_SKIP; + return SCX_TEST_PASS; +} + +static enum scx_test_status setup_cgroups(struct cgroup_nr_cpus_ctx *ctx) +{ + enum scx_test_status status; + char name[64]; + + if (cg_find_unified_root(ctx->root, sizeof(ctx->root), NULL)) + return SCX_TEST_SKIP; + + status = enable_controller(ctx->root, "cpu"); + if (status != SCX_TEST_PASS) + return status; + status = enable_controller(ctx->root, "cpuset"); + if (status != SCX_TEST_PASS) + return status; + + snprintf(name, sizeof(name), "scx_nr_cpus_%d", getpid()); + if (join_path(ctx->parent, sizeof(ctx->parent), ctx->root, name) || + join_path(ctx->child, sizeof(ctx->child), ctx->parent, "child") || + join_path(ctx->leaf, sizeof(ctx->leaf), ctx->child, "leaf")) { + SCX_ERR("Cgroup path is too long"); + return SCX_TEST_FAIL; + } + + if (cg_create(ctx->parent)) { + SCX_ERR("Failed to create cgroup %s", ctx->parent); + return SCX_TEST_FAIL; + } + ctx->parent_created = true; + if (cg_write(ctx->parent, "cgroup.subtree_control", "+cpu +cpuset")) { + SCX_ERR("Failed to enable controllers in %s", ctx->parent); + return SCX_TEST_FAIL; + } + if (cg_create(ctx->child)) { + SCX_ERR("Failed to create cgroup %s", ctx->child); + return SCX_TEST_FAIL; + } + ctx->child_created = true; + if (cg_write(ctx->child, "cgroup.subtree_control", "+cpu")) { + SCX_ERR("Failed to enable cpu in %s", ctx->child); + return SCX_TEST_FAIL; + } + if (cg_create(ctx->leaf)) { + SCX_ERR("Failed to create cgroup %s", ctx->leaf); + return SCX_TEST_FAIL; + } + ctx->leaf_created = true; + + return SCX_TEST_PASS; +} + +static enum scx_test_status run(void *arg) +{ + struct cgroup_nr_cpus_ctx ctx = {}; + enum scx_test_status status; + char value[32]; + u32 first, last; + int nr_root, nr_child; + + (void)arg; + + /* + * SCX_ENUM_INIT() exits the process if vmlinux BTF can't be loaded, so + * run it before creating any cgroups that would then be left behind. + */ + ctx.skel = cgroup_nr_cpus__open(); + if (!ctx.skel) { + SCX_ERR("Failed to open skel"); + return SCX_TEST_FAIL; + } + SCX_ENUM_INIT(ctx.skel); + + status = setup_cgroups(&ctx); + if (status != SCX_TEST_PASS) + goto out; + status = SCX_TEST_FAIL; + + nr_root = effective_nr_cpus(ctx.root, NULL, NULL); + nr_child = effective_nr_cpus(ctx.child, &first, &last); + if (nr_root < 0 || nr_child < 0) { + SCX_ERR("Failed to read effective cpusets"); + goto out; + } + /* The effective cpuset can be empty, e.g. under a partition root. */ + if (nr_child < 2) { + status = SCX_TEST_SKIP; + goto out; + } + + ctx.skel->bss->init_cgid = cgroup_id(ctx.leaf); + if (!ctx.skel->bss->init_cgid) { + SCX_ERR("Failed to read cgroup ID of %s", ctx.leaf); + goto out; + } + if (cgroup_nr_cpus__load(ctx.skel)) { + SCX_ERR("Failed to load skel"); + goto out; + } + + /* The kfunc must be callable without a scheduler attached. */ + if (!check_nr_cpus(&ctx, ctx.root, nr_root, "root") || + !check_nr_cpus(&ctx, ctx.child, nr_child, "child") || + !check_nr_cpus(&ctx, ctx.leaf, nr_child, "inherited leaf")) + goto out; + + /* ops.cgroup_init() runs for existing cgroups when attaching. */ + ctx.link = bpf_map__attach_struct_ops(ctx.skel->maps.cgroup_nr_cpus_ops); + if (!ctx.link) { + SCX_ERR("Failed to attach scheduler"); + goto out; + } + if (ctx.skel->data->init_nr_cpus != nr_child) { + SCX_ERR("ops.cgroup_init(): expected %d CPUs, got %lld", nr_child, + (long long)ctx.skel->data->init_nr_cpus); + goto out; + } + + /* Non-contiguous cpuset, observed by the owner and by the inheritor. */ + if (nr_child > 2) { + snprintf(value, sizeof(value), "%u,%u", first, last); + if (cg_write(ctx.child, "cpuset.cpus", value)) { + SCX_ERR("Failed to set cpuset.cpus=%s for %s", value, ctx.child); + goto out; + } + if (!check_nr_cpus(&ctx, ctx.child, 2, "sparse child") || + !check_nr_cpus(&ctx, ctx.leaf, 2, "sparse inherited leaf")) + goto out; + } + + snprintf(value, sizeof(value), "%u", first); + if (cg_write(ctx.child, "cpuset.cpus", value)) { + SCX_ERR("Failed to set cpuset.cpus=%s for %s", value, ctx.child); + goto out; + } + if (!check_nr_cpus(&ctx, ctx.child, 1, "single-CPU child") || + !check_nr_cpus(&ctx, ctx.leaf, 1, "single-CPU inherited leaf")) + goto out; + + /* + * Disabling cpuset below @parent makes @child and @leaf inherit + * @parent's effective cpuset, which spans all of the root's CPUs. + */ + if (cg_write(ctx.parent, "cgroup.subtree_control", "-cpuset")) { + SCX_ERR("Failed to disable cpuset in %s", ctx.parent); + goto out; + } + nr_child = effective_nr_cpus(ctx.parent, NULL, NULL); + if (nr_child < 0) { + SCX_ERR("Failed to read effective cpuset of %s", ctx.parent); + goto out; + } + if (!wait_nr_cpus(&ctx, ctx.child, nr_child, "child after cpuset disable") || + !wait_nr_cpus(&ctx, ctx.leaf, nr_child, "leaf after cpuset disable")) + goto out; + + if (UEI_EXITED(ctx.skel, uei)) { + SCX_ERR("Scheduler exited unexpectedly"); + goto out; + } + + status = SCX_TEST_PASS; +out: + cleanup_ctx(&ctx); + return status; +} + +struct scx_test cgroup_nr_cpus = { + .name = "cgroup_nr_cpus", + .description = "Verify scx_bpf_cgroup_nr_cpus() reports effective cpuset CPU counts", + .run = run, +}; +REGISTER_SCX_TEST(&cgroup_nr_cpus)
diff --git a/tools/testing/selftests/sched_ext/config b/tools/testing/selftests/sched_ext/config index aa901b0..8173f91 100644 --- a/tools/testing/selftests/sched_ext/config +++ b/tools/testing/selftests/sched_ext/config
@@ -1,8 +1,11 @@ CONFIG_SCHED_CLASS_EXT=y CONFIG_CGROUPS=y CONFIG_CGROUP_SCHED=y +CONFIG_CPUSETS=y CONFIG_EXT_GROUP_SCHED=y CONFIG_BPF=y CONFIG_BPF_SYSCALL=y CONFIG_DEBUG_INFO=y CONFIG_DEBUG_INFO_BTF=y +CONFIG_EXPERT=y +CONFIG_SCHED_PROXY_EXEC=y
diff --git a/tools/testing/selftests/sched_ext/create_dsq.bpf.c b/tools/testing/selftests/sched_ext/create_dsq.bpf.c index 2cfc4ff..24dacd1 100644 --- a/tools/testing/selftests/sched_ext/create_dsq.bpf.c +++ b/tools/testing/selftests/sched_ext/create_dsq.bpf.c
@@ -10,6 +10,10 @@ char _license[] SEC("license") = "GPL"; +u32 nr_lifecycle_tests; + +UEI_DEFINE(uei); + void BPF_STRUCT_OPS(create_dsq_exit_task, struct task_struct *p, struct scx_exit_task_args *args) { @@ -43,16 +47,55 @@ s32 BPF_STRUCT_OPS_SLEEPABLE(create_dsq_init) } bpf_for(i, 0, 1024) { + err = scx_bpf_create_dsq(i, -1); + if (err != -EEXIST) { + scx_bpf_error("Duplicate DSQ %d creation returned %d", i, err); + return -EINVAL; + } + + /* A rejected duplicate must leave the original DSQ accessible. */ + err = scx_bpf_dsq_nr_queued(i); + if (err) { + scx_bpf_error("Original DSQ %d queue count is %d", i, err); + return -EINVAL; + } + scx_bpf_destroy_dsq(i); + err = scx_bpf_dsq_nr_queued(i); + if (err != -ENOENT) { + scx_bpf_error("Destroyed DSQ %d queue count is %d", i, err); + return -EINVAL; + } + + err = scx_bpf_create_dsq(i, -1); + if (err) { + scx_bpf_error("Failed to recreate DSQ %d: %d", i, err); + return err; + } + + err = scx_bpf_dsq_nr_queued(i); + if (err) { + scx_bpf_error("Recreated DSQ %d queue count is %d", i, err); + return -EINVAL; + } + + scx_bpf_destroy_dsq(i); + nr_lifecycle_tests++; } return 0; } +void BPF_STRUCT_OPS(create_dsq_exit, struct scx_exit_info *ei) +{ + UEI_RECORD(uei, ei); +} + SEC(".struct_ops.link") struct sched_ext_ops create_dsq_ops = { .init_task = (void *) create_dsq_init_task, .exit_task = (void *) create_dsq_exit_task, .init = (void *) create_dsq_init, + .exit = (void *) create_dsq_exit, .name = "create_dsq", };
diff --git a/tools/testing/selftests/sched_ext/create_dsq.c b/tools/testing/selftests/sched_ext/create_dsq.c index d67431f..84143d5 100644 --- a/tools/testing/selftests/sched_ext/create_dsq.c +++ b/tools/testing/selftests/sched_ext/create_dsq.c
@@ -35,8 +35,12 @@ static enum scx_test_status run(void *ctx) return SCX_TEST_FAIL; } + SCX_ASSERT_ALIVE(skel, uei); + bpf_link__destroy(link); + SCX_EQ(skel->bss->nr_lifecycle_tests, 1024); + return SCX_TEST_PASS; } @@ -49,7 +53,7 @@ static void cleanup(void *ctx) struct scx_test create_dsq = { .name = "create_dsq", - .description = "Create and destroy a dsq in a loop", + .description = "Create, reject duplicates, destroy and recreate DSQs", .setup = setup, .run = run, .cleanup = cleanup,
diff --git a/tools/testing/selftests/sched_ext/cyclic_kick_wait.c b/tools/testing/selftests/sched_ext/cyclic_kick_wait.c index c2e5aa9..178d1d7 100644 --- a/tools/testing/selftests/sched_ext/cyclic_kick_wait.c +++ b/tools/testing/selftests/sched_ext/cyclic_kick_wait.c
@@ -152,7 +152,7 @@ static enum scx_test_status run(void *ctx) sleep(5); - if (skel->data->uei.kind != EXIT_KIND(SCX_EXIT_NONE)) { + if (UEI_EXITED(skel, uei)) { SCX_ERR("Scheduler exited unexpectedly (kind=%llu code=%lld)", (unsigned long long)skel->data->uei.kind, (long long)skel->data->uei.exit_code);
diff --git a/tools/testing/selftests/sched_ext/dequeue_remote.c b/tools/testing/selftests/sched_ext/dequeue_remote.c index f2c1901..af34458 100644 --- a/tools/testing/selftests/sched_ext/dequeue_remote.c +++ b/tools/testing/selftests/sched_ext/dequeue_remote.c
@@ -43,6 +43,7 @@ static void worker_fn(int id) for (j = 0; j < 20000 + id * 1000; j++) sum += j; + asm volatile("" : : "r"(sum)); if (id & 1) usleep(100); else
diff --git a/tools/testing/selftests/sched_ext/enq_blocked.bpf.c b/tools/testing/selftests/sched_ext/enq_blocked.bpf.c new file mode 100644 index 0000000..212690b --- /dev/null +++ b/tools/testing/selftests/sched_ext/enq_blocked.bpf.c
@@ -0,0 +1,116 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES + * + * Verify that SCX_OPS_ENQ_BLOCKED passes blocked proxy donors through + * ops.enqueue() and record whether callbacks occur on the donor or owner CPU. + */ + +#include <scx/common.bpf.h> + +#define SHARED_DSQ 0 + +char _license[] SEC("license") = "GPL"; + +s32 donor_pid; +s32 donor_cpu = -1; +s32 owner_cpu = -1; +u64 nr_blocked_enqueues; +u64 nr_blocked_enqueues_donor_cpu; +u64 nr_blocked_enqueues_owner_cpu; +u64 nr_blocked_enqueues_other_cpu; +u64 nr_blocked_wakeups; +static u64 vtime_now; + +UEI_DEFINE(uei); + +s32 BPF_STRUCT_OPS(enq_blocked_select_cpu, + struct task_struct *p, s32 prev_cpu, u64 wake_flags) +{ + return prev_cpu; +} + +void BPF_STRUCT_OPS(enq_blocked_enqueue, struct task_struct *p, u64 enq_flags) +{ + u64 vtime = p->scx.dsq_vtime; + + if (enq_flags & SCX_ENQ_BLOCKED) { + int cpu = scx_bpf_task_cpu(p); + + if (enq_flags & SCX_ENQ_WAKEUP) + __sync_fetch_and_add(&nr_blocked_wakeups, 1); + + if (p->pid == donor_pid) { + __sync_fetch_and_add(&nr_blocked_enqueues, 1); + if (cpu == donor_cpu) + __sync_fetch_and_add(&nr_blocked_enqueues_donor_cpu, 1); + else if (cpu == owner_cpu) + __sync_fetch_and_add(&nr_blocked_enqueues_owner_cpu, 1); + else + __sync_fetch_and_add(&nr_blocked_enqueues_other_cpu, 1); + } + } + + /* Limit the amount of budget an idling task can accumulate. */ + if (time_before(vtime, vtime_now - SCX_SLICE_DFL)) + vtime = vtime_now - SCX_SLICE_DFL; + + scx_bpf_dsq_insert_vtime(p, SHARED_DSQ, SCX_SLICE_DFL, vtime, + enq_flags); + scx_bpf_kick_cpu(scx_bpf_task_cpu(p), SCX_KICK_IDLE); +} + +void BPF_STRUCT_OPS(enq_blocked_dispatch, s32 cpu, struct task_struct *prev) +{ + scx_bpf_dsq_move_to_local(SHARED_DSQ, 0); +} + +void BPF_STRUCT_OPS(enq_blocked_running, struct task_struct *p) +{ + if (time_before(vtime_now, p->scx.dsq_vtime)) + vtime_now = p->scx.dsq_vtime; +} + +void BPF_STRUCT_OPS(enq_blocked_stopping, struct task_struct *p, bool runnable) +{ + u64 delta = scale_by_task_weight_inverse(p, + SCX_SLICE_DFL - p->scx.slice); + + scx_bpf_task_set_dsq_vtime(p, p->scx.dsq_vtime + delta); +} + +void BPF_STRUCT_OPS(enq_blocked_enable, struct task_struct *p) +{ + scx_bpf_task_set_dsq_vtime(p, vtime_now); +} + +s32 BPF_STRUCT_OPS_SLEEPABLE(enq_blocked_init) +{ + int ret; + + ret = scx_bpf_create_dsq(SHARED_DSQ, -1); + if (ret) { + scx_bpf_error("failed to create DSQ %d (%d)", SHARED_DSQ, ret); + return ret; + } + + return 0; +} + +void BPF_STRUCT_OPS(enq_blocked_exit, struct scx_exit_info *ei) +{ + UEI_RECORD(uei, ei); +} + +SEC(".struct_ops.link") +struct sched_ext_ops enq_blocked_ops = { + .select_cpu = (void *)enq_blocked_select_cpu, + .enqueue = (void *)enq_blocked_enqueue, + .dispatch = (void *)enq_blocked_dispatch, + .running = (void *)enq_blocked_running, + .stopping = (void *)enq_blocked_stopping, + .enable = (void *)enq_blocked_enable, + .init = (void *)enq_blocked_init, + .exit = (void *)enq_blocked_exit, + .name = "enq_blocked", +};
diff --git a/tools/testing/selftests/sched_ext/enq_blocked.c b/tools/testing/selftests/sched_ext/enq_blocked.c new file mode 100644 index 0000000..1d5e090 --- /dev/null +++ b/tools/testing/selftests/sched_ext/enq_blocked.c
@@ -0,0 +1,917 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES + * + * Exercise a priority inversion with the owner and donor first pinned to the + * same CPU, then with each on a different CPU. A high-priority donor blocks on + * a mutex held by a low-priority owner while one medium-priority contender per + * available CPU keeps the system busy. A weighted-vruntime BPF scheduler runs + * both CPU placement configurations with SCX_OPS_ENQ_BLOCKED first disabled + * and then enabled. The test validates blocked-donor admission and reports the + * average mutex hold and wait times, plus their enabled-minus-disabled deltas, + * for each configuration. The timing data is informational. + * + * CONFIG_SCHED_PROXY_EXEC=y is required to exercise the proxy-execution paths. + */ +#define _GNU_SOURCE + +#include <bpf/bpf.h> +#include <errno.h> +#include <fcntl.h> +#include <limits.h> +#include <pthread.h> +#include <sched.h> +#include <scx/common.h> +#include <stdatomic.h> +#include <stdint.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/ioctl.h> +#include <sys/resource.h> +#include <sys/syscall.h> +#include <time.h> +#include <unistd.h> + +#include "enq_blocked.bpf.skel.h" +#include "enq_blocked.h" +#include "scx_test.h" + +#define MODULE_NAME "scx_enq_blocked_test" +#define MODULE_FILE "test_modules/" MODULE_NAME ".ko" +#define DEVICE_PATH "/dev/scx_enq_blocked" +#define WAIT_STEP_US 1000 +#define WAIT_TIMEOUT_MS 2000 +#define NR_WARMUP_TRIALS 1 +#define NR_MEASURED_TRIALS 10 +#define NR_TRIALS (NR_WARMUP_TRIALS + NR_MEASURED_TRIALS) +#define JOIN_TIMEOUT_MS ((NR_TRIALS + 1) * WAIT_TIMEOUT_MS) +#define OWNER_NICE 19 +#define DONOR_NICE -20 +#define CONTENDER_NICE 0 + +struct thread_ctx { + atomic_bool start_donor; + atomic_bool abort; + atomic_bool stop_contender; + atomic_bool measurement_ready; + atomic_int donor_pid; + atomic_int donor_completed; + int fd; + int donor_cpu; + int owner_cpu; +}; + +struct contender_ctx { + struct thread_ctx *thread_ctx; + atomic_int status; + int cpu; +}; + +struct run_result { + struct enq_blocked_stats stats; + u64 nr_blocked_enqueues; + u64 nr_blocked_enqueues_donor_cpu; + u64 nr_blocked_enqueues_owner_cpu; + u64 nr_blocked_enqueues_other_cpu; + u64 nr_blocked_wakeups; +}; + +static bool parse_bool(const char *value, bool *result) +{ + if (!strcasecmp(value, "1") || !strcasecmp(value, "y") || + !strcasecmp(value, "yes") || !strcasecmp(value, "on") || + !strcasecmp(value, "true")) { + *result = true; + return true; + } + + if (!strcasecmp(value, "0") || !strcasecmp(value, "n") || + !strcasecmp(value, "no") || !strcasecmp(value, "off") || + !strcasecmp(value, "false")) { + *result = false; + return true; + } + + return false; +} + +static bool cmdline_bool(const char *name, bool default_value) +{ + char cmdline[4096], *newline, *saveptr = NULL, *token; + size_t name_len = strlen(name); + bool value = default_value; + FILE *file; + + file = fopen("/proc/cmdline", "r"); + if (!file) + return default_value; + + if (!fgets(cmdline, sizeof(cmdline), file)) { + fclose(file); + return default_value; + } + fclose(file); + newline = strchr(cmdline, '\n'); + if (newline) + *newline = '\0'; + + for (token = strtok_r(cmdline, " ", &saveptr); token; + token = strtok_r(NULL, " ", &saveptr)) { + bool parsed; + + if (strncmp(token, name, name_len) || token[name_len] != '=') + continue; + if (parse_bool(token + name_len + 1, &parsed)) + value = parsed; + } + + return value; +} + +static int module_path(char *path, size_t size) +{ + ssize_t len; + char *slash; + + len = readlink("/proc/self/exe", path, size - 1); + if (len < 0) + return -errno; + path[len] = '\0'; + + slash = strrchr(path, '/'); + if (!slash) + return -EINVAL; + *slash = '\0'; + + if (snprintf(slash, size - (slash - path), "/%s", MODULE_FILE) >= + size - (slash - path)) + return -ENAMETOOLONG; + + return 0; +} + +static int load_test_module(bool *loaded_here) +{ + char path[PATH_MAX]; + int fd, err; + + err = module_path(path, sizeof(path)); + if (err) + return err; + + fd = open(path, O_RDONLY | O_CLOEXEC); + if (fd < 0) + return -errno; + + if (syscall(SYS_finit_module, fd, "", 0)) { + err = errno; + close(fd); + if (err == EEXIST) + return 0; + return -err; + } + + close(fd); + *loaded_here = true; + return 0; +} + +static void unload_test_module(bool loaded_here) +{ + if (loaded_here && syscall(SYS_delete_module, MODULE_NAME, O_NONBLOCK)) + SCX_ERR("Failed to unload %s (%d)", MODULE_NAME, errno); +} + +static int pin_to_cpu(int cpu) +{ + cpu_set_t mask; + + CPU_ZERO(&mask); + CPU_SET(cpu, &mask); + return sched_setaffinity(0, sizeof(mask), &mask) ? errno : 0; +} + +static int select_test_cpus(bool cross_cpu, cpu_set_t *mask, int *donor_cpu, + int *owner_cpu) +{ + int cpu, first = -1; + + if (sched_getaffinity(0, sizeof(*mask), mask)) + return -errno; + + for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { + if (!CPU_ISSET(cpu, mask)) + continue; + if (first < 0) { + first = cpu; + if (!cross_cpu) + break; + } else { + *donor_cpu = first; + *owner_cpu = cpu; + return 0; + } + } + + if (first < 0) + return -ENODEV; + if (cross_cpu) + return -EAGAIN; + + *donor_cpu = first; + *owner_cpu = first; + return 0; +} + +static int set_nice(int nice) +{ + return setpriority(PRIO_PROCESS, 0, nice) ? errno : 0; +} + +static bool wait_for_pid(atomic_int *pid) +{ + int waited_ms; + + for (waited_ms = 0; waited_ms < WAIT_TIMEOUT_MS; waited_ms++) { + if (atomic_load_explicit(pid, memory_order_acquire) > 0) + return true; + usleep(WAIT_STEP_US); + } + + return false; +} + +static int wait_for_contenders(struct contender_ctx *contenders, + size_t nr_contenders) +{ + size_t i, nr_ready; + int status, waited_ms; + + for (waited_ms = 0; waited_ms < WAIT_TIMEOUT_MS; waited_ms++) { + nr_ready = 0; + for (i = 0; i < nr_contenders; i++) { + status = atomic_load_explicit(&contenders[i].status, + memory_order_acquire); + if (status < 0) + return status; + if (status > 0) + nr_ready++; + } + if (nr_ready == nr_contenders) + return 1; + usleep(WAIT_STEP_US); + } + + return -ETIMEDOUT; +} + +static int wait_for_donor_state(struct thread_ctx *ctx, int expected) +{ + int state, waited_ms; + + for (waited_ms = 0; waited_ms < WAIT_TIMEOUT_MS; waited_ms++) { + state = ioctl(ctx->fd, ENQ_BLOCKED_IOCTL_DONOR_STATE); + if (state == expected) + return state; + if (state < 0 && errno != ENOENT) + return -errno; + usleep(WAIT_STEP_US); + } + + return -ETIMEDOUT; +} + +static bool wait_for_donor(struct thread_ctx *ctx, int trial) +{ + int waited_ms; + + for (waited_ms = 0; waited_ms < WAIT_TIMEOUT_MS; waited_ms++) { + if (atomic_load_explicit(&ctx->donor_completed, + memory_order_acquire) >= trial) + return true; + if (atomic_load_explicit(&ctx->abort, memory_order_relaxed)) + return false; + usleep(WAIT_STEP_US); + } + + return false; +} + +static bool wait_for_measurement(struct thread_ctx *ctx) +{ + while (!atomic_load_explicit(&ctx->measurement_ready, + memory_order_acquire) && + !atomic_load_explicit(&ctx->abort, memory_order_relaxed)) + sched_yield(); + + return !atomic_load_explicit(&ctx->abort, memory_order_relaxed); +} + +static void *contender_fn(void *arg) +{ + struct contender_ctx *contender = arg; + struct thread_ctx *ctx = contender->thread_ctx; + int err; + + err = pin_to_cpu(contender->cpu); + if (!err) + err = set_nice(CONTENDER_NICE); + atomic_store_explicit(&contender->status, err ? -err : 1, + memory_order_release); + if (err) + return (void *)(uintptr_t)err; + + while (!atomic_load_explicit(&ctx->stop_contender, + memory_order_relaxed)) + ; + + return NULL; +} + +static void *owner_fn(void *arg) +{ + struct thread_ctx *ctx = arg; + int err, i; + + err = pin_to_cpu(ctx->owner_cpu); + if (err) + return (void *)(uintptr_t)err; + err = set_nice(OWNER_NICE); + if (err) + return (void *)(uintptr_t)err; + + for (i = 0; i < NR_TRIALS; i++) { + if (ioctl(ctx->fd, ENQ_BLOCKED_IOCTL_OWNER)) + return (void *)(uintptr_t)errno; + if (!wait_for_donor(ctx, i + 1)) + return (void *)(uintptr_t)ETIMEDOUT; + + if (i + 1 == NR_WARMUP_TRIALS && !wait_for_measurement(ctx)) + return NULL; + } + + return NULL; +} + +static int run_donor_trial(struct thread_ctx *ctx) +{ + int waited_ms; + + for (waited_ms = 0; waited_ms < WAIT_TIMEOUT_MS; waited_ms++) { + if (!ioctl(ctx->fd, ENQ_BLOCKED_IOCTL_DONOR)) + return 0; + if (errno != EAGAIN) + return -errno; + usleep(WAIT_STEP_US); + } + + return -ETIMEDOUT; +} + +static void *donor_fn(void *arg) +{ + struct thread_ctx *ctx = arg; + int err, i; + + err = pin_to_cpu(ctx->donor_cpu); + if (err) + return (void *)(uintptr_t)err; + err = set_nice(DONOR_NICE); + if (err) + return (void *)(uintptr_t)err; + + atomic_store_explicit(&ctx->donor_pid, syscall(SYS_gettid), + memory_order_release); + while (!atomic_load_explicit(&ctx->start_donor, memory_order_acquire) && + !atomic_load_explicit(&ctx->abort, memory_order_relaxed)) + sched_yield(); + + if (atomic_load_explicit(&ctx->abort, memory_order_relaxed)) + return NULL; + + for (i = 0; i < NR_TRIALS; i++) { + err = run_donor_trial(ctx); + if (err) + return (void *)(uintptr_t)-err; + atomic_store_explicit(&ctx->donor_completed, i + 1, + memory_order_release); + } + + return NULL; +} + +static void print_avg_time(const char *name, u64 total_ns, u64 samples) +{ + u64 avg_ns = samples ? total_ns / samples : 0; + + printf(" %s_avg_ns=%llu (%llu.%03llu ms, samples=%llu)\n", name, + (unsigned long long)avg_ns, + (unsigned long long)(avg_ns / 1000000), + (unsigned long long)((avg_ns / 1000) % 1000), + (unsigned long long)samples); +} + +static void print_avg_delta(const char *name, u64 disabled_total, + u64 disabled_samples, u64 enabled_total, + u64 enabled_samples) +{ + u64 disabled_avg, enabled_avg; + s64 delta_ns; + double delta_pct; + + if (!disabled_samples || !enabled_samples) + return; + + disabled_avg = disabled_total / disabled_samples; + enabled_avg = enabled_total / enabled_samples; + delta_ns = (s64)enabled_avg - (s64)disabled_avg; + delta_pct = disabled_avg ? 100.0 * delta_ns / disabled_avg : 0.0; + + printf(" %s_delta_ns=%+lld (%+.2f%%)\n", name, + (long long)delta_ns, delta_pct); +} + +static int join_thread(pthread_t thread, const struct timespec *deadline, + int *thread_err) +{ + void *result; + int err; + + err = pthread_timedjoin_np(thread, &result, deadline); + if (err) + return err; + + *thread_err = (int)(uintptr_t)result; + return 0; +} + +static void set_join_deadline(struct timespec *deadline) +{ + clock_gettime(CLOCK_REALTIME, deadline); + deadline->tv_sec += JOIN_TIMEOUT_MS / 1000; + deadline->tv_nsec += (JOIN_TIMEOUT_MS % 1000) * 1000000; + if (deadline->tv_nsec >= 1000000000) { + deadline->tv_sec++; + deadline->tv_nsec -= 1000000000; + } +} + +static enum scx_test_status setup(void **ctx) +{ + struct enq_blocked *skel; + u64 flag; + + skel = enq_blocked__open(); + SCX_FAIL_IF(!skel, "Failed to open skel"); + SCX_ENUM_INIT(skel); + + flag = SCX_OPS_ENQ_BLOCKED; + if (!flag) { + enq_blocked__destroy(skel); + fprintf(stderr, "SKIP: SCX_OPS_ENQ_BLOCKED is unavailable\n"); + return SCX_TEST_SKIP; + } + + enq_blocked__destroy(skel); + *ctx = NULL; + return SCX_TEST_PASS; +} + +static enum scx_test_status run_one(bool enq_blocked, bool cross_cpu, + struct run_result *result) +{ + struct enq_blocked *skel; + struct thread_ctx thread_ctx = {}; + struct contender_ctx *contender_ctxs = NULL; + struct bpf_link *link = NULL; + pthread_t owner, donor, *contenders = NULL; + struct timespec join_deadline; + cpu_set_t allowed_cpus; + bool module_loaded = false; + bool owner_started = false, donor_started = false; + bool join_timed_out = false; + bool proxy_enabled; + enum scx_test_status status = SCX_TEST_PASS; + int cpu, donor_pid, donor_state, err, thread_err; + size_t i, nr_contenders, nr_contenders_started = 0; + size_t nr_contenders_joined = 0; + u64 nr_blocked, nr_blocked_donor_cpu, nr_blocked_owner_cpu; + u64 nr_blocked_other_cpu, nr_blocked_wakeups; + struct enq_blocked_stats stats; + + err = select_test_cpus(cross_cpu, &allowed_cpus, &thread_ctx.donor_cpu, + &thread_ctx.owner_cpu); + if (err == -EAGAIN) { + fprintf(stderr, "SKIP: cross-CPU case requires two allowed CPUs\n"); + return SCX_TEST_SKIP; + } + if (err) { + SCX_ERR("Failed to select test CPUs (%d)", -err); + return SCX_TEST_FAIL; + } + nr_contenders = CPU_COUNT(&allowed_cpus); + contenders = calloc(nr_contenders, sizeof(*contenders)); + contender_ctxs = calloc(nr_contenders, sizeof(*contender_ctxs)); + if (!contenders || !contender_ctxs) { + SCX_ERR("Failed to allocate %zu contender threads", nr_contenders); + status = SCX_TEST_FAIL; + goto out_contenders; + } + + skel = enq_blocked__open(); + if (!skel) { + SCX_ERR("Failed to open skel"); + status = SCX_TEST_FAIL; + goto out_contenders; + } + SCX_ENUM_INIT(skel); + skel->struct_ops.enq_blocked_ops->flags = + SCX_OPS_ENQ_LAST | + (enq_blocked ? SCX_OPS_ENQ_BLOCKED : 0); + if (enq_blocked__load(skel)) { + SCX_ERR("Failed to load skel"); + status = SCX_TEST_FAIL; + goto out_skel; + } + + err = load_test_module(&module_loaded); + if (err == -EPERM || err == -ENOENT) { + fprintf(stderr, "SKIP: cannot load mutex fixture (%d)\n", -err); + status = SCX_TEST_SKIP; + goto out_skel; + } + if (err) { + SCX_ERR("Failed to load mutex fixture (%d)", -err); + status = SCX_TEST_FAIL; + goto out_skel; + } + + thread_ctx.fd = open(DEVICE_PATH, O_RDONLY | O_CLOEXEC); + if (thread_ctx.fd < 0) { + SCX_ERR("Failed to open %s (%d)", DEVICE_PATH, errno); + status = SCX_TEST_FAIL; + goto out_module; + } + err = ioctl(thread_ctx.fd, ENQ_BLOCKED_IOCTL_PROXY_SUPPORTED); + if (err < 0) { + SCX_ERR("Failed to query proxy-exec support (%d)", errno); + status = SCX_TEST_FAIL; + goto out_fd; + } + proxy_enabled = err && cmdline_bool("sched_proxy_exec", true); + if (!proxy_enabled) { + fprintf(stderr, "SKIP: proxy execution is not enabled\n"); + status = SCX_TEST_SKIP; + goto out_fd; + } + if (ioctl(thread_ctx.fd, ENQ_BLOCKED_IOCTL_RESET_STATS)) { + SCX_ERR("Failed to reset mutex statistics (%d)", errno); + status = SCX_TEST_FAIL; + goto out_fd; + } + + if (ioctl(thread_ctx.fd, ENQ_BLOCKED_IOCTL_PREP_ATTACH)) { + SCX_ERR("Failed to prepare scheduler attachment (%d)", errno); + status = SCX_TEST_FAIL; + goto out_fd; + } + + err = pthread_create(&owner, NULL, owner_fn, &thread_ctx); + if (err) { + SCX_ERR("Failed to create owner thread (%d)", err); + status = SCX_TEST_FAIL; + goto out; + } + owner_started = true; + + err = pthread_create(&donor, NULL, donor_fn, &thread_ctx); + if (err) { + SCX_ERR("Failed to create donor thread (%d)", err); + status = SCX_TEST_FAIL; + goto out; + } + donor_started = true; + + if (!wait_for_pid(&thread_ctx.donor_pid)) { + SCX_ERR("Timed out waiting for donor thread"); + status = SCX_TEST_FAIL; + goto out; + } + + donor_pid = atomic_load_explicit(&thread_ctx.donor_pid, + memory_order_acquire); + skel->bss->donor_pid = donor_pid; + skel->data->donor_cpu = thread_ctx.donor_cpu; + skel->data->owner_cpu = thread_ctx.owner_cpu; + atomic_store_explicit(&thread_ctx.start_donor, true, + memory_order_release); + + donor_state = ENQ_BLOCKED_DONOR_SLEEPING; + if (proxy_enabled) + donor_state |= ENQ_BLOCKED_DONOR_ON_RQ; + err = wait_for_donor_state(&thread_ctx, donor_state); + if (err < 0) { + SCX_ERR("Donor did not block before scheduler attachment (%d)", -err); + status = SCX_TEST_FAIL; + goto out; + } + + link = bpf_map__attach_struct_ops(skel->maps.enq_blocked_ops); + if (!link) { + SCX_ERR("Failed to attach scheduler"); + status = SCX_TEST_FAIL; + goto out; + } + + /* Scheduler ownership changes start from a fully blocked donor. */ + donor_state = ENQ_BLOCKED_DONOR_SLEEPING; + err = wait_for_donor_state(&thread_ctx, donor_state); + if (err < 0) { + SCX_ERR("Unexpected donor state after scheduler attachment (%d)", + -err); + status = SCX_TEST_FAIL; + goto out; + } + + if (ioctl(thread_ctx.fd, ENQ_BLOCKED_IOCTL_ATTACH_DONE)) { + SCX_ERR("Failed to complete scheduler attachment (%d)", errno); + status = SCX_TEST_FAIL; + goto out; + } + + i = 0; + for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { + if (!CPU_ISSET(cpu, &allowed_cpus)) + continue; + + contender_ctxs[i].thread_ctx = &thread_ctx; + contender_ctxs[i].cpu = cpu; + atomic_init(&contender_ctxs[i].status, 0); + err = pthread_create(&contenders[i], NULL, contender_fn, + &contender_ctxs[i]); + if (err) { + SCX_ERR("Failed to create contender for CPU %d (%d)", + cpu, err); + status = SCX_TEST_FAIL; + goto out; + } + nr_contenders_started++; + i++; + } + + err = wait_for_contenders(contender_ctxs, nr_contenders); + if (err != 1) { + SCX_ERR("Contender threads failed (%d)", -err); + status = SCX_TEST_FAIL; + goto out; + } + + /* + * The first trial spans scheduler attachment and validates the state + * transition, but including it would skew scheduling latency. Exclude it + * from both the mutex and BPF enqueue measurements. + */ + if (!wait_for_donor(&thread_ctx, NR_WARMUP_TRIALS)) { + SCX_ERR("Timed out waiting for warm-up trial"); + status = SCX_TEST_FAIL; + goto out; + } + if (ioctl(thread_ctx.fd, ENQ_BLOCKED_IOCTL_RESET_STATS)) { + SCX_ERR("Failed to reset mutex statistics after warm-up (%d)", + errno); + status = SCX_TEST_FAIL; + goto out; + } + skel->bss->nr_blocked_enqueues = 0; + skel->bss->nr_blocked_enqueues_donor_cpu = 0; + skel->bss->nr_blocked_enqueues_owner_cpu = 0; + skel->bss->nr_blocked_enqueues_other_cpu = 0; + skel->bss->nr_blocked_wakeups = 0; + atomic_store_explicit(&thread_ctx.measurement_ready, true, + memory_order_release); + +out: + ioctl(thread_ctx.fd, ENQ_BLOCKED_IOCTL_ATTACH_DONE); + if (status != SCX_TEST_PASS) { + atomic_store_explicit(&thread_ctx.abort, true, memory_order_release); + atomic_store_explicit(&thread_ctx.start_donor, true, + memory_order_release); + atomic_store_explicit(&thread_ctx.measurement_ready, true, + memory_order_release); + } + + set_join_deadline(&join_deadline); + if (donor_started) { + err = join_thread(donor, &join_deadline, &thread_err); + if (err == ETIMEDOUT) { + SCX_ERR("Timed out waiting for donor thread"); + join_timed_out = true; + status = SCX_TEST_FAIL; + } else if (err) { + SCX_ERR("Failed to join donor thread (%d)", err); + status = SCX_TEST_FAIL; + } else { + donor_started = false; + if (thread_err) { + SCX_ERR("Donor thread failed (%d)", thread_err); + status = SCX_TEST_FAIL; + } + } + } + if (!join_timed_out && owner_started) { + err = join_thread(owner, &join_deadline, &thread_err); + if (err == ETIMEDOUT) { + SCX_ERR("Timed out waiting for owner thread"); + join_timed_out = true; + status = SCX_TEST_FAIL; + } else if (err) { + SCX_ERR("Failed to join owner thread (%d)", err); + status = SCX_TEST_FAIL; + } else { + owner_started = false; + if (thread_err) { + SCX_ERR("Owner thread failed (%d)", thread_err); + status = SCX_TEST_FAIL; + } + } + } + atomic_store_explicit(&thread_ctx.stop_contender, true, + memory_order_release); + for (i = 0; !join_timed_out && i < nr_contenders_started; i++) { + err = join_thread(contenders[i], &join_deadline, &thread_err); + if (err == ETIMEDOUT) { + SCX_ERR("Timed out waiting for contender on CPU %d", + contender_ctxs[i].cpu); + join_timed_out = true; + status = SCX_TEST_FAIL; + } else if (err) { + SCX_ERR("Failed to join contender on CPU %d (%d)", + contender_ctxs[i].cpu, err); + status = SCX_TEST_FAIL; + } else { + nr_contenders_joined++; + if (thread_err) { + SCX_ERR("Contender on CPU %d failed (%d)", + contender_ctxs[i].cpu, thread_err); + status = SCX_TEST_FAIL; + } + } + } + + /* Restore the fair scheduler before waiting for any stranded thread. */ + if (join_timed_out) { + atomic_store_explicit(&thread_ctx.abort, true, + memory_order_release); + if (link) { + bpf_link__destroy(link); + link = NULL; + } + if (donor_started) + pthread_join(donor, NULL); + if (owner_started) + pthread_join(owner, NULL); + for (i = nr_contenders_joined; + i < nr_contenders_started; i++) + pthread_join(contenders[i], NULL); + } + + if (ioctl(thread_ctx.fd, ENQ_BLOCKED_IOCTL_GET_STATS, &stats)) { + SCX_ERR("Failed to read mutex statistics (%d)", errno); + status = SCX_TEST_FAIL; + } else { + result->stats = stats; + printf("\n[topology=%s SCX_OPS_ENQ_BLOCKED=%s]\n", + cross_cpu ? "cross-cpu" : "same-cpu", + enq_blocked ? "enabled" : "disabled"); + printf(" proxy_exec=%s\n", + proxy_enabled ? "enabled" : "disabled"); + printf(" donor_cpu=%d\n", thread_ctx.donor_cpu); + printf(" owner_cpu=%d\n", thread_ctx.owner_cpu); + printf(" nr_contenders=%zu\n", nr_contenders); + printf(" measured_trials=%d\n", NR_MEASURED_TRIALS); + printf(" owner_nice=%d\n", OWNER_NICE); + printf(" donor_nice=%d\n", DONOR_NICE); + printf(" contender_nice=%d\n", CONTENDER_NICE); + print_avg_time("mutex_hold", stats.hold_time_ns, stats.nr_holds); + print_avg_time("mutex_wait", stats.wait_time_ns, stats.nr_waits); + if (stats.nr_holds != NR_MEASURED_TRIALS || + stats.nr_waits != NR_MEASURED_TRIALS) { + SCX_ERR("Expected %d measured trials, got %llu holds and %llu waits", + NR_MEASURED_TRIALS, + (unsigned long long)stats.nr_holds, + (unsigned long long)stats.nr_waits); + status = SCX_TEST_FAIL; + } + } + + nr_blocked = skel->bss->nr_blocked_enqueues; + nr_blocked_donor_cpu = skel->bss->nr_blocked_enqueues_donor_cpu; + nr_blocked_owner_cpu = skel->bss->nr_blocked_enqueues_owner_cpu; + nr_blocked_other_cpu = skel->bss->nr_blocked_enqueues_other_cpu; + nr_blocked_wakeups = skel->bss->nr_blocked_wakeups; + result->nr_blocked_enqueues = nr_blocked; + result->nr_blocked_enqueues_donor_cpu = nr_blocked_donor_cpu; + result->nr_blocked_enqueues_owner_cpu = nr_blocked_owner_cpu; + result->nr_blocked_enqueues_other_cpu = nr_blocked_other_cpu; + result->nr_blocked_wakeups = nr_blocked_wakeups; + printf(" nr_blocked_enqueues=%llu\n", + (unsigned long long)nr_blocked); + printf(" nr_blocked_enqueues_donor_cpu=%llu\n", + (unsigned long long)nr_blocked_donor_cpu); + printf(" nr_blocked_enqueues_owner_cpu=%llu\n", + (unsigned long long)nr_blocked_owner_cpu); + printf(" nr_blocked_enqueues_other_cpu=%llu\n", + (unsigned long long)nr_blocked_other_cpu); + printf(" nr_blocked_wakeups=%llu\n", + (unsigned long long)nr_blocked_wakeups); + if (status == SCX_TEST_PASS) { + if (enq_blocked && proxy_enabled && !nr_blocked) { + SCX_ERR("ops.enqueue() did not receive the blocked donor"); + status = SCX_TEST_FAIL; + } else if ((!enq_blocked || !proxy_enabled) && nr_blocked) { + SCX_ERR("ops.enqueue() unexpectedly received %llu blocked donors", + (unsigned long long)nr_blocked); + status = SCX_TEST_FAIL; + } else if (nr_blocked_wakeups) { + SCX_ERR("Ordinary wakeups received %llu blocked enqueue flags", + (unsigned long long)nr_blocked_wakeups); + status = SCX_TEST_FAIL; + } else if (nr_blocked_other_cpu) { + SCX_ERR("Blocked donor had %llu enqueues on unexpected CPUs", + (unsigned long long)nr_blocked_other_cpu); + status = SCX_TEST_FAIL; + } + } + + if (UEI_EXITED(skel, uei)) { + SCX_ERR("Scheduler exited unexpectedly (kind=%llu code=%lld)", + (unsigned long long)skel->data->uei.kind, + (long long)skel->data->uei.exit_code); + status = SCX_TEST_FAIL; + } + + if (link) + bpf_link__destroy(link); +out_fd: + close(thread_ctx.fd); +out_module: + unload_test_module(module_loaded); +out_skel: + enq_blocked__destroy(skel); +out_contenders: + free(contender_ctxs); + free(contenders); + return status; +} + +static enum scx_test_status run_topology(bool cross_cpu) +{ + struct run_result disabled = {}, enabled = {}; + enum scx_test_status status; + + status = run_one(false, cross_cpu, &disabled); + if (status != SCX_TEST_PASS) + return status; + + status = run_one(true, cross_cpu, &enabled); + if (status != SCX_TEST_PASS) + return status; + + printf("\n[topology=%s delta: enabled - disabled]\n", + cross_cpu ? "cross-cpu" : "same-cpu"); + print_avg_delta("mutex_hold", disabled.stats.hold_time_ns, + disabled.stats.nr_holds, enabled.stats.hold_time_ns, + enabled.stats.nr_holds); + print_avg_delta("mutex_wait", disabled.stats.wait_time_ns, + disabled.stats.nr_waits, enabled.stats.wait_time_ns, + enabled.stats.nr_waits); + + return SCX_TEST_PASS; +} + +static enum scx_test_status run(void *ctx) +{ + enum scx_test_status status; + + (void)ctx; + + status = run_topology(false); + if (status != SCX_TEST_PASS) + return status; + + status = run_topology(true); + if (status == SCX_TEST_SKIP) + return SCX_TEST_PASS; + + return status; +} + +struct scx_test enq_blocked = { + .name = "enq_blocked", + .description = "Verify proxy donor admission under CPU-wide contention", + .setup = setup, + .run = run, +}; + +REGISTER_SCX_TEST(&enq_blocked)
diff --git a/tools/testing/selftests/sched_ext/enq_blocked.h b/tools/testing/selftests/sched_ext/enq_blocked.h new file mode 100644 index 0000000..ef1eb97 --- /dev/null +++ b/tools/testing/selftests/sched_ext/enq_blocked.h
@@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES */ +#ifndef __ENQ_BLOCKED_H +#define __ENQ_BLOCKED_H + +#include <linux/ioctl.h> +#include <linux/types.h> + +struct enq_blocked_stats { + __u64 hold_time_ns; + __u64 wait_time_ns; + __u64 nr_holds; + __u64 nr_waits; +}; + +#define ENQ_BLOCKED_IOCTL_OWNER _IO('s', 1) +#define ENQ_BLOCKED_IOCTL_DONOR _IO('s', 2) +#define ENQ_BLOCKED_IOCTL_RESET_STATS _IO('s', 3) +#define ENQ_BLOCKED_IOCTL_GET_STATS _IOR('s', 4, struct enq_blocked_stats) +#define ENQ_BLOCKED_IOCTL_PREP_ATTACH _IO('s', 5) +#define ENQ_BLOCKED_IOCTL_ATTACH_DONE _IO('s', 6) +#define ENQ_BLOCKED_IOCTL_DONOR_STATE _IO('s', 7) +#define ENQ_BLOCKED_IOCTL_PROXY_SUPPORTED _IO('s', 8) + +#define ENQ_BLOCKED_DONOR_SLEEPING (1U << 0) +#define ENQ_BLOCKED_DONOR_ON_RQ (1U << 1) + +#endif /* __ENQ_BLOCKED_H */
diff --git a/tools/testing/selftests/sched_ext/exit.c b/tools/testing/selftests/sched_ext/exit.c index 01b1709..fd6f1c9a 100644 --- a/tools/testing/selftests/sched_ext/exit.c +++ b/tools/testing/selftests/sched_ext/exit.c
@@ -43,8 +43,12 @@ static enum scx_test_status run(void *ctx) } /* Assumes uei.kind is written last */ - while (skel->data->uei.kind == EXIT_KIND(SCX_EXIT_NONE)) - sched_yield(); + if (!SCX_TIMED_WAIT_UEI(skel, uei, 10000)) { + SCX_ERR("Timed out waiting for scheduler to exit"); + bpf_link__destroy(link); + exit__destroy(skel); + return SCX_TEST_FAIL; + } SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_UNREG_BPF)); SCX_EQ(skel->data->uei.exit_code, tc);
diff --git a/tools/testing/selftests/sched_ext/hotplug.c b/tools/testing/selftests/sched_ext/hotplug.c index 0cfbb111..3c07686 100644 --- a/tools/testing/selftests/sched_ext/hotplug.c +++ b/tools/testing/selftests/sched_ext/hotplug.c
@@ -21,15 +21,17 @@ static bool is_cpu_online(void) return file_read_long(online_path) > 0; } -static void toggle_online_status(bool online) +static int toggle_online_status(bool online) { long val = online ? 1 : 0; int ret; ret = file_write_long(online_path, val); if (ret != 0) - fprintf(stderr, "Failed to bring CPU %s (%s)", + fprintf(stderr, "Failed to bring CPU %s (%s)\n", online ? "online" : "offline", strerror(errno)); + + return ret; } static enum scx_test_status setup(void **ctx) @@ -44,6 +46,7 @@ static enum scx_test_status test_hotplug(bool onlining, bool cbs_defined) { struct hotplug *skel; struct bpf_link *link; + enum scx_test_status status = SCX_TEST_FAIL; long kind, code; SCX_ASSERT(is_cpu_online()); @@ -54,8 +57,8 @@ static enum scx_test_status test_hotplug(bool onlining, bool cbs_defined) SCX_FAIL_IF(hotplug__load(skel), "Failed to load skel"); /* Testing the offline -> online path, so go offline before starting */ - if (onlining) - toggle_online_status(0); + if (onlining && toggle_online_status(0)) + goto out_destroy_skel; if (cbs_defined) { kind = SCX_KIND_VAL(SCX_EXIT_UNREG_BPF); @@ -79,28 +82,34 @@ static enum scx_test_status test_hotplug(bool onlining, bool cbs_defined) return SCX_TEST_FAIL; } - toggle_online_status(onlining ? 1 : 0); + if (toggle_online_status(onlining ? 1 : 0)) + goto out_destroy_link; - while (!UEI_EXITED(skel, uei)) - sched_yield(); + if (!SCX_TIMED_WAIT_UEI(skel, uei, 10000)) { + SCX_ERR("Timed out waiting for scheduler to exit"); + goto out_destroy_link; + } SCX_EQ(skel->data->uei.kind, kind); SCX_EQ(UEI_REPORT(skel, uei), code); - if (!onlining) - toggle_online_status(1); + if (!onlining && toggle_online_status(1)) + goto out_destroy_link; + status = SCX_TEST_PASS; +out_destroy_link: bpf_link__destroy(link); +out_destroy_skel: hotplug__destroy(skel); - return SCX_TEST_PASS; + return status; } static enum scx_test_status test_hotplug_attach(void) { struct hotplug *skel; struct bpf_link *link; - enum scx_test_status status = SCX_TEST_PASS; + enum scx_test_status status = SCX_TEST_FAIL; long kind, code; SCX_ASSERT(is_cpu_online()); @@ -115,14 +124,18 @@ static enum scx_test_status test_hotplug_attach(void) * Take the CPU offline to increment the global hotplug seq, which * should cause attach to fail due to us setting the hotplug seq above */ - toggle_online_status(0); + if (toggle_online_status(0)) + goto out_destroy_skel; link = bpf_map__attach_struct_ops(skel->maps.hotplug_nocb_ops); - toggle_online_status(1); + if (toggle_online_status(1)) + goto out_destroy_link; SCX_ASSERT(link); - while (!UEI_EXITED(skel, uei)) - sched_yield(); + if (!SCX_TIMED_WAIT_UEI(skel, uei, 10000)) { + SCX_ERR("Timed out waiting for scheduler to exit"); + goto out_destroy_link; + } kind = SCX_KIND_VAL(SCX_EXIT_UNREG_KERN); code = SCX_ECODE_VAL(SCX_ECODE_ACT_RESTART) | @@ -130,7 +143,10 @@ static enum scx_test_status test_hotplug_attach(void) SCX_EQ(skel->data->uei.kind, kind); SCX_EQ(UEI_REPORT(skel, uei), code); + status = SCX_TEST_PASS; +out_destroy_link: bpf_link__destroy(link); +out_destroy_skel: hotplug__destroy(skel); return status;
diff --git a/tools/testing/selftests/sched_ext/init_enable_count.bpf.c b/tools/testing/selftests/sched_ext/init_enable_count.bpf.c index 5eb9edb..c0a5dd8 100644 --- a/tools/testing/selftests/sched_ext/init_enable_count.bpf.c +++ b/tools/testing/selftests/sched_ext/init_enable_count.bpf.c
@@ -15,6 +15,8 @@ char _license[] SEC("license") = "GPL"; u64 init_task_cnt, exit_task_cnt, enable_cnt, disable_cnt; u64 init_fork_cnt, init_transition_cnt; +UEI_DEFINE(uei); + s32 BPF_STRUCT_OPS_SLEEPABLE(cnt_init_task, struct task_struct *p, struct scx_init_task_args *args) { @@ -43,11 +45,17 @@ void BPF_STRUCT_OPS(cnt_disable, struct task_struct *p) __sync_fetch_and_add(&disable_cnt, 1); } +void BPF_STRUCT_OPS(cnt_exit, struct scx_exit_info *ei) +{ + UEI_RECORD(uei, ei); +} + SEC(".struct_ops.link") struct sched_ext_ops init_enable_count_ops = { .init_task = (void *) cnt_init_task, .exit_task = (void *) cnt_exit_task, .enable = (void *) cnt_enable, .disable = (void *) cnt_disable, + .exit = (void *) cnt_exit, .name = "init_enable_count", };
diff --git a/tools/testing/selftests/sched_ext/init_enable_count.c b/tools/testing/selftests/sched_ext/init_enable_count.c index 44577e3..c4a5703 100644 --- a/tools/testing/selftests/sched_ext/init_enable_count.c +++ b/tools/testing/selftests/sched_ext/init_enable_count.c
@@ -5,6 +5,7 @@ * Copyright (c) 2023 Tejun Heo <tj@kernel.org> */ #include <signal.h> +#include <string.h> #include <stdio.h> #include <unistd.h> #include <sched.h> @@ -72,7 +73,17 @@ static enum scx_test_status run_test(bool global) close(pipe_fds[1]); signal(SIGCHLD, SIG_DFL); + SCX_ASSERT_ALIVE(skel, uei); + bpf_link__destroy(link); + + /* + * The clean unregister above is recorded in uei and would + * otherwise trip the liveness check of the second cycle, which + * reuses this skeleton. + */ + memset(&skel->data->uei, 0, sizeof(skel->data->uei)); + SCX_GE(skel->bss->init_task_cnt, num_pre_forks); SCX_GE(skel->bss->exit_task_cnt, num_pre_forks); @@ -124,6 +135,8 @@ static enum scx_test_status run_test(bool global) status); } + SCX_ASSERT_ALIVE(skel, uei); + bpf_link__destroy(link); SCX_GE(skel->bss->init_task_cnt, 2 * num_children);
diff --git a/tools/testing/selftests/sched_ext/kick.bpf.c b/tools/testing/selftests/sched_ext/kick.bpf.c new file mode 100644 index 0000000..bd9605d --- /dev/null +++ b/tools/testing/selftests/sched_ext/kick.bpf.c
@@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES + */ +#include <scx/common.bpf.h> + +#include "kick_test.h" + +char _license[] SEC("license") = "GPL"; + +const volatile u32 scenario; +const volatile s32 victim_pid; +const volatile s32 challenger_pid; +const volatile s32 target_cpu; +const volatile s32 lazy_resched_override = -1; + +u32 state; +u64 slice_before; +u64 slice_at_resched; +s32 resched_tif; +u64 nr_wait_callbacks; +bool enq_preempt_issued; + +UEI_DEFINE(uei); + +static bool is_trace_scenario(void) +{ + return scenario <= TICK_EXPIRY; +} + +void BPF_STRUCT_OPS(kick_enqueue, struct task_struct *p, u64 enq_flags) +{ + switch (scenario) { + case ENQ_BOTH: + if (p->pid == victim_pid) { + scx_bpf_dsq_insert(p, SCX_DSQ_GLOBAL, SCX_SLICE_INF, enq_flags); + } else if (p->pid == challenger_pid && state == KICK_STATE_QUEUED) { + enq_preempt_issued = true; + scx_bpf_dsq_insert(p, SCX_DSQ_LOCAL, SCX_SLICE_DFL, + enq_flags | SCX_ENQ_PREEMPT | + SCX_ENQ_PREEMPT_LAZY); + } else { + scx_bpf_dsq_insert(p, SCX_DSQ_GLOBAL, SCX_SLICE_DFL, enq_flags); + } + goto kick_last; + case INVALID_KICK_IDLE: + scx_bpf_kick_cpu(scx_bpf_task_cpu(p), SCX_KICK_PREEMPT_LAZY | SCX_KICK_IDLE); + break; + case INVALID_KICK_UNKNOWN: + scx_bpf_kick_cpu(scx_bpf_task_cpu(p), 1LLU << 63); + break; + } + + scx_bpf_dsq_insert(p, SCX_DSQ_GLOBAL, SCX_SLICE_DFL, enq_flags); +kick_last: + if (enq_flags & SCX_ENQ_LAST) + scx_bpf_kick_cpu(target_cpu, SCX_KICK_IDLE); +} + +static void set_lazy_resched_override(struct task_struct *p) +{ + if (p->pid == victim_pid && lazy_resched_override >= 0) + scx_bpf_task_set_lazy_resched(p, lazy_resched_override); +} + +void BPF_STRUCT_OPS(kick_running, struct task_struct *p) +{ + if (!is_trace_scenario() || p->pid != victim_pid) + return; + set_lazy_resched_override(p); + if (__sync_val_compare_and_swap(&state, KICK_STATE_ARMED, KICK_STATE_QUEUED) != + KICK_STATE_ARMED) + return; + + slice_before = p->scx.slice; + + switch (scenario) { + case KICK_IMMEDIATE: + scx_bpf_kick_cpu(target_cpu, SCX_KICK_PREEMPT); + break; + case KICK_LAZY: + scx_bpf_kick_cpu(target_cpu, SCX_KICK_PREEMPT_LAZY); + break; + case KICK_LAZY_THEN_IMMEDIATE: + scx_bpf_kick_cpu(target_cpu, SCX_KICK_PREEMPT_LAZY); + scx_bpf_kick_cpu(target_cpu, SCX_KICK_PREEMPT); + break; + case KICK_IMMEDIATE_THEN_LAZY: + scx_bpf_kick_cpu(target_cpu, SCX_KICK_PREEMPT); + scx_bpf_kick_cpu(target_cpu, SCX_KICK_PREEMPT_LAZY); + break; + case KICK_PLAIN_THEN_LAZY: + scx_bpf_kick_cpu(target_cpu, 0); + scx_bpf_kick_cpu(target_cpu, SCX_KICK_PREEMPT_LAZY); + break; + case KICK_LAZY_THEN_PLAIN: + scx_bpf_kick_cpu(target_cpu, SCX_KICK_PREEMPT_LAZY); + scx_bpf_kick_cpu(target_cpu, 0); + break; + case KICK_BOTH: + scx_bpf_kick_cpu(target_cpu, SCX_KICK_PREEMPT | SCX_KICK_PREEMPT_LAZY); + break; + case KICK_LAZY_WAIT: + scx_bpf_kick_cpu(target_cpu, SCX_KICK_PREEMPT_LAZY | SCX_KICK_WAIT); + break; + case ENQ_BOTH: + /* The userspace controller wakes a competing task. */ + break; + case TICK_EXPIRY: + /* no kick: the slice runs out at the tick */ + break; + } +} + +SEC("fexit/__resched_curr") +int BPF_PROG(kick_need_resched, struct rq *rq, int tif) +{ + struct task_struct *task = BPF_CORE_READ(rq, curr); + u64 slice; + + if (!task || BPF_CORE_READ(task, pid) != victim_pid || + BPF_CORE_READ(rq, cpu) != target_cpu || state != KICK_STATE_QUEUED) + return 0; + if (scenario == ENQ_BOTH && !enq_preempt_issued) + return 0; + + slice = BPF_CORE_READ(task, scx.slice); + if (slice) + return 0; + + slice_at_resched = slice; + resched_tif = tif; + state = KICK_STATE_RESCHED; + return 0; +} + +SEC("fentry/kick_sync_wait_bal_cb") +int BPF_PROG(kick_wait_callback, struct rq *rq) +{ + if (scenario == KICK_LAZY_WAIT && BPF_CORE_READ(rq, cpu) == target_cpu) + __sync_fetch_and_add(&nr_wait_callbacks, 1); + return 0; +} + +void BPF_STRUCT_OPS(kick_stopping, struct task_struct *p, bool runnable) +{ + if (p->pid == victim_pid && state == KICK_STATE_RESCHED) + state = KICK_STATE_DONE; +} + +void BPF_STRUCT_OPS(kick_exit, struct scx_exit_info *ei) +{ + UEI_RECORD(uei, ei); +} + +SEC(".struct_ops.link") +struct sched_ext_ops kick_ops = { + .enqueue = (void *)kick_enqueue, + .running = (void *)kick_running, + .stopping = (void *)kick_stopping, + .exit = (void *)kick_exit, + .flags = SCX_OPS_ENQ_LAST, + .name = "kick", +};
diff --git a/tools/testing/selftests/sched_ext/kick.c b/tools/testing/selftests/sched_ext/kick.c new file mode 100644 index 0000000..40c91d5 --- /dev/null +++ b/tools/testing/selftests/sched_ext/kick.c
@@ -0,0 +1,521 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES + */ +#define _GNU_SOURCE +#include <bpf/bpf.h> +#include <errno.h> +#include <linux/sched.h> +#include <sched.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/prctl.h> +#include <sys/wait.h> +#include <unistd.h> +#include <scx/common.h> + +#include "kick.bpf.skel.h" +#include "kick_test.h" +#include "scx_test.h" +#include "util.h" + +#define WAIT_LOOPS 3000 + +struct observation { + u64 slice_before; + u64 slice_at_resched; + u64 nr_wait_callbacks; + s32 resched_tif; +}; + +struct kick_ctx { + cpu_set_t original_mask; + int target_cpu; +}; + +static bool enum_supported(const char *type, const char *name) +{ + u64 value; + + return __COMPAT_read_enum(type, name, &value); +} + +static enum scx_test_status setup_controller(void **ctx_ptr) +{ + struct kick_ctx *ctx; + cpu_set_t controller_mask; + int cpu, controller_cpu = -1; + + ctx = calloc(1, sizeof(*ctx)); + SCX_FAIL_IF(!ctx, "Failed to allocate context"); + if (sched_getaffinity(0, sizeof(ctx->original_mask), &ctx->original_mask)) { + free(ctx); + SCX_FAIL("Failed to get affinity (%d)", errno); + } + + for (cpu = 0; cpu < CPU_SETSIZE; cpu++) { + if (!CPU_ISSET(cpu, &ctx->original_mask)) + continue; + if (controller_cpu < 0) { + controller_cpu = cpu; + } else { + ctx->target_cpu = cpu; + break; + } + } + if (cpu == CPU_SETSIZE) { + printf("SKIP: two allowed CPUs are required\n"); + free(ctx); + return SCX_TEST_SKIP; + } + + CPU_ZERO(&controller_mask); + CPU_SET(controller_cpu, &controller_mask); + if (sched_setaffinity(0, sizeof(controller_mask), &controller_mask)) { + free(ctx); + SCX_FAIL("Failed to pin controller to CPU %d (%d)", controller_cpu, errno); + } + + *ctx_ptr = ctx; + return SCX_TEST_PASS; +} + +static void cleanup_controller(void *ctx_ptr) +{ + struct kick_ctx *ctx = ctx_ptr; + + sched_setaffinity(0, sizeof(ctx->original_mask), &ctx->original_mask); + free(ctx); +} + +static bool wait_for_state(struct kick *skel, u32 wanted) +{ + int i; + + for (i = 0; i < WAIT_LOOPS; i++) { + if (__atomic_load_n(&skel->bss->state, __ATOMIC_ACQUIRE) == wanted) + return true; + if (UEI_EXITED(skel, uei)) + return false; + usleep(1000); + } + return false; +} + +static bool wait_for_counter(struct kick *skel, const u64 *counter, u64 wanted) +{ + int i; + + for (i = 0; i < WAIT_LOOPS; i++) { + if (__atomic_load_n(counter, __ATOMIC_ACQUIRE) >= wanted) + return true; + if (UEI_EXITED(skel, uei)) + return false; + usleep(1000); + } + return false; +} + +static enum scx_test_status trace_one(struct kick_ctx *ctx, u32 scenario, u64 ops_flags, + s32 lazy_resched_override, struct observation *obs) +{ + struct bpf_link *ops_link = NULL; + struct kick *skel = NULL; + struct scx_test_gated_worker challenger = { .pid = -1, .start_fd = -1 }; + struct scx_test_gated_worker victim; + enum scx_test_status ret = SCX_TEST_FAIL; + int cpu = ctx->target_cpu; + + victim = scx_test_spawn_gated_worker(cpu, false); + if (victim.pid < 0) { + SCX_ERR("Failed to spawn victim"); + return SCX_TEST_FAIL; + } + if (scenario == ENQ_BOTH) { + challenger = scx_test_spawn_gated_worker(cpu, false); + if (challenger.pid < 0) { + SCX_ERR("Failed to spawn enqueue challenger"); + goto out; + } + } + + skel = kick__open(); + if (!skel) { + SCX_ERR("Failed to open scenario %u", scenario); + goto out; + } + SCX_ENUM_INIT(skel); + skel->rodata->scenario = scenario; + skel->rodata->victim_pid = victim.pid; + skel->rodata->challenger_pid = challenger.pid; + skel->rodata->target_cpu = cpu; + skel->rodata->lazy_resched_override = lazy_resched_override; + skel->struct_ops.kick_ops->flags |= ops_flags; + if (scenario != KICK_LAZY_WAIT) + bpf_program__set_autoload(skel->progs.kick_wait_callback, false); + if (kick__load(skel)) { + SCX_ERR("Failed to load scenario %u", scenario); + goto out; + } + + bpf_map__set_autoattach(skel->maps.kick_ops, false); + if (kick__attach(skel)) { + SCX_ERR("Failed to attach __resched_curr tracer"); + goto out; + } + skel->bss->state = KICK_STATE_ARMED; + ops_link = bpf_map__attach_struct_ops(skel->maps.kick_ops); + if (!ops_link) { + SCX_ERR("Failed to attach scenario %u", scenario); + goto out; + } + if (!scx_test_start_gated_worker(&victim)) { + SCX_ERR("Failed to start victim"); + goto out; + } + if (scenario == ENQ_BOTH) { + if (!wait_for_state(skel, KICK_STATE_QUEUED)) { + SCX_ERR("Enqueue scenario did not arm"); + goto out; + } + if (!scx_test_start_gated_worker(&challenger)) { + SCX_ERR("Failed to start enqueue challenger"); + goto out; + } + } + if (!wait_for_state(skel, KICK_STATE_DONE)) { + SCX_ERR("Scenario %u stopped in state %u, exit kind %d", scenario, skel->bss->state, + skel->data->uei.kind); + goto out; + } + if (scenario == KICK_LAZY_WAIT && + !wait_for_counter(skel, &skel->bss->nr_wait_callbacks, 1)) { + SCX_ERR("WAIT callback did not run"); + goto out; + } + + obs->slice_before = skel->bss->slice_before; + obs->slice_at_resched = skel->bss->slice_at_resched; + obs->nr_wait_callbacks = skel->bss->nr_wait_callbacks; + obs->resched_tif = skel->bss->resched_tif; + ret = SCX_TEST_PASS; +out: + scx_test_stop_gated_worker(&victim); + scx_test_stop_gated_worker(&challenger); + if (ops_link) + bpf_link__destroy(ops_link); + if (skel) + kick__destroy(skel); + return ret; +} + +static bool observation_valid(const struct observation *obs) +{ + return obs->slice_before > 0 && !obs->slice_at_resched; +} + +static bool trace_target_supported(const char *name, enum bpf_attach_type attach_type) +{ + return libbpf_find_vmlinux_btf_id(name, attach_type) > 0; +} + +static enum scx_test_status setup_immediate(void **ctx) +{ + if (!enum_supported("scx_kick_flags", "SCX_KICK_PREEMPT")) { + printf("SKIP: SCX_KICK_PREEMPT is not supported\n"); + return SCX_TEST_SKIP; + } + if (!trace_target_supported("__resched_curr", BPF_TRACE_FEXIT)) { + printf("SKIP: __resched_curr is not available in BTF\n"); + return SCX_TEST_SKIP; + } + return setup_controller(ctx); +} + +static enum scx_test_status setup_lazy(void **ctx) +{ + if (!enum_supported("scx_kick_flags", "SCX_KICK_PREEMPT_LAZY")) { + printf("SKIP: SCX_KICK_PREEMPT_LAZY is not supported\n"); + return SCX_TEST_SKIP; + } + return setup_immediate(ctx); +} + +static enum scx_test_status setup_tick(void **ctx) +{ + if (!enum_supported("scx_ops_flags", "SCX_OPS_LAZY_RESCHED")) { + printf("SKIP: SCX_OPS_LAZY_RESCHED is not supported\n"); + return SCX_TEST_SKIP; + } + return setup_lazy(ctx); +} + +static enum scx_test_status setup_coalesce(void **ctx) +{ + if (!enum_supported("scx_enq_flags", "SCX_ENQ_PREEMPT_LAZY")) { + printf("SKIP: SCX_ENQ_PREEMPT_LAZY is not supported\n"); + return SCX_TEST_SKIP; + } + if (!trace_target_supported("kick_sync_wait_bal_cb", BPF_TRACE_FENTRY)) { + printf("SKIP: kick_sync_wait_bal_cb is not available in BTF\n"); + return SCX_TEST_SKIP; + } + return setup_lazy(ctx); +} + +static enum scx_test_status setup_invalid(void **ctx) +{ + if (!enum_supported("scx_kick_flags", "SCX_KICK_PREEMPT_LAZY")) { + printf("SKIP: SCX_KICK_PREEMPT_LAZY is not supported\n"); + return SCX_TEST_SKIP; + } + return setup_controller(ctx); +} + +static enum scx_test_status run_immediate(void *ctx) +{ + struct observation obs; + enum scx_test_status status; + + status = trace_one(ctx, KICK_IMMEDIATE, 0, -1, &obs); + SCX_EQ(status, SCX_TEST_PASS); + SCX_ASSERT(observation_valid(&obs)); + return SCX_TEST_PASS; +} + +static enum scx_test_status run_lazy(void *ctx) +{ + struct observation immediate, lazy; + enum scx_test_status status; + int lazy_mode = scx_test_preempt_lazy_mode(); + + if (lazy_mode < 0) { + printf("SKIP: running kernel preemption mode is unavailable\n"); + return SCX_TEST_SKIP; + } + + status = trace_one(ctx, KICK_IMMEDIATE, 0, -1, &immediate); + SCX_EQ(status, SCX_TEST_PASS); + SCX_ASSERT(observation_valid(&immediate)); + status = trace_one(ctx, KICK_LAZY, 0, -1, &lazy); + SCX_EQ(status, SCX_TEST_PASS); + SCX_ASSERT(observation_valid(&lazy)); + + if (lazy_mode > 0) + SCX_FAIL_IF(lazy.resched_tif == immediate.resched_tif, + "Lazy mode used immediate TIF %d", lazy.resched_tif); + else if (!lazy_mode) + SCX_EQ(lazy.resched_tif, immediate.resched_tif); + + return SCX_TEST_PASS; +} + +static enum scx_test_status run_coalesce(void *ctx) +{ + struct observation immediate, lazy_first, immediate_first; + struct observation plain_first, lazy_then_plain; + struct observation both, lazy_wait, enq_both; + enum scx_test_status status; + + if (scx_test_preempt_lazy_mode() != 1) { + printf("SKIP: kick coalescing requires active lazy preemption\n"); + return SCX_TEST_SKIP; + } + + status = trace_one(ctx, KICK_IMMEDIATE, 0, -1, &immediate); + SCX_EQ(status, SCX_TEST_PASS); + SCX_ASSERT(observation_valid(&immediate)); + status = trace_one(ctx, KICK_LAZY_THEN_IMMEDIATE, 0, -1, &lazy_first); + SCX_EQ(status, SCX_TEST_PASS); + SCX_ASSERT(observation_valid(&lazy_first)); + status = trace_one(ctx, KICK_IMMEDIATE_THEN_LAZY, 0, -1, &immediate_first); + SCX_EQ(status, SCX_TEST_PASS); + SCX_ASSERT(observation_valid(&immediate_first)); + SCX_EQ(lazy_first.resched_tif, immediate.resched_tif); + SCX_EQ(immediate_first.resched_tif, immediate.resched_tif); + + /* + * A plain kick in the same batch doesn't clear the slice by itself. The + * lazy preemption must still expire it, and the plain kick must still + * reschedule immediately, whichever came first. + */ + status = trace_one(ctx, KICK_PLAIN_THEN_LAZY, 0, -1, &plain_first); + SCX_EQ(status, SCX_TEST_PASS); + SCX_ASSERT(observation_valid(&plain_first)); + status = trace_one(ctx, KICK_LAZY_THEN_PLAIN, 0, -1, &lazy_then_plain); + SCX_EQ(status, SCX_TEST_PASS); + SCX_ASSERT(observation_valid(&lazy_then_plain)); + SCX_EQ(plain_first.resched_tif, immediate.resched_tif); + SCX_EQ(lazy_then_plain.resched_tif, immediate.resched_tif); + + /* Immediate kick and WAIT both take precedence over lazy preemption. */ + status = trace_one(ctx, KICK_BOTH, 0, -1, &both); + SCX_EQ(status, SCX_TEST_PASS); + SCX_ASSERT(observation_valid(&both)); + status = trace_one(ctx, KICK_LAZY_WAIT, 0, -1, &lazy_wait); + SCX_EQ(status, SCX_TEST_PASS); + SCX_ASSERT(observation_valid(&lazy_wait)); + SCX_EQ(both.resched_tif, immediate.resched_tif); + SCX_EQ(lazy_wait.resched_tif, immediate.resched_tif); + SCX_GT(lazy_wait.nr_wait_callbacks, 0); + + /* Immediate enqueue preemption likewise takes precedence over lazy. */ + status = trace_one(ctx, ENQ_BOTH, 0, -1, &enq_both); + SCX_EQ(status, SCX_TEST_PASS); + SCX_ASSERT(observation_valid(&enq_both)); + SCX_EQ(enq_both.resched_tif, immediate.resched_tif); + return SCX_TEST_PASS; +} + +/* + * A slice running out at the tick reschedules immediately by default and lazily + * with SCX_OPS_LAZY_RESCHED, the way fair.c expires a slice. + */ +static enum scx_test_status run_tick(void *ctx) +{ + struct observation immediate, lazy, force_lazy, force_immediate; + enum scx_test_status status; + u64 lazy_flag; + int lazy_mode = scx_test_preempt_lazy_mode(); + bool found; + + if (lazy_mode < 0) { + printf("SKIP: running kernel preemption mode is unavailable\n"); + return SCX_TEST_SKIP; + } + + found = __COMPAT_read_enum("scx_ops_flags", "SCX_OPS_LAZY_RESCHED", &lazy_flag); + SCX_ASSERT(found); + status = trace_one(ctx, TICK_EXPIRY, 0, -1, &immediate); + SCX_EQ(status, SCX_TEST_PASS); + SCX_ASSERT(observation_valid(&immediate)); + status = trace_one(ctx, TICK_EXPIRY, lazy_flag, -1, &lazy); + SCX_EQ(status, SCX_TEST_PASS); + SCX_ASSERT(observation_valid(&lazy)); + if (lazy_mode > 0) { + SCX_FAIL_IF(lazy.resched_tif == immediate.resched_tif, + "Lazy slice expiry used immediate TIF %d", lazy.resched_tif); + + status = trace_one(ctx, TICK_EXPIRY, 0, 1, &force_lazy); + SCX_EQ(status, SCX_TEST_PASS); + SCX_ASSERT(observation_valid(&force_lazy)); + status = trace_one(ctx, TICK_EXPIRY, lazy_flag, 0, &force_immediate); + SCX_EQ(status, SCX_TEST_PASS); + SCX_ASSERT(observation_valid(&force_immediate)); + SCX_EQ(force_lazy.resched_tif, lazy.resched_tif); + SCX_EQ(force_immediate.resched_tif, immediate.resched_tif); + } else { + SCX_EQ(lazy.resched_tif, immediate.resched_tif); + } + + return SCX_TEST_PASS; +} + +static enum scx_test_status invalid_one(struct kick_ctx *ctx, u32 scenario) +{ + struct bpf_link *ops_link = NULL; + struct kick *skel = NULL; + struct scx_test_gated_worker victim; + enum scx_test_status ret = SCX_TEST_FAIL; + int cpu = ctx->target_cpu; + int i; + u64 error_kind; + + error_kind = EXIT_KIND(SCX_EXIT_ERROR); + victim = scx_test_spawn_gated_worker(cpu, false); + if (victim.pid < 0) + return SCX_TEST_FAIL; + + skel = kick__open(); + if (!skel) + goto out; + SCX_ENUM_INIT(skel); + skel->rodata->scenario = scenario; + bpf_program__set_autoload(skel->progs.kick_need_resched, false); + bpf_program__set_autoload(skel->progs.kick_wait_callback, false); + if (kick__load(skel)) + goto out; + ops_link = bpf_map__attach_struct_ops(skel->maps.kick_ops); + if (!ops_link || !scx_test_start_gated_worker(&victim)) + goto out; + + for (i = 0; i < WAIT_LOOPS; i++) { + if (UEI_EXITED(skel, uei) == error_kind) { + ret = SCX_TEST_PASS; + break; + } + usleep(1000); + } +out: + scx_test_stop_gated_worker(&victim); + if (ops_link) + bpf_link__destroy(ops_link); + if (skel) + kick__destroy(skel); + return ret; +} + +static enum scx_test_status run_invalid(void *ctx) +{ + enum scx_test_status status; + u32 scenario; + + for (scenario = INVALID_KICK_IDLE; + scenario <= INVALID_KICK_UNKNOWN; scenario++) { + status = invalid_one(ctx, scenario); + SCX_EQ(status, SCX_TEST_PASS); + } + return SCX_TEST_PASS; +} + +static struct scx_test kick_immediate = { + .name = "kick_immediate", + .description = "Trace immediate kick slice expiration and rescheduling", + .setup = setup_immediate, + .run = run_immediate, + .cleanup = cleanup_controller, +}; + +static struct scx_test kick_lazy = { + .name = "kick_lazy", + .description = "Trace lazy kick slice expiration and rescheduling", + .setup = setup_lazy, + .run = run_lazy, + .cleanup = cleanup_controller, +}; + +static struct scx_test kick_coalesce = { + .name = "kick_coalesce", + .description = "Verify lazy preemption coalesces with immediate requests", + .setup = setup_coalesce, + .run = run_coalesce, + .cleanup = cleanup_controller, +}; + +static struct scx_test kick_tick = { + .name = "kick_tick", + .description = "Trace slice expiry at the tick, immediate and lazy", + .setup = setup_tick, + .run = run_tick, + .cleanup = cleanup_controller, +}; + +static struct scx_test kick_invalid = { + .name = "kick_invalid", + .description = "Verify invalid kick flag combinations fail", + .setup = setup_invalid, + .run = run_invalid, + .cleanup = cleanup_controller, +}; + +__attribute__((constructor)) +static void register_kick_tests(void) +{ + scx_test_register(&kick_immediate); + scx_test_register(&kick_lazy); + scx_test_register(&kick_coalesce); + scx_test_register(&kick_tick); + scx_test_register(&kick_invalid); +}
diff --git a/tools/testing/selftests/sched_ext/kick_test.h b/tools/testing/selftests/sched_ext/kick_test.h new file mode 100644 index 0000000..7d3c608 --- /dev/null +++ b/tools/testing/selftests/sched_ext/kick_test.h
@@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES */ +#ifndef __KICK_TEST_H__ +#define __KICK_TEST_H__ + +enum kick_scenario { + KICK_IMMEDIATE, + KICK_LAZY, + KICK_LAZY_THEN_IMMEDIATE, + KICK_IMMEDIATE_THEN_LAZY, + KICK_PLAIN_THEN_LAZY, + KICK_LAZY_THEN_PLAIN, + KICK_BOTH, + KICK_LAZY_WAIT, + ENQ_BOTH, + TICK_EXPIRY, + INVALID_KICK_IDLE, + INVALID_KICK_UNKNOWN, +}; + +enum kick_state { + KICK_STATE_IDLE, + KICK_STATE_ARMED, + KICK_STATE_QUEUED, + KICK_STATE_RESCHED, + KICK_STATE_DONE, +}; + +#endif /* __KICK_TEST_H__ */
diff --git a/tools/testing/selftests/sched_ext/maximal.bpf.c b/tools/testing/selftests/sched_ext/maximal.bpf.c index 04a3690..9ea664e 100644 --- a/tools/testing/selftests/sched_ext/maximal.bpf.c +++ b/tools/testing/selftests/sched_ext/maximal.bpf.c
@@ -14,6 +14,8 @@ char _license[] SEC("license") = "GPL"; #define DSQ_ID 0 +UEI_DEFINE(uei); + s32 BPF_STRUCT_OPS(maximal_select_cpu, struct task_struct *p, s32 prev_cpu, u64 wake_flags) { @@ -132,7 +134,9 @@ s32 BPF_STRUCT_OPS_SLEEPABLE(maximal_init) } void BPF_STRUCT_OPS(maximal_exit, struct scx_exit_info *info) -{} +{ + UEI_RECORD(uei, info); +} SEC(".struct_ops.link") struct sched_ext_ops maximal_ops = {
diff --git a/tools/testing/selftests/sched_ext/maximal.c b/tools/testing/selftests/sched_ext/maximal.c index 1dc3692..6c6b80e 100644 --- a/tools/testing/selftests/sched_ext/maximal.c +++ b/tools/testing/selftests/sched_ext/maximal.c
@@ -35,6 +35,8 @@ static enum scx_test_status run(void *ctx) link = bpf_map__attach_struct_ops(skel->maps.maximal_ops); SCX_FAIL_IF(!link, "Failed to attach scheduler"); + SCX_ASSERT_ALIVE(skel, uei); + bpf_link__destroy(link); return SCX_TEST_PASS;
diff --git a/tools/testing/selftests/sched_ext/nohz_tick.bpf.c b/tools/testing/selftests/sched_ext/nohz_tick.bpf.c index 6998c5dd..5fec567 100644 --- a/tools/testing/selftests/sched_ext/nohz_tick.bpf.c +++ b/tools/testing/selftests/sched_ext/nohz_tick.bpf.c
@@ -6,13 +6,22 @@ */ #include <scx/common.bpf.h> +#include "nohz_tick_test.h" + char _license[] SEC("license") = "GPL"; const volatile s32 test_cpu; -bool finite_phase; +u32 phase; +s32 victim_pid; +s32 challenger_pid; +s32 trigger_pid; u64 nr_inf_running; u64 nr_finite_running; u64 nr_finite_ticks; +u64 nr_lazy_victim_running; +u64 nr_lazy_enq_running; +u64 nr_lazy_kick_running; +u64 nr_lazy_ticks; UEI_DEFINE(uei); @@ -24,9 +33,31 @@ s32 BPF_STRUCT_OPS(nohz_tick_select_cpu, struct task_struct *p, s32 prev_cpu, void BPF_STRUCT_OPS(nohz_tick_enqueue, struct task_struct *p, u64 enq_flags) { - u64 slice = finite_phase ? 1000000ULL : SCX_SLICE_INF; + u64 slice; + u64 dsq_id = SCX_DSQ_GLOBAL; - scx_bpf_dsq_insert(p, SCX_DSQ_GLOBAL, slice, enq_flags); + switch (phase) { + case NOHZ_PHASE_INF: + slice = SCX_SLICE_INF; + break; + case NOHZ_PHASE_FINITE: + slice = 1000000ULL; + break; + case NOHZ_PHASE_LAZY_ENQ: + case NOHZ_PHASE_LAZY_KICK: + dsq_id = SCX_DSQ_LOCAL; + slice = p->pid == victim_pid ? SCX_SLICE_INF : SCX_SLICE_DFL; + if (phase == NOHZ_PHASE_LAZY_ENQ && p->pid == challenger_pid) + enq_flags |= SCX_ENQ_PREEMPT_LAZY; + break; + default: + slice = SCX_SLICE_DFL; + break; + } + + scx_bpf_dsq_insert(p, dsq_id, slice, enq_flags); + if (phase == NOHZ_PHASE_LAZY_KICK && p->pid == trigger_pid) + scx_bpf_kick_cpu(test_cpu, SCX_KICK_PREEMPT_LAZY); if (enq_flags & SCX_ENQ_LAST) scx_bpf_kick_cpu(test_cpu, SCX_KICK_IDLE); } @@ -36,16 +67,28 @@ void BPF_STRUCT_OPS(nohz_tick_running, struct task_struct *p) if (bpf_get_smp_processor_id() != test_cpu) return; - if (finite_phase) + if (phase == NOHZ_PHASE_FINITE) __sync_fetch_and_add(&nr_finite_running, 1); - else + else if (phase == NOHZ_PHASE_INF) __sync_fetch_and_add(&nr_inf_running, 1); + else if (p->pid == victim_pid) + __sync_fetch_and_add(&nr_lazy_victim_running, 1); + else if (phase == NOHZ_PHASE_LAZY_ENQ && p->pid == challenger_pid) + __sync_fetch_and_add(&nr_lazy_enq_running, 1); + else if (phase == NOHZ_PHASE_LAZY_KICK && p->pid == challenger_pid) + __sync_fetch_and_add(&nr_lazy_kick_running, 1); } void BPF_STRUCT_OPS(nohz_tick_tick, struct task_struct *p) { - if (bpf_get_smp_processor_id() == test_cpu && finite_phase) + if (bpf_get_smp_processor_id() != test_cpu) + return; + + if (phase == NOHZ_PHASE_FINITE) __sync_fetch_and_add(&nr_finite_ticks, 1); + else if ((phase == NOHZ_PHASE_LAZY_ENQ || + phase == NOHZ_PHASE_LAZY_KICK) && p->pid == victim_pid) + __sync_fetch_and_add(&nr_lazy_ticks, 1); } void BPF_STRUCT_OPS(nohz_tick_exit, struct scx_exit_info *ei) @@ -61,5 +104,5 @@ struct sched_ext_ops nohz_tick_ops = { .tick = (void *)nohz_tick_tick, .exit = (void *)nohz_tick_exit, .name = "nohz_tick", - .timeout_ms = 1000U, + .timeout_ms = 5000U, };
diff --git a/tools/testing/selftests/sched_ext/nohz_tick.c b/tools/testing/selftests/sched_ext/nohz_tick.c index 028f543..e19a970 100644 --- a/tools/testing/selftests/sched_ext/nohz_tick.c +++ b/tools/testing/selftests/sched_ext/nohz_tick.c
@@ -21,19 +21,24 @@ #include <scx/common.h> #include "nohz_tick.bpf.skel.h" +#include "nohz_tick_test.h" #include "scx_test.h" +#include "util.h" #ifndef SCHED_EXT #define SCHED_EXT 7 #endif #define MIN_FINITE_TICKS 3 -#define PHASE_TIMEOUT_MS 1000 +#define PHASE_TIMEOUT_MS 5000 +#define TICK_STOP_STABLE_MS 100 struct nohz_tick_ctx { struct nohz_tick *skel; cpu_set_t original_mask; int test_cpu; + int housekeeping_cpu; + bool test_lazy; }; static int first_allowed_cpu(const cpu_set_t *mask, int first, int last) @@ -47,20 +52,21 @@ static int first_allowed_cpu(const cpu_set_t *mask, int first, int last) return -1; } -static int find_nohz_full_cpu(const cpu_set_t *allowed) +static int read_nohz_full_mask(cpu_set_t *mask) { char buf[4096], *cur, *end; FILE *file; + int ret = 0; file = fopen("/sys/devices/system/cpu/nohz_full", "r"); if (!file) - return -1; + return -errno; if (!fgets(buf, sizeof(buf), file)) { - fclose(file); - return -1; + ret = ferror(file) ? -errno : -EINVAL; + goto out; } - fclose(file); + CPU_ZERO(mask); cur = buf; while (*cur) { long first, last; @@ -73,25 +79,30 @@ static int find_nohz_full_cpu(const cpu_set_t *allowed) errno = 0; first = strtol(cur, &end, 10); - if (errno || end == cur || first < 0 || first >= CPU_SETSIZE) - return -1; + if (errno || end == cur || first < 0 || first >= CPU_SETSIZE) { + ret = -EINVAL; + goto out; + } cur = end; last = first; if (*cur == '-') { cur++; errno = 0; last = strtol(cur, &end, 10); - if (errno || end == cur || last < first) - return -1; + if (errno || end == cur || last < first) { + ret = -EINVAL; + goto out; + } cur = end; } - cpu = first_allowed_cpu(allowed, first, last); - if (cpu >= 0) - return cpu; + for (cpu = first; cpu <= last && cpu < CPU_SETSIZE; cpu++) + CPU_SET(cpu, mask); } - return -1; +out: + fclose(file); + return ret; } static pid_t start_worker(int cpu) @@ -146,24 +157,53 @@ static int pause_worker(pid_t pid) return 0; } -static bool wait_for_counter(const u64 *counter, u64 value, int timeout_ms) +static bool wait_for_counter(struct nohz_tick *skel, const u64 *counter, u64 value, + int timeout_ms) { int elapsed; for (elapsed = 0; elapsed < timeout_ms; elapsed++) { if (__atomic_load_n(counter, __ATOMIC_RELAXED) >= value) return true; + if (UEI_EXITED(skel, uei)) + return false; usleep(1000); } return false; } +static bool wait_for_tick_stop(struct nohz_tick *skel, const u64 *counter, int timeout_ms) +{ + u64 prev = __atomic_load_n(counter, __ATOMIC_RELAXED); + int elapsed, stable = 0; + + for (elapsed = 0; elapsed < timeout_ms; elapsed++) { + u64 curr; + + usleep(1000); + if (UEI_EXITED(skel, uei)) + return false; + curr = __atomic_load_n(counter, __ATOMIC_RELAXED); + if (curr == prev) { + if (++stable >= TICK_STOP_STABLE_MS) + return true; + } else { + prev = curr; + stable = 0; + } + } + + return false; +} + static enum scx_test_status setup(void **ctx_ptr) { struct nohz_tick_ctx *ctx; - cpu_set_t controller_mask; - int cpu; + cpu_set_t controller_mask, nohz_full_mask; + bool lazy_supported; + u64 enum_value, lazy_ops_flag; + int cpu, i, lazy_mode, ret; ctx = calloc(1, sizeof(*ctx)); SCX_FAIL_IF(!ctx, "Failed to allocate context"); @@ -173,15 +213,26 @@ static enum scx_test_status setup(void **ctx_ptr) SCX_FAIL("Failed to get affinity (%d)", errno); } - cpu = find_nohz_full_cpu(&ctx->original_mask); - if (cpu < 0) { + ret = read_nohz_full_mask(&nohz_full_mask); + if (ret) { + fprintf(stderr, "SKIP: failed to read NOHZ_FULL mask (%d)\n", ret); + free(ctx); + return SCX_TEST_SKIP; + } + + for (cpu = 0; cpu < CPU_SETSIZE; cpu++) + if (CPU_ISSET(cpu, &ctx->original_mask) && CPU_ISSET(cpu, &nohz_full_mask)) + break; + if (cpu == CPU_SETSIZE) { fprintf(stderr, "SKIP: no allowed NOHZ_FULL CPU\n"); free(ctx); return SCX_TEST_SKIP; } controller_mask = ctx->original_mask; - CPU_CLR(cpu, &controller_mask); + for (i = 0; i < CPU_SETSIZE; i++) + if (CPU_ISSET(i, &nohz_full_mask)) + CPU_CLR(i, &controller_mask); if (CPU_COUNT(&controller_mask) == 0) { fprintf(stderr, "SKIP: no housekeeping CPU available\n"); free(ctx); @@ -189,6 +240,21 @@ static enum scx_test_status setup(void **ctx_ptr) } ctx->test_cpu = cpu; + ctx->housekeeping_cpu = first_allowed_cpu(&controller_mask, 0, CPU_SETSIZE - 1); + lazy_supported = __COMPAT_read_enum("scx_enq_flags", "SCX_ENQ_PREEMPT_LAZY", + &enum_value) && + __COMPAT_read_enum("scx_kick_flags", "SCX_KICK_PREEMPT_LAZY", + &enum_value) && + __COMPAT_read_enum("scx_ops_flags", "SCX_OPS_LAZY_RESCHED", + &lazy_ops_flag); + lazy_mode = scx_test_preempt_lazy_mode(); + ctx->test_lazy = lazy_supported && lazy_mode > 0; + if (lazy_supported && lazy_mode < 0) + fprintf(stderr, + "SKIP: kernel preemption mode unavailable; skipping lazy NOHZ_FULL phases\n"); + else if (lazy_supported && !lazy_mode) + fprintf(stderr, + "SKIP: lazy preemption inactive; skipping lazy NOHZ_FULL phases\n"); ctx->skel = nohz_tick__open(); if (!ctx->skel) { free(ctx); @@ -199,6 +265,8 @@ static enum scx_test_status setup(void **ctx_ptr) ctx->skel->rodata->test_cpu = cpu; ctx->skel->struct_ops.nohz_tick_ops->flags |= SCX_OPS_SWITCH_PARTIAL | SCX_OPS_ENQ_LAST; + if (lazy_supported) + ctx->skel->struct_ops.nohz_tick_ops->flags |= lazy_ops_flag; if (nohz_tick__load(ctx->skel)) { nohz_tick__destroy(ctx->skel); free(ctx); @@ -220,11 +288,15 @@ static enum scx_test_status run(void *ctx_ptr) struct nohz_tick_ctx *ctx = ctx_ptr; struct nohz_tick *skel = ctx->skel; struct bpf_link *link = NULL; + struct scx_test_gated_worker victim = { .pid = -1, .start_fd = -1 }; + struct scx_test_gated_worker challenger = { .pid = -1, .start_fd = -1 }; + struct scx_test_gated_worker trigger = { .pid = -1, .start_fd = -1 }; enum scx_test_status status = SCX_TEST_FAIL; pid_t finite_worker = -1; pid_t inf_worker = -1; u64 finite_running; u64 finite_ticks; + u64 victim_running; int ret; link = bpf_map__attach_struct_ops(skel->maps.nohz_tick_ops); @@ -241,7 +313,7 @@ static enum scx_test_status run(void *ctx_ptr) SCX_ERR("Failed to start infinite-slice worker (%d)", errno); goto out; } - if (!wait_for_counter(&skel->bss->nr_inf_running, 1, + if (!wait_for_counter(skel, &skel->bss->nr_inf_running, 1, PHASE_TIMEOUT_MS)) { SCX_ERR("Infinite-slice worker was not scheduled"); goto out; @@ -260,18 +332,18 @@ static enum scx_test_status run(void *ctx_ptr) /* * The next EXT task receives a finite slice and must restart the tick. */ - __atomic_store_n(&skel->bss->finite_phase, true, __ATOMIC_RELEASE); + __atomic_store_n(&skel->bss->phase, NOHZ_PHASE_FINITE, __ATOMIC_RELEASE); finite_worker = start_worker(ctx->test_cpu); if (finite_worker < 0) { SCX_ERR("Failed to start finite-slice worker (%d)", errno); goto out; } - if (!wait_for_counter(&skel->bss->nr_finite_running, 1, + if (!wait_for_counter(skel, &skel->bss->nr_finite_running, 1, PHASE_TIMEOUT_MS)) { SCX_ERR("Finite-slice worker was not scheduled"); goto out; } - if (!wait_for_counter(&skel->bss->nr_finite_ticks, MIN_FINITE_TICKS, + if (!wait_for_counter(skel, &skel->bss->nr_finite_ticks, MIN_FINITE_TICKS, PHASE_TIMEOUT_MS)) { SCX_ERR("Finite-slice worker received only %llu scheduler ticks", (unsigned long long)skel->bss->nr_finite_ticks); @@ -295,12 +367,12 @@ static enum scx_test_status run(void *ctx_ptr) SCX_ERR("Failed to start second finite-slice worker (%d)", errno); goto out; } - if (!wait_for_counter(&skel->bss->nr_finite_running, + if (!wait_for_counter(skel, &skel->bss->nr_finite_running, finite_running + 1, PHASE_TIMEOUT_MS)) { SCX_ERR("Second finite-slice worker was not scheduled"); goto out; } - if (!wait_for_counter(&skel->bss->nr_finite_ticks, + if (!wait_for_counter(skel, &skel->bss->nr_finite_ticks, finite_ticks + MIN_FINITE_TICKS, PHASE_TIMEOUT_MS)) { SCX_ERR("Second finite-slice worker received only %llu scheduler ticks", @@ -308,8 +380,88 @@ static enum scx_test_status run(void *ctx_ptr) finite_ticks)); goto out; } + stop_worker(finite_worker); + finite_worker = -1; + stop_worker(inf_worker); + inf_worker = -1; + if (!ctx->test_lazy) + goto check_exit; - if (skel->data->uei.kind != EXIT_KIND(SCX_EXIT_NONE)) { + /* + * A lazy local enqueue must restart the tick after clearing the slice + * of an infinite-slice task on a full-dynticks CPU. + */ + __atomic_store_n(&skel->bss->phase, NOHZ_PHASE_LAZY_ENQ, __ATOMIC_RELEASE); + victim = scx_test_spawn_gated_worker(ctx->test_cpu, true); + challenger = scx_test_spawn_gated_worker(ctx->test_cpu, true); + if (victim.pid < 0 || challenger.pid < 0) { + SCX_ERR("Failed to spawn lazy-enqueue workers"); + goto out; + } + skel->bss->victim_pid = victim.pid; + skel->bss->challenger_pid = challenger.pid; + if (!scx_test_start_gated_worker(&victim) || + !wait_for_counter(skel, &skel->bss->nr_lazy_victim_running, 1, + PHASE_TIMEOUT_MS)) { + SCX_ERR("Lazy-enqueue victim was not scheduled"); + goto out; + } + if (!wait_for_tick_stop(skel, &skel->bss->nr_lazy_ticks, PHASE_TIMEOUT_MS)) { + SCX_ERR("Tick did not stop before lazy enqueue"); + goto out; + } + + if (!scx_test_start_gated_worker(&challenger) || + !wait_for_counter(skel, &skel->bss->nr_lazy_enq_running, 1, PHASE_TIMEOUT_MS)) { + SCX_ERR("Lazy enqueue made no progress on CPU %d", ctx->test_cpu); + goto out; + } + scx_test_stop_gated_worker(&victim); + scx_test_stop_gated_worker(&challenger); + + /* Repeat with a lazy kick delivered from a housekeeping CPU. */ + __atomic_store_n(&skel->bss->phase, NOHZ_PHASE_LAZY_KICK, __ATOMIC_RELEASE); + victim = scx_test_spawn_gated_worker(ctx->test_cpu, true); + challenger = scx_test_spawn_gated_worker(ctx->test_cpu, true); + trigger = scx_test_spawn_gated_worker(ctx->housekeeping_cpu, true); + if (victim.pid < 0 || challenger.pid < 0 || trigger.pid < 0) { + SCX_ERR("Failed to spawn lazy-kick workers"); + goto out; + } + skel->bss->victim_pid = victim.pid; + skel->bss->challenger_pid = challenger.pid; + skel->bss->trigger_pid = trigger.pid; + victim_running = __atomic_load_n(&skel->bss->nr_lazy_victim_running, + __ATOMIC_RELAXED); + if (!scx_test_start_gated_worker(&victim) || + !wait_for_counter(skel, &skel->bss->nr_lazy_victim_running, victim_running + 1, + PHASE_TIMEOUT_MS)) { + SCX_ERR("Lazy-kick victim was not scheduled"); + goto out; + } + if (!scx_test_start_gated_worker(&challenger)) { + SCX_ERR("Failed to start lazy-kick challenger"); + goto out; + } + if (!wait_for_tick_stop(skel, &skel->bss->nr_lazy_ticks, PHASE_TIMEOUT_MS)) { + SCX_ERR("Tick did not stop before lazy kick"); + goto out; + } + if (__atomic_load_n(&skel->bss->nr_lazy_kick_running, __ATOMIC_RELAXED)) { + SCX_ERR("Lazy-kick challenger ran before the kick"); + goto out; + } + if (!scx_test_start_gated_worker(&trigger) || + !wait_for_counter(skel, &skel->bss->nr_lazy_kick_running, 1, PHASE_TIMEOUT_MS)) { + SCX_ERR("Lazy kick made no progress on CPU %d", ctx->test_cpu); + goto out; + } + scx_test_stop_gated_worker(&trigger); + scx_test_stop_gated_worker(&victim); + scx_test_stop_gated_worker(&challenger); + +check_exit: + if (UEI_EXITED(skel, uei)) { SCX_ERR("Scheduler exited unexpectedly (kind=%llu code=%lld)", (unsigned long long)skel->data->uei.kind, (long long)skel->data->uei.exit_code); @@ -321,6 +473,9 @@ static enum scx_test_status run(void *ctx_ptr) (unsigned long long)skel->bss->nr_finite_ticks); status = SCX_TEST_PASS; out: + scx_test_stop_gated_worker(&trigger); + scx_test_stop_gated_worker(&victim); + scx_test_stop_gated_worker(&challenger); stop_worker(finite_worker); stop_worker(inf_worker); if (link)
diff --git a/tools/testing/selftests/sched_ext/nohz_tick_test.h b/tools/testing/selftests/sched_ext/nohz_tick_test.h new file mode 100644 index 0000000..b122d72 --- /dev/null +++ b/tools/testing/selftests/sched_ext/nohz_tick_test.h
@@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES */ +#ifndef __NOHZ_TICK_TEST_H__ +#define __NOHZ_TICK_TEST_H__ + +enum nohz_phase { + NOHZ_PHASE_INF, + NOHZ_PHASE_FINITE, + NOHZ_PHASE_LAZY_ENQ, + NOHZ_PHASE_LAZY_KICK, +}; + +#endif /* __NOHZ_TICK_TEST_H__ */
diff --git a/tools/testing/selftests/sched_ext/prog_run.c b/tools/testing/selftests/sched_ext/prog_run.c index 1129ec2..369c744 100644 --- a/tools/testing/selftests/sched_ext/prog_run.c +++ b/tools/testing/selftests/sched_ext/prog_run.c
@@ -55,8 +55,11 @@ static enum scx_test_status run(void *ctx) } /* Assumes uei.kind is written last */ - while (skel->data->uei.kind == EXIT_KIND(SCX_EXIT_NONE)) - sched_yield(); + if (!SCX_TIMED_WAIT_UEI(skel, uei, 10000)) { + SCX_ERR("Timed out waiting for scheduler to exit"); + status = SCX_TEST_FAIL; + goto out; + } if (skel->data->uei.kind != EXIT_KIND(SCX_EXIT_UNREG_BPF)) { SCX_ERR("Unexpected exit kind: %llu",
diff --git a/tools/testing/selftests/sched_ext/reload_loop.c b/tools/testing/selftests/sched_ext/reload_loop.c index 49297b8..7d8880f 100644 --- a/tools/testing/selftests/sched_ext/reload_loop.c +++ b/tools/testing/selftests/sched_ext/reload_loop.c
@@ -4,6 +4,7 @@ * Copyright (c) 2024 David Vernet <dvernet@meta.com> */ #include <bpf/bpf.h> +#include <errno.h> #include <pthread.h> #include <scx/common.h> #include <sys/wait.h> @@ -11,8 +12,14 @@ #include "maximal.bpf.skel.h" #include "scx_test.h" +enum { + RELOAD_ITERS = 1024, + RELOAD_THREADS = 2, +}; + static struct maximal *skel; -static pthread_t threads[2]; +static pthread_t threads[RELOAD_THREADS]; +static int unexpected_errno; bool force_exit = false; @@ -31,32 +38,58 @@ static enum scx_test_status setup(void **ctx) static void *do_reload_loop(void *arg) { - u32 i; + u32 i, failures = 0; - for (i = 0; i < 1024 && !force_exit; i++) { + for (i = 0; i < RELOAD_ITERS && !force_exit; i++) { struct bpf_link *link; + errno = 0; link = bpf_map__attach_struct_ops(skel->maps.maximal_ops); - if (link) - bpf_link__destroy(link); + if (!link) { + int e = errno; + + if (e != EBUSY) + __atomic_store_n(&unexpected_errno, e, + __ATOMIC_RELAXED); + failures++; + continue; + } + + bpf_link__destroy(link); } - return NULL; + return (void *)(unsigned long)failures; } static enum scx_test_status run(void *ctx) { - int err; + unsigned long failures[RELOAD_THREADS] = {}; + int err, i; void *ret; err = pthread_create(&threads[0], NULL, do_reload_loop, NULL); SCX_FAIL_IF(err, "Failed to create thread 0"); err = pthread_create(&threads[1], NULL, do_reload_loop, NULL); - SCX_FAIL_IF(err, "Failed to create thread 1"); + if (err) { + force_exit = true; + pthread_join(threads[0], NULL); + SCX_FAIL("Failed to create thread 1"); + } SCX_FAIL_IF(pthread_join(threads[0], &ret), "thread 0 failed"); + failures[0] = (unsigned long)ret; + SCX_FAIL_IF(pthread_join(threads[1], &ret), "thread 1 failed"); + failures[1] = (unsigned long)ret; + + SCX_FAIL_IF(unexpected_errno, "unexpected attach errno %d", + unexpected_errno); + + for (i = 0; i < RELOAD_THREADS; i++) + SCX_FAIL_IF(failures[i] == RELOAD_ITERS, + "thread %d: every attach failed (%lu EBUSY)", + i, failures[i]); return SCX_TEST_PASS; }
diff --git a/tools/testing/selftests/sched_ext/rt_stall.c b/tools/testing/selftests/sched_ext/rt_stall.c index a5041fc2..a1552b3 100644 --- a/tools/testing/selftests/sched_ext/rt_stall.c +++ b/tools/testing/selftests/sched_ext/rt_stall.c
@@ -17,7 +17,6 @@ #include <scx/common.h> #include "rt_stall.bpf.skel.h" #include "scx_test.h" -#include "../kselftest.h" #define CORE_ID 0 /* CPU to pin tasks to */ #define RUN_TIME 5 /* How long to run the test in seconds */ @@ -35,15 +34,17 @@ static void signal_ready(int fd) } /* Wait for a child to signal readiness via a pipe */ -static void wait_ready(int fd) +static bool wait_ready(int fd) { + bool ready; char c; - if (read(fd, &c, 1) != 1) { + ready = read(fd, &c, 1) == 1; + if (!ready) perror("read from ready pipe"); - exit(EXIT_FAILURE); - } close(fd); + + return ready; } /* Simple busy-wait function for test tasks */ @@ -151,13 +152,11 @@ static bool sched_stress_test(bool is_ext) float ext_runtime, rt_runtime, actual_ratio; int ext_pid, rt_pid; int ext_ready[2], rt_ready[2]; - - ksft_print_header(); - ksft_set_plan(1); + bool ret = false; if (pipe(ext_ready) || pipe(rt_ready)) { perror("pipe"); - ksft_exit_fail(); + return false; } /* Create and set up a EXT task */ @@ -172,7 +171,7 @@ static bool sched_stress_test(bool is_ext) exit(0); } else if (ext_pid < 0) { perror("fork task"); - ksft_exit_fail(); + return false; } /* Create an RT task */ @@ -188,7 +187,7 @@ static bool sched_stress_test(bool is_ext) exit(0); } else if (rt_pid < 0) { perror("fork for RT task"); - ksft_exit_fail(); + goto out_kill_ext; } /* @@ -199,45 +198,47 @@ static bool sched_stress_test(bool is_ext) */ close(ext_ready[1]); close(rt_ready[1]); - wait_ready(ext_ready[0]); - wait_ready(rt_ready[0]); + if (!wait_ready(ext_ready[0]) || !wait_ready(rt_ready[0])) + goto out_kill; /* Let the processes run for the specified time */ sleep(RUN_TIME); /* Get runtime for the EXT task */ ext_runtime = get_process_runtime(ext_pid); - if (ext_runtime == -1) - ksft_exit_fail_msg("Error getting runtime for %s task (PID %d)\n", - class_str, ext_pid); - ksft_print_msg("Runtime of %s task (PID %d) is %f seconds\n", - class_str, ext_pid, ext_runtime); + if (ext_runtime == -1) { + fprintf(stderr, "Failed to read %s task runtime\n", class_str); + goto out_kill; + } /* Get runtime for the RT task */ rt_runtime = get_process_runtime(rt_pid); - if (rt_runtime == -1) - ksft_exit_fail_msg("Error getting runtime for RT task (PID %d)\n", rt_pid); - ksft_print_msg("Runtime of RT task (PID %d) is %f seconds\n", rt_pid, rt_runtime); - - /* Kill the processes */ - kill(ext_pid, SIGKILL); - kill(rt_pid, SIGKILL); - waitpid(ext_pid, NULL, 0); - waitpid(rt_pid, NULL, 0); + if (rt_runtime == -1) { + fprintf(stderr, "Failed to read RT task runtime\n"); + goto out_kill; + } /* Verify that the scx task got enough runtime */ actual_ratio = ext_runtime / (ext_runtime + rt_runtime); - ksft_print_msg("%s task got %.2f%% of total runtime\n", - class_str, actual_ratio * 100); + fprintf(stderr, "%s task ran %.3fs, RT task ran %.3fs (%.2f%% of runtime)\n", + class_str, ext_runtime, rt_runtime, actual_ratio * 100); - if (actual_ratio >= expected_min_ratio) { - ksft_test_result_pass("PASS: %s task got more than %.2f%% of runtime\n", - class_str, expected_min_ratio * 100); - return true; + if (actual_ratio < expected_min_ratio) { + fprintf(stderr, "%s task got less than %.2f%% of runtime\n", + class_str, expected_min_ratio * 100); + goto out_kill; } - ksft_test_result_fail("FAIL: %s task got less than %.2f%% of runtime\n", - class_str, expected_min_ratio * 100); - return false; + + ret = true; + +out_kill: + kill(rt_pid, SIGKILL); + waitpid(rt_pid, NULL, 0); +out_kill_ext: + kill(ext_pid, SIGKILL); + waitpid(ext_pid, NULL, 0); + + return ret; } static enum scx_test_status run(void *ctx) @@ -263,14 +264,17 @@ static enum scx_test_status run(void *ctx) link = bpf_map__attach_struct_ops(skel->maps.rt_stall_ops); SCX_FAIL_IF(!link, "Failed to attach scheduler"); } + res = sched_stress_test(is_ext); + if (is_ext) { - SCX_EQ(skel->data->uei.kind, EXIT_KIND(SCX_EXIT_NONE)); + int exit_kind = skel->data->uei.kind; bpf_link__destroy(link); + SCX_EQ(exit_kind, EXIT_KIND(SCX_EXIT_NONE)); } if (!res) - ksft_exit_fail(); + return SCX_TEST_FAIL; } return SCX_TEST_PASS;
diff --git a/tools/testing/selftests/sched_ext/runner.c b/tools/testing/selftests/sched_ext/runner.c index c264807..57dda75 100644 --- a/tools/testing/selftests/sched_ext/runner.c +++ b/tools/testing/selftests/sched_ext/runner.c
@@ -243,7 +243,7 @@ int main(int argc, char **argv) printf(" - %s\n", failed_tests[i]); } - return failed > 0 ? 1 : 0; + return failed > 0 || exit_req ? 1 : 0; } void scx_test_register(struct scx_test *test)
diff --git a/tools/testing/selftests/sched_ext/scx_test.h b/tools/testing/selftests/sched_ext/scx_test.h index 90b8d69..8490b01 100644 --- a/tools/testing/selftests/sched_ext/scx_test.h +++ b/tools/testing/selftests/sched_ext/scx_test.h
@@ -18,8 +18,6 @@ enum scx_test_status { SCX_TEST_FAIL, }; -#define EXIT_KIND(__ent) __COMPAT_ENUM_OR_ZERO("scx_exit_kind", #__ent) - struct scx_test { /** * name - The name of the testcase. @@ -110,6 +108,41 @@ void scx_test_register(struct scx_test *test); #define SCX_ASSERT(_x) SCX_FAIL_IF(!(_x), "Expected %s to be true (%lu)", \ #_x, (u64)(_x)) +/* + * SCX_ASSERT_ALIVE - Fail the test if the scheduler under test exited + * on its own between attach and this check, e.g. from a runtime error. + * A scheduler that dies mid-test freezes whatever state the test is + * about to assert on, which can make the assertions pass vacuously. + * uei.msg carries the actual error text, so print it alongside the + * recorded kind and exit code. + */ +#define SCX_ASSERT_ALIVE(__skel, __uei) \ + do { \ + if (UEI_EXITED(__skel, __uei)) \ + SCX_FAIL("Scheduler exited unexpectedly" \ + " (kind=%llu code=%lld msg='%s')", \ + (unsigned long long)(__skel)->data->__uei.kind, \ + (long long)(__skel)->data->__uei.exit_code, \ + (__skel)->data->__uei.msg); \ + } while (0) + +/* + * SCX_TIMED_WAIT_UEI - Wait for the scheduler under test to exit, i.e. + * its uei to be filled in, for up to @__ms iterations at ~1ms each. + * Returns true if the scheduler exited and false on timeout, so a + * scheduler that never exits fails the test instead of hanging it. + * The bound is iteration-based rather than wall-clock and stretches + * on a loaded system instead of failing early. + */ +#define SCX_TIMED_WAIT_UEI(__skel, __uei, __ms) \ + ({ \ + s64 __left = (__ms); \ + \ + while (__left-- > 0 && !UEI_EXITED(__skel, __uei)) \ + usleep(1000); \ + UEI_EXITED(__skel, __uei) != 0; \ + }) + #define SCX_ECODE_VAL(__ecode) ({ \ u64 __val = 0; \ bool __found = false; \ @@ -119,13 +152,25 @@ void scx_test_register(struct scx_test *test); (s64)__val; \ }) +/* + * SCX_KIND_VAL - Resolve an scx_exit_kind enumerator from kernel BTF. + * + * Unlike __COMPAT_ENUM_OR_ZERO(), a missing enumerator fails the test + * loudly instead of silently resolving to 0 (== SCX_EXIT_NONE), which + * would make the comparison vacuous. + */ #define SCX_KIND_VAL(__kind) ({ \ - u64 __val = 0; \ - bool __found = false; \ + u64 __val = 0; \ \ - __found = __COMPAT_read_enum("scx_exit_kind", #__kind, &__val); \ - SCX_ASSERT(__found); \ + if (!__COMPAT_read_enum("scx_exit_kind", #__kind, &__val)) \ + SCX_FAIL("scx_exit_kind.%s not found in kernel BTF", #__kind); \ __val; \ }) +/* + * EXIT_KIND - Alias of SCX_KIND_VAL() for resolving scx_exit_kind + * enumerator values, kept for readability at the EXIT_KIND() call sites. + */ +#define EXIT_KIND(__ent) SCX_KIND_VAL(__ent) + #endif // # __SCX_TEST_H__
diff --git a/tools/testing/selftests/sched_ext/test_modules/Makefile b/tools/testing/selftests/sched_ext/test_modules/Makefile new file mode 100644 index 0000000..a0e9e94 --- /dev/null +++ b/tools/testing/selftests/sched_ext/test_modules/Makefile
@@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0 +# Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES + +TESTMODS_DIR := $(realpath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))) +KDIR ?= $(if $(O),$(O),$(realpath ../../../../..)) + +obj-m += scx_enq_blocked_test.o + +all: + +$(Q)$(MAKE) -C $(KDIR) M=$(TESTMODS_DIR) modules + +clean: + +$(Q)$(MAKE) -C $(KDIR) M=$(TESTMODS_DIR) clean
diff --git a/tools/testing/selftests/sched_ext/test_modules/scx_enq_blocked_test.c b/tools/testing/selftests/sched_ext/test_modules/scx_enq_blocked_test.c new file mode 100644 index 0000000..908689e --- /dev/null +++ b/tools/testing/selftests/sched_ext/test_modules/scx_enq_blocked_test.c
@@ -0,0 +1,195 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES + * + * Kernel mutex fixture for the sched_ext SCX_OPS_ENQ_BLOCKED selftest. + */ + +#include <linux/atomic.h> +#include <linux/fs.h> +#include <linux/jiffies.h> +#include <linux/ktime.h> +#include <linux/miscdevice.h> +#include <linux/module.h> +#include <linux/mutex.h> +#include <linux/sched.h> +#include <linux/uaccess.h> + +#include "../enq_blocked.h" + +#define DONOR_WAIT_TIMEOUT msecs_to_jiffies(2000) +#define ATTACH_WAIT_TIMEOUT msecs_to_jiffies(10000) +#define MUTEX_HOLD_TIME msecs_to_jiffies(200) + +static DEFINE_MUTEX(test_mutex); +static DEFINE_SPINLOCK(donor_lock); +static struct task_struct *donor_task; +static atomic_t owner_ready = ATOMIC_INIT(0); +static atomic_t donor_started = ATOMIC_INIT(0); +static atomic_t attach_pending = ATOMIC_INIT(0); +static atomic_t attach_done = ATOMIC_INIT(0); +static atomic64_t hold_time_ns = ATOMIC64_INIT(0); +static atomic64_t wait_time_ns = ATOMIC64_INIT(0); +static atomic64_t nr_holds = ATOMIC64_INIT(0); +static atomic64_t nr_waits = ATOMIC64_INIT(0); + +static long run_owner(void) +{ + unsigned long timeout; + u64 start_ns; + long ret = 0; + + atomic_set(&donor_started, 0); + mutex_lock(&test_mutex); + start_ns = ktime_get_ns(); + atomic_set(&owner_ready, 1); + + timeout = jiffies + DONOR_WAIT_TIMEOUT; + while (!atomic_read(&donor_started)) { + if (time_after(jiffies, timeout)) { + ret = -ETIMEDOUT; + goto out; + } + cond_resched(); + } + if (atomic_xchg(&attach_pending, 0)) { + timeout = jiffies + ATTACH_WAIT_TIMEOUT; + while (!atomic_read(&attach_done)) { + if (time_after(jiffies, timeout)) { + ret = -ETIMEDOUT; + goto out; + } + cond_resched(); + } + } + + /* Keep yielding while the donor blocks on test_mutex. */ + timeout = jiffies + MUTEX_HOLD_TIME; + while (time_before(jiffies, timeout)) + cond_resched(); + +out: + atomic_set(&owner_ready, 0); + atomic64_add(ktime_get_ns() - start_ns, &hold_time_ns); + atomic64_inc(&nr_holds); + mutex_unlock(&test_mutex); + return ret; +} + +static long run_donor(void) +{ + unsigned long flags; + u64 start_ns; + + if (!atomic_read(&owner_ready)) + return -EAGAIN; + + get_task_struct(current); + spin_lock_irqsave(&donor_lock, flags); + WARN_ON_ONCE(donor_task); + donor_task = current; + spin_unlock_irqrestore(&donor_lock, flags); + + atomic_set(&donor_started, 1); + start_ns = ktime_get_ns(); + mutex_lock(&test_mutex); + + spin_lock_irqsave(&donor_lock, flags); + donor_task = NULL; + spin_unlock_irqrestore(&donor_lock, flags); + put_task_struct(current); + + atomic64_add(ktime_get_ns() - start_ns, &wait_time_ns); + atomic64_inc(&nr_waits); + mutex_unlock(&test_mutex); + return 0; +} + +static long get_donor_state(void) +{ + struct task_struct *task; + unsigned long flags; + long state = 0; + + spin_lock_irqsave(&donor_lock, flags); + task = donor_task; + if (task) + get_task_struct(task); + spin_unlock_irqrestore(&donor_lock, flags); + if (!task) + return -ENOENT; + + if (READ_ONCE(task->__state) != TASK_RUNNING) + state |= ENQ_BLOCKED_DONOR_SLEEPING; + if (READ_ONCE(task->on_rq)) + state |= ENQ_BLOCKED_DONOR_ON_RQ; + put_task_struct(task); + return state; +} + +static void reset_stats(void) +{ + atomic64_set(&hold_time_ns, 0); + atomic64_set(&wait_time_ns, 0); + atomic64_set(&nr_holds, 0); + atomic64_set(&nr_waits, 0); +} + +static long get_stats(unsigned long arg) +{ + struct enq_blocked_stats stats = { + .hold_time_ns = atomic64_read(&hold_time_ns), + .wait_time_ns = atomic64_read(&wait_time_ns), + .nr_holds = atomic64_read(&nr_holds), + .nr_waits = atomic64_read(&nr_waits), + }; + + return copy_to_user((void __user *)arg, &stats, sizeof(stats)) ? + -EFAULT : 0; +} + +static long enq_blocked_ioctl(struct file *file, unsigned int cmd, + unsigned long arg) +{ + switch (cmd) { + case ENQ_BLOCKED_IOCTL_OWNER: + return run_owner(); + case ENQ_BLOCKED_IOCTL_DONOR: + return run_donor(); + case ENQ_BLOCKED_IOCTL_RESET_STATS: + reset_stats(); + return 0; + case ENQ_BLOCKED_IOCTL_GET_STATS: + return get_stats(arg); + case ENQ_BLOCKED_IOCTL_PREP_ATTACH: + atomic_set(&attach_done, 0); + atomic_set(&attach_pending, 1); + return 0; + case ENQ_BLOCKED_IOCTL_ATTACH_DONE: + atomic_set(&attach_done, 1); + return 0; + case ENQ_BLOCKED_IOCTL_DONOR_STATE: + return get_donor_state(); + case ENQ_BLOCKED_IOCTL_PROXY_SUPPORTED: + return IS_ENABLED(CONFIG_SCHED_PROXY_EXEC); + default: + return -EINVAL; + } +} + +static const struct file_operations enq_blocked_fops = { + .owner = THIS_MODULE, + .unlocked_ioctl = enq_blocked_ioctl, +}; + +static struct miscdevice enq_blocked_device = { + .minor = MISC_DYNAMIC_MINOR, + .name = "scx_enq_blocked", + .fops = &enq_blocked_fops, + .mode = 0600, +}; + +module_misc_device(enq_blocked_device); +MODULE_AUTHOR("Andrea Righi <arighi@nvidia.com>"); +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("sched_ext blocked donor test module");
diff --git a/tools/testing/selftests/sched_ext/util.c b/tools/testing/selftests/sched_ext/util.c index 2111329..c93fc5d 100644 --- a/tools/testing/selftests/sched_ext/util.c +++ b/tools/testing/selftests/sched_ext/util.c
@@ -5,10 +5,21 @@ */ #include <errno.h> #include <fcntl.h> +#include <sched.h> +#include <signal.h> #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/prctl.h> +#include <sys/wait.h> #include <unistd.h> +#include <zlib.h> + +#include "util.h" + +#ifndef SCHED_EXT +#define SCHED_EXT 7 +#endif /* Returns read len on success, or -errno on failure. */ static ssize_t read_text(const char *path, char *buf, size_t max_len) @@ -69,3 +80,135 @@ int file_write_long(const char *path, long val) return 0; } + +struct scx_test_gated_worker scx_test_spawn_gated_worker(int cpu, bool set_sched_ext) +{ + struct scx_test_gated_worker worker = { .pid = -1, .start_fd = -1 }; + int ready[2], start[2]; + pid_t parent = getpid(); + char byte = 1; + + if (pipe(ready)) + return worker; + if (pipe(start)) { + close(ready[0]); + close(ready[1]); + return worker; + } + + worker.pid = fork(); + if (!worker.pid) { + struct sched_param param = {}; + cpu_set_t mask; + + close(ready[0]); + close(start[1]); + if (prctl(PR_SET_PDEATHSIG, SIGKILL) || getppid() != parent) + _exit(1); + CPU_ZERO(&mask); + CPU_SET(cpu, &mask); + if (sched_setaffinity(0, sizeof(mask), &mask)) + _exit(1); + if (set_sched_ext && sched_setscheduler(0, SCHED_EXT, ¶m)) + _exit(1); + if (write(ready[1], &byte, 1) != 1) + _exit(1); + close(ready[1]); + if (read(start[0], &byte, 1) != 1) + _exit(1); + close(start[0]); + for (;;) + asm volatile("" ::: "memory"); + } + if (worker.pid < 0) { + close(ready[0]); + close(ready[1]); + close(start[0]); + close(start[1]); + return worker; + } + + close(ready[1]); + close(start[0]); + if (read(ready[0], &byte, 1) != 1) { + close(ready[0]); + close(start[1]); + kill(worker.pid, SIGKILL); + waitpid(worker.pid, NULL, 0); + worker.pid = -1; + return worker; + } + close(ready[0]); + worker.start_fd = start[1]; + return worker; +} + +bool scx_test_start_gated_worker(struct scx_test_gated_worker *worker) +{ + char byte = 1; + + if (write(worker->start_fd, &byte, 1) != 1) + return false; + close(worker->start_fd); + worker->start_fd = -1; + return true; +} + +void scx_test_stop_gated_worker(struct scx_test_gated_worker *worker) +{ + if (worker->start_fd >= 0) + close(worker->start_fd); + if (worker->pid > 0) { + kill(worker->pid, SIGKILL); + waitpid(worker->pid, NULL, 0); + } + worker->pid = -1; + worker->start_fd = -1; +} + +static int config_preempt_lazy_mode(void) +{ + bool dynamic = false, lazy = false, immediate = false; + char buf[128]; + gzFile file; + + file = gzopen("/proc/config.gz", "r"); + if (!file) + return -1; + + while (gzgets(file, buf, sizeof(buf))) { + if (!strcmp(buf, "CONFIG_PREEMPT_DYNAMIC=y\n")) + dynamic = true; + else if (!strcmp(buf, "CONFIG_PREEMPT_LAZY=y\n")) + lazy = true; + else if (!strcmp(buf, "CONFIG_PREEMPT_NONE=y\n") || + !strcmp(buf, "CONFIG_PREEMPT_VOLUNTARY=y\n") || + !strcmp(buf, "CONFIG_PREEMPT=y\n") || + !strcmp(buf, "CONFIG_PREEMPT_RT=y\n")) + immediate = true; + } + gzclose(file); + + if (dynamic) + return -1; + if (lazy) + return 1; + if (immediate) + return 0; + return -1; +} + +int scx_test_preempt_lazy_mode(void) +{ + char buf[128]; + + if (read_text("/sys/kernel/debug/sched/preempt", buf, sizeof(buf)) > 0) { + if (strstr(buf, "(lazy)")) + return 1; + if (strstr(buf, "(none)") || strstr(buf, "(voluntary)") || + strstr(buf, "(full)")) + return 0; + } + + return config_preempt_lazy_mode(); +}
diff --git a/tools/testing/selftests/sched_ext/util.h b/tools/testing/selftests/sched_ext/util.h index 681cec0..aac34fc 100644 --- a/tools/testing/selftests/sched_ext/util.h +++ b/tools/testing/selftests/sched_ext/util.h
@@ -7,7 +7,19 @@ #ifndef __SCX_TEST_UTIL_H__ #define __SCX_TEST_UTIL_H__ +#include <stdbool.h> +#include <sys/types.h> + +struct scx_test_gated_worker { + pid_t pid; + int start_fd; +}; + long file_read_long(const char *path); int file_write_long(const char *path, long val); +struct scx_test_gated_worker scx_test_spawn_gated_worker(int cpu, bool set_sched_ext); +bool scx_test_start_gated_worker(struct scx_test_gated_worker *worker); +void scx_test_stop_gated_worker(struct scx_test_gated_worker *worker); +int scx_test_preempt_lazy_mode(void); #endif // __SCX_TEST_UTIL_H__